def __build_accounting_blueprints_nested( __item_id, sde_type_ids, sde_market_groups, eve_market_prices_data, corp_assets_tree, corp_assets_data, corp_accounting_stat, __ca1_region, __ca3_station): __ca5_station_flag = __cas1_stat_flag = None __tree_dict = corp_assets_tree[str(__item_id)] __item_dict = corp_assets_data[int(__tree_dict["index"])] __type_id = int(__item_dict["type_id"]) __quantity = int(__item_dict["quantity"]) # __location_flag = __item_dict["location_flag"] __group_id = eve_sde_tools.get_basis_market_group_by_type_id(sde_type_ids, sde_market_groups, __type_id) if not (__group_id is None) and (__group_id == 2): # Blueprints and Reactions (добавляем только этот тип) # регистрируем регион и станцию, на которой обнаружены blueprint if __ca5_station_flag is None: __location_flag = "BlueprintsReactions" __ca5_station_flag, __cas1_stat_flag = __build_accounting_register_flag( __location_flag, __ca1_region, __ca3_station, corp_accounting_stat) __cas1_stat_flag.update({"omit_in_summary": True}) # определяем, является ли чертёж БПО или БПЦ? (для БПО предпочтительная цена : base_price, для БПЦ : average_price и adjusted_price) __is_blueprint_copy = ("is_blueprint_copy" in __item_dict) and bool(__item_dict["is_blueprint_copy"]) __build_accounting_append( __type_id, __quantity, __group_id, sde_market_groups[str(__group_id)]["nameID"]["en"], sde_market_groups[str(__group_id)]["iconID"] if "iconID" in sde_market_groups[str(__group_id)] else None, eve_market_prices_data, sde_type_ids, __cas1_stat_flag, __ca5_station_flag, None, # в статистику попадают все группы, но следующий фильтр ограничит... [2], # ...обработку только Blueprints and Reactions not __is_blueprint_copy, # признак использования base_price __is_blueprint_copy, # поправка: для БПЦ-чертежей любая цена от ЦЦП невалидна None, #TODO: номер ангара None) # это не Ship и не какая-то другая возможная вложенность if str(__item_id) in corp_assets_tree: __cat1 = corp_assets_tree[str(__item_id)] if "items" in __cat1: for __nested_item_id in __cat1["items"]: __build_accounting_blueprints_nested( __nested_item_id, sde_type_ids, sde_market_groups, eve_market_prices_data, corp_assets_tree, corp_assets_data, corp_accounting_stat, __ca1_region, __ca3_station)
def __build_contracts_stat( sde_type_ids, sde_market_groups, corp_contracts_data, corp_contract_items_data, various_characters_data): corp_sell_contracts = [] # в рамках работы с чертежами, нас интересует только набор контрактов, в которых продаются чертежи # ищем публичные контракты типа "обмен предметами" for __contract_items_dict in corp_contract_items_data: __contract_id_key = __contract_items_dict.keys() for __contract_id in __contract_id_key: __items = __contract_items_dict[str(__contract_id)] __is_it_ship = None for __items_dict in __items: # пропускаем отклонения от нормы, а также контракты на покупку, а не на продажу if not ("is_included" in __items_dict): continue elif not bool(__items_dict["is_included"]): continue __type_id = __items_dict["type_id"] __group_id = eve_sde_tools.get_basis_market_group_by_type_id(sde_type_ids, sde_market_groups, __type_id) if not (__group_id is None) and (__group_id == 4): # Ships (добавляем только этот тип) __type_desc = sde_type_ids[str(__type_id)] __is_it_ship = {"type_id": __type_id, "name": __type_desc["name"]["en"]} break # проверяем, найдены ли контракты на продажу кораблей? if not (__is_it_ship is None): # # получение общих данных данных по контракту __contract_dict = next((c for c in corp_contracts_data if c['contract_id'] == int(__contract_id)), None) # добавляем контракт в список для формирование отчёта по балансу __issuer_id = __contract_dict["issuer_id"] # пилот м.б. быть в списке с dict=None __issuer_name = various_characters_data.get(str(__issuer_id), {"name": "Deleted #"+str(__issuer_id)}).get("name") corp_sell_contracts.append({ "loc": __contract_dict["start_location_id"], "ship_type_id": __is_it_ship["type_id"], "ship_name": __is_it_ship["name"], "flag": __contract_dict["title"], "price": __contract_dict["price"], "volume": __contract_dict["volume"], "cntrct_sta": __contract_dict["status"], "cntrct_typ": __contract_dict["type"], "cntrct_issuer": __issuer_id, "cntrct_issuer_name": __issuer_name }) return corp_sell_contracts
def __group_blueprints_by_category(blueprints, sde_type_ids, sde_market_groups): blueprint_categories = [] for bp in enumerate(blueprints): __product_type_id = bp[1]["product_type_id"] __blueprint_name = bp[1]["name"] # проверяем список market-груп, которым принадлежит продукт и отбираем # базовый как самый информативный __market_group_id = eve_sde_tools.get_basis_market_group_by_type_id( sde_type_ids, sde_market_groups, __product_type_id) __category_dict = next((bc for bc in blueprint_categories if bc["id"] == __market_group_id), None) if __category_dict is None: __market_group_name = eve_sde_tools.get_market_group_name_by_id(sde_market_groups, __market_group_id) __category_dict = {"id": __market_group_id, "name": __market_group_name, "products": []} blueprint_categories.append(__category_dict) __category_dict["products"].append({"type_id": __product_type_id, "sort": __blueprint_name, "index": bp[0]}) # пересортировка всех списков, с тем, чтобы при выводе в отчёт они были по алфавиту blueprint_categories.sort(key=lambda bc: bc["name"]) for bc in blueprint_categories: bc["products"].sort(key=lambda bc: bc["sort"]) return blueprint_categories
def get_new_product_dict(container_id, hangar_dict, type_id: int, item_name: str, quantity: int): if isinstance(container_id, str): # ангар __available121 = 0 elif isinstance(container_id, int): # контейнер __available121 = sum([a["quantity"] for a in corp_assets_data if (a["type_id"] == type_id) and (a["location_id"] == container_id)]) else: __available121 = 0 __market123 = eve_sde_tools.get_basis_market_group_by_type_id(sde_type_ids, sde_market_groups, type_id) if not (hangar_dict is None): hangar_loc_id: int = int(hangar_dict["location_id"]) # это может быть, например, номер офиса на станции hangar_num: str = hangar_dict["location_flag"] # название в формате CorpSAG? __available121 += sum([a["quantity"] for a in corp_assets_data if (a["type_id"] == type_id) and (a["location_id"] == hangar_loc_id) and (a["location_flag"] == hangar_num)]) push_into_regroup_market_groups(__market123) return { "name": item_name, "quantity": quantity, "available": __available121, "market": __market123, }
def __dump_corp_capital( glf, # настройки генерации отчёта report_options, # sde данные, загруженные из .converted_xxx.json файлов sde_type_ids, sde_bp_materials, sde_market_groups, sde_icon_ids, # esi данные, загруженные с серверов CCP corp_assets_data, corp_industry_jobs_data, corp_blueprints_data, eve_market_prices_data): product_name = report_options["product"] blueprint_containter_ids = [c["id"] for c in report_options["blueprints"]] stock_containter_ids = [c['id'] for c in report_options["stock"]] stock_containter_flag_ids = [{ 'id': c['id'], 'flag': c['flag'] } for c in report_options['stock'] if 'flag' in c] enable_copy_to_clipboard = True __type_id = eve_sde_tools.get_type_id_by_item_name(sde_type_ids, product_name) if __type_id is None: return __capital_blueprint_type_id, __capital_blueprint_materials = eve_sde_tools.get_blueprint_type_id_by_product_id( __type_id, sde_bp_materials) __is_reaction_formula = eve_sde_tools.is_type_id_nested_into_market_group( __type_id, [1849], sde_type_ids, sde_market_groups) glf.write(""" <div class="container-fluid"> <div class="media"> <div class="media-left"> """) glf.write( ' <img class="media-object icn64" src="{src}" alt="{nm}">\n' ' </div>\n' ' <div class="media-body">\n' ' <h4 class="media-heading">{nm}</h4>\n' '<p>\n' 'EveUniversity {nm} wiki: <a href="https://wiki.eveuniversity.org/{nm}">https://wiki.eveuniversity.org/{nm}</a><br/>\n' 'EveMarketer {nm} tradings: <a href="https://evemarketer.com/types/{pid}">https://evemarketer.com/types/{pid}</a><br/>\n' 'EveMarketer {nm} Blueprint tradings: <a href="https://evemarketer.com/types/{bid}">https://evemarketer.com/types/{bid}</a><br/>\n' 'Adam4EVE {nm} manufacturing calculator: <a href="https://www.adam4eve.eu/manu_calc.php?typeID={bid}">https://www.adam4eve.eu/manu_calc.php?typeID={bid}</a><br/>\n' 'Adam4EVE {nm} price history: <a href="https://www.adam4eve.eu/commodity.php?typeID={pid}">https://www.adam4eve.eu/commodity.php?typeID={pid}</a><br/>\n' 'Adam4EVE {nm} Blueprint price history: <a href="https://www.adam4eve.eu/commodity.php?typeID={bid}">https://www.adam4eve.eu/commodity.php?typeID={bid}</a>\n' .format(nm=product_name, src=render_html.__get_img_src(__type_id, 64), pid=__type_id, bid=__capital_blueprint_type_id)) # создаём запись несуществующего пока чертежа __capital_blueprint_dict = { "cp": True, # блюпринт на титан - копия "qr": 1, "me": 0, "te": 0, "st": None, "id": None } for b in corp_blueprints_data: __type_id = int(b["type_id"]) if __capital_blueprint_type_id != __type_id: continue # __location_id = int(b["location_id"]) # if not (__location_id in blueprint_containter_ids): # continue if (__capital_blueprint_dict["me"] < b["material_efficiency"]) or ( __capital_blueprint_dict["id"] is None): __quantity = int(b["quantity"]) # A range of numbers with a minimum of -2 and no maximum value where -1 is an original and -2 is a copy. # It can be a positive integer if it is a stack of blueprint originals fresh from the market (e.g. no # activities performed on them yet). __is_blueprint_copy = __quantity == -2 __capital_blueprint_dict = { "cp": __is_blueprint_copy, "me": b["material_efficiency"], "te": b["time_efficiency"], "qr": b["runs"] if __is_blueprint_copy else (1 if __quantity == -1 else __quantity), "id": b["item_id"] } print('Found {} Blueprint: '.format(product_name), __capital_blueprint_dict) # __capital_is_blueprint_copy = __capital_blueprint_dict["cp"] __capital_material_efficiency = __capital_blueprint_dict["me"] # __capital_time_efficiency = __capital_blueprint_dict["te"] # __capital_blueprint_status = __capital_blueprint_dict["st"] __capital_quantity_or_runs = __capital_blueprint_dict["qr"] glf.write(""" </p> </div> <!--media-body--> </div> <!--media--> <hr> <div class="media"> <div class="media-left"> """) glf.write( ' <img class="media-object icn64" src="{src}" alt="Summary raw materials">\n' .format(src=render_html.__get_icon_src( 1436, sde_icon_ids))) # Manufacture & Research glf.write(""" </div> <div class="media-body"> <h4 class="media-heading">Manufacturing materials</h4> """) for m in __capital_blueprint_materials["activities"]["manufacturing"][ "materials"]: bpmm_used = int(m["quantity"]) bpmm_tid = int(m["typeID"]) bpmm_tnm = eve_sde_tools.get_item_name_by_type_id( sde_type_ids, bpmm_tid) # вывод наименования ресурса glf.write('<span style="white-space:nowrap">' '<img class="icn24" src="{src}"> {q:,d} x {nm} ' '</span>\n'.format(src=render_html.__get_img_src( bpmm_tid, 32), q=bpmm_used, nm=bpmm_tnm)) glf.write(""" </div> <!--media-body--> </div> <!--media--> <hr> <div class="media"> <div class="media-left"> """) glf.write( '<img class="media-object icn64" src="{src}" alt="{nm} Components">\n'. format(src=render_html.__get_icon_src(2863, sde_icon_ids), nm=product_name)) # Standard Capital Ship Components glf.write(""" </div> <div class="media-body"> """) glf.write('<h4 class="media-heading">{nm} Components</h4>\n'.format( nm=product_name)) # Standard Capital Ship Components glf.write(""" <p><var>Efficiency</var> = <var>Required</var> * (100 - <var>material_efficiency</var> - 1 - 4.2) / 100,<br/> where <var>material_efficiency</var> for unknown and unavailable blueprint is 0.</p> <style> .table-borderless > tbody > tr > td, .table-borderless > tbody > tr > th, .table-borderless > tfoot > tr > td, .table-borderless > tfoot > tr > th, .table-borderless > thead > tr > td, .table-borderless > thead > tr > th { border: none; padding: 0px; } </style> <table class="table table-borderless table-condensed" style="font-size:small"> <thead> <tr> <th style="width:50px;">#</th> <th>Materials</th> <th>Available +<br/>In progress</th> <th>Standard</th> <th>Efficiency</th> <th>Required<br/>(Not enough)</th> </tr> </thead> <tbody> """) materials_summary = [] # debug = __capital_blueprint_materials["activities"]["manufacturing"]["materials"][:] # debug.append({"typeID": 11186, "quantity": 15}) # debug.append({"typeID": 41332, "quantity": 10}) blueprints_cache: typing.Dict[int, typing.Any] = {} assets_cache: typing.Dict[int, int] = {} industry_jobs_cache: typing.Dict[int, int] = {} __dump_blueprint_materials( glf, '', [], # сведения о чертеже, его материалах, эффективности и т.п. 1, __capital_blueprint_materials["activities"]["manufacturing"] ["materials"], __capital_material_efficiency, __is_reaction_formula, # ... # сводная статистика (формируется в процессе работы метода) materials_summary, blueprints_cache, assets_cache, industry_jobs_cache, # настройки генерации отчёта report_options, # параметры/настройки генерации отчёта blueprint_containter_ids, stock_containter_ids, stock_containter_flag_ids, # sde данные, загруженные из .converted_xxx.json файлов sde_type_ids, sde_bp_materials, sde_market_groups, # esi данные, загруженные с серверов CCP corp_assets_data, corp_industry_jobs_data, corp_blueprints_data) glf.write(""" </tbody> </table> </div> <!--media-body--> </div> <!--media--> <hr> <div class="media"> <div class="media-left"> """) glf.write( ' <img class="media-object icn64" src="{src}" alt="Summary raw materials">\n' .format( src=render_html.__get_icon_src(1201, sde_icon_ids))) # Materials glf.write(""" </div> <div class="media-body"> <h4 class="media-heading">Summary raw materials</h4> """) str_stock_cont_names = "" for st in report_options["stock"]: if str_stock_cont_names: str_stock_cont_names = str_stock_cont_names + ', ' str_stock_cont_names += '<mark>' + st.get('name', st.get('flag')) + '</mark>' if not str_stock_cont_names: str_stock_cont_names = '<mark></mark>' glf.write( '<p>The number of Minerals and Components is considered based on the presence of aseets in container(s) {}.</p>\n' .format(str_stock_cont_names)) # Materials str_bp_cont_names = "" for bp in report_options["blueprints"]: if str_bp_cont_names: str_bp_cont_names = str_bp_cont_names + ', ' str_bp_cont_names += '<mark>' + bp['name'] + '</mark>' if not str_bp_cont_names: str_bp_cont_names = '<mark></mark>' glf.write( '<p>The number of Blueprints is considered based on the presence of blueprints in container(s) {}.</p>\n' .format(str_bp_cont_names)) # Blueprints glf.write(""" <div class="table-responsive"> <table class="table table-condensed" style="font-size:small"> <thead> <tr> <th style="width:40px;">#</th> <th>Materials</th> <th>Exists +<br/>In progress</th> <th>Need<br/>(Efficiency)</th> <th>Progress, %</th> <th style="text-align:right;">Price per<br/>Unit, ISK</th> <th style="text-align:right;">Sum, ISK</th> <th style="text-align:right;">Volume, m³</th> </tr> </thead> <tbody> """) material_groups = {} # not_enough_materials = [] # stock_resources = [] # подсчёт кол-ва имеющихся в наличии материалов # составляем список тех материалов, у которых нет поля 'a', что говорит о том, что ассеты по # этим материалам не проверялись (в список они попали в результате анализа БП второго уровня) materials_summary_without_a = [ int(ms["id"]) for ms in materials_summary if not ("a" in ms) ] for a in corp_assets_data: __location_id = int(a["location_id"]) if not (__location_id in stock_containter_ids): continue __stock_flag_dict = next( (c for c in stock_containter_flag_ids if c['id'] == __location_id), None) if not (__stock_flag_dict is None): if not (__stock_flag_dict['flag'] == a['location_flag']): continue __type_id = int(a["type_id"]) if int(__type_id) in materials_summary_without_a: __summary_dict = next( (ms for ms in materials_summary if ms['id'] == __type_id), None) if __summary_dict is None: continue __quantity = int(a["quantity"]) if "a" in __summary_dict: __summary_dict["a"] += __quantity else: __summary_dict.update({"a": __quantity}) # получаем список работ, которые ведутся с материалами materials_summary_without_j = [ int(ms["id"]) for ms in materials_summary if not ("j" in ms) ] for j in corp_industry_jobs_data: __type_id = j["product_type_id"] if __type_id in materials_summary_without_j: __summary_dict = next( (ms for ms in materials_summary if ms['id'] == __type_id), None) if __summary_dict is None: continue __runs = int(j["runs"]) if "j" in __summary_dict: __summary_dict["j"] += __runs else: __summary_dict.update({"j": __runs}) # поиск групп, которым принадлежат материалы, которых не хватает для завершения производства по списку # чертежей в этом контейнере (планетарка отдельно, композиты отдельно, запуск работ отдельно) for __summary_dict in materials_summary: __quantity = __summary_dict["q"] __assets = __summary_dict["a"] if "a" in __summary_dict else 0 __blueprints = __summary_dict["b"] if "b" in __summary_dict else [] __in_progress = __summary_dict["j"] if "j" in __summary_dict else 0 __products_available_and_in_progress = __summary_dict.get("ajp", 0) __type_id = __summary_dict["id"] __item_name = __summary_dict["nm"] # --- __quantity -= __products_available_and_in_progress if __quantity < 0: __quantity = 0 # --- __market_group = eve_sde_tools.get_basis_market_group_by_type_id( sde_type_ids, sde_market_groups, __type_id) __material_dict = { "id": __type_id, "q": __quantity, "nm": __item_name, "a": __assets, "b": __blueprints, "j": __in_progress } if str(__market_group) in material_groups: material_groups[str(__market_group)].append(__material_dict) else: material_groups.update({str(__market_group): [__material_dict]}) # добавление чертежа на корабль в список требуемых материалов # Vanquisher Blueprint не имеет marketGroupID, что является ошибкой ССР, и поэтому приходится изгаляться... __capital_blueprint = { "id": __capital_blueprint_type_id, "q": __capital_quantity_or_runs, "nm": eve_sde_tools.get_item_name_by_type_id(sde_type_ids, __capital_blueprint_type_id), "a": 0, "b": [__capital_blueprint_dict] if not (__capital_blueprint_dict["id"] is None) else [], "j": 0 } # не показываем, что строим титан materials_summary.append(__capital_blueprint) material_groups["2"].append(__capital_blueprint) # Blueprints & Reactions # вывод окончательного summary-списка материалов для постройки по чертежу ms_groups = material_groups.keys() row3_num = 0 for __group_id in ms_groups: __is_blueprints_group = __group_id == "2" # Blueprints & Reactions __mg1 = material_groups[__group_id] if (__group_id == "None") or (int(__group_id) == 1857): # Minerals __mg1.sort(key=lambda m: m["q"], reverse=True) else: __mg1.sort(key=lambda m: m["q"]) # выводим название группы материалов (Ship Equipment, Materials, Components, ...) if __group_id == "None": __group_name = "" else: __group_name = sde_market_groups[__group_id]["nameID"]["en"] # подготовка элементов управления копирования данных в clipboard __copy2clpbrd = '' if not enable_copy_to_clipboard else \ ' <a data-target="#" role="button" class="qind-copy-btn"' \ ' data-toggle="tooltip"><button type="button" class="btn btn-default btn-xs"><span' \ ' class="glyphicon glyphicon-copy" aria-hidden="true"></span> Export to multibuy</button></a>' glf.write( '<tr>\n' ' <td class="active" colspan="8"><strong>{nm}</strong><!--{id}-->{clbrd}</td>\n' '</tr>'.format(nm=__group_name, id=__group_id, clbrd=__copy2clpbrd)) # вывод материалов в группе __summary_cost = 0 __summary_volume = 0 for __material_dict in __mg1: # получение данных по материалу bpmm3_tid = __material_dict["id"] bpmm3_tnm = __material_dict["nm"] bpmm3_q = __material_dict[ "q"] # quantity (required, not available yet) bpmm3_a = __material_dict["a"] # available in assets bpmm3_b = __material_dict["b"] # blueprints list bpmm3_j = __material_dict["j"] # in progress (runs of jobs) row3_num = row3_num + 1 # получение справочной информации о материале __type_dict = sde_type_ids[str(bpmm3_tid)] # получение цены материала bpmm3_price = None if not __is_blueprints_group: __price_dict = next((p for p in eve_market_prices_data if p['type_id'] == int(bpmm3_tid)), None) if not (__price_dict is None): if "average_price" in __price_dict: bpmm3_price = __price_dict["average_price"] elif "adjusted_price" in __price_dict: bpmm3_price = __price_dict["adjusted_price"] elif "basePrice" in __type_dict: bpmm3_price = __type_dict["basePrice"] elif "basePrice" in __type_dict: bpmm3_price = __type_dict["basePrice"] # получение информации о кол-ве материала (сперва по блюпринтам, потом по ассетам) me_te_tags_list = [] me_te_tags = "" if not __is_blueprints_group: bpmm3_available = bpmm3_a else: bpmm3_available = 0 for b in bpmm3_b: if not bool(b["cp"]): # найден оригинал, это значит что можно произвести ∞ кол-во материалов bpmm3_available = -1 if bpmm3_available >= 0: bpmm3_available += int(b["qr"]) # составляем тэги с информацией о me/te чертежей __me_te = '{me} {te}'.format(me=b["me"], te=b["te"]) if not (__me_te in me_te_tags_list): me_te_tags += ' <span class="label label-success">{}</span>'.format( __me_te) me_te_tags_list.append(__me_te) # расчёт прогресса выполнения (постройки, сбора) материалов (bpmm3_j пропускаем, т.к. они не готовы ещё) if bpmm3_available >= bpmm3_q: bpmm3_progress = 100 elif bpmm3_q == 0: bpmm3_progress = 100 else: bpmm3_progress = float(100 * bpmm3_available / bpmm3_q) # вывод наименования ресурса glf.write( '<tr>\n' ' <th scope="row">{num}</th>\n' ' <td data-copy="{nm}"><img class="icn24" src="{src}"> {nm}{me_te}</td>\n' ' <td>{qa}{qip}</td>\n' ' <td quantity="{qneed}">{qr:,d}</td>\n' ' <td><div class="progress" style="margin-bottom:0px"><div class="progress-bar{prcnt100}" role="progressbar"' ' aria-valuenow="{prcnt}" aria-valuemin="0" aria-valuemax="100" style="width: {prcnt}%;">{fprcnt:.1f}%</div></div></td>\n' ' <td align="right">{price}</td>' ' <td align="right">{cost}</td>' ' <td align="right">{volume}</td>' '</tr>'.format( num=row3_num, nm=bpmm3_tnm, me_te=me_te_tags, src=render_html.__get_img_src(bpmm3_tid, 32), qr=bpmm3_q, qneed=bpmm3_q - bpmm3_available - bpmm3_j if bpmm3_q > (bpmm3_available + bpmm3_j) else 0, qa='{:,d}'.format(bpmm3_available) if bpmm3_available >= 0 else "∞ <small>runs</small>", qip="" if bpmm3_j == 0 else '<mark>+ {}</mark>'.format(bpmm3_j), prcnt=int(bpmm3_progress), fprcnt=bpmm3_progress, prcnt100=" progress-bar-success" if bpmm3_progress == 100 else "", price='{:,.1f}'.format(bpmm3_price) if not (bpmm3_price is None) else "", cost='{:,.1f}'.format(bpmm3_price * bpmm3_q) if not (bpmm3_price is None) else "", volume='{:,.1f}'.format(__type_dict["volume"] * bpmm3_q) if not __is_blueprints_group else "")) # подсчёт summary кол-ва по всем материалам группы if not (bpmm3_price is None): __summary_cost = __summary_cost + (bpmm3_price * bpmm3_q) __summary_volume = __summary_volume + (__type_dict["volume"] * bpmm3_q) # вывод summary-строки для текущей группы материалов if not (__group_id == "None") and not (__group_id == "2"): glf.write( '<tr style="font-weight:bold">' ' <th></th>' ' <td colspan="4">Summary (<small>{nm}</small>)</td>' ' <td colspan="2" align="right">{cost:,.1f} ISK</td>' ' <td align="right">{volume:,.1f} m³</td>' '</tr>\n'.format(nm=__group_name, cost=__summary_cost, volume=__summary_volume)) glf.write(""" </tbody> </table> </div> <!--table-responsive--> </div> <!--media-body--> </div> <!--media--> </div> <!--container-fluid--> <script> // Capital Ship' Options menu and submenu setup $(document).ready(function(){ // Working with clipboard $('a.qind-copy-btn').each(function() { $(this).tooltip(); }) $('a.qind-copy-btn').bind('click', function () { var data_copy = $(this).attr('data-copy'); if (data_copy === undefined) { var tr = $(this).parent().parent(); var tbody = tr.parent(); var rows = tbody.children('tr'); var start_row = rows.index(tr); data_copy = ''; rows.each( function(idx) { if (!(start_row === undefined) && (idx > start_row)) { var td = $(this).find('td').eq(0); if (!(td.attr('class') === undefined)) start_row = undefined; else { var nm = td.attr('data-copy'); if (!(nm === undefined)) { if (data_copy) data_copy += "\\n"; data_copy += nm + "\\t" + $(this).find('td').eq(2).attr('quantity'); } } } }); } var $temp = $("<textarea>"); $("body").append($temp); $temp.val(data_copy).select(); try { success = document.execCommand("copy"); if (success) { $(this).trigger('copied', ['Copied!']); } } finally { $temp.remove(); } }); $('a.qind-copy-btn').bind('copied', function(event, message) { $(this).attr('title', message) .tooltip('fixTitle') .tooltip('show') .attr('title', "Copy to clipboard") .tooltip('fixTitle'); }); if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) { // какой-то код ... $('a.qind-copy-btn').each(function() { $(this).addClass('hidden'); }) } }); </script> """)
def __build_accounting( sde_type_ids, sde_inv_names, sde_inv_items, sde_market_groups, eve_market_prices_data, corp_ass_names_data, foreign_structures_data, foreign_structures_forbidden_ids, corp_assets_tree, corp_assets_data): # проверяем, может быть у корпы нет ассетов? if not ("roots" in corp_assets_tree): return {}, {} corp_accounting_stat = {} corp_accounting_tree = {} __roots = corp_assets_tree["roots"] for loc_id in __roots: region_id, region_name, loc_name, __dummy0 = eve_esi_tools.get_assets_location_name( loc_id, sde_inv_names, sde_inv_items, corp_ass_names_data, foreign_structures_data) if not (region_id is None): __ca1_region, __ca2_system = __build_accounting_register_region( region_id, region_name, loc_id, loc_name, corp_accounting_tree) for itm in corp_assets_tree[str(loc_id)]["items"]: __itm = str(itm) __ca2_system["items"].update({__itm: {"type_id": corp_assets_tree[__itm]["type_id"]}}) __dummy1, __dummy2, loc_name, foreign = eve_esi_tools.get_assets_location_name( itm, sde_inv_names, sde_inv_items, corp_ass_names_data, foreign_structures_data) __ca3_station = __ca2_system["items"][__itm] __ca3_station.update({"loc_name": loc_name, "foreign": foreign, "flags": {}}) # имущество собственных станций и таможек тоже учитываем в сводной статистике if not foreign: __tree_dict = corp_assets_tree[str(itm)] if str(itm) in corp_assets_tree else None __item_dict = corp_assets_data[int(__tree_dict["index"])] if "index" in __tree_dict else None if not (__item_dict is None): # может попастся NPC-станция, пропускаем, это точно не наше имущество __location_flag = __item_dict["location_flag"] if __location_flag == "AutoFit": __ca5_station_flag, __cas1_stat_flag = __build_accounting_register_flag( __location_flag, __ca1_region, __ca3_station, corp_accounting_stat) __type_id = int(__item_dict["type_id"]) __group_id = eve_sde_tools.get_basis_market_group_by_type_id(sde_type_ids, sde_market_groups, __type_id) if not (__group_id is None): __build_accounting_append( __type_id, 1, __group_id, sde_market_groups[str(__group_id)]["nameID"]["en"], sde_market_groups[str(__group_id)]["iconID"] if "iconID" in sde_market_groups[str(__group_id)] else None, eve_market_prices_data, sde_type_ids, __cas1_stat_flag, __ca5_station_flag, [2], # пропускаем: Blueprints and Reactions (собирается в отдельную группу) None, # Обрабатываем все остальные типы и группы имущества False, False, None, #TODO: а какой тут номер ангара? None) # это не Ship и не какая-то другая возможная вложенность # на текущей станции получаем все location_flag и собираем сводную статистику по каждой группе __build_accounting_station( itm, corp_assets_data, corp_accounting_stat, corp_assets_tree, sde_type_ids, sde_market_groups, eve_market_prices_data, __ca1_region, __ca3_station, [2], # пропускаем: Blueprints and Reactions (собирается в отдельную группу) None) # Обрабатываем все остальные типы и группы имущества # с Blueprints & Reactions работаем индивидуально! (добавляем их в отдельную виртуальную группу) __build_accounting_blueprints( itm, corp_assets_data, corp_accounting_stat, corp_assets_tree, sde_type_ids, sde_market_groups, eve_market_prices_data, __ca1_region, __ca3_station) else: # не удалось получить сведения о регионе, - это неспроста, скорее всего на эту стуктуру у корпы forbidden __region_id = None if int(loc_id) in foreign_structures_forbidden_ids: __region_id = 0 # "(none)" __ca1_region, __ca2_system = __build_accounting_register_region( __region_id, "Forbidden", 0, "(no data)", corp_accounting_tree) __ca2_system["items"].update({str(loc_id): {"type_id": None}}) __ca3_station = __ca2_system["items"][str(loc_id)] __ca3_station.update({"loc_name": str(loc_id), "foreign": True, "forbidden": True, "flags": {}}) else: __region_id = 3006 # "Unknown" __ca1_region, __ca2_system = __build_accounting_register_region( __region_id, "Unknown", 0, "(no data)", corp_accounting_tree) __ca2_system["items"].update({str(loc_id): {"type_id": None}}) __ca3_station = __ca2_system["items"][str(loc_id)] __ca3_station.update({"loc_name": str(loc_id), "foreign": True, "flags": {}}) # на текущей станции получаем все location_flag и собираем сводную статистику по каждой группе __build_accounting_station( loc_id, corp_assets_data, corp_accounting_stat, corp_assets_tree, sde_type_ids, sde_market_groups, eve_market_prices_data, __ca1_region, __ca3_station, [2], # пропускаем: Blueprints and Reactions (собирается в отдельную группу) None) # Обрабатываем все остальные типы и группы имущества # возможная ситуация - в список попал, но не добавился EVE Alliance маркер, который есть только у СЕО if len(__ca1_region["flags"]) == 0: del corp_accounting_tree[str(__region_id)] return corp_accounting_stat, corp_accounting_tree
def __build_accounting_nested( itm_id, sde_type_ids, sde_market_groups, eve_market_prices_data, corp_assets_tree, corp_assets_data, __cas1_stat_flag, __ca5_station_flag, skip_certain_groups, process_only_specified_groups, top_level_hangar, append_as_nested): __tree_dict = corp_assets_tree[str(itm_id)] __item_dict = corp_assets_data[int(__tree_dict["index"])] __type_id = int(__item_dict["type_id"]) __quantity = int(__item_dict["quantity"]) # __location_flag = __item_dict["location_flag"] __group_id = eve_sde_tools.get_basis_market_group_by_type_id(sde_type_ids, sde_market_groups, __type_id) # номер ангара добывается на первом и сохраняется на всех последующих уровнях вложенности if top_level_hangar is None: if __item_dict["location_flag"][:-1] == "CorpSAG": top_level_hangar = int(__item_dict["location_flag"][-1:]) if not (__group_id is None): # если в процессе обработки иерархии находится корабль (с патронами, дронами,...) то создаём # новую виртуальную вложенность if append_as_nested is None: if __group_id == 4: # Ships append_as_nested = {"nested_type_id": __type_id, "nested_group_id": __group_id} # добавляем в copr_accounting_tree информацию о цене и объёме предмета(ов) __build_accounting_append( __type_id, __quantity, __group_id, sde_market_groups[str(__group_id)]["nameID"]["en"], sde_market_groups[str(__group_id)]["iconID"] if "iconID" in sde_market_groups[str(__group_id)] else None, eve_market_prices_data, sde_type_ids, __cas1_stat_flag, __ca5_station_flag, skip_certain_groups, process_only_specified_groups, False, False, top_level_hangar, append_as_nested) # Ships, и может быть ещё что-то вложенное? if str(itm_id) in corp_assets_tree: __cat1 = corp_assets_tree[str(itm_id)] if "items" in __cat1: for __itm_id in __cat1["items"]: __build_accounting_nested( __itm_id, sde_type_ids, sde_market_groups, eve_market_prices_data, corp_assets_tree, corp_assets_data, __cas1_stat_flag, __ca5_station_flag, skip_certain_groups, process_only_specified_groups, top_level_hangar, append_as_nested) return
def __dump_corp_assets_tree_nested( glf, parent_location_id, location_id, corp_assets_data, corp_assets_tree, corp_ass_names_data, foreign_structures_data, eve_market_prices_data, sde_type_ids, sde_inv_names, sde_inv_items, sde_market_groups): region_id, region_name, loc_name, foreign = eve_esi_tools.get_assets_location_name( location_id, sde_inv_names, sde_inv_items, corp_ass_names_data, foreign_structures_data) itm_dict = None loc_dict = corp_assets_tree[str(location_id)] type_id = loc_dict["type_id"] if "type_id" in loc_dict else None group_id = eve_sde_tools.get_basis_market_group_by_type_id( sde_type_ids, sde_market_groups, type_id) items = loc_dict["items"] if "items" in loc_dict else None nested_quantity = None items_quantity = None base_price = None volume = None if not (items is None): nested_quantity = len(items) if itm_dict is None: itm_dict = corp_assets_data[ loc_dict["index"]] if "index" in loc_dict else None if not (itm_dict is None): items_quantity = itm_dict["quantity"] if str(type_id) in sde_type_ids: __type_dict = sde_type_ids[str(type_id)] if "basePrice" in __type_dict: base_price = __type_dict["basePrice"] * items_quantity if "volume" in __type_dict: volume = __type_dict["volume"] * items_quantity if type_id is None: __price_dict = None else: __price_dict = next( (p for p in eve_market_prices_data if p['type_id'] == int(type_id)), None) glf.write( '<div class="media">\n' ' <div class="media-left media-top">{img}</div>\n' ' <div class="media-body">\n' ' <h4 class="media-heading" id="id{id}">{where}{what}{iq}{nq}</h4>\n' ' {parent_id}<span class="label label-info">{id}</span>{loc_flag}{foreign}\n' ' {grp}{base}{average}{adjusted}{volume}\n'.format( img='<img class="media-object icn32" src="{src}">'.format( src=render_html.__get_img_src(type_id, 32)) if not (type_id is None) else "", where='{} '.format(loc_name) if not (loc_name is None) else "", what='<small>{}</small> '.format( eve_sde_tools.get_item_name_by_type_id(sde_type_ids, type_id)) if not (type_id is None) else "", parent_id= '<a href="#id{id}"><span class="label label-primary">parent:{id}</span></a> ' .format(id=parent_location_id) if not (parent_location_id is None) else "", id=location_id, nq=' <span class="badge">{}</span>'.format(items_quantity) if not (items_quantity is None) and (items_quantity > 1) else "", iq=' <span class="label label-info">{}</span>'.format( nested_quantity) if not (nested_quantity is None) and (nested_quantity > 1) else "", loc_flag=' <span class="label label-default">{}</span>'.format( itm_dict["location_flag"]) if not (itm_dict is None) else "", foreign='<br/><span class="label label-warning">foreign</span>' if foreign else "", grp='</br><span class="label label-success">{}</span>'.format( sde_market_groups[str(group_id)]["nameID"]["en"]) if not (group_id is None) else "", base='</br>base: {:,.1f} ISK'.format(base_price) if not (base_price is None) else "", average='</br>average: {:,.1f} ISK'.format( __price_dict["average_price"] * items_quantity) if not (items_quantity is None) and not (__price_dict is None) and ("average_price" in __price_dict) else "", adjusted='</br>adjusted: {:,.1f} ISK'.format( __price_dict["adjusted_price"] * items_quantity) if not (items_quantity is None) and not (__price_dict is None) and ("adjusted_price" in __price_dict) else "", volume='</br>{:,.1f} m³'.format(volume) if not (volume is None) else "")) if not (items is None): for itm in items: __dump_corp_assets_tree_nested( glf, location_id, itm, corp_assets_data, corp_assets_tree, corp_ass_names_data, foreign_structures_data, eve_market_prices_data, sde_type_ids, sde_inv_names, sde_inv_items, sde_market_groups) glf.write(' </div>\n' '</div>\n')
def __build_blueprints(corp_blueprints_data, corp_industry_jobs_data, eve_market_prices_data, corp_contracts_data, corp_contract_items_data, various_characters_data, sde_type_ids, sde_inv_names, sde_inv_items, sde_market_groups, corp_assets_tree, corp_ass_names_data, foreign_structures_data): blueprints = [] blueprints_locations = {} keys_to_skip_on_compare = [ 'name', 'item_id', 'q', 'base_price', 'average_price', 'adjusted_price' ] for __blueprint_dict in corp_blueprints_data: # A range of numbers with a minimum of -2 and no maximum value where -1 is an original and -2 is a copy. # It can be a positive integer if it is a stack of blueprint originals fresh from the market (e.g. no # activities performed on them yet). __quantity: int = __blueprint_dict["quantity"] __is_blueprint_copy: bool = bool(__quantity == -2) __type_id: int = int(__blueprint_dict["type_id"]) __type_desc = sde_type_ids.get(str(__type_id), None) if __type_desc is None: __type_desc = {} __is_t2_blueprint = None else: __is_t2_blueprint = __type_desc.get("metaGroupID", None) == 2 # отсеиваем подраздел Manufacture & Research, который встречается в blueprints-данных от ССР, например: # будут пропущены Intact Power Cores, Malfunctioning Weapon Subroutines и т.п. # но поскольку проверка выполняется с помощью marketGroupID, то дополнительно проверяем, что чертёж # является T2, и соответственно поскольку не продаётся на рынке - всё равно должен попасть в отчёт if not __is_t2_blueprint: __group_id = eve_sde_tools.get_root_market_group_by_type_id( sde_type_ids, sde_market_groups, __type_id) if __group_id != 2: # Blueprints & Reactions continue __blueprint_id = __blueprint_dict["item_id"] __location_id = __blueprint_dict["location_id"] __blueprint = { "item_id": __blueprint_id, "type_id": __type_id, "name": __type_desc.get("name", {}).get( "en", "Unknown Type {} Blueprint".format(__type_id)), "copy": __is_blueprint_copy, "me": __blueprint_dict["material_efficiency"], "te": __blueprint_dict["time_efficiency"], "q": 1 if __quantity < 0 else __quantity, "loc": __location_id, "flag": __blueprint_dict["location_flag"] } # если чертёж в единичном экземпляре, не stacked, смотрим что с ним происходит? (jobs?) blueprint_job_found = False if __quantity < 0: __job_dict = next((j for j in corp_industry_jobs_data if j['blueprint_id'] == int(__blueprint_id)), None) if not (__job_dict is None): blueprint_job_found = True # особенность : чертежи могут отсутствовать в assets по указанному location_id, при этом чертёж будет в # blueprints, но его location_id будет указывать на станцию, а не на контейнер, в то же время в # industrial jobs этот же самый чертёж будет находиться в списке и иметь blueprint_location_id который # указывает на искомый контейнер __location_id = __job_dict["blueprint_location_id"] # сохранение информации о текущей работе, ведущейся с использованием чертежа __blueprint.update({ "st": __job_dict["status"], "act": __job_dict["activity_id"], "loc": __location_id, # переопределяем!!! "out": __job_dict["output_location_id"], }) # осуществляем поиск местоположения чертежа __push_location_into_blueprints_locations( __job_dict["output_location_id"], blueprints_locations, sde_inv_names, sde_inv_items, corp_assets_tree, corp_ass_names_data, foreign_structures_data) # ищем уже существующий чертёж в списке ранее добавленных same_blueprint_found = None for b in blueprints: # не стравниваем чертежи у одного из которых не ведутся работы, иначе код ниже не сможет # сравнить просто перебирая ключи dict-ов с разным составом параметров if blueprint_job_found == bool(b.get('st') is None): continue same_blueprint = True for key in b: if key in keys_to_skip_on_compare: continue elif not (key in __blueprint): same_blueprint = False break elif b[key] != __blueprint[key]: same_blueprint = False break if same_blueprint: same_blueprint_found = b break if not same_blueprint_found: # T2 чертежи не имеют какую-то точную маркет-цену, т.к. либо не продаются, либо продаются через # контракты, поэтому base_price и/или average_price, или adjusted_price невалидны if __is_t2_blueprint == False: # выясняем стоимость чертежа if "basePrice" in __type_desc: __blueprint.update( {"base_price": __type_desc["basePrice"]}) else: __price_dict = next((p for p in eve_market_prices_data if p['type_id'] == int(__type_id)), None) if not (__price_dict is None): if "average_price" in __price_dict: __blueprint.update({ "average_price": __price_dict["average_price"] }) elif "adjusted_price" in __price_dict: __blueprint.update({ "adjusted_price": __price_dict["adjusted_price"] }) # осуществляем поиск местоположения чертежа __push_location_into_blueprints_locations( __location_id, blueprints_locations, sde_inv_names, sde_inv_items, corp_assets_tree, corp_ass_names_data, foreign_structures_data) # добавляем собранную информацию в список чертежей blueprints.append(__blueprint) else: same_blueprint_found["q"] += __blueprint["q"] # debug contracts only: blueprints = [] # debug contracts only: blueprints_locations = {} # в рамках работы с чертежами, нас интересует только набор контрактов, в которых продаются чертежи # ищем публичные контракты типа "обмен предметами" for __contract_items_dict in corp_contract_items_data: __contract_id_key = __contract_items_dict.keys() for __contract_id in __contract_id_key: __items = __contract_items_dict[str(__contract_id)] for __items_dict in __items: # пропускаем отклонения от нормы, а также контракты на покупку, а не на продажу if not ("is_included" in __items_dict): continue elif not bool(__items_dict["is_included"]): continue __type_id = __items_dict["type_id"] __type_desc = sde_type_ids.get(str(__type_id), {}) __is_t2_blueprint = __type_desc.get("metaGroupID", None) == 2 # отсеиваем подраздел Manufacture & Research, который встречается в blueprints-данных от ССР, например: # будут пропущены Intact Power Cores, Malfunctioning Weapon Subroutines и т.п. # но поскольку проверка выполняется с помощью marketGroupID, то дополнительно проверяем, что чертёж # является T2, и соответственно поскольку не продаётся на рынке - всё равно должен попасть в отчёт if __is_t2_blueprint == False: # Blueprints and Reactions (добавляем только этот тип), а также T2-чертежи __group_id = eve_sde_tools.get_basis_market_group_by_type_id( sde_type_ids, sde_market_groups, __type_id) if __group_id != 2: continue # raw_quantity = -1 indicates that the item is a singleton (non-stackable). If the item happens to # be a Blueprint, -1 is an Original and -2 is a Blueprint Copy __is_blueprint_copy: bool = False if "raw_quantity" in __items_dict: __raw_qauntity = __items_dict["raw_quantity"] if __raw_qauntity == -2: __is_blueprint_copy = True # получение данных по чертежу, находящемуся в продаже __quantity = __items_dict["quantity"] # получение общих данных данных по контракту __contract_dict = next( (c for c in corp_contracts_data if c['contract_id'] == int(__contract_id)), None) __location_id = __contract_dict["start_location_id"] __issuer_id = __contract_dict["issuer_id"] __issuer_name = next( (list(i.values())[0]["name"] for i in various_characters_data if int(list(i.keys())[0]) == int(__issuer_id)), None) __blueprint = { "item_id": __items_dict["record_id"], "type_id": __type_id, "name": __type_desc.get("name", {}).get( "en", "Unknown Type {} Blueprint".format(__type_id)), "copy": __is_blueprint_copy, # "me": None, # "te": None, "q": __quantity, "loc": __location_id, "flag": __contract_dict["title"], "price": __contract_dict["price"], "cntrct_sta": __contract_dict["status"], "cntrct_typ": __contract_dict["type"], "cntrct_issuer": __issuer_id, "cntrct_issuer_name": __issuer_name } # осуществляем поиск местоположения чертежа __push_location_into_blueprints_locations( __location_id, blueprints_locations, sde_inv_names, sde_inv_items, corp_assets_tree, corp_ass_names_data, foreign_structures_data) # добавляем собранную информацию в список чертежей blueprints.append(__blueprint) return blueprints, blueprints_locations
def __build_industry( # настройки qidb, module_settings, # sde данные, загруженные из .converted_xxx.json файлов sde_type_ids, sde_bp_materials, sde_market_groups, sde_named_type_ids, # esi данные, загруженные с серверов CCP corp_industry_jobs_data): corp_industry_stat = { "new_jobs_found": 0, "current_month": -1, "conveyor_scheduled_products": [], "workflow_industry_jobs": [], "workflow_last_industry_jobs": [], "conveyor_market_groups": {} } def push_into_conveyor_market_groups(__market_group_id): if corp_industry_stat["conveyor_market_groups"].get( str(__market_group_id), None) is None: corp_industry_stat["conveyor_market_groups"].update({ str(__market_group_id): eve_sde_tools.get_market_group_name_by_id( sde_market_groups, __market_group_id) }) # получаем текущий месяц с помощью sql-запроса db_current_month = qidb.select_one_row( "SELECT EXTRACT(MONTH FROM CURRENT_DATE)") corp_industry_stat["current_month"] = int(db_current_month[0]) # сохраняем данные по производству в БД wij = db.QWorkflowIndustryJobs(qidb) corp_industry_stat["new_jobs_found"] = wij.actualize( corp_industry_jobs_data, sde_bp_materials) del wij db_conveyor_jobs = qidb.select_all_rows( "SELECT wmj_quantity,wmj_eft " "FROM workflow_monthly_jobs " "WHERE wmj_active AND wmj_conveyor;") # конвертация ETF в список item-ов conveyor_product_type_ids = [] conveyor_scheduled_products = [] for job in db_conveyor_jobs: __total_quantity = job[0] __eft = job[1] __converted = eve_sde_tools.get_items_list_from_eft( __eft, sde_named_type_ids) __converted.update({"quantity": __total_quantity}) if not (__converted["ship"] is None): __product_type_id = __converted["ship"]["type_id"] if conveyor_product_type_ids.count(__product_type_id) == 0: conveyor_product_type_ids.append(__product_type_id) __market_group_id = eve_sde_tools.get_basis_market_group_by_type_id( sde_type_ids, sde_market_groups, __product_type_id) push_into_conveyor_market_groups(__market_group_id) conveyor_scheduled_products.append({ "name": __converted["ship"]["name"], "type_id": __product_type_id, "quantity": __total_quantity, "market": __market_group_id }) else: __job_dict = next((j for j in conveyor_scheduled_products if j["type_id"] == __product_type_id), None) __job_dict["quantity"] += __total_quantity for __item_dict in __converted["items"]: __product_type_id = __item_dict["type_id"] if conveyor_product_type_ids.count(__product_type_id) == 0: conveyor_product_type_ids.append(__product_type_id) __market_group_id = eve_sde_tools.get_basis_market_group_by_type_id( sde_type_ids, sde_market_groups, __product_type_id) push_into_conveyor_market_groups(__market_group_id) conveyor_scheduled_products.append({ "name": __item_dict["name"], "type_id": __product_type_id, "quantity": __total_quantity * __item_dict["quantity"], "market": __market_group_id }) else: __job_dict = next((j for j in conveyor_scheduled_products if j["type_id"] == __product_type_id), None) __job_dict[ "quantity"] += __total_quantity * __item_dict["quantity"] corp_industry_stat[ "conveyor_scheduled_products"] = conveyor_scheduled_products # выбираем накопленные данные по производству из БД if conveyor_product_type_ids: db_workflow_industry_jobs = qidb.select_all_rows( "SELECT ptid,SUM(cst),SUM(prdcts),mnth " "FROM (SELECT " " ecj.ecj_product_type_id AS ptid," " ecj.ecj_cost AS cst," " ecj.ecj_runs*coalesce(pi.sdebp_quantity,1) AS prdcts," " EXTRACT(MONTH FROM ecj.ecj_end_date) AS mnth" " FROM qi.esi_corporation_industry_jobs ecj" " LEFT OUTER JOIN qi.eve_sde_blueprint_products pi ON (" " pi.sdebp_activity=1 AND" " pi.sdebp_blueprint_type_id=ecj.ecj_blueprint_type_id AND" " pi.sdebp_product_id=ecj.ecj_product_type_id" " )" " WHERE ecj.ecj_activity_id=1 AND" " ecj.ecj_product_type_id=ANY(%s) AND" " ecj.ecj_end_date > (current_date - interval '93' day)" ") AS a " "WHERE mnth=%s OR mnth=%s OR mnth=%s " "GROUP BY 1,4 " "ORDER BY 1;", conveyor_product_type_ids, int(db_current_month[0]), # january=1, december=12 int((db_current_month[0] - 2 + 12) % 12 + 1), int((db_current_month[0] - 3 + 12) % 12 + 1)) corp_industry_stat["workflow_industry_jobs"] = [{ "ptid": wij[0], "cost": wij[1], "products": wij[2], "month": int(wij[3]) } for wij in db_workflow_industry_jobs] del db_workflow_industry_jobs # выбираем накопленные данные по производству из БД (за последние 30 дней) db_workflow_last_industry_jobs = qidb.select_all_rows( "SELECT" " ecj.ecj_product_type_id," " SUM(ecj.ecj_runs*coalesce(pi.sdebp_quantity,1)) " "FROM qi.esi_corporation_industry_jobs ecj" " LEFT OUTER JOIN qi.eve_sde_blueprint_products pi ON (" " pi.sdebp_activity=1 AND" " pi.sdebp_blueprint_type_id=ecj.ecj_blueprint_type_id AND" " pi.sdebp_product_id=ecj.ecj_product_type_id" " )" "WHERE ecj.ecj_activity_id=1 AND" " ecj.ecj_product_type_id=ANY(%s) AND" " ecj.ecj_end_date > (current_date - interval '30' day) " "GROUP BY 1;", conveyor_product_type_ids) corp_industry_stat["workflow_last_industry_jobs"] = [{ "ptid": wij[0], "products": wij[1] } for wij in db_workflow_last_industry_jobs] del db_workflow_last_industry_jobs del conveyor_product_type_ids return corp_industry_stat
def __init__( self, type_id: int, # sde данные, загруженные из .converted_xxx.json файлов sde_type_ids, sde_bp_materials, sde_market_groups, # esi данные, загруженные с серверов CCP corp_industry_jobs_data, # списки контейнеров и станок из экземпляра контейнера manufacturing_blueprint_loc_ids, manufacturing_stock_loc_ids, reaction_stock_loc_ids, # список ресурсов, которые используются в производстве manufacturing_stock_resources, reaction_stock_resources): # код продукта self.type_id: int = type_id # название продукта self.name: str = eve_sde_tools.get_item_name_by_type_id( sde_type_ids, type_id) # market-группа, которой принадлежит продукт self.market_group: int = eve_sde_tools.get_market_group_by_type_id( sde_type_ids, type_id) self.market_group_dict = sde_market_groups.get(str(self.market_group)) # базовая (основная) market-группа, которой принадлежит товар self.basis_market_group: int = eve_sde_tools.get_basis_market_group_by_type_id( sde_type_ids, sde_market_groups, type_id) self.basis_market_group_dict = sde_market_groups.get( str(self.basis_market_group)) # кол-во данного продукта, который имеется на manufacturing-станции self.exist_in_manuf_stock: int = manufacturing_stock_resources.get( type_id, 0) # кол-во данного продукта, который имеется на reaction-станции self.exist_in_react_stock: int = reaction_stock_resources.get( type_id, 0) # кол-во данного продукта, который зарезервирован на manufacturing-станции (в результате расчёта производства) self.reserved_in_manuf_stock: int = 0 # кол-во данного продукта, который зарезервирован на reaction-станции (в результате расчёта производства) self.reserved_in_react_stock: int = 0 # поиск чертежа, который подходит для производства данного типа продукта self.blueprint_type_id = None self.blueprint_name = None self.blueprint_activity = None self.blueprint_activity_dict = None # признак, получается ли данный продукт в результате реакции self.is_reaction = None # 'символ' станции, на которой происходит производство данного продукта # 'M' - индустриальная станция (Sotiyo) # 'R' - станция проведения реакций (Tatara) # None - если продукт не производится (например Tritanium) или данных по нему нет (не обновлён SDE) self.where = None # сведения о запуске чертежа/ей self.products_per_single_run = None self.runs_number_per_day = None # настраиваем запуски чертежей: списка запусков (план по имеющимся в наличие чертежам) self.runs_and_jobs = [] # настраиваем справочник для сохранения "пользовательских" данных в объекте (очищается методом clear) self.user_data = {} # сводные сведения о работах self.in_progress: int = 0 # --- # получаем информацию о чертежах и способе производства материала # настройка запусков чертежей self.setup_blueprint_details(sde_type_ids, sde_bp_materials) # получаем список работ, которые ведутся с этим материалом, а результаты сбрасываются в сток self.setup_industry_jobs(corp_industry_jobs_data, manufacturing_blueprint_loc_ids, manufacturing_stock_loc_ids, reaction_stock_loc_ids)