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
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()