Example #1
0
class FrmDevolucion( Ui_frmDevoluciones, Base ):
    """
    Formulario para crear nuevas devoluciones
    """
    web = "devoluciones.php?doc="
    def __init__( self, parent = None ):
        """
        Constructor
        """
        super( FrmDevolucion, self ).__init__( parent )



        self.editmodel = None

        self.status = True

#        las acciones deberian de estar ocultas


#        El modelo principal
        self.navmodel = RONavigationModel( self )
#        El modelo que filtra a self.navmodel
        self.navproxymodel = QSortFilterProxyModel( self )
        self.navproxymodel.setSourceModel( self.navmodel )
#        Este es el modelo con los datos de la tabla para navegar
        self.detailsmodel = QSqlQueryModel( self )
#        Este es el filtro del modelo anterior
        self.detailsproxymodel = QSortFilterProxyModel( self )
        self.detailsproxymodel.setSourceModel( self.detailsmodel )



#        Cargar los modelos en un hilo aparte
        QTimer.singleShot( 0, self.loadModels )



    def addLine( self ):
        """
        Redefiniendo addLine, se supone que en una 
        liquidacion no se pueden añadir lineas
        """
        raise RuntimeError( "Las devoluciones no deben de añadir lineas nuevas" )

    def updateModels( self ):
#        El modelo principal
        self.navmodel = RONavigationModel( self )
#        El modelo que filtra a self.navmodel
        self.navproxymodel = QSortFilterProxyModel( self )
        self.navproxymodel.setSourceModel( self.navmodel )
        self.navproxymodel.setFilterKeyColumn( -1 )
        self.navproxymodel.setFilterCaseSensitivity ( Qt.CaseInsensitive )

#        Este es el modelo con de la tabla con los detalles
        self.detailsmodel = QSqlQueryModel( self )
