Exemple #1
0
def operations_table(oper_: DataFrame) -> DataFrame:
    """
    Главная задача функции - установка даты учета на основании дат заказа или дат поступлений
    Если списание не из поступлений, то 'Дата учета' = 'Дата списания остат'
    Если списание из поступлений и 'Дата потребности' > 'Дата списания остат',
        то 'Дата учета' = 'Дата потребности'
    Если списание из поступлений и 'Дата потребности' <= 'Дата списания остат',
        то 'Дата учета' = 'Дата списания остат'
    Так же сразу записываем файл с операциями.

    :param oper_: список операций
    :return: отформатированная таблица с операциями
    """
    table = oper_.copy()
    table['Дата учета'] = table['Дата потребности'].where(
        table['Склад'] != 'Поступления', table['Дата списания остат'])
    table['Дата учета'] = table['Дата потребности'].where(
        (table['Склад'] == 'Поступления') &
        (table['Дата потребности'] > table['Дата списания остат']),
        table['Дата учета'])
    name_oper = r'.\support_data\output_tables\oper_{0}.csv'.format(
        NOW.strftime('%Y%m%d'))
    table.to_csv(name_oper, sep=";", encoding='ansi', index=False)

    return table
Exemple #2
0
def operations_table(oper_: list) -> DataFrame:
    """
    Главная задача функции - установка даты учета на основании дат заказа или дат поступлений
    Если списание не из поступлений, то 'Дата учета' = 'Дата списания остат'
    Если списание из поступлений и 'Дата потребности' > 'Дата списания остат',
        то 'Дата учета' = 'Дата потребности'
    Если списание из поступлений и 'Дата потребности' <= 'Дата списания остат',
        то 'Дата учета' = 'Дата списания остат'
    Так же сразу записываем файл с операциями.

    :param oper_: список операций
    :return: отформатированная таблица с операциями
    """
    columns = [
        'Дата потребности', 'Порядковый номер', 'Заказ-Партия',
        'Номенклатура потребности', 'Потребность из файла', 'Потребность нач',
        'Потребность кон', 'Списание потребности', 'Склад',
        'Дата списания остат', 'Номенклатура Списания', 'Остатки нач',
        'Остатки кон', 'Списание остатков'
    ]
    table = DataFrame(data=oper_, columns=columns)
    table['Дата учета'] = table['Дата потребности'].where(
        table['Склад'] != 'Поступления', table['Дата списания остат'])
    table['Дата учета'] = table['Дата потребности'].where(
        (table['Склад'] == 'Поступления') &
        (table['Дата потребности'] > table['Дата списания остат']),
        table['Дата учета'])
    name_oper = r'.\support_data\output_tables\oper_{0}.csv'.format(
        NOW.strftime('%Y%m%d'))
    table.to_csv(name_oper, sep=";", encoding='ansi', index=False)

    return table
Exemple #3
0
def daily_tables() -> None:
    """Создание таблиц для ежедневных отчетов"""
    name_output_req = r'.\support_data\output_tables\ask_{0}.csv'.format(
        NOW.strftime('%Y%m%d'))
    output_req = read_csv(name_output_req,
                          sep=";",
                          encoding='ansi',
                          parse_dates=['Дата запуска', 'Дата начала факт'],
                          dtype={'Номер победы': 'object'})
    output_req.to_csv(
        f'W:\\Analytics\\Илья\\!deficit_work_files\\ask {NOW.strftime("%y%m%d %H_%M_%S")}.csv',
        sep=";",
        encoding='ansi',
        index=False)  # запись используемых файлов, для взгляда в прошлое
    deficit(output_req)
