def newDocument( self ): """ Iniciar un nuevo documento """ query = QSqlQuery() try: if not QSqlDatabase.database().isOpen() and not QSqlDatabase.database().open(): raise UserWarning( u"No se pudo establecer una conexión " "con la base de datos" ) dlgCuenta = dlgSelectCuenta( self ) fila = -1 #REPETIR MIENTRAS NO SELECCIONE UNA FILA while fila == -1: if dlgCuenta.exec_() == QDialog.Accepted: fila = dlgCuenta.tblCuenta.selectionModel().currentIndex().row() if fila == -1: QMessageBox.information( self, qApp.organizationName(), "Por favor seleccione una cuenta" ) else: #SALIR return # SI SELECCIONO UNA FILA SIGUE self.editmodel = ConciliacionModel( dlgCuenta.data['saldo_inicial_libro'], dlgCuenta.data['fecha'], dlgCuenta.data['banco'], dlgCuenta.data['cuenta_bancaria'], dlgCuenta.data['id_cuenta_contable'], dlgCuenta.data['codigo_cuenta_contable'], dlgCuenta.data['moneda'] ) self.txtbanco.setText( self.editmodel.banco ) self.txtcuentabanco.setText( self.editmodel.cuenta_bancaria ) self.txtmoneda.setText( self.editmodel.moneda ) self.txtcuenta.setText( self.editmodel.codigo_cuenta_contable ) self.lblfecha.setText( self.editmodel.datetime.toString( "MMMM yyyy" ).upper() ) if not query.exec_( "CALL spMovimientoCuenta( %d, %s )" % ( self.editmodel.id_cuenta_contable, self.editmodel.fecha_conciliacion.toString( "yyyyMMdd" ) ) ): raise Exception( query.lastError().text() ) row = 0 while query.next(): linea = LineaConciliacion( query.value( 5 ).toBool(), #del_banco Decimal( query.value( 3 ).toString() ), #saldo_inicial Decimal( query.value( DEBE ).toString() ), #monto QDate.fromString( query.value( FECHA ).toString(), 'dd/M/yy' ), #fecha query.value( 6 ).toInt()[0], # tipo_doc query.value( 8 ).toInt()[0], # id_documento query.value( CONCEPTO ).toString() #descripcion ) linea.monto = Decimal( query.value( 2 ).toString() ) self.editmodel.insertRows( row ) self.editmodel.lines[row] = linea row += 1 #self.editmodel.saldoInicialLibro = self.editmodel.lines[row - 1].saldo self.txtsaldolibro.setText( moneyfmt( self.editmodel.saldo_inicial_libro, 4, self.editmodel.moneda ) ) self.updateLabels() self.proxymodel.setSourceModel( self.editmodel ) self.setControls( False ) self.tabnavigation.setEnabled( False ) self.tabWidget.setCurrentIndex( 0 ) self.tabledetails.setModel( self.editmodel ) self.tabledetails.resizeColumnsToContents() self._ocultar_columnas() self.editmodel.dataChanged[QModelIndex, QModelIndex].connect( self.updateLabels ) except UserWarning as inst: logging.error( unicode( inst ) ) QMessageBox.critical( self, qApp.organizationName(), unicode( inst ) ) except Exception as inst: logging.critical( unicode( inst ) ) QMessageBox.critical( self, qApp.organizationName(), u"Hubo un error al intentar iniciar una" + u" nueva conciliación" ) finally: if self.database.isOpen(): self.database.close()
class FrmConciliacion( Base , Ui_frmConciliacion ): """ Formulario para crear nuevas conciliaciones bancarias """ def __init__( self , parent = None ): """ Constructor """ super( FrmConciliacion, self ).__init__( parent ) self.user = parent.user self.editmodel = None self.status = True # las acciones deberian de estar ocultas self.actionSave.setVisible( False ) self.actionCancel.setVisible( False ) # El modelo principal self.navmodel = RONavigationModel( self ) # El modelo que filtra a self.navmodel self.navproxymodel = QSortFilterProxyModel( self ) self.navproxymodel.setFilterKeyColumn( -1 ) self.navproxymodel.setSourceModel( self.navmodel ) self.navproxymodel.setFilterCaseSensitivity ( Qt.CaseInsensitive ) # Este es el modelo con los datos de la tabla para navegar self.detailsmodel = ReadOnlyTableModel( self ) self.proxymodel = QSortFilterProxyModel( self ) # CREAR TODOS LOS PROXY MODEL self._create_filter_models() self.detailsmodel.dataChanged[QModelIndex, QModelIndex].connect( self.updateLabels ) # Cargar los modelos en un hilo aparte QTimer.singleShot( 0, self.loadModels ) def _create_filter_models( self ): #CREAR PROXY MODEL self.proxymodel.setDynamicSortFilter( True ) self.proxymodel.setFilterRole( Qt.EditRole ) self.proxymodel.setFilterRegExp( "1" ) self.proxymodel.setFilterKeyColumn( CONCILIADO ) #CREAR PROXY MODEL PARA VERIFICAR SI FUE GENERADO POR EL BANCO delbancoproxymodel = QSortFilterProxyModel( self ) delbancoproxymodel.setSourceModel( self.proxymodel ) delbancoproxymodel.setDynamicSortFilter( True ) delbancoproxymodel.setFilterRole( Qt.EditRole ) delbancoproxymodel.setFilterRegExp( "0" ) delbancoproxymodel.setFilterKeyColumn( DELBANCO ) #CREAR PROXY MODEL PARA VERIFICAR SI FUE GENERADO POR LA EMPRESA empresaproxymodel = QSortFilterProxyModel( self ) empresaproxymodel.setSourceModel( self.proxymodel ) empresaproxymodel.setDynamicSortFilter( True ) empresaproxymodel.setFilterRole( Qt.EditRole ) empresaproxymodel.setFilterRegExp( "1" ) empresaproxymodel.setFilterKeyColumn( DELBANCO ) filtroMenos = "^" + str( constantes.IDND ) + "$|^" + str( constantes.IDCHEQUE ) + "$|^" + str( constantes.IDERROR ) +"$|^" + str( constantes.IDERROR ) + "$" filtroMas = "[" + filtroMenos + "]" #CREAR MODELO PARA DEPOSITOS self._setup_proxy_model(DetalleTableModel(self), empresaproxymodel, filtroMas, IDTIPODOC, self.tablalibromas) #CREAR MODELO PARA CHEQUES self._setup_proxy_model(DetalleTableModel(self), empresaproxymodel, filtroMenos, IDTIPODOC, self.tablalibromenos) #CREAR MODELO PARA NOTAS DE CREDITO self._setup_proxy_model(DetalleTableModel(self), delbancoproxymodel, filtroMas, IDTIPODOC, self.tablabancomas) #CREAR MODELO PARA NOTAS DE DEBITO self._setup_proxy_model(DetalleTableModel(self), delbancoproxymodel, filtroMenos, IDTIPODOC, self.tablabancomenos) def _setup_proxy_model(self, model, source, regexp, column, table, role = Qt.DisplayRole): model.setSourceModel( source ) model.setFilterRegExp( regexp ) model.setFilterKeyColumn( column ) model.setFilterRole(role) table.setModel( model ) def updateModels( self ): """ Recargar todos los modelos """ try: if not(QSqlDatabase.database().isOpen() or QSqlDatabase.database().open()): raise Exception( "No se pudo abrir la base" ) self.navmodel.setQuery( """ SELECT c.Fecha, b.descripcion as Banco, cb.ctabancaria, m.Simbolo, cc.Codigo, c.saldolibro, c.saldobanco, cb.idcuentacontable, c.iddocumento FROM conciliaciones c JOIN cuentasbancarias cb ON c.idcuentabancaria = cb.idcuentacontable JOIN bancos b ON b.idbanco = cb.idbanco JOIN tiposmoneda m ON m.idtipomoneda = cb.idtipomoneda JOIN cuentascontables cc ON cc.idcuenta = cb.idcuentacontable ORDER BY c.iddocumento ; """ ) # Este objeto mapea una fila del modelo self.navproxymodel a los controles self.mapper.setSubmitPolicy( QDataWidgetMapper.ManualSubmit ) self.mapper.setModel( self.navproxymodel ) self.mapper.addMapping( self.txtbanco, BANCO ) self.mapper.addMapping( self.txtmoneda, MONEDA ) self.mapper.addMapping( self.txtcuentabanco, CUENTABANCO ) self.mapper.addMapping( self.txtcuenta, CUENTA ) # asignar los modelos a sus tablas self.tablenavigation.setModel( self.navproxymodel ) self.tabledetails.setModel( self.detailsmodel ) self.proxymodel.setSourceModel( self.detailsmodel ) self.tablenavigation.setColumnHidden( SALDOBANCO, True ) self.tablenavigation.setColumnHidden( SALDOLIBRO, True ) self.tablenavigation.setColumnHidden( IDCUENTABANCO, True ) self.tablenavigation.setColumnHidden( IDDOC, True ) self._ocultar_columnas() except UserWarning as inst: logging.error( unicode( inst ) ) QMessageBox.critical( self, qApp.organizationName(), unicode( inst ) ) except Exception as inst: logging.critical( unicode( inst ) ) QMessageBox.critical( self, qApp.organizationName(), u"Hubo un error al tratar de iniciar una nueva conciliación "\ + "bancaria" ) finally: if QSqlDatabase.database().isOpen(): QSqlDatabase.database().close() def updateDetailFilter( self, _index ): if self.tabWidget.currentIndex() == 0: self.cargarMovimientos() def cargarMovimientos( self ): index = self.mapper.currentIndex() saldobanco = Decimal( self.navmodel.record( index ).value( "saldobanco" ).toString() ) saldolibro = Decimal( self.navmodel.record( index ).value( "saldolibro" ).toString() ) fecha = self.navmodel.record( index ).value( "fecha" ).toDate() self.lblfecha.setText( fecha.toString( "MMMM yyyy" ).upper() ) ctaBanco = self.navmodel.record( index ).value( "idcuentacontable" ).toString() try: if not self.database.isOpen(): if not self.database.open(): raise Exception( "No se pudo abrir la base" ) self.detailsmodel.setQuery( "CALL spMovimientoCuenta(" + ctaBanco + "," + fecha.toString( "yyyyMMdd" ) + ");" ) self.proxymodel.setSourceModel( self.detailsmodel ) except Exception as inst: logging.error( unicode( inst ) ) finally: if self.database.isOpen(): self.database.close() self.tablenavigation.selectRow( self.mapper.currentIndex() ) self.spbsaldobanco.setValue( saldobanco ) self.txtsaldolibro.setText( moneyfmt( saldolibro, 4, "C$" ) ) nc = self.tablabancomas.model().total nd = self.tablabancomenos.model().total depositos = self.tablalibromas.model().total cheques = self.tablalibromenos.model().total self.txtcheque.setText( moneyfmt( cheques, 4, "C$" ) ) self.txtdeposito.setText( moneyfmt( depositos, 4, self.editmodel.moneda ) ) self.txtnotacredito.setText( moneyfmt( nc, 4, self.editmodel.moneda ) ) self.txtnotadebito.setText( moneyfmt( nd, 4, self.editmodel.moneda ) ) self.txttotallibro.setText( moneyfmt( saldobanco + depositos + cheques, 4, self.editmodel.moneda ) ) self.txttotalbanco.setText( moneyfmt( saldolibro + nc + nd , 4, self.editmodel.moneda ) ) dif = saldobanco + depositos + cheques - ( saldolibro + nc + nd ) self.lbldiferencia.setText( moneyfmt( dif, 4, self.editmodel.moneda ) if dif != 0 else "CONCILIADO" ) def updateLabels( self ): self.txttotallibro.setText( moneyfmt( self.editmodel.total_libro, 4, self.editmodel.moneda ) ) self.txtcheque.setText( moneyfmt( self.editmodel.total_cheques, 4, self.editmodel.moneda ) ) self.txtdeposito.setText( moneyfmt( self.editmodel.total_depositos, 4, self.editmodel.moneda ) ) self.txtnotacredito.setText( moneyfmt( self.editmodel.total_nota_credito, 4, self.editmodel.moneda ) ) self.txtnotadebito.setText( moneyfmt( self.editmodel.total_nota_debito, 4, self.editmodel.moneda ) ) self.txttotalbanco.setText( moneyfmt( self.editmodel.total_banco, 4, self.editmodel.moneda ) ) dif = self.editmodel.diferencia self.lbldiferencia.setText( ( "Diferencia " + moneyfmt( dif, 4, self.editmodel.moneda ) ) if dif != 0 else "CONCILIADO" ) @pyqtSlot( float ) def on_spbsaldobanco_valueChanged ( self, value ): """ Asignar el saldo inicial del banco al modelo """ if not self.editmodel is None: # value = self.spbsaldobanco.value() self.editmodel.saldo_inicial_banco = Decimal( str( value ) ) self.updateLabels() @pyqtSlot( ) def on_btnAdd_clicked(self): if not self.database.isOpen(): if not self.database.open(): raise UserWarning( u"No se pudo establecer la conexión con "\ + "la base de datos" ) try: mov = dlgmovimientosbancarios(self) # Rellenar el combobox de las CONCEPTOS if mov.conceptosModel.rowCount() == 0: raise UserWarning( u"No existen conceptos en la base de "\ + "datos que justifiquen la elaboración de Notas de Crédito o Débito" ) mov.exec_() except UserWarning as inst: QMessageBox.critical( self, qApp.organizationName(), unicode( inst ) ) logging.error( unicode( inst ) ) logging.error( mov.conceptosModel.query().lastError().text() ) # except Exception as inst: # QMessageBox.critical( self, qApp.organizationName(), # "Hubo un problema al tratar de crear"\ # + " el nuevo pago" ) # logging.critical( unicode( inst ) ) # logging.error( query.lastError().text() ) finally: if QSqlDatabase.database().isOpen(): QSqlDatabase.database().close() # notas = dlgMovimientosBancarios( self ) # notas.setWindowModality( Qt.WindowModal ) # if notas.exec_() == QDialog.Accepted: # row = self.editmodel.rowCount() # # datosDoc = notas.editmodel.datos # # linea = LineaConciliacion( self.editmodel ) # linea.fecha = datosDoc.dateTime.toString( "dd/MM/yy" ) # linea.monto = datosDoc.total # linea.idTipoDoc = datosDoc.idTipoDoc # # linea.concepto = notas.editmodel.codigoDoc + " " + linea.fecha # linea.saldo = self.editmodel.lines[row - 1].saldo + linea.monto # linea.conciliado = 1 # linea.delBanco = 1 # linea.concepto2 = notas.editmodel.descripcionDoc + " " + linea.fecha # linea.idDoc = 0 # linea.datos = datosDoc # self.editmodel.insertRows( row ) # self.editmodel.lines[row] = linea # index = self.editmodel.index( row, CONCILIADO ) # self.editmodel.dataChanged.emit( index, index ) def setControls( self, status ): """ En esta funcion cambio el estado enabled de todos los items en el formulario @param status: false = editando true = navegando """ self.actionPrint.setVisible( status ) self.btnAdd.setVisible( not status ) self.btnRemove.setVisible( not status ) self.actionSave.setVisible( not status ) self.actionCancel.setVisible( not status ) self.tabnavigation.setEnabled( status ) self.actionNew.setVisible( status ) self.actionGoFirst.setVisible( status ) self.actionGoPrevious.setVisible( status ) self.actionGoNext.setVisible( status ) self.actionGoLast.setVisible( status ) self.actionPreview.setVisible( status ) self.spbsaldobanco.setReadOnly( status ) # self.tabledetails.setColumnHidden(DELBANCO,not status) if status: self.navigate( 'last' ) self.tabledetails.setEditTriggers( QAbstractItemView.NoEditTriggers ) else: self.tabledetails.setEditTriggers( QAbstractItemView.AllEditTriggers ) self.spbsaldobanco.setValue( 0 ) self.tabWidget.setCurrentIndex( 0 ) def newDocument( self ): """ Iniciar un nuevo documento """ query = QSqlQuery() try: if not QSqlDatabase.database().isOpen() and not QSqlDatabase.database().open(): raise UserWarning( u"No se pudo establecer una conexión " "con la base de datos" ) dlgCuenta = dlgSelectCuenta( self ) fila = -1 #REPETIR MIENTRAS NO SELECCIONE UNA FILA while fila == -1: if dlgCuenta.exec_() == QDialog.Accepted: fila = dlgCuenta.tblCuenta.selectionModel().currentIndex().row() if fila == -1: QMessageBox.information( self, qApp.organizationName(), "Por favor seleccione una cuenta" ) else: #SALIR return # SI SELECCIONO UNA FILA SIGUE self.editmodel = ConciliacionModel( dlgCuenta.data['saldo_inicial_libro'], dlgCuenta.data['fecha'], dlgCuenta.data['banco'], dlgCuenta.data['cuenta_bancaria'], dlgCuenta.data['id_cuenta_contable'], dlgCuenta.data['codigo_cuenta_contable'], dlgCuenta.data['moneda'] ) self.txtbanco.setText( self.editmodel.banco ) self.txtcuentabanco.setText( self.editmodel.cuenta_bancaria ) self.txtmoneda.setText( self.editmodel.moneda ) self.txtcuenta.setText( self.editmodel.codigo_cuenta_contable ) self.lblfecha.setText( self.editmodel.datetime.toString( "MMMM yyyy" ).upper() ) if not query.exec_( "CALL spMovimientoCuenta( %d, %s )" % ( self.editmodel.id_cuenta_contable, self.editmodel.fecha_conciliacion.toString( "yyyyMMdd" ) ) ): raise Exception( query.lastError().text() ) row = 0 while query.next(): linea = LineaConciliacion( query.value( 5 ).toBool(), #del_banco Decimal( query.value( 3 ).toString() ), #saldo_inicial Decimal( query.value( DEBE ).toString() ), #monto QDate.fromString( query.value( FECHA ).toString(), 'dd/M/yy' ), #fecha query.value( 6 ).toInt()[0], # tipo_doc query.value( 8 ).toInt()[0], # id_documento query.value( CONCEPTO ).toString() #descripcion ) linea.monto = Decimal( query.value( 2 ).toString() ) self.editmodel.insertRows( row ) self.editmodel.lines[row] = linea row += 1 #self.editmodel.saldoInicialLibro = self.editmodel.lines[row - 1].saldo self.txtsaldolibro.setText( moneyfmt( self.editmodel.saldo_inicial_libro, 4, self.editmodel.moneda ) ) self.updateLabels() self.proxymodel.setSourceModel( self.editmodel ) self.setControls( False ) self.tabnavigation.setEnabled( False ) self.tabWidget.setCurrentIndex( 0 ) self.tabledetails.setModel( self.editmodel ) self.tabledetails.resizeColumnsToContents() self._ocultar_columnas() self.editmodel.dataChanged[QModelIndex, QModelIndex].connect( self.updateLabels ) except UserWarning as inst: logging.error( unicode( inst ) ) QMessageBox.critical( self, qApp.organizationName(), unicode( inst ) ) except Exception as inst: logging.critical( unicode( inst ) ) QMessageBox.critical( self, qApp.organizationName(), u"Hubo un error al intentar iniciar una" + u" nueva conciliación" ) finally: if self.database.isOpen(): self.database.close() def _ocultar_columnas( self ): for table in ( self.tablabancomas, self.tablalibromas, self.tablabancomenos, self.tablalibromenos): table.setColumnHidden( HABER, True ) table.setColumnHidden( CONCILIADO, True ) table.setColumnHidden( SALDO, True ) table.setColumnHidden( IDTIPODOC, True ) table.setColumnHidden( DELBANCO, True ) self.tabledetails.setColumnHidden( IDTIPODOC, True ) def save( self ): """ Guardar el documento actual """ if not self.valid: return None if QMessageBox.question( self, qApp.organizationName(), u"¿Desea guardar el documento?", QMessageBox.Yes | QMessageBox.No ) == QMessageBox.Yes: if self.editmodel.save(): QMessageBox.information( self, qApp.organizationName(), u"El documento se ha guardado con éxito" ) self.editmodel = None self.updateModels() self.navigate( 'last' ) self.status = True else: QMessageBox.critical( self, qApp.organizationName(), "Ha ocurrido un error al guardar el documento" ) def cancel( self ): self.editmodel = None self.tablenavigation.setModel( self.navproxymodel ) self.tabledetails.setModel( self.detailsmodel ) self.proxymodel.setSourceModel( self.detailsmodel ) self._ocultar_columnas() self.status = True @pyqtSlot( bool ) @if_edit_model def on_btnremove_clicked( self, _checked ): filas = [] for index in self.tabledetails.selectedIndexes(): pos = index.row() if pos > 0 and not pos in filas and self.editmodel.lines[pos].idDoc == 0: filas.append( pos ) if len( filas ) > 0: filas.sort( None, None, True ) for pos in filas: self.editmodel.removeRows( pos ) self.updateLabels()