def handle(self, *args, **options): now = datetime.datetime.now() #seven_days_ago = date_plus_days(now, days=-7) #start_date = seven_days_ago.strftime('%Y-%m-%d') year_ago = date_plus_days(now, days=-365) start_date = year_ago.strftime('%Y-%m-%d') end_date = now.strftime('%Y-%m-%d') if options.get('start_date'): date = str_to_date(options['start_date']) if date: start_date = date if options.get('end_date'): date = str_to_date(options['end_date']) if date: end_date = date api = APIJDOCS() #print(start_date, end_date) if options.get('check_lot'): # UP2618689 / m28195967844 test_lot = api.load_exmple_from_old_format(options['check_lot']) api.prepare_data([test_lot]) return if options.get('get_lots'): #print(json_pretty_print(api.get_lots(start_date, end_date))) lots = api.get_lots(start_date, end_date) #print(len(lots)) api.prepare_data(lots)
def handle(self, *args, **options): today = datetime.date.today() end_date = date_plus_days(today, days=1) start_date = date_plus_days(end_date, days=-360) # --------------------------- # Задать дату начала парсинга # --------------------------- if options.get('start'): date = str_to_date(options['start']) if date: start_date = date # ------------------------------ # Задать дату окончания парсинга # ------------------------------ if options.get('end'): date = str_to_date(options['end']) if date: end_date = date root_url = "http://jsmnew.doko.link/service_api.php" key = "d296c101daa88a51f6ca8cfc1ac79b50" urla = "{}?key={}&module=yahoo&startDate={}&endDate={}".format(root_url, key, start_date.strftime("%Y-%m-%d"), end_date.strftime("%Y-%m-%d")) fname = "ylots.json" r = requests.post(urla) content = r.json() f = open_file(fname, "w+") f.write(json.dumps(content)) f.close()
def get_admission_sheet(row, i: int, welder, with_date: bool = False): """Допускной лист :param row: строка :param i: номер ячейки :param welder: сварщик :param with_date: столбик с датой """ admission_sheet = None admission_number = row[i].value admission_date = None if admission_number: if with_date: # дата - следующая ячейка после номера admission_date = row[i + 1].value admission_date = str(admission_date).strip().replace('г', '') admission_date = str_to_date(admission_date) admission_number = str(admission_number).strip() admission_sheet = AdmissionSheet.objects.filter( number=admission_number).first() if not admission_sheet: admission_sheet = AdmissionSheet(number=admission_number) admission_sheet.welder = welder admission_sheet.date = admission_date admission_sheet.save() return admission_sheet
def cond_for_query(self, key: str, value: str, types: dict, query): """Подготовка условия для запроса в зависимости от типа параметра :param key: название поля :param value: значения поля :param types: типы полей :param query: QuerySet """ if types[key] in ('int', 'float', 'primary_key', 'boolean'): query = query.filter(**{key: value}) # -------------------------------------- # По дате производим нестандартный поиск # -------------------------------------- elif types[key] in ('date', 'datetime'): value = str_to_date(value) if value: if types[key] == 'datetime' and isinstance( value, datetime.date): start_date = datetime.datetime(value.year, value.month, value.day, 0, 0, 0) end_date = datetime.datetime(value.year, value.month, value.day, 23, 59, 59) query = query.filter( **{'%s__range' % (key, ): [start_date, end_date]}) else: query = query.filter(**{key: value}) else: key = '%s__icontains' % key query = query.filter(**{key: value}) return query
def calls_history(request): """Загрузить историю звонков по пользователю""" result = {} shopper = get_shopper(request) if request.method == 'GET' and shopper: date = str_to_date(request.GET.get('date')) if not date: date = datetime.date.today() start_date = '%s-%s-%s 00:00:00' % (date.year, date.month, date.day) end_date = '%s-%s-%s 23:59:59' % (date.year, date.month, date.day) params = { 'page': request.GET.get('page', 0), 'filter__created__lte': end_date, 'filter__created__gte': start_date, 'order__created': 'desc', 'only_fields': 'dest,created,duration,billing,state,client_name', } headers = { 'token': '%s-%s' % (settings.FS_USER, shopper.id), } r = requests.get('%s/freeswitch/cdr_csv/api/' % settings.FREESWITCH_DOMAIN, params=params, headers=headers) result = r.json() return JsonResponse(result, safe=False)
def load_titul(): cur_titul = Titul.objects.filter(name='У920').first() if not cur_titul: logger.info('[ERROR]: titul У920 not found') return i = 0 wb = open_wb('920.xlsx') sheet = wb.active rows = sheet.rows for row in rows: if i < 2: i += 1 continue cell_values = [cell.value for cell in row] line_str = cell_values[0].strip() joint_str = '%s' % cell_values[1] joint_str = joint_str.strip() stigma = None if cell_values[2]: stigma = cell_values[2].strip() material = cell_values[3].strip() diameter = '%s' % cell_values[4] diameter = diameter.strip().replace(',', '.') side_thickness = '%s' % cell_values[5] side_thickness = side_thickness.strip().replace(',', '.') welding_date = '%s' % cell_values[6] welding_date = welding_date.strip() if welding_date.endswith('/20'): welding_date = '%s2020' % welding_date[:-2] welding_date = str_to_date(welding_date) welding_type = cell_values[7].strip() conn_view = cell_values[8].strip() el1 = cell_values[9].strip() el2 = cell_values[10].strip() line = Line.objects.filter(name=line_str).first() if line: joint = Joint.objects.filter(name=joint_str, line=line).first() if not joint: joint = Joint( line=line, name=joint_str, ) joint.diameter = diameter joint.side_thickness = side_thickness joint.welding_date = welding_date joint.material = search_choice(replace_eng2rus(material.upper()), MATERIALS) joint.welding_type = search_choice( replace_eng2rus(welding_type.upper()), WELDING_TYPES) joint.welding_conn_view = search_choice( replace_eng2rus(conn_view.upper()), Joint.welding_conn_view_choices) joint.join_type_from = search_choice(replace_eng2rus(el1.lower()), JOIN_TYPES) joint.join_type_to = search_choice(replace_eng2rus(el2.lower()), JOIN_TYPES) joint.save() else: print('линия не найдена %s стык %s' % (line_str, joint_str))
def get_welding_date(value): """Находим дату сварки :param value: значение даты """ if not value: return welding_date_str = '%s' % value welding_date_str = welding_date_str.replace(',', '.') return str_to_date(welding_date_str.strip())
def handle(self, *args, **options): wipe() #exit() # ---------------------------------- # Парсим всегда с завтрашнего числа, # чтобы увидеть все сеансы # ---------------------------------- today = datetime.date.today() start_date = date_plus_days(today, days=1) end_date = date_plus_days(today, days=10) # --------------------------- # Задать дату начала парсинга # --------------------------- if options.get('start'): date = str_to_date(options['start']) if date: start_date = date # ------------------------------ # Задать дату окончания парсинга # ------------------------------ if options.get('end'): date = str_to_date(options['end']) if date: end_date = date if start_date > end_date: end_date = date_plus_days(start_date, days=1) rubrics, genres = get_rubrics() cur_date = start_date while cur_date <= end_date: RSeances.objects.filter(date=cur_date).delete() for genre in genres: logger.info('{} {}'.format(genre.tag, genre.name)) if 'cinema' in genre.tag: get_cinema_seances(cur_date) else: get_seances(genre.tag, cur_date) cur_date = date_plus_days(cur_date, days=1)
def metrika(request): """Страничка для отчета по апи Яндекс.Метрики """ context = {} context.update(metrika_vars) method = request.GET if request.method == 'POST': method = request.POST params = {} proxies = {} ip = method.get('ip') if ip: params['filters'] = '(ym:s:paramsLevel2=@\'%s\')' % ip dates = method.get('dates') date1 = None date2 = None if dates: dates_arr = dates.split(' - ') date1 = str_to_date(dates_arr[0]) date2 = str_to_date(dates_arr[1]) if date1: params['date1'] = date1.strftime('%Y-%m-%d') if date2: params['date2'] = date2.strftime('%Y-%m-%d') ym = YandexMetrika() if request.is_ajax(): result = {} action = method.get('action') if action == 'bad_users': result = ym.get_bad_users(**params) elif action == 'weak_users': result = ym.get_weak_users(**params) elif action == 'robots': result = ym.get_robots(**params) return JsonResponse(result, safe=False) template = 'yandex_metrika.html' return render(request, template, context)
def migrate_joints(): """Выполняется после миграции""" f = open_file('migrate_joints.json') data = json.loads(f.read()) f.close() for welding_joint in data: joint = Joint.objects.filter(pk=welding_joint['id']).first() if not joint: logger.info('joint is absent %s' % welding_joint['id']) continue if welding_joint['diameter']: joint.diameter = welding_joint['diameter'] if welding_joint['side_thickness']: joint.side_thickness = welding_joint['side_thickness'] joint.welding_date = str_to_date(welding_joint['welding_date']) joint.save()
def get_vik(row, i: int, welder): """Создать/обновить Акт ВИК :param row: строка :param i: номер ячейки :param welder: сварщик """ vik = None vik_number = row[i].value # дата - следующая ячейка после номера vik_date = row[i + 1].value if vik_number and vik_date: vik_number = str(vik_number).strip() vik_date = str(vik_date).strip().replace('г', '') vik_date = str_to_date(vik_date) vik = Vik.objects.filter(number=vik_number).first() if not vik: vik = Vik(number=vik_number) vik.date = vik_date vik.welder = welder vik.save() return vik
def get_mechtest(row, i: int, welder): """Мехиспытание :param row: строка :param i: номер ячейки :param welder: сварщик """ mechtest = None mechtest_number = row[i].value # дата - следующая ячейка после номера mechtest_date = row[i + 1].value if mechtest_number and mechtest_date: mechtest_number = str(mechtest_number).strip() mechtest_date = str(mechtest_date).strip().replace('г', '') mechtest_date = str_to_date(mechtest_date) mechtest = MechTest.objects.filter(number=mechtest_number).first() if not mechtest: mechtest = MechTest(number=mechtest_number) mechtest.date = mechtest_date mechtest.welder = welder mechtest.save() return mechtest
def get_controlk(row, i: int, welder): """УЗК/РК контроль :param row: строка :param i: номер ячейки :param welder: сварщик """ controlk = None control_number = row[i].value # дата - следующая ячейка после номера control_date = row[i + 1].value if control_number and control_date: control_number = str(control_number).strip() control_date = str(control_date).strip().replace('г', '') control_date = str_to_date(control_date) controlk = ControlK.objects.filter(number=control_number).first() if not controlk: controlk = ControlK(number=control_number) controlk.date = control_date controlk.welder = welder controlk.save() return controlk
def get_currency_cbr(date=None): """Получить курс валют за дату :param date: дата за которую запрашиваем курс """ if not date: date = datetime.date.today() elif type(date) in (str, unicode): date = str_to_date(date) if not date: return [] urla = 'https://www.cbr.ru/scripts/XML_daily.asp' params = { 'date_req': date.strftime("%d/%m/%Y"), } r = requests.get(urla, params=params) result = r.text handler = CBRCurrencyParser() xml.sax.parseString(result, handler) return handler.result
def handle(self, *args, **options): s = requests.Session() today = datetime.date.today() end_date = date_plus_days(today, days=1) start_date = date_plus_days(end_date, days=-1) sessid = 'vg8gii226edl4iv7nfm5fsfd25' # ------------------ # Задать дату начала парсинга # ------------------ if options.get('start'): date = str_to_date(options['start']) if date: start_date = date # --------------------- # Задать дату окончания парсинга # --------------------- if options.get('end'): date = str_to_date(options['end']) if date: end_date = date # ------------- # Задать сессию # ------------- if options.get('sessid'): sessid = options['sessid'] s.cookies.update({'PHPSESSID': sessid}) urla = 'https://jsmnew.doko.link/jp_jsm_balance.php' urla = 'https://jsmnew.doko.link/jp_victoria_balance_ajax.php' params = { 'client': 181, 'an': end_date.year, 'luna': 'все', 'dinterv': 1, 'datas': start_date.strftime('%d.%m.%Y'), 'datae': end_date.strftime('%d.%m.%Y'), } headers = { 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'Accept-Encoding': 'gzip, deflate, br', 'Accept-Language': 'en-US,en;q=0.5', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive', 'Cookie': 'PHPSESSID=%s' % sessid, 'Host': 'jsmnew.doko.link', 'Pragma': 'no-cache', 'Referer': 'https://jsmnew.doko.link/menu.php', 'Upgrade-Insecure-Requests': '1', 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:81.0) Gecko/20100101 Firefox/81.0', } r = s.get(urla, params=params, headers=headers) tree = html.fromstring(r.text) spans = tree.xpath('//span') for i, span in enumerate(spans): if span.text and 'ОБЩИЙ БАЛАНС' in span.text: print(spans[i + 1].text) break
def standard_show(self, only_query: bool = False, only_fields: list = None, related_fields: list = ()): """Стандартный вывод данных по модели filters = Q(name__isnull=True)|Q(name="") :param only_query: просто вернуть запрос с фильтрами :param only_fields: достать только определенные поля :param related_fields: ссылающиеся объекты (OneToOneRel) для фильтра """ result = [] # -------------------------- # Если прав нету на просмотр # - ну тогда "пасется" пусть # -------------------------- if not self.permissions['view']: if only_query: return self.model.objects.none() paginator, records = myPaginator(0, self.q_string['page'], self.q_string['by']) self.raw_paginator = paginator self.context['raw_paginator'] = self.raw_paginator self.paginator = navigator(paginator, self.q_string, self.paginator_template) self.context['paginator'] = self.paginator self.context['rows'] = result return result # ---------------------------- # OneToOneRel поля для фильтра # ---------------------------- related_types = {} if related_fields: for item in self.model._meta.related_objects: if item.name in related_fields and isinstance( item, fields.related.OneToOneRel): related_types[item.name] = object_fields_types( item.related_model()) types = object_fields_types(self.model()) query = self.model.objects.all() if self.select_related: query = query.select_related(*self.select_related) if only_fields: query = query.only(*only_fields) q = None if self.request: # ---------- # GET / POST # ---------- for q_var in ('q', 'data[q]'): if self.request.method == 'GET': if self.request.GET.get(q_var) and self.search_fields: q = self.request.GET[q_var] if self.request.method == 'POST': if self.request.POST.get(q_var) and self.search_fields: q = self.request.POST[q_var] # ------------------------------------------- # Если вдруг поисковая фраза не в q-параметре # ------------------------------------------- if self.q: q = self.q cond = Q() if q: if not self.q: # ----------------------------------------- # Мы не хотим, чтобы q писалось в # постраничную пагинацию параметром, # поэтому вообще не вносим его в q_string # это можно сделать после l.standard_show() # во view (l.q_string['q']['q'] = q # ----------------------------------------- self.q_string['q']['q'] = q # ----------------- # RAW / сырой поиск # ----------------- raw_qqize = [] q_array = q.split(' ') for item in q_array: tmp_cond = Q() for field in self.search_fields: if field in types: # --------------------------- # По целому числу, возможно, # стоит сделать строгий поиск # ("primary_key", "int") # --------------------------- # -------------------------------------- # По дате производим нестандартный поиск # -------------------------------------- if types[field] in ('date', 'datetime'): d = str_to_date(q) if d: tmp_cond.add(Q(**{field: d}), Q.OR) continue else: key = '%s__icontains' % field tmp_cond.add(Q(**{key: item}), Q.OR) raw_qqize.append(item) elif '__' in field: # Похоже ищем foreign_key fkey = field.rsplit('__', 1)[0] if fkey in self.select_related: key = '%s__icontains' % field tmp_cond.add(Q(**{key: item}), Q.OR) raw_qqize.append(item) if tmp_cond: cond.add(tmp_cond, Q.AND) # ----------------------------------------------------- # Заполняем слова для подсветки (если они не заполнены, # что гарантировано, если мы не юзаем поиск по индексу) # ----------------------------------------------------- if not self.words: self.words = raw_qqize # ------------------------------------------------------- # Чтобы расширить поиск скажем своим списком айдишников, # нужно ввести это условие как Q.OR тогда сможем искать # стандартным поиском, однако добавлять свои результаты # скажем необходимо найти запись по переводу из Languages # ------------------------------------------------------- if self.custom_filter: query = query.filter(Q(cond) | Q(self.custom_filter)) else: query = query.filter(cond) if self.filters: for item in self.filters: # ----------------------------------- # Принимаем в фильтры словарь или Q() # ----------------------------------- if isinstance(item, dict): key, value = item.popitem() if key in types: query = self.cond_for_query(key, value, types, query) elif '__' in key: key_arr = key.split('__') related_model = key_arr[-2] related_field = key_arr[-1] # -------------------------- # Обратная связь OneToOneRel # -------------------------- if related_types: if related_model in related_types and related_field in related_types[ related_model]: prefix = '__'.join(key_arr[:-1]) custom_types = { '%s__%s' % (prefix, k): v for k, v in related_types[related_model].items() if k == related_field } query = self.cond_for_query( key, value, custom_types, query) continue # ------------------------------ # Прямая связь на OneToOneRel/FK # ForwardOneToOneDescriptor # field.field.model - эта модель # field.field.remote_field.model # на связанную модель # ------------------------------ if related_model in types and types[ related_model] == 'foreign_key': field = getattr(self.model, related_model) remote_types = object_fields_types( field.field.remote_field.model()) prefix = '__'.join(key_arr[:-1]) remote_types = { '%s__%s' % (prefix, k): v for k, v in remote_types.items() if k == related_field } rfield = '%s__%s' % (prefix, related_field) query = self.cond_for_query( rfield, value, remote_types, query) continue query = query.filter(**{key: value}) elif isinstance(item, Q): query = query.filter(item) if self.excludes: for item in self.excludes: query = query.exclude(item) # ---------------------------- # Вернуть запрос для отдельных # предварительных манипуляций # ---------------------------- self.query = query if only_query: return query total_records = query.aggregate(Count("id"))['id__count'] paginator, records = myPaginator(total_records, self.q_string['page'], self.q_string['by']) self.raw_paginator = paginator self.context['raw_paginator'] = self.raw_paginator self.paginator = navigator(paginator, self.q_string, self.paginator_template) self.context['paginator'] = self.paginator if not total_records: self.context['rows'] = [] return [] if self.custom_order: order_by = [ 'ordering', ] # ---------- # Сортировки # ---------- if self.order_by: for item in self.order_by: order_by.append(item) query = query.extra(select={ 'ordering': self.custom_order, }, order_by=order_by) # ---------- # Сортировки # ---------- if self.order_by and not self.custom_order: query = query.order_by(*self.order_by) result = query[records['start']:records['end']] self.context['rows'] = result # ------- # Перевод # ------- if settings.IS_DOMAINS: domains = get_translate(result, self.context['domains']) # --------------------------------- # отдаем перевод по текущему домену # --------------------------------- if self.request and get_admin_translate_rows(self.request): domain = get_domain(self.request, domains, priority='session') translate_rows(result, domain) return result
def schedule_constructor(request, *args, **kwargs): """Изменение расписаний демона через fullcalendar""" result = {} if not request.is_ajax(): return JsonResponse(result, safe=False) body = request.GET if request.method == 'POST': body = request.POST robot_id = body.get('robot') schedule_id = body.get('id') action = body.get('action') title = body.get('title') event = None for schedule in Schedule.event_choices: if schedule[1] == title: event = schedule[0] start = str_to_date(body.get('start')) end = str_to_date(body.get('end')) robot = Robots.objects.filter(pk=robot_id).first() if action == 'new': if robot and event and start and end: new_schedule = Schedule.objects.create(robot=robot, event=event, start=start, end=end) result['start'] = start result['end'] = end result['id'] = new_schedule.id elif action == 'edit': schedule = Schedule.objects.filter(pk=schedule_id).first() if schedule and start and end: Schedule.objects.filter(pk=schedule.id).update(start=start, end=end) result['start'] = start result['end'] = end result['id'] = schedule.id elif action == 'show': if robot and start and end: result = [] schedules = Schedule.objects.filter(robot=robot, start__gte=start, end__lte=end) for schedule in schedules: result.append({ 'id': schedule.id, 'title': schedule.get_event_display(), 'start': schedule.start.strftime('%Y-%m-%dT%H:%M:%S'), 'end': schedule.end.strftime('%Y-%m-%dT%H:%M:%S'), 'allDay': False, }) elif action == 'drop': schedule = Schedule.objects.filter(pk=schedule_id).first() if schedule: result['id'] = schedule.id schedule.delete() return JsonResponse(result, safe=False)
def save_row(self, pass_fields: tuple = (), set_fields: dict = None): """Сохранение записи - запись значений row_vars, если нужно записать свои значения, тогда, просто пишем в row_vars заданные значения :param pass_fields: пропустить поля :param set_fields: задать свои значения для полей """ if not self.row or not self.row_vars: return None if not set_fields: set_fields = {} # -------------------- # Находим ForeignKey's # -------------------- foreign_keys = object_foreign_keys(self.row) types = object_fields_types(self.row) # -------------------------------------- # Значения полей, указанные по умолчанию # -------------------------------------- default_values = object_default_values(self.model) auto_now_fields = object_auto_now_fields(self.model) for key, value in self.row_vars.items(): if key in pass_fields or key == 'img': continue if value is None: if key in types: if types[key] in ('date', 'datetime'): value = default_values.get(key) # --------------------------------------------------- # Обработка данных в соответствии с типом поля модели # --------------------------------------------------- elif key in types: if types[key] == 'int': try: value = int(value) except ValueError: value = None elif types[key] == 'boolean': try: value = int(value) except ValueError: value = False if value: value = True elif types[key] == 'float': if value == "nan": value = None else: try: value = float(value) except ValueError: value = None elif types[key] in ('date', 'datetime'): if not isinstance(value, (datetime.date, datetime.datetime)): value = str_to_date(value) if not value and key in auto_now_fields: value = default_values.get(key) elif types[key] == 'foreign_key' and value: if not key in foreign_keys: value = None elif not type(value) == type(foreign_keys[key]): # ------------------ # Находим ForeignKey # ------------------ try: value = foreign_keys[key].objects.get( pk=int(value)) except ValueError: continue except foreign_keys[key].DoesNotExist: continue setattr(self.row, key, value) # --------------------------------- # Переопределение своими значениями # --------------------------------- if set_fields: for key, value in set_fields.items(): setattr(self.row, key, value) # --------------------------- # Проверка на unique_together # --------------------------- unique_together = self.model._meta.unique_together for pair in unique_together: cond = {field: getattr(self.row, field) for field in pair} analogs = self.model.objects.filter(**cond) # самого себя то не надо считать дубликатом if self.row.id: analogs = analogs.exclude(id=self.row.id) analog = analogs.values_list('id', flat=True) # ------------ # Пишем ошибку # ------------ if analog: self.error = 'Вы создаете дубль' if self.row.id: self.error = 'Нельзя сделать дубль' return None self.row.save() # --------------- # Загружаем файлы # --------------- self.uploads() # ------- # Перевод # ------- if settings.IS_DOMAINS: domains = save_translate(self.row, self.row_vars, self.request.POST) return self.row
def get_nax(row, i: int, welder, wrong_order: bool = False): """Аттестат (НАКС) :param row: строка :param i: номер ячейки :param welder: сварщик :param wrong_order: другой порядок полей """ nax = None # Номер удостоверения nax_number = row[i].value # способ сварки - следующая ячейка после номера nax_welding_type = row[i + 1].value # годен до - следующая ячейка после способа сварки nax_best_before = row[i + 2].value # НГДО/СК - следующая ячейка после годен до nax_acl = row[i + 3].value # место удостоверения - следующая ячейка после НГДО/СК nax_identification = row[i + 4].value # полугодовая отметка - следующая ячейка после места удостоверения nax_half_year_mark = row[i + 5].value if wrong_order: # способ сварки nax_welding_type = row[i].value # Номер удостоверения - следующая ячейка после способа сварки nax_number = row[i + 1].value # НГДО/СК nax_acl = None # место удостоверения nax_identification = None # полугодовая отметка nax_half_year_mark = None if nax_number and nax_best_before and nax_welding_type: number = str(nax_number).strip() nax_welding_type = str(nax_welding_type).strip().replace(' ', '') nax_best_before = str(nax_best_before).strip().replace('г', '') if nax_acl: nax_acl = str(nax_acl).strip() if nax_identification: nax_identification = str(nax_identification).strip() if nax_half_year_mark: nax_half_year_mark = str(nax_half_year_mark).strip() welding_type = None for item in WELDING_TYPES: if item[1] == nax_welding_type: welding_type = item[0] best_before = str_to_date(nax_best_before) if welding_type and best_before: nax = NAX.objects.filter(number=number).first() if not nax: nax = NAX(number=number) nax.best_before = best_before nax.welder = welder nax.identification = 1 if nax_identification else None nax.welding_type = welding_type nax.half_year_mark = True if nax_half_year_mark else False nax.acl = nax_acl nax.save() else: logger.info('something wrong: welding_type %s, best_before %s' % (nax_welding_type, nax_best_before)) return nax
def post_vars(self, pass_fields: list = None): """Получаем переменные из формы :param pass_fields: пропускаем поля """ if not self.request: self.error = 1 return None if not pass_fields: pass_fields = [] types = object_fields_types(self.model()) auto_now_fields = object_auto_now_fields(self.model) pass_fields += ('id', 'created', 'updated', 'img') row_vars = {} form_fields = [ field.name for field in self.model().__class__._meta.fields if not field.name in pass_fields ] for key in form_fields: value = self.request.POST.get(key, '') if value: value = value.strip() # --------------------------------------------------- # Обработка данных в соответствии с типом поля модели # данные из POST, там None НЕТУ # --------------------------------------------------- if key in types: if types[key] in ('int', 'foreign_key'): try: value = int(value) except ValueError: value = None elif types[key] == 'boolean': try: value = int(value) except ValueError: value = False if value: value = True elif types[key] == 'float': try: value = float(value.replace(',', '.')) except ValueError: value = None elif types[key] in ('date', 'datetime'): if key in auto_now_fields: continue value = str_to_date(value) else: logger.warning('there is no field %s in %s model types' % (key, self.model)) row_vars[key] = value if self.request.FILES: if self.request.FILES.get('img'): row_vars['img'] = self.request.FILES['img'] # Если мы хотим загрузить изображение не в текущую модель, # а, например, в галерею текущей модели (другая модель), # тогда просто pass_fields = ('grab_img_by_url', ), # и обрабатываем отдельно, например, так # new_photo = Photos() # new_photo.upload_img(request.POST.get('grab_img_by_url')) gibu = 'grab_img_by_url' in pass_fields if self.request.POST.get('grab_img_by_url') and not gibu: row_vars['img'] = self.request.POST['grab_img_by_url'] self.row_vars = row_vars
def save_from_excel(model, data, cond_fields: list = None, reverse_params: dict = None): """Сохранение массива в базу :param model: модель, в которую импортируем данные :param data: массив с данными для импорта :param cond_fields: поля по которым ищем аналоги (обновляем) :param reverse_params: словарь параметров, которые могут указывать на foreign keys # inject reverse params for build response # with correct foreign keys if reverse_params: item.update(reverse_params) """ result = {'errors': []} if not data: result['errors'].append('Не переданы данные для сохранения') return result if not cond_fields: result['errors'].append('Не переданы условия для обновления') return result field_types = object_fields_types(model()) fkeys = object_foreign_keys(model()) # Небольшой хак на foreign key + reverse_params # Убираем _id, и, # если у нас есть такой foreign key, # пробуем записать fk_updates = {} if reverse_params: for rparam, rvalue in reverse_params.items(): if not rparam.endswith('_id'): continue rparam_fk_name = rparam.replace('_id', '') if field_types.get(rparam_fk_name) == 'foreign_key': fk_updates[rparam] = rvalue create_tasks = [] update_tasks = [] cached_fk = {} for cond_field in cond_fields: if cond_field.count('__') == 1: del cond_fields[cond_fields.index(cond_field)] for item in data: cond = Q() # id обновлять - плохая затея for key in ('id', 'img', 'created', 'updated'): if key in item: del item[key] fordel = {} for k, v in item.items(): if not k in field_types: fordel[k] = v continue field_type = field_types[k] # Некоторые типы полей пока пропускаем if field_type in ('foreign_key', ): continue if v: item[k] = v.strip() if field_type in ('date', 'datetime'): item[k] = str_to_date(item[k]) elif field_type in ('int', ): try: item[k] = int(item[k]) except ValueError: item[k] = None elif field_type in ('boolean', ): item[k] = True if item[k] in (1, '1') else False # Дропаем всякое говно, которое не в полях модели for k, v in fordel.items(): del item[k] # Поддерживаем только одноуровневый fk # TODO: адаптировать под key1__key2__... (больше 1) вложенность # TODO: обработать по правилам поля (например, url до домена) if k.count('__') == 1: f_key, f_value = k.split('__') if not f_key in fkeys: continue if k in cached_fk: fk_obj = cached_fk[k] else: fk_model = fkeys[f_key] fk_obj = fk_model.objects.filter(**{f_value: v}).first() if not fk_obj: fk_obj = fk_model.objects.create(**{f_value: v}) cached_fk[k] = fk_obj cond.add(Q(**{f_key: fk_obj}), Q.AND) item[f_key] = fk_obj if fk_updates: item.update(fk_updates) for cond_field in cond_fields: cond.add(Q(**{cond_field: item.get(cond_field)}), Q.AND) print(cond) analog = model.objects.filter(cond).only('id').first() if analog: update_tasks.append({'id': analog.id, 'data': item}) else: create_tasks.append(item) with transaction.atomic(): for update_task in update_tasks: model.objects.filter(pk=update_task['id']).update( **update_task['data']) for create_task in create_tasks: model.objects.create(**create_task) result['created'] = len(create_tasks) result['updated'] = len(update_tasks) return result
def prepare_data_from_excel(excel_file, stigmas): """Подготовить проанализированные данные в том виде, в котором они будут выведены в базу :param excel_file: BytesIO(excel_file.read()) для request.FILES['file'] или путь к файлу :param stigmas: словарь с клеймами """ result = {'errors': []} wb = load_workbook(excel_file) sheet = wb.active rows = list(sheet.rows) if not len(rows) > 0: result['errors'].append('Файл пустой') return result i = 0 errors = [] names = {} data = [] unique_joints = [] required_keys = TITUL_REQUIRED_FIELDS.keys() for row in rows: if not names: for i, cell in enumerate(row): if cell.value in required_keys: names[i] = cell.value if not names: continue if not len(names.keys()) == len(required_keys): values = names.values() absent_names =[name for name in required_keys if not name in values] result['errors'].append('обязательные поля %s' % absent_names) break item = {} for ind, name in names.items(): value = row[ind].value if names[ind] == 'welding_date': value = str_to_date('%s' % value) if value: value = value.strftime('%Y-%m-%d') elif names[ind] in ('join_type_from', 'join_type_to'): value = search_join_type(value) elif names[ind] == 'welding_type': value = search_welding_type(value) elif names[ind] == 'material': value = search_material(value) elif names[ind] == 'welding_conn_view': value = search_conn_view(value) elif names[ind] == 'stigma': values = str(value).split() if value else [] value = '' for stigma in values: stigma = stigma.strip() if stigma in stigmas: value += '%s ' % stigma item[name] = value uniq_name = '%s%s' % (item['line'], item['joint']) if uniq_name in unique_joints: logger.info('duplet %s' % uniq_name) continue unique_joints.append(uniq_name) data.append(item) result['resp'] = {'data': data[1:]} if result['errors']: result['error'] = 'Ошибка при анализе файла' else: result['success'] = 'Проверьте данные и нажмите кнопку сохранения' return result
def more_lines_helper(path: str): """Загрузка дополнительных узлов в дополнительным линиям :param path: путь до эксельки """ subject = Subject.objects.all().first() wb = open_wb(path) sheet = wb.active rows = sheet.rows cur_titul = None for row in rows: cell_values = [cell.value for cell in row] # 1 - линия # 2 - стык # 3 - диаметр х тощина стенки # 4 - дата сварки # 5 - клеймо # 6 - вид сварного соединения # 7 - тип сварки # 12 - статус (новый/готов) digit = row[0].value if not digit: continue digit = str(digit) if 'Титул ' in digit: titul_str = digit.split('Титул ')[1] titul_str = titul_str.split(' ')[0] titul_str = titul_str.split('.')[0] titul = Titul.objects.filter(name=titul_str).first() if not titul: logger.info('[ERROR]: titul not found %s' % titul_str) cur_titul = Titul.objects.create(name=titul_str, subject=subject) else: cur_titul = titul #logger.info('TITUL %s' % cur_titul.name) diameter = side_thickness = date = stigma = welding_conn_view = welding_type = None joint_str = row[2].value size = row[3].value if size and ('х' in size or 'ъ' in size): size = str(size).strip() if 'ъ' in size: diameter, side_thickness = size.split('ъ') elif 'х' in size: diameter, side_thickness = size.split('х') elif 'x' in size: diameter, side_thickness = size.split('x') diameter = diameter.strip().replace(',', '.') side_thickness = side_thickness.strip().replace(',', '.') if '/' in side_thickness: side_thickness = side_thickness.split('/')[0] if row[4].value: date = str_to_date(str(row[4].value)) if row[5].value: stigma = str(row[5].value).strip() try: stigma = replace_rus2eng(stigma) except Exception as e: print('[ERROR]: %s' % e) stigma = None if row[6].value: welding_conn_view_str = replace_eng2rus(row[6].value) welding_conn_view = get_choice( welding_conn_view_str, WeldingJoint.welding_conn_view_choices) if row[7].value: welding_type = row[7].value.replace('+', ' - ') welding_type = replace_eng2rus(welding_type) welding_type = welding_type.replace(' ', ' ') welding_type = get_choice(welding_type, WELDING_TYPES) line_str = row[1].value if not line_str or not 'Линия ' in line_str: #print(digit, line_str) continue line_str = line_str.split('Линия ')[1] line_str = line_str.strip() try: line_str = replace_rus2eng(line_str) except Exception: print('Русские буквы даже после всех замен %s, стык %s' % (line_str, joint_str)) continue analogs = Line.objects.filter(name__startswith=line_str, titul=cur_titul) for item in analogs: if item.name.split('-')[0] == line_str: analogs = [item] break repair = None state = 1 state_str = row[12].value if state_str: if 'готов' in state_str: state = 3 elif 'ремонт' in state_str: repair = 1 #print(state_str) if not analogs: print('Линия не найдена %s в титуле %s, стык %s' % (line_str, cur_titul.name, joint_str)) continue elif len(analogs) > 1: print( 'Найдено больше 1 линии по "%s", это %s в титуле %s, стык %s' % (line_str, [item.name for item in analogs], cur_titul.name, joint_str)) pass else: line = analogs[0] #print('line %s' % line.name) #print(diameter, side_thickness, date, stigma, welding_conn_view, welding_type) joint = get_object(row, 2, Joint, {'line': line}) welding_joint_obj = { 'joint': joint, 'diameter': diameter, 'side_thickness': side_thickness, 'request_control_date': date, 'welding_conn_view': welding_conn_view, 'welding_type': welding_type, 'state': state, 'repair': repair, } #print(welding_joint_obj) # Ищем аналог analog = get_welding_joint_analog(joint, welding_joint_obj) if analog: continue welding_joint = WeldingJoint.objects.create(**welding_joint_obj) print(' --- добавлен в титул %s линию %s стык %s' % (cur_titul.name, line.name, joint.name)) if not stigma: continue welder = Welder.objects.filter(stigma__icontains=stigma).first() if not welder: ###print('welder not found %s' % stigma) continue JointWelder.objects.create(welding_joint=welding_joint, welder=welder, position=1)
def analyze_daily_report_weldings(): """Заполнение базы уникальными значениями из эксельки""" company = Company.objects.create( name='ООО "Транспромстрой"', customer='ООО "ИНК"', location='г. Усть-Кут', contractor='ООО "Транспромстрой"', fitter='ООО "Транспромстрой"', code='ТПС', ) subject = Subject.objects.create( name='Усть-Кутская газофракционирующая установка', code='ГФУ', company=company, ) wb = open_wb(daily_report_weldings) sheet = None for item in wb: if item.title in ('Отчет по стыкам ГФУ', ): sheet = item if not sheet: logger.info('[ERROR]: sheet not found') return rows = sheet.rows i, header = search_header(rows) if header is None: logger.info('[ERROR]: header not found') workshifts = [] control_types = [] conn_types_views = [] welding_types = [] categories = [] control_results = [] materials = [] join_types = [] for row in rows: # Продолжаем обход по генератору cell_values = [cell.value for cell in row] if not any(cell_values): logger.info('EOF reached') break # Титул это i+1 ячейка titul = get_object(row, i + 1, Titul, {'subject': subject}) if not titul: continue diameter = row[i + 7].value if row[i + 7].value else None if diameter: diameter = str(diameter).replace(',', '.') try: diameter = float(diameter) except ValueError: diameter = None logger.info('[ERROR]: diameter %s' % diameter) side_thickness = row[i + 8].value if row[i + 8].value else None if side_thickness: side_thickness = str(side_thickness).replace(',', '.') try: side_thickness = float(side_thickness) except ValueError: side_thickness = None logger.info('[ERROR]: side_thickness %s' % side_thickness) # Линия это i+2 ячейка line = get_object(row, i + 2, Line, {'titul': titul}) if not line: #logger.info('line is empty {}'.format(row)) continue # № стыка это i+3 ячейка joint = None joint_str = row[i + 3].value if line and joint_str: joint_str = '%s' % joint_str joint_str = joint_str.strip() if '*' in joint_str: continue joint = Joint.objects.filter(name=joint_str, line=line).first() if not joint: joint = Joint.objects.create(name=joint_str, line=line) # материал (сталь) это i+9 ячейка material_str = accumulate_data(row, i + 9, materials) # свариваемые элементы это i+10 ячейка #join_type = get_object(row, i+10, JoinType, {'line': line}) join_type = accumulate_data(row, i + 10, join_types) # смена это i+12 ячейка workshift_str = accumulate_data(row, i + 12, workshifts) # Сварщик welders = [] stigma = row[i + 14].value # клеймо сварщика это i+14 ячейка if stigma: stigma_arr = stigma.split('+') for stigma in stigma_arr: stigma = '%s' % stigma stigma = stigma.strip() welder = Welder.objects.filter(stigma=stigma).first() if welder: welders.append(welder) # контроль это i+17 ячейка control_type_str = accumulate_data(row, i + 17, control_types) # вид сварного соединения это i+18 ячейка conn_type_view_str = accumulate_data(row, i + 18, conn_types_views) # тип сварки это i+19 ячейка welding_type_str = accumulate_data(row, i + 19, welding_types) # категория это i+20 ячейка category_str = accumulate_data(row, i + 20, categories) # результат контроля это i+22 ячейка control_result_str = accumulate_data(row, i + 22, control_results) repair = 1 if row[i + 4].value else None if row[i + 5].value: repair = 2 welding_date = row[i + 11].value if row[i + 11].value else None if welding_date: welding_date = str_to_date(str(welding_date)) request_number = row[i + 15].value if row[i + 15].value else None request_control_date = row[i + 16].value if row[i + 16].value else None if request_control_date: request_control_date = str_to_date(str(request_control_date)) notice = row[i + 23].value if row[i + 23].value else None dinc = row[i + 24].value if row[i + 24].value else None if dinc: dinc = str(dinc).replace(',', '.') try: dinc = float(dinc) except ValueError: dinc = None logger.info('[ERROR]: dinc %s' % dinc) workshift = get_choice(workshift_str, WeldingJoint.workshift_choices) control_type = get_choice(control_type_str, WeldingJoint.control_choices) welding_conn_view = get_choice(conn_type_view_str, WeldingJoint.welding_conn_view_choices) welding_type = get_choice(welding_type_str, WELDING_TYPES) category = get_choice(category_str, WeldingJoint.category_choices) control_result = get_choice(control_result_str, CONCLUSION_STATES) material = get_choice(material_str, MATERIALS) join_type_from = None join_type_to = None if join_type: join_type_arr = join_type.split('/') if len(join_type_arr) == 2: for item in JOIN_TYPES: if item[1][:-1] in join_type_arr[0]: join_type_from = item[0] if item[1][:-1] in join_type_arr[1]: join_type_to = item[0] #print(join_type_from, join_type_to, join_type) state = 1 if repair: state = 4 welding_joint_obj = { 'joint': joint, 'repair': repair, 'material': material, 'welding_date': welding_date, 'workshift': workshift, 'request_number': request_number, 'request_control_date': request_control_date, 'control_type': control_type, 'welding_conn_view': welding_conn_view, 'welding_type': welding_type, 'category': category, 'control_result': control_result, 'notice': notice, 'join_type_from': join_type_from, 'join_type_to': join_type_to, 'diameter': diameter, 'side_thickness': side_thickness, 'state': state, } # Ищем аналог analog = get_welding_joint_analog(joint, welding_joint_obj) if analog: continue welding_joint = WeldingJoint.objects.create(**welding_joint_obj) for w, welder in enumerate(welders): JointWelder.objects.create( **{ 'welding_joint': welding_joint, 'welder': welder, 'position': w + 1, }) logger.info('Workshifts: %s' % workshifts) logger.info('ControlTypes: %s' % control_types) logger.info('ConnTypesViews: %s' % conn_types_views) logger.info('WeldingTypes: %s' % welding_types) logger.info('Categories: %s' % categories) logger.info('ControlResults: %s' % control_results) #logger.info('WeldingJoints: %s' % welding_joints) logger.info('JoinTypes: %s' % join_types)