def building_purchase_analysis() -> DataFrame:
    """Повторение алгоритма расчета потребности на файле из прошлого"""
    sep_date = separate_date()

    operations = list()
    dict_nom = nomenclature()
    dict_repl_mark = replacements(PATH_REP_MARK)
    dict_repl_gost = replacements(PATH_REP_GOST)
    dict_repl_pokr = replacements(PATH_REP_POKR)
    dict_repl_prochn = replacements(PATH_REP_PROCHN)

    start_rest_center = void_rests(dict_nom=dict_nom)
    start_rest_tn = void_rests(dict_nom=dict_nom)

    start_fut = modify_orders_to_supplier(table=load_orders_to_supplier(),
                                          dict_nom=dict_nom)
    start_ask = old_requirements()

    end_rest_center = start_rest_center.copy()
    end_rest_tn = start_rest_tn.copy()
    end_fut = start_fut.copy()
    end_ask = start_ask.copy()

    # списание остатков на потребности
    end_ask, end_rest_tn, end_rest_center, end_fut, operations = write_off(
        table=end_ask,
        rest_tn=end_rest_tn,
        rest_c=end_rest_center,
        fut=end_fut,
        oper_=operations,
        nom_=dict_nom,
        repl_={
            'mark': dict_repl_mark,
            'gost': dict_repl_gost,
            'pokr': dict_repl_pokr,
            'prochn': dict_repl_prochn
        })

    check_calculation_right(
        start_ask_=start_ask,
        end_ask_=end_ask,
        start_c_=start_rest_center,
        end_c_=end_rest_center,
        start_tn_=start_rest_tn,
        end_tn_=end_rest_tn,
        start_fut_=start_fut,
        end_fut_=end_fut,
    )

    weekly_tables(start_ask_=start_ask,
                  end_ask_=end_ask,
                  oper_=operations,
                  sep_date=sep_date)
    weekly_excel_reports()

    # построение таблицы-----------------------------------------------
    name_oper = r'.\support_data\output_tables\oper_{0}.csv'.format(
        NOW.strftime('%Y%m%d'))
    data = read_csv(name_oper,
                    sep=";",
                    encoding='ansi',
                    usecols=[0, 3, 7, 10],
                    parse_dates=['Дата потребности'])
    data = data[data['Дата потребности'] <= sep_date]\
        [['Номенклатура потребности', 'Номенклатура Списания', 'Списание потребности']]
    data = data.\
        groupby(by=['Номенклатура потребности', 'Номенклатура Списания']).\
        sum().\
        reset_index().\
        rename(columns={'Номенклатура потребности': 'Номенклатура',
                        'Номенклатура Списания': 'Номенклатура_заказа',
                        "Списание потребности": 'План_закупа'})
    data['Заказано'] = data['План_закупа']
    data = data[[
        'Номенклатура', 'План_закупа', 'Номенклатура_заказа', 'Заказано'
    ]]

    additional_plan = end_ask.copy(
    )  # план закупа, который остался без заказов поставщикам
    additional_plan = additional_plan[additional_plan['Дата запуска'] <= sep_date]\
        [['Номенклатура', 'Дефицит']].\
        groupby(by=['Номенклатура']).\
        sum().\
        reset_index().\
        rename(columns={'Дефицит': 'План_закупа'})
    additional_plan['Номенклатура_заказа'] = None
    additional_plan['Заказано'] = 0
    additional_plan = additional_plan[[
        'Номенклатура', 'План_закупа', 'Номенклатура_заказа', 'Заказано'
    ]]
    additional_plan = additional_plan[additional_plan['План_закупа'] > 0]

    data = concat((data, additional_plan))

    additional_futures = end_fut.copy()
    additional_futures = additional_futures[additional_futures['Количество'] > 0].\
        groupby(by=['Номенклатура'])\
        ['Количество'].\
        sum().\
        reset_index().\
        rename(columns={'Номенклатура': 'Номенклатура_заказа',
                        'Количество': 'Заказано'})
    additional_futures['Номенклатура'] = None
    additional_futures['План_закупа'] = 0
    additional_futures = additional_futures[[
        'Номенклатура', 'План_закупа', 'Номенклатура_заказа', 'Заказано'
    ]]

    data = concat((data, additional_futures))

    # добавление Поступило и остаточная потребность-------------------------------------
    inputs = load_orders_to_supplier()
    inputs = inputs[['Номенклатура', 'Заказано', 'Доставлено']].\
        rename(columns={'Номенклатура': 'Номенклатура_заказа',
                        'Заказано': 'Заказано_всего'}).\
        fillna(0)
    data = data.\
        merge(inputs, on='Номенклатура_заказа', how='left').\
        fillna(0)
    data['Процент_заказа'] = data['Заказано'] / data['Заказано_всего']
    data['Доставлено'] = data['Доставлено'] * data['Процент_заказа']

    data['Еще_заказать'] = data['План_закупа'] - data['Заказано']
    data['Еще_заказать'] = data['Еще_заказать']. \
        where(data['Еще_заказать'] > 0, 0)
    data = data. \
        sort_values(by=['Номенклатура', 'Номенклатура_заказа'])

    data = data[[
        'Номенклатура', 'План_закупа', 'Номенклатура_заказа', 'Заказано',
        'Доставлено', 'Еще_заказать'
    ]].fillna(0)

    data.\
        rename(columns={'Дефицит': 'План_закупа', 'Еще_заказать': 'Остаточная_потребность'}).\
        to_excel(
            r".\support_data\purchase_analysis\purchase_analysis.xlsx",
            index=False
        )

    return data
