Exemplo n.º 1
0
 def update(self):
     self.clear()
     labels = self._labels.copy()
     isRollback = False
     dbfFile = None
     self._db.transaction()
     try:
         for fileName in self._fileNames:
             if fileName[:1] in labels.keys():
                 try:
                     dbfFile = Dbf(os.path.join(self._dirName, fileName), readOnly=True, encoding='cp866')
                     if dbfFile.recordCount:
                         if not self._callbackUpdate(fileName, 0, dbfFile.recordCount):
                             isRollback = True
                             return
                         insertRowCount = 0
                         rbTable = self._db.table('rbCheckAccounts' + fileName[:1])
                         for dbfRow in dbfFile:
                             newRecord = rbTable.newRecord()
                             for fieldName, fieldValue in dbfRow.asDict().items():
                                 fieldValue = forceStringEx(fieldValue)
                                 if fieldValue:
                                     newRecord.setValue(forceString(fieldName), toVariant(fieldValue))
                             self._db.insertRecord(rbTable, newRecord)
                             insertRowCount += 1
                             if not self._callbackUpdate(fileName, insertRowCount, dbfFile.recordCount):
                                 isRollback = True
                                 return
                         del labels[fileName[:1]]
                     dbfFile.close()
                     dbfFile = None
                 except Exception as e:
                     isRollback = True
                     raise self.InsertError(fileName, e)
         requiredFiles = [label for label, required in labels.items() if required]
         if requiredFiles:
             isRollback = True
             raise self.RequiredFilesNotFoundError(requiredFiles)
         self._db.commit()
     finally:
         if isRollback:
             self._db.rollback()
         if dbfFile:
             dbfFile.close()
         QtGui.qApp.removeTmpDir(self._dirName)
Exemplo n.º 2
0
def getDataFromDbfFile(parentWidget, fileName):
    from library.dbfpy.dbf import Dbf

    reportDataByNumbers = {}

    dbf = Dbf(fileName,
              readOnly=True,
              encoding='cp866',
              enableFieldNameDups=True)

    unexistsFields = []
    for needField in [
            'NREESTR', 'NSVOD', 'KODLPU', 'KSPEC', 'NSCHT', 'STOIM', 'ZPL',
            'DOPL', 'MED', 'M_INV', 'NAKL'
    ]:
        if needField not in dbf.fieldNames:
            unexistsFields.append(needField)
    if unexistsFields:
        QtGui.QMessageBox.warning(
            parentWidget,
            u'Ошибка',
            u'В указанном файле исходных данных отчета\n отсутсвтуют поля:\n%s'
            % ('\n'.join(unexistsFields)),
            buttons=QtGui.QMessageBox.Ok,
            defaultButton=QtGui.QMessageBox.NoButton)
        return reportDataByNumbers, '_____________________________________________'

    rows = dbf.recordCount
    row = 0

    nr = u'%05d' % forceInt(dbf[row]['NREESTR'])
    table = QtGui.qApp.db.table('Organisation')
    platrec = QtGui.qApp.db.getRecordEx(
        table, 'shortName',
        'infisCode LIKE \'61%%%s\' and deleted = 0' % nr[:2])
    plat = forceString(platrec.value('shortName'))

    specialityNameCashe = {}
    while row < rows:
        dbfRecord = dbf[row]

        nsvod = forceString(dbfRecord['NSVOD'])

        reportData = reportDataByNumbers.setdefault(nsvod, {})
        orgStructureCode = forceStringEx(dbfRecord['KODLPU'])

        serviceCode = forceString(dbfRecord['KSPEC'])
        if not specialityNameCashe.has_key(serviceCode):
            rbSpecialityTable = QtGui.qApp.db.table('rbSpeciality')
            specialityNameCashe[serviceCode] = forceString(
                QtGui.qApp.db.translate(rbSpecialityTable,
                                        rbSpecialityTable['federalCode'],
                                        serviceCode,
                                        rbSpecialityTable['OKSOName']))
        specialityName = specialityNameCashe[serviceCode]

        visitCount = 1

        nscht = forceInt(dbfRecord['NSCHT'])

        tariffPrice = forceDouble(dbfRecord['STOIM'])

        sum = visitCount * tariffPrice

        wages = forceDouble(dbfRecord['ZPL'])  #1

        additionalPayments = forceDouble(dbfRecord['DOPL'])  #5

        drugs = forceDouble(dbfRecord['MED'])  #2

        softInventory = forceDouble(dbfRecord['M_INV'])  #3

        overhead = forceDouble(dbfRecord['NAKL'])  #4

        orgStructureData = reportData.setdefault(serviceCode, {})
        serviceData = orgStructureData.setdefault(
            serviceCode, {
                'orgStructureCode': orgStructureCode,
                'serviceCode': serviceCode,
                'specialityName': specialityName,
                'visitCount': 0,
                'eventCount': 0,
                'sum': 0.0,
                'wages': 0.0,
                'additionalPayments': 0.0,
                'drugs': 0.0,
                'softInventory': 0.0,
                'overhead': 0.0,
                'nschtValueSet': []
            })
        serviceData['visitCount'] += visitCount
        if nscht not in serviceData['nschtValueSet']:
            serviceData['nschtValueSet'].append(nscht)
            serviceData['eventCount'] += 1
        serviceData['sum'] += sum
        serviceData['wages'] += wages
        serviceData['additionalPayments'] += additionalPayments
        serviceData['drugs'] += drugs
        serviceData['softInventory'] += softInventory
        serviceData['overhead'] += overhead
        row += 1

    dbf.close()
    return reportDataByNumbers, plat
