Beispiel #1
0
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)
Beispiel #2
0
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
Beispiel #3
0
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
Beispiel #4
0
 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,
     }
Beispiel #5
0
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,&nbsp;ISK</th>
  <th style="text-align:right;">Volume,&nbsp;m&sup3;</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 \
                '&nbsp;<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 += '&nbsp;<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 "&infin; <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&nbsp;(<small>{nm}</small>)</td>'
                ' <td colspan="2" align="right">{cost:,.1f}&nbsp;ISK</td>'
                ' <td align="right">{volume:,.1f}&nbsp;m&sup3;</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>
""")
Beispiel #6
0
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
Beispiel #7
0
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
Beispiel #8
0
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&sup3'.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
Beispiel #10
0
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)