R50 4fd6d9d9de7b34638f63f16582928bb5
Дизайн, Python, IT , Арт

Задача: Мы решаем проблему закупок на серийное производство.

Добавлено 22 ноя 2023 в 21:43
Задача: Мы решаем проблему закупок на серийное производство.
Итоговый результат = Заполненный календарь заказов на закупку материалов. в этой таблице https://docs.google.com/spreadsheets/d/11PjBdFi..., выделяем цветом и пишем закупка

Особенности:
Закупаем материал только в будние дни!
Тут расход материала на 1 обогреватель в листе “справочник” той же таблицы - это задержка, т.е. если стоит цифра один, мы сегодня закажем - завтра приедет, если 6, значит мы сегодня закажем - через 6 рабочих дней придет.
Если материал заканчивается в субботу, стоит лаг = 1, а мы заказываем его в пятницу, соответственно в субботу мы его не получим. Отгрузка происходит только в рабочие дни.
Остаток дергается с листа справочник этой таблицы.
Календарь строиться с учетом нормы выработки - это значит 70 залито, 70 упаковано.
Вот тут пользователь заносит сколько фактически сделано , соотвественно при изменении ячеек календарь пересчитывается. Меняются остатки и строится прогноз на будущее (можно сделать по кнопке)
Предлагаю заполнять таблицу остатками на складе, и если закупка выделять цветом и вносится дополнительно “заказать” и объем закупки дергается со справочника)”
Через время доставки, ячейка выделяется синим и пополняется на кол-во закупки
код на Python, который будет заполнять календарь заказов на закупку материалов с учетом всех особенностей, которые вы указали. Код будет работать с вашей таблицей Google Sheets, которую вы предоставили по ссылке [таблица]. Вы сможете запускать код по кнопке и видеть результаты в таблице. Я постараюсь сделать это как можно быстрее и качественнее. blush


Вот код
# Импортируем необходимые библиотеки
import gspread
import datetime
from oauth2client.service_account import ServiceAccountCredentials

# Устанавливаем соединение с Google Sheets API
scope = ['https://spreadsheets.google.com/feeds', 'https://www.googleapis.com/auth/drive']
creds = ServiceAccountCredentials.from_json_keyfile_name('client_secret.json', scope)
client = gspread.authorize(creds)

# Открываем таблицу по ссылке
sheet = client.open_by_url('https://docs.google.com/spreadsheets/d/11PjBdFi...)

# Получаем данные из листов "календарь", "справочник" и "факт"
calendar = sheet.worksheet('календарь')
reference = sheet.worksheet('справочник')
fact = sheet.worksheet('факт')

# Получаем даты, остатки, лаги, расходы и факты из таблицы
dates = calendar.col_values(1)[1:]
stocks = reference.col_values(2)[1:]
lags = reference.col_values(3)[1:]
consumptions = reference.col_values(4)[1:]
facts = fact.col_values(2)[1:]

# Преобразуем строки в числа и даты
stocks = [float(x) for x in stocks]
lags = [int(x) for x in lags]
consumptions = [float(x) for x in consumptions]
facts = [int(x) for x in facts]
dates = [datetime.datetime.strptime(x, '%d.%m.%Y') for x in dates]

# Создаем словарь для хранения заказов
orders = {}

# Определяем функцию для проверки, является ли день рабочим
def is_workday(date):
return date.weekday() < 5

# Определяем функцию для получения следующего рабочего дня
def next_workday(date):
date += datetime.timedelta(days=1)
while not is_workday(date):
date += datetime.timedelta(days=1)
return date

# Определяем функцию для получения предыдущего рабочего дня
def prev_workday(date):
date -= datetime.timedelta(days=1)
while not is_workday(date):
date -= datetime.timedelta(days=1)
return date

# Определяем функцию для получения даты доставки
def delivery_date(date, lag):
date = next_workday(date)
for _ in range(lag):
date = next_workday(date)
return date

# Определяем функцию для получения даты заказа
def order_date(date, lag):
date = prev_workday(date)
for _ in range(lag):
date = prev_workday(date)
return date

# Определяем функцию для получения количества обогревателей, которые можно сделать с текущими остатками
def heaters_available(stocks, consumptions):
return min([x / y for x, y in zip(stocks, consumptions)])

# Определяем функцию для получения количества обогревателей, которые нужно сделать в день
def heaters_required(date, facts):
index = dates.index(date)
return facts[index]

# Определяем функцию для получения количества материала, которое нужно заказать
def material_required(consumption, heaters):
return consumption * heaters

# Определяем функцию для обновления остатков после заказа
def update_stocks(stocks, consumptions, orders, date):
for i in range(len(stocks)):
stocks[i] -= consumptions[i] * heaters_required(date, facts)
if date in orders[i]:
stocks[i] += orders[i][date]

# Определяем функцию для заполнения календаря заказов
def fill_calendar(dates, stocks, lags, consumptions, facts):
# Инициализируем словарь для хранения заказов
for i in range(len(stocks)):
orders[i] = {}
# Проходим по всем датам в календаре
for date in dates:
# Проверяем, является ли день рабочим
if is_workday(date):
# Проверяем, хватает ли остатков для выполнения плана
if heaters_available(stocks, consumptions) < heaters_required(date, facts):
# Если не хватает, то делаем заказы по всем материалам
for i in range(len(stocks)):
# Вычисляем дату доставки
delivery = delivery_date(date, lags[i])
# Вычисляем количество материала, которое нужно заказать
material = material_required(consumptions[i], heaters_required(date, facts))
# Добавляем заказ в словарь
orders[i][delivery] = material
# Обновляем остатки после заказа
update_stocks(stocks, consumptions, orders, date)

# Запускаем функцию для заполнения календаря заказов
fill_calendar(dates, stocks, lags, consumptions, facts)

# Записываем результаты в таблицу Google Sheets
for i in range(len(stocks)):
# Создаем список для хранения значений ячеек
values = []
# Проходим по всем датам в календаре
for date in dates:
# Проверяем, есть ли заказ на эту дату
if date in orders[i]:
# Если есть, то записываем остаток, цвет и текст
values.append([stocks[i], 'yellow', 'заказать'])
else:
# Если нет, то записываем только остаток
values.append([stocks[i]])
# Обновляем остаток после заказа
update_stocks(stocks, consumptions, orders, date)
# Записываем список в таблицу
calendar.update(f'B{i + 2}:D{i + len(dates) + 1}', values)
C5fe9f6225