# coding: utf-8 ''' Created on 21.10.2016 @author: d.gulyakin ''' from java.io import InputStreamReader, BufferedReader import json from java.text import SimpleDateFormat try: from ru.curs.showcase.core.jython import JythonDTO, JythonDownloadResult, JythonErrorResult except: from ru.curs.celesta.showcase import JythonDTO, JythonDownloadResult, JythonErrorResult from ru.curs.celesta.showcase.utils import XMLJSONConverter from ru.curs.showcase.core import UserMessageFactory from ru.curs.showcase.app.api.grid import GridSaveResult # from security.functions import userHasPermission from edu.constants import * from medstaff._medstaff_orm import student_certificateCursor,\ student_eor_tasksCursor, vw_student_cycleCursor,\ practical_filesCursor from common.sysfunctions import toHexForXml, getGridHeight _header = {"id": ["~~id"], "name": [u'Слущатель'], "eor_type": [u'Тип ЭОР'], "score": [u'Оценка'], "score_date": [u'Дата оценки'], "attempts_count": [u'Кол-во оставшихся попыток'], "file":[u"Файл"], "HasChildren": [u'HasChildren'], 'properties': [u'properties']} def getTreeData(context, main, add, filterinfo, session, elementId, sortColumnList, firstrecord, pagesize, parentId=None): u'''Функция получения данных для tree-грида. ''' for column in _header: _header[column].append(toHexForXml(_header[column][0])) data = {"records":{"rec":[]}} course_id = main if parentId is None: studentCur = student_certificateCursor(context) studentCur.setRange('course_id', course_id) # Проходят обучение studentCur.setRange('status', 20) studentCur.orderBy('surname', 'name', 'patronymic', 'certificate_number') for student in studentCur.iterate(): row = {} row[_header["id"][1]] = "person.{}".format(student.uid) row[_header["name"][1]] = u'{} {} {} ({})'.format(student.surname, student.name, student.patronymic, student.certificate_number) # row[_header['properties'][1]] = {'event': {}} data["records"]["rec"].append(row) studentCur.close() else: parent = parentId.split('.') parent_type = parent[0] parent_id = parent[1] if parent_type == 'person': cycleCur = vw_student_cycleCursor(context) cycleCur.setRange('certificate', parent_id) cycleCur.setRange('cycle_open', True) cycleCur.orderBy('cycle_order') for cycle in cycleCur.iterate(): row = {} row[_header["id"][1]] = "cycle.{}.{}".format(cycle.cycle_id, cycle.certificate) row[_header["name"][1]] = cycle.name row[_header['properties'][1]] = {"readonly": {"@value": "true"}} data["records"]["rec"].append(row) cycleCur.close() elif parent_type == "cycle": eor_tasksCursor = student_eor_tasksCursor(context) eor_tasksCursor.setRange('student_certificate', parent[2]) eor_tasksCursor.setRange('cycle_id', parent_id) eor_tasksCursor.setFilter('eor_type', '!{}'.format(LECTURE)) eor_tasksCursor.orderBy('qti_order') filesCur = practical_filesCursor(context) for task in eor_tasksCursor.iterate(): type = task.eor_type row = {} id = "task.{}".format(task.task_id) row[_header["id"][1]] = id row[_header["name"][1]] = task.package_name row[_header["eor_type"][1]] = EOR_TYPE[type][0] row[_header["score"][1]] = task.score row[_header["score_date"][1]] = SimpleDateFormat("dd.MM.yyyy").format(task.score_date) if task.score_date else "" if type == TEST: row[_header["attempts_count"][1]] = task.attempts_count row[_header["HasChildren"][1]] = 0 row[_header['properties'][1]] = {'event': { '@name': 'row_save_data', 'action': { '#sorted': [ {'main_context': 'current'}, {'datapanel': { '@type': 'current', '@tab': 'current', "element": [ {"@id": "studentsTreeGrid", "@keep_user_settings": "true", "@partial_update": "true", "add_context": id}]}}]}}} elif task.eor_type == PRACTICAL: filesCur.setRange('task_id', task.task_id) row[_header["HasChildren"][1]] = 1 if filesCur.count()>0 else 0 row[_header['properties'][1]] = {"readonly": {"@value": "true"}} data["records"]["rec"].append(row) filesCur.close() eor_tasksCursor.close() elif parent_type == 'task': pr_filesCur = practical_filesCursor(context) pr_filesCur.setRange('task_id', parent_id) for pr_file in pr_filesCur.iterate(): row = {} row[_header["id"][1]] = "file.{}".format(pr_file.id) row[_header["name"][1]] = pr_file.file_name row[_header["eor_type"][1]] = u'Файл' row[_header["file"][1]] = u'Скачать ' row[_header["HasChildren"][1]] = 0 row[_header['properties'][1]] = {"readonly": {"@value": "true"}} data["records"]["rec"].append(row) pr_filesCur.close() res = XMLJSONConverter.jsonToXml(json.dumps(data)) return JythonDTO(res, None) def getTreeSettings(context, main, add, filterinfo, session, elementId): u'''Функция получения настроек для tree-грида. ''' panelWidth = '100%' panelHeight = getGridHeight(session, numberOfGrids = 1, delta=35) course_id = main studentCur = student_certificateCursor(context) studentCur.setRange('course_id', course_id) # Проходят обучение studentCur.setRange('status', 20) # totalCount = studentCur.count() totalCount = 0 studentCur.close() # Определяем список полей таблицы для отображения settings = {} settings["gridsettings"] = { # "labels": {'header': u'ЭОР по теме'}, "columns": {"col":[ {"@id":_header["name"][0], "@width":"300px", '@readonly': "true"}, {"@id":_header["eor_type"][0], "@width":"100px", '@readonly': "true", "@horAlign": 'CENTER'}, {"@id":_header["score"][0], "@width":"50px", '@readonly': "true", "@horAlign": 'CENTER'}, {"@id":_header["score_date"][0], "@width":"50px", '@readonly': "true", "@horAlign": 'CENTER'}, {"@id":_header["attempts_count"][0], "@width":"50px", "@horAlign": 'CENTER', '@editor': "{editOn: has('touch') ? 'click' : 'dblclick', editor: NumberSpinner, editorArgs: {style: 'width: 50px', smallDelta: 1, constraints: {min: 0, max: 5}, disableMouseWheel: true}}"}, {"@id":_header["file"][0], "@width":"50px", "@type":"DOWNLOAD", "@linkId":"pzDownload", '@readonly': "true", "@horAlign": 'CENTER'}, ]}, "properties": { "@gridHeight": panelHeight, "@gridWidth": panelWidth, "@pagesize": "25", "@totalCount": totalCount}} # constraints: { min:9, max:1550, places:0 } res_set = XMLJSONConverter.jsonToXml(json.dumps(settings)) return JythonDTO(None, res_set) # def gridToolBar(context, main=None, add=None, filterinfo=None, session=None, elementId=None): # courseCycleId = main # # try: # qtiRow = json.loads(session)['sessioncontext']['related']['gridContext']["currentRecordId"] # except: # qtiRow = None # # u"""Дизактивация кнопок. Для активации кнопок, # необходимо, чтобы статус программы был 'Утвежден(-а)'""" # delete_style = 'true' # add_style = 'true' # control_style = 'true' # # u"""Если программа утрвеждена, разрешить модификации циклов""" # if courseCycleId: # courseCycleCur = course_cycleCursor(context) # courseCycleCur.get(courseCycleId) # if courseCycleCur.status_id == 3: # add_style = 'false' # if qtiRow: # delete_style = 'false' # # courseCycleCur.close() # # if courseCycleId and qtiRow: # qtiPackageCur = course_cycle_qti_packageCursor(context) # if qtiPackageCur.tryGet(courseCycleId, qtiRow): # control_style = 'false' if EOR_TYPE[qtiPackageCur.eor_type][5] else 'true' # qtiPackageCur.close() # # # grid_toolbar = { # 'gridtoolbar': { # '#sorted': [ # {'item': { # '@text': u'Добавить', # '@hint': u'Добавить ЭОР в тему', # '@disable': add_style, # 'action': { # '@show_in': 'MODAL_WINDOW', # '#sorted': [ # {'main_context': 'current'}, # {'modalwindow': { # '@caption': u'Добавление ЭОР', # '@height': '430', # '@width': '480'}}, # {'datapanel': { # '@type': 'current', # '@tab': 'current', # 'element': { # '@id': 'courseCycleQtiCard', # 'add_context': qtiRow}}}]}}}, # {'item': { # '@text': u'Удалить', # '@hint': u'Удалить ЭОР из темы', # '@disable': delete_style, # 'action': { # '@show_in': 'MODAL_WINDOW', # '#sorted': [ # {'main_context': 'current'}, # {'modalwindow': { # '@caption': u'Удаление ЭОР', # '@height': '145', # '@width': '400'}}, # {'datapanel': { # '@type': 'current', # '@tab': 'current', # 'element': { # '@id': 'courseCycleQtiDeleteCard', # 'add_context': 'delete'}}}]}}}, # {'item': { # '@text': u'Тип контроля', # '@hint': u'Изменить тип контроля', # '@disable': control_style, # 'action': { # '@show_in': 'MODAL_WINDOW', # '#sorted': [ # {'main_context': 'current'}, # {'modalwindow': { # '@caption': u'Изменение типа контроля', # '@height': '120', # '@width': '340'}}, # {'datapanel': { # '@type': 'current', # '@tab': 'current', # 'element': { # '@id': 'qtiControlTypeChangeCard', # 'add_context': json.dumps({"cycle_id": courseCycleId, "qti_id": qtiRow})}}}]}}}]}} # # return XMLJSONConverter.jsonToXml(json.dumps(grid_toolbar)) def gridSaveData(context, main, add, filterinfo, session, elementId, editorData): u"""Сохранение отредактированных данных""" print 'gridSaveData ==============================================================' print 'User %s' % context.userId print 'main "%s".' % main print 'add "%s".' % add print 'filterinfo "%s".' % filterinfo print 'session "%s".' % session print 'elementId "%s".' % elementId print 'editorData: %s' % editorData data = json.loads(editorData)['savedata']['data'] row = data['id'].split('.') row_type = row[0] row_id = row[1] if row_type == 'task': eor_tasksCursor = student_eor_tasksCursor(context) if eor_tasksCursor.tryGet(row_id) and eor_tasksCursor.eor_type == TEST: eor_tasksCursor.attempts_count = int(data['col4']) eor_tasksCursor.update() eor_tasksCursor.close() res = GridSaveResult(context.message(u"Данные обновлены")) res.setRefreshAfterSave(0); return res def gridPartialUpdate(context, main, add, filterinfo, session, elementId, sortColumnList, firstrecord, pagesize, parentId=None): u"""Частичное обновление грида""" data = {"records":{"rec":[]}} if add: row = add.split('.') row_type = row[0] row_id = row[1] if row_type == 'task': eor_tasksCursor = student_eor_tasksCursor(context) if eor_tasksCursor.tryGet(row_id): type = eor_tasksCursor.eor_type id = "task.{}".format(eor_tasksCursor.task_id) row = {} row[_header["id"][1]] = id row[_header["name"][1]] = eor_tasksCursor.package_name row[_header["eor_type"][1]] = EOR_TYPE[type][0] row[_header["score"][1]] = eor_tasksCursor.score if type == TEST: row[_header["attempts_count"][1]] = eor_tasksCursor.attempts_count row[_header["HasChildren"][1]] = 0 row[_header['properties'][1]] = {'event': { '@name': 'row_save_data', 'action': { '#sorted': [ {'main_context': 'current'}, {'datapanel': { '@type': 'current', '@tab': 'current', "element": [ {"@id": "studentsTreeGrid", "@keep_user_settings": "true", "@partial_update": "true", "add_context": id}]}}]}}} data["records"]["rec"].append(row) eor_tasksCursor.close() res = XMLJSONConverter.jsonToXml(json.dumps(data)) return JythonDTO(res, None) def downloadPzFile(context, main=None, add=None, filterinfo=None, session=None, elementId=None, recordId=None): u'''Процедура скачивание файла''' record = recordId.split('.') record_type = record[0] record_id = record[1] if record_type == 'file' and record_id: pr_filesCur = practical_filesCursor(context) if pr_filesCur.tryGet(record_id): fileName = pr_filesCur.file_name pr_filesCur.calcfile_resource() ins = pr_filesCur.file_resource.getInStream() if ins: #Помним о том, что в поле может быть NULL # data = InputStreamReader(ins, 'utf-8') return JythonDownloadResult(ins, fileName)