Exemplo n.º 3
0
 def update(self):
     isRollback = False
     dbfFile = Dbf(os.path.join(self._dirName, self._fileName),
                   readOnly=True,
                   encoding='cp866')
     try:
         if not self._callbackUpdate(0, dbfFile.recordCount):
             return
         fileHash = forceString(
             hashlib.md5(dbfFile.stream.read()).hexdigest())
         if not self._rbTable or fileHash != forceString(self._metaData.value('hash')) or \
                 self._db.getCount(self._rbTable, countCol='id') != dbfFile.recordCount:
             self._drop()
             rbTableFields = [
                 trim(field) for field in forceString(
                     self._metaData.value('fields')).split(',')
             ]
             fieldsStatement = ''
             fieldsStatementCount = 0
             for dbfField in dbfFile.fieldDefs:
                 if forceString(dbfField.name) in rbTableFields:
                     fieldsStatement += u'`%s` %s DEFAULT NULL COMMENT \'Поле %s\', ' % (
                         forceString(
                             dbfField.name), self._getType(dbfField),
                         forceString(dbfField.name))
                     fieldsStatementCount += 1
             if len(rbTableFields) != fieldsStatementCount:
                 raise self.MetadataMappingError()
             rbTableIndexes = [
                 index for index in map(
                     trim,
                     forceString(self._metaData.value('indexes')).split(
                         ',')) if index
             ]
             indexesStatement = ''
             for index in rbTableIndexes:
                 indexesStatement += u', INDEX `%s` (`%s`)' % (index, index)
             createStatement = u"""
             CREATE TABLE `%s` (
                 `id` int(11) NOT NULL AUTO_INCREMENT,
                 `deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Отметка удаления записи',
                 %s
                 PRIMARY KEY (`id`)
                 %s
             ) ENGINE = InnoDB DEFAULT charset = utf8 COMMENT = '%s';""" % (
                 forceString(self._metaData.value('tableName')),
                 fieldsStatement, indexesStatement,
                 forceString(self._metaData.value('name')))
             try:
                 self._db.query(createStatement)
                 self._db.transaction()
                 try:
                     insertRowCount = 0
                     self._rbTable = self._db.table(
                         forceString(self._metaData.value('tableName')))
                     for dbfRow in dbfFile:
                         newRecord = self._rbTable.newRecord()
                         for field in rbTableFields:
                             fieldValue = forceStringEx(dbfRow[field])
                             if fieldValue:
                                 newRecord.setValue(field,
                                                    toVariant(fieldValue))
                         self._db.insertRecord(self._rbTable, newRecord)
                         insertRowCount += 1
                         if not self._callbackUpdate(
                                 insertRowCount, dbfFile.recordCount):
                             isRollback = True
                             return
                     self._metaData.setValue('hash', toVariant(fileHash))
                     self._db.updateRecord(self._additionalRBs,
                                           self._metaData)
                     self._db.commit()
                 except:
                     isRollback = True
                     raise
             except Exception as e:
                 raise self.CreateError(e)
         else:
             self._callbackUpdate(dbfFile.recordCount, dbfFile.recordCount)
     finally:
         if isRollback:
             self._db.rollback()
             self._drop()
         dbfFile.close()