#        Este es el filtro del modelo anterior
        self.detailsproxymodel = QSortFilterProxyModel( self )
        self.detailsproxymodel.setSourceModel( self.detailsmodel )


        try:

            if not self.database.isOpen():
                if not self.database.open():
                    raise UserWarning( u"No se pudo abrir la conexión con la base de datos" )
            query = u"""
             SELECT
                d.iddocumento,
                d.ndocimpreso AS 'Numero de Entrada',
                padre.ndocimpreso AS padre,
                p.nombre as 'Cliente',
                d.observacion,
                d.fechacreacion AS 'Fecha',
                (@subtotald:=(d.total / ( 1 + ( IF( ca.valorcosto IS NOT NULL , ca.valorcosto / 100, 0 ) )) ) ) AS subtotald,
                @subtotald * (IF( ca.valorcosto IS NOT NULL , ca.valorcosto / 100, 0 )  ) AS ivad,
                SUM( axd.costounit ) as costod,
                d.total AS totald,
                tc.tasa,
                c.descripcion AS 'Concepto',
                b.nombrebodega AS 'Bodega'
            FROM documentos d
            JOIN bodegas b ON d.idbodega = b.idbodega
            JOIN conceptos c ON c.idconcepto = d.idconcepto
            JOIN docpadrehijos dpd ON dpd.idhijo = d.iddocumento
            JOIN documentos padre ON dpd.idpadre = padre.iddocumento
            JOIN tiposcambio tc ON d.idtipocambio = tc.idtc
            JOIN personasxdocumento pd ON d.iddocumento=pd.iddocumento
            LEFT JOIN personas p ON p.idpersona=pd.idpersona
            JOIN articulosxdocumento axd ON axd.iddocumento = d.iddocumento
            LEFT JOIN costosxdocumento cxd ON cxd.iddocumento = padre.iddocumento
            LEFT JOIN costosagregados ca ON ca .idcostoagregado = cxd.idcostoagregado
            WHERE d.idtipodoc = %d AND p.tipopersona=%d
            GROUP BY d.iddocumento""" % ( constantes.IDNC, constantes.CLIENTE )

            self.navmodel.setQuery( query )

            self.detailsmodel.setQuery( u"""
            SELECT 
                ad.idarticulo, 
                ad.descripcion as 'Descripción', 
                axd.unidades as 'Cantidad', 
                axd.precioventa as 'Precio de venta',
                axd.unidades * axd.precioventa as Total,
                axd.iddocumento
            FROM articulosxdocumento axd
            JOIN vw_articulosdescritos ad ON axd.idarticulo = ad.idarticulo
            JOIN documentos d ON d.iddocumento = axd.iddocumento 
            WHERE d.idtipodoc = %d
            """ % constantes.IDNC )




            #        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.txtDocumentNumber, NDOCIMPRESO )
            self.mapper.addMapping( self.txtObservations, OBSERVACION )
            self.mapper.addMapping( self.dtPicker, FECHA )
            self.mapper.addMapping( self.txtClient, CLIENTE, "text" )
            self.mapper.addMapping( self.txtBill, FACTURA, "text" )
            self.mapper.addMapping( self.lblTotal, TOTAL, "text" )
            self.mapper.addMapping( self.lblSubtotal, SUBTOTAL, "text" )
            #self.mapper.addMapping( self.lblCost, COSTO, "text" )
            self.mapper.addMapping( self.lblTaxes, IMPUESTOS, "text" )
            self.mapper.addMapping( self.txtConcept, CONCEPTO, "text" )
            self.mapper.addMapping( self.txtWarehouse, NOMBREBODEGA, "text" )

    #        asignar los modelos a sus tablas
            self.tablenavigation.setModel( self.navproxymodel )
            self.tabledetails.setModel( self.detailsproxymodel )

            self.tablenavigation.setColumnHidden( IDDOCUMENTO, True )
            self.tablenavigation.setColumnHidden( OBSERVACION, True )
            self.tablenavigation.setColumnHidden( SUBTOTAL, True )
            self.tablenavigation.setColumnHidden( IMPUESTOS, True )
            self.tablenavigation.setColumnHidden( TASA, True )
            self.tablenavigation.setColumnHidden( COSTO, True )


            self.tablenavigation.resizeColumnsToContents()
            self.tablenavigation.horizontalHeader().setStretchLastSection( True )

        except UserWarning as inst:
            QMessageBox.critical( self, qApp.organizationName(), unicode( inst ) )
            logging.error( unicode( inst ) )
        except Exception as inst:
            logging.critical( unicode( inst ) )
            QMessageBox.critical( self, qApp.organizationName(), u"Hubo un error al cargar la lista de devoluciones" )
        finally:
            if self.database.isOpen():
                self.database.close()

    def updateDetailFilter( self, index ):
        self.detailsproxymodel.setFilterRegExp( self.navmodel.record( index ).value( "iddocumento" ).toString() )
        self.detailsproxymodel.setFilterKeyColumn( IDDOCUMENTOT )
        self.tablenavigation.selectRow( self.mapper.currentIndex() )

    def updateLabels( self ):
        self.lblTotal.setText( moneyfmt( self.editmodel.totalD, 4, "US$" ) + " / " + moneyfmt( self.editmodel.totalC, 4, "C$" ) )
        self.lblSubtotal.setText( moneyfmt( self.editmodel.subtotalD, 4, "US$" ) + " / " + moneyfmt( self.editmodel.subtotalC, 4, "C$" ) )
        self.lblTaxes.setText( moneyfmt( self.editmodel.ivaD, 4, "US$" ) + " / " + moneyfmt( self.editmodel.ivaC, 4, "C$" ) )
        #self.lblCost.setText( moneyfmt( self.editmodel.totalCostD, 4, "US$" ) + " / " + moneyfmt( self.editmodel.totalCostC, 4, "C$" ) )

    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.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.txtDocumentNumber.setReadOnly( status )
        self.txtObservations.setReadOnly( status )
        self.dtPicker.setReadOnly( status )

        self.actionSave.setVisible( not status )
        self.actionCancel.setVisible( not status )

        self.swConcept.setCurrentIndex( 1 if status else 0 )
        if status:

            self.navigate( 'last' )
            self.tabledetails.setEditTriggers( QAbstractItemView.NoEditTriggers )
        else:
            self.txtClient.setText( self.editmodel.clientName )
            self.txtObservations.setPlainText( "" )
            self.lblTotal.setText( "US$0.0000 / C$0.0000" )
            #self.lblCost.setText( "US$0.0000 / C$0.0000" )
            self.lblTaxes.setText( "US$0.0000 / C$0.0000" )
            self.lblSubtotal.setText( "US$0.0000 / C$0.0000" )
            self.tabledetails.setEditTriggers( QAbstractItemView.AllEditTriggers )
            self.tabWidget.setCurrentIndex( 0 )

