158 lines
5.0 KiB
Python
158 lines
5.0 KiB
Python
from datetime import datetime
|
||
from xml.dom import minidom
|
||
from dataclasses import dataclass
|
||
import os
|
||
import csv
|
||
import logging
|
||
from typing import List
|
||
|
||
logger = logging.getLogger('application')
|
||
logger.setLevel(logging.INFO)
|
||
fh = logging.FileHandler('app.log', encoding='utf-8')
|
||
logger.addHandler(fh)
|
||
|
||
|
||
class DNaPlanGenerator:
|
||
|
||
@dataclass
|
||
class DataNode:
|
||
fam: str = ''
|
||
im: str = ''
|
||
ot: str = ''
|
||
dr: str = ''
|
||
w: str = ''
|
||
npolis: str = ''
|
||
mes: str = ''
|
||
nzap: str = ''
|
||
mcode: str = ''
|
||
|
||
def to_dict(self) -> dict:
|
||
return {
|
||
'N_ZAP': self.nzap,
|
||
'FAM': self.fam,
|
||
'IM': self.im,
|
||
'OT': self.ot,
|
||
'W': self.w,
|
||
'DR': self.dr,
|
||
'NPOLIS': self.npolis,
|
||
'MDP': '0',
|
||
'SMOCOD': '35003',
|
||
'DISP_TYP': '6',
|
||
'MES': self.mes,
|
||
}
|
||
|
||
def __init__(self, mo_code: str, year: int, month: int):
|
||
self.mo_code = mo_code
|
||
self.year = 2026
|
||
self.month = month
|
||
self.doc = minidom.Document()
|
||
self.root = self.doc.createElement('ZL_LIST')
|
||
self.xml_name = f'D-M{self.mo_code}-F35-2026-{month}'
|
||
self.root.appendChild(self.header())
|
||
self.doc.appendChild(self.root)
|
||
|
||
def header(self):
|
||
zglv_tag = self.doc.createElement('ZGLV')
|
||
|
||
fname_tag = self.doc.createElement('FILENAME')
|
||
fname_tag.appendChild(self.doc.createTextNode(self.xml_name))
|
||
|
||
data_tag = self.doc.createElement('DATA')
|
||
data_tag.appendChild(self.doc.createTextNode(
|
||
datetime.now().strftime('%Y-%m-%d')))
|
||
|
||
mo_tag = self.doc.createElement('CODE_MO')
|
||
mo_tag.appendChild(self.doc.createTextNode(self.mo_code))
|
||
|
||
year_tag = self.doc.createElement('YEAR')
|
||
year_tag.appendChild(self.doc.createTextNode(str(self.year)))
|
||
|
||
r_tag = self.doc.createElement('R')
|
||
r_tag.appendChild(self.doc.createTextNode(str(self.month)))
|
||
|
||
for item in (fname_tag, data_tag, mo_tag, year_tag, r_tag):
|
||
zglv_tag.appendChild(item)
|
||
|
||
return zglv_tag
|
||
|
||
def fill(self, data: List[dict]):
|
||
for node_data in data:
|
||
node = self.DataNode(**node_data)
|
||
zap_tag = self.doc.createElement('ZAP')
|
||
for tag_name, tag_value in node.to_dict().items():
|
||
t = self.doc.createElement(tag_name)
|
||
t.appendChild(self.doc.createTextNode(str(tag_value)))
|
||
zap_tag.appendChild(t)
|
||
self.root.appendChild(zap_tag)
|
||
|
||
def save(self):
|
||
xml_path = os.path.join(os.getcwd(), f'{self.xml_name}.xml')
|
||
with open(xml_path, 'w', encoding='cp1251') as f:
|
||
f.write(self.doc.toprettyxml(indent='\t',
|
||
encoding='windows-1251').decode('cp1251'))
|
||
logger.info(f'Файл успешно создан: {xml_path}')
|
||
|
||
|
||
if __name__ == '__main__':
|
||
mo_code = input('Введите код МО (6 цифр, например, 352530): ').strip()
|
||
|
||
if not (mo_code.isdigit() and len(mo_code) == 6):
|
||
print('Некорректный код МО. Нужно ввести ровно 6 цифр, например 352530.')
|
||
exit(1)
|
||
|
||
number_package = input('Введите порядковый номер пакета: ')
|
||
year_now = datetime.now().year
|
||
|
||
csv_filename = f"{mo_code}.csv"
|
||
csv_path = os.path.join(os.getcwd(), csv_filename)
|
||
|
||
if not os.path.exists(csv_path):
|
||
print('Файл не найден!')
|
||
exit(1)
|
||
|
||
data_list = []
|
||
seen_policies = set()
|
||
mes_counter = 1
|
||
|
||
with open(csv_path, encoding='utf-8') as f:
|
||
reader = csv.reader(f, delimiter=';')
|
||
for i, row in enumerate(reader, start=1):
|
||
try:
|
||
fam, im, ot, dr, npolis, w = row[:6]
|
||
|
||
if npolis in seen_policies:
|
||
continue
|
||
seen_policies.add(npolis)
|
||
|
||
try:
|
||
dr_obj = datetime.strptime(dr, '%d.%m.%Y')
|
||
dr_iso = dr_obj.strftime('%Y-%m-%d')
|
||
except ValueError:
|
||
logger.warning(f'Ошибка формата даты в строке {i}: {dr}')
|
||
dr_iso = dr
|
||
|
||
data_list.append({
|
||
'fam': fam,
|
||
'im': im,
|
||
'ot': ot,
|
||
'dr': dr_iso,
|
||
'w': w,
|
||
'npolis': npolis,
|
||
'mes': mes_counter,
|
||
'nzap': str(i),
|
||
'mcode': mo_code
|
||
})
|
||
|
||
mes_counter += 1
|
||
if mes_counter > 12:
|
||
mes_counter = 1
|
||
|
||
except Exception as e:
|
||
logger.warning(f'Ошибка в строке {i}: {e}')
|
||
|
||
generator = DNaPlanGenerator(mo_code, year_now, int(number_package))
|
||
generator.fill(data_list)
|
||
generator.save()
|
||
|
||
print('✅ XML-файл успешно создан!')
|