Beispiel #1
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()
Beispiel #2
0
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()