#            mostrar las columnas para el modeo edicion u ocultar para navegación
        self.tabledetails.setColumnHidden( IDARTICULO, status )
        self.tabledetails.setColumnHidden( IDDOCUMENTOT, status )

    @pyqtSlot( unicode )
    @if_edit_model
    def on_txtDocumentNumber_textEdited( self, string ):
        """
        Slot documentation goes here.
        """
        self.editmodel.printedDocumentNumber = string

    @pyqtSlot( unicode )
    @if_edit_model
    def on_txtnotacredito_textEdited( self, string ):
        """
        Slot documentation goes here.
        """
        self.editmodel.numnotacredito = string


    @pyqtSlot()
    @if_edit_model
    def on_txtObservations_textChanged( self ):
        """
        Slot documentation goes here.
        """
        self.editmodel.observations = self.txtObservations.toPlainText()

    def newDocument( self ):
        """
        Slot documentation goes here.
        """
        query = QSqlQuery()
        try:
            if not self.database.isOpen():
                if not self.database.open():
                    raise Exception( u"No se pudo establecer una conexión con la base de datos" )

            self.conceptsmodel = QSqlQueryModel()
            self.conceptsmodel.setQuery( """
            SELECT idconcepto, descripcion 
            FROM conceptos 
            WHERE idtipodoc = %d
            """ % constantes.IDNC )

            if self.conceptsmodel.rowCount() == 0:
                raise UserWarning( u"No existen conceptos para devolución" )


            dlgbill = DlgSelectInvoice()
            if dlgbill.exec_() == QDialog.Accepted:
                self.editmodel = DevolucionModel()
                row = dlgbill.tblBills.selectionModel().currentIndex().row()
                self.editmodel.invoiceId = dlgbill.filtermodel.index( 
                                                 row, 0 ).data().toInt()[0]
                self.editmodel.billPrinted = dlgbill.filtermodel.index( 
                                               row, 1 ).data().toString()
                self.editmodel.clientName = dlgbill.filtermodel.index( 
                                                  row, 3 ).data().toString()

                self.editmodel.clientId = dlgbill.filtermodel.index( 
                                            row, 5 ).data().toInt()[0]

                self.editmodel.ivaRate = Decimal( dlgbill.filtermodel.index( 
                                             row, 6 ).data().toString() )
                self.editmodel.ivaRateId = dlgbill.filtermodel.index( 
                                             row, 7 ).data().toInt()[0]

                self.editmodel.exchangeRate = Decimal( dlgbill.filtermodel.index( 
                                                row, 8 ).data().toString() )
                self.editmodel.exchangeRateId = dlgbill.filtermodel.index( 
                                                  row, 9 ).data().toInt()[0]

                self.editmodel.warehouseName = dlgbill.filtermodel.index( 
                                                 row, 10 ).data().toString()
                self.editmodel.warehouseId = dlgbill.filtermodel.index( 
                                               row, 11 ).data().toInt()[0]


                self.editmodel.uid = self.user.uid


                query = QSqlQuery( """
                CALL spConsecutivo(%d,NULL);
                """ % constantes.IDNC )
                if not query.exec_():
                    raise UserWarning( u"No se pudo calcular el numero de la devolución" )
                query.first()
                self.editmodel.printedDocumentNumber = query.value( 0 ).toString()



                query.prepare( """
                SELECT 
                    v.idarticulo, 
                    v.descripcion,
                    facs.costounit,
                    facs.precioventa, 
                    -1*SUM(unidades) as existencia
                FROM articulosxdocumento facs
                JOIN vw_articulosdescritos v ON facs.idarticulo = v.idarticulo
                LEFT JOIN docpadrehijos devs ON devs.idhijo = facs.iddocumento
                WHERE facs.iddocumento = %d OR devs.idpadre = %d
                GROUP BY v.idarticulo
                """ % ( self.editmodel.invoiceId, self.editmodel.invoiceId ) )
                if not query.exec_():
                    raise Exception( "Ocurrio un error en la consulta" )

                while query.next():
                    linea = LineaDevolucion( self.editmodel )
                    linea.itemId = query.value( 0 ).toInt()[0]
                    linea.itemDescription = query.value( 1 ).toString()
                    linea.itemCost = Decimal( query.value( 2 ).toString() )
                    linea.itemPrice = Decimal( query.value( 3 ).toString() )
                    linea.maxquantity = query.value( 4 ).toInt()[0]


                    row = self.editmodel.rowCount()
                    self.editmodel.insertRows( row )

                    self.editmodel.lines[row] = linea


                self.cbConcept.setModel( self.conceptsmodel )
                self.cbConcept.setModelColumn( 1 )
                self.cbConcept.setCurrentIndex( -1 )


                self.tabnavigation.setEnabled( False )
                self.tabWidget.setCurrentIndex( 0 )
                self.tabledetails.setModel( self.editmodel )

                delegate = DevolucionDelegate()
                self.tabledetails.setItemDelegate( delegate )

                self.tabledetails.resizeColumnsToContents()
                self.dtPicker.setDateTime( QDateTime.currentDateTime() )
                self.editmodel.dataChanged[QModelIndex, QModelIndex].connect( self.updateLabels )


                self.txtDocumentNumber.setText( self.editmodel.printedDocumentNumber )
                self.txtBill.setText( self.editmodel.billPrinted )
                self.txtWarehouse.setText( self.editmodel.warehouseName )

                self.status = False
        except UserWarning as inst:
            QMessageBox.critical( self, qApp.organizationName(),
                                   unicode( inst ) )
            logging.error( unicode( inst ) )
            self.status = True
        except Exception as inst:
            QMessageBox.critical( self, qApp.organizationName(),
                                  u"Hubo un error al intentar crear una "\
                                  + "nueva devolución" )
            logging.critical( unicode( inst ) )
            self.status = True
        finally:
            if self.database.isOpen():
                self.database.close()

    @pyqtSlot( "int" )
    def on_cbConcept_currentIndexChanged( self, index ):
        """
        asignar proveedor al objeto self.editmodel
        """
        if not self.editmodel is None:
            self.editmodel.conceptId = self.conceptsmodel.record( index
                                          ).value( "idconcepto" ).toInt()[0]

    @property
    def printIdentifier( self ):
        return self.navmodel.record( self.mapper.currentIndex()
                                      ).value( "iddocumento" ).toString()

    def cancel( self ):
        self.editmodel = None

        self.tablenavigation.setModel( self.navproxymodel )
        self.tabledetails.setModel( self.detailsproxymodel )

        self.txtBill.setText( "" )
        self.txtClient.setText( "" )
        self.txtDocumentNumber.setText( "" )
        self.txtWarehouse.setText( "" )
        self.tabWidget.setCurrentIndex( 1 )
        self.status = True
