def getSQLDataset(self, sql_text): """ Получить набор записей по заполненному SQL выражению. @param sql_text: SQL выражение. @return: Заполненная таблица запроса. Формат: ТАБЛИЦА ЗАПРОСА ПРЕДСТАВЛЯЕТСЯ В ВИДЕ СЛОВАРЯ {'__fields__': имена полей таблицы, '__data__': данные таблицы} """ if self.db is None: error_txt = u'Не установлен объект БД в окне просмотра результатов SQL запроса' else: try: query_table = self.db.executeSQL(sql_text) query_table['__fields__'] = [ field[0] for field in query_table['__fields__'] ] query_table['__data__'] = list(query_table['__data__']) for i, rec in enumerate(query_table['__data__']): query_table['__data__'][i] = [ ic_str.toUnicode(value, self.db.getEncoding()) for value in rec ] return query_table except: error_txt = traceback.format_exc() log.fatal( u'Ошибка получения набора записей по SQL выражению <%s>' % sql_text) error_list = error_txt.split(UNIX_CR) return { '__fields__': ERROR_FIELD, '__data__': [(line, ) for line in error_list] }
def add_sprav_list_row(self, record, is_col_autosize=True): """ Добавить новую строку в список справочника. @param record: Запись справочника асоциированая со строкой списка. @param is_col_autosize: Произвести после добавления строки автоматическое переразмеривание колонок? """ fields = self.get_tab_editable_fields() list_item = -1 for i, field in enumerate(fields): value = ic_str.toUnicode(record[field['name']]) # В случае многострочных наименования выделять только первую строку value = [line.strip() for line in value.split(u'\n')][0] if i == 0: list_item = self.recs_listCtrl.InsertStringItem( sys.maxint, value, i) self._list_ctrl_dataset.append(record) else: self.recs_listCtrl.SetStringItem(list_item, i, value) if is_col_autosize: # Переразмерить колонки for i, field in enumerate(fields): self.recs_listCtrl.SetColumnWidth(i, wx.LIST_AUTOSIZE_USEHEADER)
def gen_words(self, *value_list): """ Разбивка списка предложенных значений на слова и их сортировка. В новом варианте используем сортировку по тексту в нижнем регистре @param value_list: Список часто используемых значений. @return: Список часто используемых значений отсортированных и с выделенными словами. Например: Список ['Договор поставки оборудования'] разобъется на ['договор', 'договор поставки', 'договор поставки оборудования'] """ result = list() for value in value_list: if not isinstance(value, unicode): value = ic_str.toUnicode(value, DEFAULT_ENCODING) words = value.split(u' ') sub_value = u'' for word in words: sub_value = sub_value + u' ' + word sub_value = sub_value.strip() if sub_value not in result: result.append(sub_value) result = sorted(result, key=lambda item: item[0].lower()) return result
def get_field_label(self, field): """ Определить надпись соответствующую полю по его описанию. @param field: Описание поля. @return: Строка надписи в юникоде. """ if field is None: return TREE_ITEM_LABEL label = field['label'] if field.get('label', None) else \ (field['description'] if field.get('description', None) else field['name']) return ic_str.toUnicode(label)
def getReportDescription(self, report_filename): """ Получить описание отчета @param report_filename: Имя шаблона отчета. @return: Описание отчета или имя файла отчета, если не определено описание. """ res_filename = self.getReportResourceFilename(report_filename, self.getReportDir()) report_res = self.loadReportResource(res_filename) description = report_res.get( 'description', u'') if report_res and report_res.get( 'description', None) else report_filename return ic_str.toUnicode(description)
def find_word_in_records(self, find_word, start_row=None, start_col=None): """ Поиск слова в текущем списке записей справочника. @param find_word: Искомое слово. @param start_row: Начальная строка для начала поиска. Если не указана, то берется первая. @param start_col: Начальная колонка для начала поиска. Если не указана, то берется первая. @return: Индекс записи, индекс поля, где найдено слово. Или None если ничего не найдено. """ if start_row is None: start_row = 0 if start_col is None: start_col = 0 find_word = find_word.lower() fields = self.get_tab_editable_fields() for i_row, row in enumerate(self._list_ctrl_dataset[start_row:]): if i_row == 0: for i_col, field in enumerate(fields[start_col:]): field_name = field['name'] value = ic_str.toUnicode(row[field_name]).lower() if find_word in value: log.debug(u'Найдено соответствие %s <%s> в <%s>' % (field_name, find_word, value)) return start_row + i_row, start_col + i_col else: for i_col, field in enumerate(fields): field_name = field['name'] value = ic_str.toUnicode(row[field_name]).lower() if find_word in value: log.debug( u'Найдено соответствие в поле %s <%s> : <%s>' % (field_name, find_word, value)) return start_row + i_row, i_col log.warning(u'Не найдено <%s> в списке. Поиск окончен.' % find_word) return None
def refresh_sprav_list_item(self, sprav_code=None, sprav_record=None): """ Обновить элемент списка справочника. @param sprav_code: Код справочнка, ассоциируемый с элементом дерева. @param sprav_record: Запись справочника, ассоциируемая с элементом дерева. """ find_idx = self.find_sprav_list_item(sprav_code) if find_idx: self._list_ctrl_dataset[find_idx] = sprav_record fields = self.get_tab_editable_fields() for i, field in enumerate(fields): value = ic_str.toUnicode(sprav_record[field['name']]) self.recs_listCtrl.SetStringItem(find_idx, i, value)
def get_label(self, record, table_data=None): """ Функция полчения надписи элемента @param record: Текущая обрабатываемая запись. @param table_data: Табличные данные. @return: Текст элемента выбора. """ if table_data is None: table_data = self.getTableData() label = u'' label_field_name = self.getLabelField() if label_field_name: # Определено имя поля надписи в явном виде field_names = [ field[0] for field in table_data.get('__fields__', []) ] field_idx = field_names.index(label_field_name) label = ic_str.toUnicode(record[field_idx]) else: # Если не определено имя поля, # то должна быть определена функция определения надписи элемента is_label_func = self.isLabelFunc() if is_label_func: rec_dict = self._src_data.get_record_dict( normal_data=table_data, record=record) label = self.getLabelFunc(RECORD=rec_dict) if label is None: label = u'' else: label = ic_str.toUnicode(label) else: log.warning( u'Не определен метод получения надписи элемента списка выбора в компоненте <%s>' % self.name) return label
def set_sprav_tree_item(self, parent_item, record): """ Установить элемент дерева справочника. @param parent_item: Родительский элемент дерева. @param record: Запись справочника, ассоциируемая с элементом. """ # Запись в виде словаря rec_dict = self.sprav.getStorage()._getSpravFieldDict(record) name = ic_str.toUnicode(rec_dict['name']) # В случае многострочных наименования выделять только первую строку name = [line.strip() for line in name.split(u'\n')][0] item = self.sprav_treeCtrl.AppendItem(parent_item, name) self.sprav_treeCtrl.SetPyData(item, rec_dict) code = rec_dict['cod'] if self.sprav.isSubCodes(code): # Есть подкоды. Для отображения + в контроле дерева # необходиом добавить фиктивный элемент self.sprav_treeCtrl.AppendItem(item, TREE_ITEM_LABEL)
def post_select_action(self, report_filename, parent=None, db_url=None, sql=None, command=None, stylelib_filename=None, variables=None): """ Выбрать действие, которое хотим сделать с отчетом, после генерации отчета. @param report_filename: Имя файла шаблона отчета. Пути задаются относительно папки отчетов. @param parent: Родительское wxWindow окно для диалога. Если не указано, то береться wx.GetAppt().GetTopWindow(). @param db_url: Connection string в виде url. Например postgresql+psycopg2://postgres:[email protected]:5432/realization. @param sql: Запрос SQL. @param command: Комманда после генерации. print/preview/export. @param stylelib_filename: Файл библиотеки стилей. @param variables: Словарь дополнительных переменных. @return: True/False. """ if os.path.exists(self._report_exec_filename): cmd = 'python2 %s --select=%s --path=%s' % ( self._report_exec_filename, report_filename, self.getReportDir()) cmd = self._addCmdExtArgs(cmd, db_url, sql, command, stylelib_filename, variables) if isinstance(cmd, unicode): cmd = cmd.encode(config.DEFAULT_ENCODING) msg_cmd = ic_str.toUnicode(cmd, config.DEFAULT_ENCODING) try: io_prnt.outLog(u'Запуск внешней программы <%s>' % msg_cmd) os.system(cmd) except: io_prnt.outLastErr( u'Запуск программы <icReport> в режиме выбора действия над отчетом отчета: <%s>' % msg_cmd) else: io_prnt.outWarning( u'Запускаемый модуль программы <icReport> : <%s> не найден' % self._report_exec_filename)
def report_export(self, report_filename, db_url=None, sql=None, command=None, stylelib_filename=None, variables=None): """ Запуск генерации отчета с конвертацией в офисную программу. @param report_filename: Имя файла шаблона отчета. Пути задаются относительно папки отчетов. @param db_url: Connection string в виде url. Например postgresql+psycopg2://postgres:[email protected]:5432/realization. @param sql: Запрос SQL. @param command: Комманда после генерации. print/preview/export. @param stylelib_filename: Файл библиотеки стилей. @param variables: Словарь дополнительных переменных. @return: True/False. """ if os.path.exists(self._report_exec_filename): cmd = 'python2 %s --export=%s --path=%s' % ( self._report_exec_filename, report_filename, self.getReportDir()) cmd = self._addCmdExtArgs(cmd, db_url, sql, command, stylelib_filename, variables) if isinstance(cmd, unicode): cmd = cmd.encode(config.DEFAULT_ENCODING) msg_cmd = ic_str.toUnicode(cmd, config.DEFAULT_ENCODING) try: io_prnt.outLog(u'Запуск внешней программы <%s>' % msg_cmd) os.system(cmd) except: io_prnt.outLastErr( u'Запуск программы <icReport> в режиме экспорта отчета: <%s>' % msg_cmd) else: io_prnt.outWarning( u'Запускаемый модуль программы <icReport> : <%s> не найден' % self._report_exec_filename)
def setControlValue(self, ctrl, value): """ Установить значение в найденный контрол. @param ctrl: Контрол. @param value: Значение кoнтрола. @return: True/False. """ result = False if hasattr(ctrl, 'setData'): # Обработка методом setData try: io_prnt.outLog( u'Заполнение данных объекта <%s> методом setData.' % ctrl.__class__.__name__) ctrl.setData(value) result = True except: io_prnt.outErr( u'Ошибка заполнения данных объекта <%s> методом setData. Значение <%s : %s>' % (ctrl.__class__.__name__, type(value), value)) result = False elif hasattr(ctrl, 'setValue'): # Обработка методом setValue try: io_prnt.outLog( u'Заполнение данных объекта <%s> методом setValue.' % ctrl.__class__.__name__) ctrl.setValue(value) result = True except: io_prnt.outErr( u'Ошибка заполнения данных объекта <%s> методом setValue. Значение <%s : %s>' % (ctrl.__class__.__name__, type(value), value)) result = False elif hasattr(ctrl, 'SetValue'): # Обработка методом SetValue try: if isinstance(ctrl, wx.DatePickerCtrl): # Преобразование типа для wxDatePickerCtrl if isinstance(value, datetime.date): value = ic_time.pydate2wxdate(value) elif isinstance(value, datetime.datetime): value = ic_time.pydatetime2wxdatetime(value) io_prnt.outLog( u'Заполнение данных объекта <%s> методом SetValue.' % ctrl.__class__.__name__) ctrl.SetValue(value) result = True except: io_prnt.outErr( u'Ошибка заполнения данных объекта <%s> методом SetValue. Значение <%s : %s>' % (ctrl.__class__.__name__, type(value), value)) result = False elif hasattr(ctrl, 'SetLabel'): # Обработка методом SetValue (Только для объектов wxStaticText) try: io_prnt.outLog( u'Заполнение данных объекта <%s> методом SetLabel.' % ctrl.__class__.__name__) value = ic_str.toUnicode(value) ctrl.SetLabel(value) result = True except: io_prnt.outErr( u'Ошибка заполнения данных объекта <%s> методом SetLabel. Значение <%s : %s>' % (ctrl.__class__.__name__, type(value), value)) result = False else: io_prnt.outWarning( u'Не определен метод заполнения данных объекта <%s>' % ctrl.__class__.__name__) return result
def build(self): """ Инициализировать объект и создать все его дочерние объекты. """ cf_cfg_filename = os.path.join(os.path.abspath(self.cf_dir), 'metadata', self.uid) if not os.path.exists(cf_cfg_filename): cf_cfg_filename = os.path.join(os.path.abspath(self.cf_dir), self.uid) if not os.path.exists(cf_cfg_filename): log.warning(u'Не найден файл <%s>' % cf_cfg_filename) return cf_cfg_res = iccfresource.icCFResource(cf_cfg_filename) cf_cfg_res.loadData() if cf_cfg_res.data is None: log.warning(u'Ошибка загрузки данных дерева конфигурации') return self.name = ic_str.toUnicode(cf_cfg_res.data[3][1][1][1][1][2], DEFAULT_ENCODING) # После определения имени метаобъекта можно изменить прогресс бар iccfobject.icCFObject.build(self) log.info(u'CONFIGURATION RESOURCE: <%s>' % self.name) # util1c.print_idx_paths(cf_cfg_res.data) # idx = util1c.ValueIndexPath(cf_cfg_res.data, '4938909f-92f5-4cd8-992f-6c53996d1af9') # Справочники sprav_uid_lst = cf_cfg_res.data[4][1][1][16][2:] log.info(u'Количество справочников: <%d>' % len(sprav_uid_lst)) self.spravs = [iccfsprav.icCFSprav(self, uid) for uid in sprav_uid_lst] for sprav in self.spravs: sprav.build() # Документы doc_uid_lst = cf_cfg_res.data[4][1][1][4][2:] log.info(u'Количество документов: <%d>' % len(doc_uid_lst)) self.documents = [ iccfdocument.icCFDocument(self, uid) for uid in doc_uid_lst ] for doc in self.documents: doc.build() # Перечисления enum_uid_lst = cf_cfg_res.data[4][1][1][17][2:] log.info(u'Количество перечислений: <%d>' % len(enum_uid_lst)) self.enums = [iccfenum.icCFEnum(self, uid) for uid in enum_uid_lst] for enum in self.enums: enum.build() # Регистры накопления acc_uid_lst = cf_cfg_res.data[4][1][1][13][2:] log.info(u'Количество регистров накопления: <%d>' % len(acc_uid_lst)) self.acc_regs = [ iccfaccreg.icCFAccRegistry(self, uid) for uid in acc_uid_lst ] for acc_reg in self.acc_regs: acc_reg.build() # Регистры сведений info_uid_lst = cf_cfg_res.data[4][1][1][6][2:] log.info(u'Количество регистров сведений: <%d>' % len(info_uid_lst)) self.info_regs = [ iccfinforeg.icCFInfoRegistry(self, uid) for uid in acc_uid_lst ] for info_reg in self.info_regs: info_reg.build() self.children = [ iccfobject.icCFFolder(parent=self, name=u'Справочники', children=self.spravs, img_filename=os.path.join( os.path.dirname( os.path.dirname(__file__)), 'img', 'books-brown.png')), iccfobject.icCFFolder(parent=self, name=u'Документы', children=self.documents, img_filename=os.path.join( os.path.dirname( os.path.dirname(__file__)), 'img', 'documents-text.png')), iccfobject.icCFFolder(parent=self, name=u'Перечисления', children=self.enums, img_filename=os.path.join( os.path.dirname( os.path.dirname(__file__)), 'img', 'sort-alphabet.png')), iccfobject.icCFFolder(parent=self, name=u'Регистры накопления', children=self.acc_regs, img_filename=os.path.join( os.path.dirname( os.path.dirname(__file__)), 'img', 'table-money.png')), iccfobject.icCFFolder(parent=self, name=u'Регистры сведений', children=self.info_regs, img_filename=os.path.join( os.path.dirname( os.path.dirname(__file__)), 'img', 'table-join.png')), ]