# -*- coding: utf-8 -*- """ Полная перестройка прайса ИСКЛЮЧИТЕЛЬНО из трёх файлов 1С (ЦОМ/Остео/Дети). Данные из дампа Bitrix (старого сайта) в прайс больше не подмешиваются. Правила: - Позиция группируется по (целевой раздел, название). - Если во всех файлах, где она встретилась, цена одна и та же — одна строка, имя без изменений. - Если цена расходится — по одной строке на каждую уникальную цену, имя подписывается источником в скобках: (ЦОМ), (Остео), (Дети), либо их сочетанием, если несколько файлов сошлись на одной цене, а другой(ие) — разошлись. """ import io import build_price_map as b DEPT_LABEL = {'D:/ЦОМ.xlsx': 'ЦОМ', 'D:/Остео.xlsx': 'Остео', 'D:/Дана Дети.xls': 'Дети'} LABEL_ORDER = ['ЦОМ', 'Остео', 'Дети'] def esc(s): # В PostgreSQL со standard_conforming_strings обратный слэш — обычный символ. # Удваивать его нельзя: имя «Справка №003 П\У» превращалось в «П\У». return "'" + str(s).replace("'", "''") + "'" items = [] # (label, slug, name, price) for path, kind, ncol, pcol in b.FILES: rows = b.parse_xlsx(path) if kind == 'xlsx' else b.parse_xls(path) parsed = b.extract(rows, ncol, pcol) label = DEPT_LABEL[path] for sec, name, price in parsed: key = (sec or '').strip().lower() slug = b.MAP.get(key, 'prochee-price') items.append((label, slug, name.strip(), price)) groups = {} # (slug, name) -> {price: set(labels)} for label, slug, name, price in items: groups.setdefault((slug, name), {}).setdefault(price, set()).add(label) same_label_conflicts = [] # случаи, когда один и тот же файл даёт 2 разные цены rows_out = [] # (slug, final_name, price) for (slug, name), pricemap in groups.items(): if len(pricemap) == 1: (price,) = pricemap.keys() rows_out.append((slug, name, price)) continue for price, labels in pricemap.items(): label_str = ', '.join(l for l in LABEL_ORDER if l in labels) rows_out.append((slug, '%s (%s)' % (name, label_str), price)) # диагностика: конфликт внутри одного и того же файла (не разных отделений) all_labels_per_price = list(pricemap.values()) if any(len(all_labels_per_price[i] & all_labels_per_price[j]) > 0 for i in range(len(all_labels_per_price)) for j in range(i + 1, len(all_labels_per_price))): same_label_conflicts.append((name, pricemap)) o = io.open('seed_price_final.sql', 'w', encoding='utf-8') o.write('BEGIN;\n') o.write('DELETE FROM price_items;\n') # прайс теперь целиком из 3 файлов 1С for i, (slug, name, price) in enumerate(rows_out): o.write("INSERT INTO price_items (section_id,name,price,sort,published) " "SELECT id,%s,%s,%s,true FROM price_sections WHERE slug=%s;\n" % ( esc(name), price, i + 1, esc(slug))) o.write('COMMIT;\n') o.close() print('исходных строк с ценой (3 файла):', len(items)) print('уникальных групп (раздел,название):', len(groups)) print('групп с расхождением цены:', sum(1 for v in groups.values() if len(v) > 1)) print('итоговых строк прайса:', len(rows_out)) print('конфликтов внутри одного файла (2 цены на одно имя в одном отделении):', len(same_label_conflicts)) for name, pm in same_label_conflicts[:15]: print(' ', name, dict(pm))