Exemple #5
0
def weekly_tables(start_ask_: DataFrame,
                  end_ask_: DataFrame,
                  oper_: DataFrame,
                  sep_date: datetime = None) -> None:
    """Подготовка таблиц для недельных отчетов

    :param start_ask_: начальная поребность
    :param end_ask_: конечная поребность после списаний
    :param oper_: список операций
    :param sep_date: Дата разделения краткосрочного периода и долгосрочного = последний день краткосрочного
    """
    oper_columns = [
        'Заказ-Партия', 'Номенклатура потребности', 'Склад',
        'Списание потребности'
    ]
    oper_gr_columns = ['Заказ-Партия', 'Номенклатура потребности', 'Склад']

    # oper_write_off - укороченная версия operations_table для мержа к output_req
    oper_write_off = operations_table(oper_)
    oper_write_off = oper_write_off[oper_columns].groupby(
        oper_gr_columns).sum().reset_index()

    center_write_off = write_off_tables(table_=oper_write_off,
                                        from_='Центральный склад')
    tn_write_off = write_off_tables(table_=oper_write_off, from_='ТН')
    future_input_write_off = write_off_tables(table_=oper_write_off,
                                              from_='Поступления')

    #  output_req - это start_ask с изменениями для вывода в файл
    output_req = main_table(
        start_ask_=start_ask_,
        end_ask_=end_ask_,
        list_tables=[center_write_off, tn_write_off, future_input_write_off])

    name_output_req = r'.\support_data\output_tables\ask_{0}.csv'.format(
        NOW.strftime('%Y%m%d'))
    output_req.to_csv(name_output_req, sep=";", encoding='ansi', index=False)

    # создание файлов для макроса экселя
    # detail_table - таблица для краткосрочного закупа
    if sep_date is None:  # если None, то для дефицита ежедневного и далее ну нужно идти
        return None
    else:
        # подготовка detail.csv
        make_detail_table(data=output_req, sep_date=sep_date)

        # подготовка graf.csv и graf_without_feat.csv
        # эти графики только для краткосрочного периода
        short_term = output_req[output_req['Дата запуска'] <= sep_date]
        graph(table_=short_term, method='with_future_inputs')
        graph(table_=short_term, method='without_future_inputs')

        # подготовка problem_orders.csv
        # это заказы с проблемами для краткосрочной и долгосрочной перспективы
        unpr_orders = make_unapproved_orders(data=output_req,
                                             sep_date=sep_date)
        unpr_long_orders = make_unapproved_long_orders(data=output_req,
                                                       sep_date=sep_date)
        problem_orders = concat([unpr_orders, unpr_long_orders], axis=0)
        problem_orders.to_csv(
            r".\support_data\data_for_reports\problem_orders.csv",
            sep=";",
            encoding='ansi',
            index=False)

        # подготовка long_nomenclature_orders.csv и long_nomenclature_possible_orders.csv
        # это дефицит длинной номенклатуры в долгосрочной перспективе
        long_nomenclature_orders(data=output_req, sep_date=sep_date)