Example #2
0
    def newDocument( self ):
        """
        Slot documentation goes here.
        """
        query = QSqlQuery()
        try:
            if not self.database.isOpen():
                if not self.database.open():
                    raise Exception( u"No se pudo establecer una conexión con la base de datos" )

            self.conceptsmodel = QSqlQueryModel()
            self.conceptsmodel.setQuery( """
            SELECT idconcepto, descripcion 
            FROM conceptos 
            WHERE idtipodoc = %d
            """ % constantes.IDNC )

            if self.conceptsmodel.rowCount() == 0:
                raise UserWarning( u"No existen conceptos para devolución" )


            dlgbill = DlgSelectInvoice()
            if dlgbill.exec_() == QDialog.Accepted:
                self.editmodel = DevolucionModel()
                row = dlgbill.tblBills.selectionModel().currentIndex().row()
                self.editmodel.invoiceId = dlgbill.filtermodel.index( 
                                                 row, 0 ).data().toInt()[0]
                self.editmodel.billPrinted = dlgbill.filtermodel.index( 
                                               row, 1 ).data().toString()
                self.editmodel.clientName = dlgbill.filtermodel.index( 
                                                  row, 3 ).data().toString()

                self.editmodel.clientId = dlgbill.filtermodel.index( 
                                            row, 5 ).data().toInt()[0]

                self.editmodel.ivaRate = Decimal( dlgbill.filtermodel.index( 
                                             row, 6 ).data().toString() )
                self.editmodel.ivaRateId = dlgbill.filtermodel.index( 
                                             row, 7 ).data().toInt()[0]

                self.editmodel.exchangeRate = Decimal( dlgbill.filtermodel.index( 
                                                row, 8 ).data().toString() )
                self.editmodel.exchangeRateId = dlgbill.filtermodel.index( 
                                                  row, 9 ).data().toInt()[0]

                self.editmodel.warehouseName = dlgbill.filtermodel.index( 
                                                 row, 10 ).data().toString()
                self.editmodel.warehouseId = dlgbill.filtermodel.index( 
                                               row, 11 ).data().toInt()[0]


                self.editmodel.uid = self.user.uid


                query = QSqlQuery( """
                CALL spConsecutivo(%d,NULL);
                """ % constantes.IDNC )
                if not query.exec_():
                    raise UserWarning( u"No se pudo calcular el numero de la devolución" )
                query.first()
                self.editmodel.printedDocumentNumber = query.value( 0 ).toString()



                query.prepare( """
                SELECT 
                    v.idarticulo, 
                    v.descripcion,
                    facs.costounit,
                    facs.precioventa, 
                    -1*SUM(unidades) as existencia
                FROM articulosxdocumento facs
                JOIN vw_articulosdescritos v ON facs.idarticulo = v.idarticulo
                LEFT JOIN docpadrehijos devs ON devs.idhijo = facs.iddocumento
                WHERE facs.iddocumento = %d OR devs.idpadre = %d
                GROUP BY v.idarticulo
                """ % ( self.editmodel.invoiceId, self.editmodel.invoiceId ) )
                if not query.exec_():
                    raise Exception( "Ocurrio un error en la consulta" )

                while query.next():
                    linea = LineaDevolucion( self.editmodel )
                    linea.itemId = query.value( 0 ).toInt()[0]
                    linea.itemDescription = query.value( 1 ).toString()
                    linea.itemCost = Decimal( query.value( 2 ).toString() )
                    linea.itemPrice = Decimal( query.value( 3 ).toString() )
                    linea.maxquantity = query.value( 4 ).toInt()[0]


                    row = self.editmodel.rowCount()
                    self.editmodel.insertRows( row )

                    self.editmodel.lines[row] = linea


                self.cbConcept.setModel( self.conceptsmodel )
                self.cbConcept.setModelColumn( 1 )
                self.cbConcept.setCurrentIndex( -1 )


                self.tabnavigation.setEnabled( False )
                self.tabWidget.setCurrentIndex( 0 )
                self.tabledetails.setModel( self.editmodel )

                delegate = DevolucionDelegate()
                self.tabledetails.setItemDelegate( delegate )

                self.tabledetails.resizeColumnsToContents()
                self.dtPicker.setDateTime( QDateTime.currentDateTime() )
                self.editmodel.dataChanged[QModelIndex, QModelIndex].connect( self.updateLabels )


                self.txtDocumentNumber.setText( self.editmodel.printedDocumentNumber )
                self.txtBill.setText( self.editmodel.billPrinted )
                self.txtWarehouse.setText( self.editmodel.warehouseName )

                self.status = False
        except UserWarning as inst:
            QMessageBox.critical( self, qApp.organizationName(),
                                   unicode( inst ) )
            logging.error( unicode( inst ) )
            self.status = True
        except Exception as inst:
            QMessageBox.critical( self, qApp.organizationName(),
                                  u"Hubo un error al intentar crear una "\
                                  + "nueva devolución" )
            logging.critical( unicode( inst ) )
            self.status = True
        finally:
            if self.database.isOpen():
                self.database.close()