Exemplo n.º 4
0
class CImportMKB(QtGui.QDialog, Ui_ImportMKB):
    def __init__(self, parent):
        QtGui.QDialog.__init__(self, parent)
        self.setupUi(self)
        self.progressBar.setMinimum(0)
        self.progressBar.setMaximum(1)
        self.progressBar.setValue(0)
        self.btnImport.setEnabled(False)
        self.importDBF = None

    def openFile(self, fileName):

        archive, nameFiles = getFilesZipArchive(fileName)
        if archive:
            for name in nameFiles:
                if not unicode(name.lower()).endswith('spr20.dbf'):
                    continue
                self.importDBF = getDBFFileFromZipArchive(archive, name)
                break
        else:
            if unicode(fileName.lower()).endswith('spr20.dbf'):
                self.importDBF = Dbf(fileName, encoding='cp866')
        if not self.importDBF:
            self.logBrowser.append(u'В архиве нет spr20.dbf файла.' if archive
                                   else u'Необходимо выбрать файл spr20.dbf.')
            self.logBrowser.update()
            return
        self.btnImport.setEnabled(True)

    def updateMKB(self, mapMKB):
        db = QtGui.qApp.db
        self.progressBar.setRange(0, len(mapMKB))
        self.logBrowser.append(u'Конструирование запроса')
        dateLeft = dateLeftInfinity.toString('yyyy-MM-dd')
        dateRight = dateRightInfinity.toString('yyyy-MM-dd')
        stmt = u'UPDATE MKB_Tree SET begDate=\'%s\', endDate=\'%s\', OMS=\'1\' WHERE parent_code IS NULL;\n' % (
            dateLeft, dateRight)
        for i, code in enumerate(mapMKB):
            stmt += u'UPDATE MKB SET OMS=\'{OMS}\', begDate=\'{begDate}\', endDate=\'{endDate}\', DiagName=\'{name}\' WHERE DiagID=\'{code}\';\n' \
                    u'UPDATE MKB_Tree SET OMS=\'{OMS}\', begDate=\'{begDate}\', endDate=\'{endDate}\', DiagName=\'{name}\' WHERE DiagID=\'{code}\';\n'.format(
                        OMS=mapMKB[code][0],
                        begDate=mapMKB[code][1] or dateLeft,
                        endDate=mapMKB[code][2] or dateRight,
                        code=code,
                        name=mapMKB[code][3]
                    )
            self.progressBar.setValue(i)
            if not i % 30:
                db.query(stmt)
                stmt = ''
        db.query(stmt)

    def insertMKB(self, mapMKB):
        self.progressBar.setRange(0, 0)
        mapMKB = mapMKB.copy()
        db = QtGui.qApp.db
        self.logBrowser.append(u'Конструирование запроса')
        tbl_tree = db.table('MKB_Tree')
        view_tree = db.table('vMKBTree')
        tbl = view_tree.leftJoin(tbl_tree,
                                 view_tree['BlockID'].eq(tbl_tree['DiagID']))
        blocks = dict((forceString(rec.value(1)),
                       forceString(rec.value(0)).strip('()').split('-'))
                      for rec in db.getRecordList(
                          tbl, 'DISTINCT vMKBTree.BlockID, MKB_Tree.id'))
        exist = (forceString(rec.value(0))
                 for rec in db.getRecordList(tbl_tree, 'DiagID'))
        for diag in exist:
            if diag in mapMKB:
                del mapMKB[diag]

        def get_block(code):
            for tree_id, mkb_range in blocks.iteritems():
                if (len(mkb_range) == 1 and mkb_range[0]
                        == code) or (len(mkb_range) == 2
                                     and mkb_range[0] <= code <= mkb_range[1]):
                    return tree_id
            return None

        values = []

        dateLeft = dateLeftInfinity.toString('yyyy-MM-dd')
        dateRight = dateRightInfinity.toString('yyyy-MM-dd')

        self.progressBar.setRange(0, len(mapMKB))
        for k, v in mapMKB.iteritems():
            if len(k) == 3:
                parent = get_block(k)
                if not parent:
                    continue
            elif len(k) == 5:
                parent = k[:3]
            elif len(k) == 6:
                parent = k[:5]
            else:
                continue
            values.append(
                '(\'%s\', \'%s\', \'%s\', \'%s\', \'%s\', \'%s\', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)'
                % (
                    k,  # DiagID
                    v[3],  # DiagName
                    parent,
                    v[0],  # OMS
                    v[1] or dateLeft,  # begDate
                    v[2] or dateRight  # endDate
                ))
            self.progressBar.step()
        if values:
            stmt = u'INSERT INTO MKB_Tree (DiagID, DiagName, parent_code, OMS, begDate, endDate, Prim, sex, age, characters, duration, USL_OK1, USL_OK2, USL_OK3, USL_OK4, SELF) ' \
                   u'VALUES ' + ', '.join(values)
            db.query(stmt)

    @QtCore.pyqtSlot()
    def on_btnImport_clicked(self):
        db = QtGui.qApp.db
        mapMKB = {}
        self.progressBar.setMinimum(0)
        self.progressBar.setMaximum(len(self.importDBF))
        self.progressBar.setValue(0)
        self.logBrowser.append(
            u'Импорт начат: %s' %
            (QtCore.QTime.currentTime().toString('hh:mm:ss')))
        self.logBrowser.update()
        insertValues = []
        self.progressBar.setText(u'Считывание данных из файла')
        for recordDBF in self.importDBF:
            self.progressBar.step()
            try:
                code = forceString(recordDBF['CODE'])
                mapMKB[code] = (forceString(recordDBF['IS_OMS']),
                                forceString(recordDBF['DATN']),
                                forceString(recordDBF['DATO']),
                                forceString(recordDBF['NAME']))
            except KeyError:
                self.logBrowser.append(
                    u'Неправильный формат файла\nИмпорт прерван: %s' %
                    (QtCore.QTime.currentTime().toString('hh:mm:ss')))
                self.logBrowser.update()
                self.importDBF.close()
                return
        self.importDBF.close()
        db.transaction()
        try:
            self.progressBar.setText(u'Обновление записей')
            self.updateMKB(mapMKB)
            self.progressBar.setText(u'Вставка записей')
            self.insertMKB(mapMKB)
            self.logBrowser.append(
                u'Импорт окончен: %s' %
                (QtCore.QTime.currentTime().toString('hh:mm:ss')))
            self.logBrowser.update()
            db.commit()
        except:
            self.logBrowser.append(
                u'Ошибка импорта: %s' %
                (QtCore.QTime.currentTime().toString('hh:mm:ss')))
            db.rollback()
            QtGui.qApp.logCurrentException()
        self.progressBar.setRange(0, 1)
        self.progressBar.setValue(1)

    @QtCore.pyqtSlot()
    def on_btnSelectFile_clicked(self):
        fileName = QtGui.QFileDialog.getOpenFileName(
            self, u'Укажите файл с данными', self.edtFileName.text(),
            u'Файлы DBF, ZIP (*.dbf *.zip)')
        if fileName:
            self.edtFileName.setText(QtCore.QDir.toNativeSeparators(fileName))
            self.openFile(unicode(fileName))