Exemple #6
0
def graph(table_: DataFrame, method: str) -> None:
    """Создание графика дефицита по дням и по номенклатуре для
    
    :param table_: таблица output_req из weekly_tables
    :param method: 'with_future_inputs' or 'without_future_inputs'
    """
    if method == 'with_future_inputs':
        need_table = table_.copy()
        name_combin_graph = r'.\support_data\output_tables\graf_{0}.csv'.format(
            NOW.strftime('%Y%m%d'))
        name_combin_graph_excel = r".\support_data\data_for_reports\graf.csv"
    elif method == 'without_future_inputs':
        need_table = table_.copy()
        need_table['Остаток дефицита'] = need_table[
            'Остаток дефицита'] + need_table['Списание из Поступлений']
        name_combin_graph = r'.\support_data\output_tables\graf_without_feat_{0}.csv'.format(
            NOW.strftime('%Y%m%d'))
        name_combin_graph_excel = r".\support_data\data_for_reports\graf_without_feat.csv"
    else:
        raise AttributeError(
            'Argument "method" receives only 2 values: with_future_inputs or without_future_inputs'
        )

    # clean_for_graf - output_req только с потребностями больше 0
    clean_for_graf = need_table[(need_table['Остаток дефицита'] > 0)
                                & (need_table['Заказ обеспечен'] == 0) &
                                (need_table['Пометка удаления'] == 0)].copy()
    # для схлопывания указанных гостов
    old_nomenclature = clean_for_graf[['Номенклатура', 'Код']].copy()
    del old_nomenclature['Код']
    old_nomenclature['Номенклатура_с_заменами_гостов'] = clean_for_graf[
        'Номенклатура'].map(lambda x: (x.replace(
            'ГОСТ 7798-70', 'ГОСТ Р ИСО 4014-2013').replace(
                'ГОСТ Р ИСО 4017-2013', 'ГОСТ Р ИСО 4014-2013').replace(
                    'ГОСТ 5915-70', 'ГОСТ ISO 4032-2014'))).drop_duplicates()
    clean_for_graf['Номенклатура'] = clean_for_graf['Номенклатура'].map(
        lambda x: (x.replace('ГОСТ 7798-70', 'ГОСТ Р ИСО 4014-2013').replace(
            'ГОСТ Р ИСО 4017-2013', 'ГОСТ Р ИСО 4014-2013').replace(
                'ГОСТ 5915-70', 'ГОСТ ISO 4032-2014')))

    # graph_ - график-календарь по дням и по номенклатурам из поребностей
    graph_ = pivot_table(data=clean_for_graf,
                         values='Остаток дефицита',
                         columns='Дата запуска',
                         index='Номенклатура',
                         aggfunc='sum').fillna(0).sort_index()

    # создание comdin_graf файла
    need_date = Series(graph_.columns)
    need_date = need_date[need_date >= NOW]
    cum_column = graph_[graph_.columns[graph_.columns < NOW]].sum(
        axis=1)  # столбец с кумулятивными данными предыдущих дней

    combin_graph = graph_[need_date].copy()
    if len(
            combin_graph.columns
    ) != 0:  # проблемный случай, если в промежутке от текущего дня до тек день + 2 дня нет данных, то сформировать как нулевые
        combin_graph[
            need_date.iloc[0]] = cum_column + combin_graph[need_date.iloc[0]]
    else:
        combin_graph['first_column'] = cum_column
        combin_graph['second_column'] = 0
        combin_graph['third_column'] = 0
        combin_graph.columns = [
            NOW, NOW + timedelta(days=1), NOW + timedelta(days=2)
        ]

    # создание мультииндекса, где верхний уровень отклонение от первого дня
    columns = Series(
        combin_graph.columns).diff().map(extract_day).cumsum().replace(
            {None: 0})
    combin_graph.columns = [columns, combin_graph.columns]

    filter1 = combin_graph.sum(axis=1).replace({0: None}).notna()

    # добавление коэффициентов, что бы потом посчитать в единицах отчета через ексель
    nom_data = nomenclature()
    old_nomenclature = old_nomenclature.merge(
        nom_data[['Номенклатура', 'coeff', 'Единица отчета']],
        left_on='Номенклатура',
        right_on='Номенклатура',
        how='left',
        copy=False)
    del old_nomenclature['Номенклатура']
    old_nomenclature = old_nomenclature.drop_duplicates().\
        set_index('Номенклатура_с_заменами_гостов')
    old_nomenclature.columns = [
        range(len(old_nomenclature.columns)), old_nomenclature.columns
    ]

    combin_graph = combin_graph.merge(old_nomenclature,
                                      left_index=True,
                                      right_index=True,
                                      how='left',
                                      copy=False)

    combin_graph[filter1].to_csv(name_combin_graph, sep=";", encoding='ansi')
    combin_graph[filter1].to_csv(name_combin_graph_excel,
                                 sep=";",
                                 encoding='ansi')
Exemple #7
0
def graph(table_: DataFrame, method: str) -> None:
    """Создание графика дефицита по дням и по номенклатуре для
    
    :param table_: таблица output_req из weekly_tables
    :param method: 'with_future_inputs' or 'without_future_inputs'
    """
    if method == 'with_future_inputs':
        need_table = table_.copy()
        name_combin_graph = r'.\support_data\output_tables\graf_{0}.csv'.format(
            NOW.strftime('%Y%m%d'))
        name_combin_graph_excel = r".\support_data\data_for_reports\graf.csv"
    elif method == 'without_future_inputs':
        need_table = table_.copy()
        need_table['Остаток дефицита'] = need_table[
            'Остаток дефицита'] + need_table['Списание из Поступлений']
        name_combin_graph = r'.\support_data\output_tables\graf_without_feat_{0}.csv'.format(
            NOW.strftime('%Y%m%d'))
        name_combin_graph_excel = r".\support_data\data_for_reports\graf_without_feat.csv"
    else:
        raise AttributeError(
            'Argument "method" receives only 2 values: with_future_inputs or without_future_inputs'
        )

    # clean_for_graf - output_req только с потребностями больше 0
    clean_for_graf = need_table[(need_table['Остаток дефицита'] > 0)
                                & (need_table['Заказ обеспечен'] == 0) &
                                (need_table['Пометка удаления'] == 0)]

    # graph_ - график-календарь по дням и по номенклатурам из поребностей
    graph_ = pivot_table(data=clean_for_graf,
                         values='Остаток дефицита',
                         columns='Дата запуска',
                         index='Номенклатура',
                         aggfunc='sum').fillna(0).sort_index()

    # создание comdin_graf файла
    need_date = Series(graph_.columns)
    need_date = need_date[need_date >= NOW]
    cum_column = graph_[graph_.columns[graph_.columns < NOW]].sum(
        axis=1)  # столбец с кумулятивными данными предыдущих дней

    combin_graph = graph_[need_date].copy()
    if len(
            combin_graph.columns
    ) != 0:  # проблемный случай, если в промежутке от текущего дня до тек день + 2 дня нет данных, то сформировать как нулевые
        combin_graph[
            need_date.iloc[0]] = cum_column + combin_graph[need_date.iloc[0]]
    else:
        combin_graph['first_column'] = cum_column
        combin_graph['second_column'] = 0
        combin_graph['third_column'] = 0
        combin_graph.columns = [
            NOW, NOW + timedelta(days=1), NOW + timedelta(days=2)
        ]

    # создание мультииндекса, где верхний уровень отклонение от первого дня
    columns = Series(
        combin_graph.columns).diff().map(extract_day).cumsum().replace(
            {None: 0})
    combin_graph.columns = [columns, combin_graph.columns]

    filter1 = combin_graph.sum(axis=1).replace({0: None}).notna()

    combin_graph[filter1].to_csv(name_combin_graph, sep=";", encoding='ansi')
    combin_graph[filter1].to_csv(name_combin_graph_excel,
                                 sep=";",
                                 encoding='ansi')
Exemple #8
0
def main_deficit_table(table: DataFrame) -> DataFrame:
    """Создание заготовки главной таблицы ежедневного отчета по дефициту

    :param table: таблица с подготовленными данными output_req из deficit()
    """
    need_columns = [
        'Номер победы', 'Партия', 'Дата запуска', 'Номенклатура',
        'Количество в заказе', 'Заказчик', 'Изделие', 'Остаток дефицита',
        'Дата начала факт'
    ]
    group_columns = [
        'Номер победы', 'Партия', 'Дата запуска', 'Заказчик', 'Изделие',
        'Дата начала факт'
    ]
    problems = compare_with_prev_ask(
        table
    )  # готовая таблица с индикатором проблем (переносы, отклонение потреб)

    detail_table = table[need_columns].copy()
    detail_table = detail_table.groupby(by=group_columns).sum().reset_index()
    detail_table['Проблема'] = None
    detail_table['Обеспеченность'] = 1 - (detail_table['Остаток дефицита'] /
                                          detail_table['Количество в заказе'])
    detail_table['Остаточная потребность'] = None
    detail_table['Дата запуска ФАКТ'] = detail_table['Дата начала факт']
    del detail_table['Дата начала факт']
    detail_table = detail_table[detail_table['Остаток дефицита'] >= 0.01]
    detail_table = detail_table.sort_values(by=['Дата запуска'])

    first_table = list()
    for i in range(len(detail_table)):  # заполнение первой таблицы отчета
        row = detail_table.iloc[i]
        first_table.append(row.to_list())

        nomenclature_row = table[(table['Номер победы'] == row['Номер победы'])
                                 & (table['Партия'] == row['Партия']) &
                                 (table['Остаток дефицита'] > 0)].copy()
        nomenclature_row['Заказчик'] = nomenclature_row['Номенклатура']
        nomenclature_row['Остаточная потребность'] = nomenclature_row[
            'Остаток дефицита']

        nomenclature_row = nomenclature_row.merge(
            problems,
            how='left',
            on=['Номер победы', 'Партия', 'Номенклатура'])

        nomenclature_row['Обеспеченность'] = None
        nomenclature_row['Дата запуска ФАКТ'] = None
        row_columns = set(
            table.columns) - {'Заказчик', 'Остаточная потребность'}
        nomenclature_row[list(row_columns)] = None
        nomenclature_row = nomenclature_row[detail_table.columns]
        for ii in range(len(nomenclature_row)):
            first_table.append(nomenclature_row.iloc[ii].to_list())

    # работа с колонками
    first_table = DataFrame(data=first_table, columns=detail_table.columns)
    first_table = first_table[[
        'Дата запуска', 'Дата запуска ФАКТ', 'Заказчик', 'Изделие',
        'Номер победы', 'Партия', 'Остаточная потребность', 'Обеспеченность',
        'Проблема'
    ]]
    first_table = first_table.rename(
        columns={
            'Дата запуска': 'Дата запуска ПЛАН',
            'Заказчик': 'Заказчик/Сортамент',
            'Номер победы': '№ заказа'
        })
    first_table['Дата закрытия дефицита с учетом поступлений'] = None
    first_table['Примечание МТО'] = None
    first_table['Примечание ПО'] = None
    # first_table['Дата запуска ФАКТ'] = first_table['Дата запуска ФАКТ'].replace({'0': None})

    # добавление колонки с датами закрытия дефицита из поступлений
    # если в строчке номенклатура, то дата закрытия дефицита номенклатуры из поступлений
    # если в строчке заказ, то дата закрытия заказа
    name_oper = r'.\support_data\output_tables\oper_{0}.csv'.format(
        NOW.strftime('%Y%m%d'))
    data_oper = read_csv(name_oper,
                         sep=";",
                         encoding='ansi',
                         parse_dates=['Дата учета'])
    data_oper.to_csv(
        f'W:\\Analytics\\Илья\\!deficit_work_files\\oper {NOW.strftime("%y%m%d %H_%M_%S")}.csv',
        sep=";",
        encoding='ansi',
        index=False)  # запись используемых файлов, для взгляда в прошлое

    done_orders = table.copy()
    done_orders['Заказ-Партия'] = done_orders[
        'Номер победы'] + '-' + done_orders['Партия'].map(str)
    done_orders = done_orders.groupby(
        by='Заказ-Партия')['Остаток дефицита с поступлениями'].sum(
        ).reset_index()
    done_orders = done_orders[done_orders['Остаток дефицита с поступлениями']
                              == 0]

    data_for_orders = data_oper[(data_oper['Склад'] == 'Поступления') & (
        data_oper['Заказ-Партия'].isin(done_orders['Заказ-Партия']))][[
            'Заказ-Партия', 'Дата учета'
        ]]
    data_for_orders = data_for_orders.groupby(
        by='Заказ-Партия')['Дата учета'].max().reset_index()

    data_for_nomen = data_oper[(data_oper['Склад'] == 'Поступления')
                               & (data_oper['Потребность кон'] == 0)][[
                                   'Заказ-Партия', 'Номенклатура потребности',
                                   'Дата учета'
                               ]]
    data_for_nomen = data_for_nomen.rename(
        columns={'Номенклатура потребности': 'Заказчик/Сортамент'})

    first_table['Партия'] = first_table['Партия'].fillna('nan')
    first_table['Заказ-Партия'] = first_table['№ заказа'] + '-' + first_table[
        'Партия'].map(lambda x: str(int(x)) if (x is not 'nan') else None)
    first_table['Партия'] = first_table['Партия'].replace({'nan': None})
    first_table['Заказ-Партия'] = first_table['Заказ-Партия'].ffill()
    first_table = first_table\
        .merge(data_for_orders, on='Заказ-Партия', how='left')\
        .rename(columns={'Дата учета': 'Дата учета заказ'})
    first_table = first_table \
        .merge(data_for_nomen, on=['Заказ-Партия', 'Заказчик/Сортамент'], how='left') \
        .rename(columns={'Дата учета': 'Дата учета номен'})
    first_table['Дата закрытия дефицита с учетом поступлений'] = first_table['Дата учета номен']\
        .where(first_table['Дата запуска ПЛАН'].isna(), first_table['Дата учета заказ'])
    del first_table['Дата учета заказ'], first_table[
        'Дата учета номен'], first_table['Заказ-Партия']

    return first_table