def tabChangedSlot(self,argTabIndex): if argTabIndex==1: db = QtSql.QSqlDatabase.addDatabase("QSQLITE") self.tableView.setWindowTitle("Connect to QSQLITE Database Example") db.setHostName("localhost") db.setDatabaseName("serm_shadow.db") db.setUserName("") db.setPassword("") if (db.open()==False): message = "Database Error" msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setText("Error at opening database") msg.setInformativeText(message) msg.setWindowTitle("Informative Message") msg.setStandardButtons(QMessageBox.Close) msg.exec_() projectModel = QSqlQueryModel() projectModel.setQuery("SELECT datetime,temperature,humidity,smoke,lpg,co,windspeed,winddir,ffwi,risk FROM data_means ORDER BY recid DESC",db) self.tableView.setModel(projectModel) self.tableView.adjustSize self.tableView.setColumnWidth(0,168) self.tableView.show() elif argTabIndex==3: conn = sqlite3.connect('serm.db') ds = pd.read_sql("SELECT timestamp,datetime,risk,smoke,temperature,humidity,windspeed,ffwi from data_means", conn); conn.close() ds.to_csv("serm.csv") self.show_predictions_table()
def show_predictions_table(self): db = QtSql.QSqlDatabase.addDatabase("QSQLITE") self.tableView_PM.setWindowTitle("Connect to QSQLITE Database Example") db.setHostName("localhost") db.setDatabaseName("serm.db") db.setUserName("") db.setPassword("") if (db.open()==False): message = "Database Error" msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setText("Error at opening database") msg.setInformativeText(message) msg.setWindowTitle("Informative Message") msg.setStandardButtons(QMessageBox.Close) msg.exec_() projectModel = QSqlQueryModel() projectModel.setQuery("SELECT datetime,smoke,temperature,humidity,windspeed,fri,ffwi FROM predictions ORDER BY recid DESC",db) self.tableView_PM.setModel(projectModel) self.tableView_PM.adjustSize self.tableView_PM.setColumnWidth(0,160) self.tableView_PM.show()
def __init__(self, parent=None): QDialog.__init__(self, parent) self.ui = sm.Ui_Dialog() self.ui.setupUi(self) self.ui.table_studentList # Call DB self.db = QSqlDatabase.addDatabase("QSQLITE") self.db.setDatabaseName("studentInformation001.db") self.db.open() # End of call DB # student info into table view projectModel = QSqlQueryModel() projectModel.setQuery( "SELECT schoolNumber, Name FROM Student ORDER BY schoolNumber ASC", self.db) projectView = self.ui.table_studentList projectView.setModel(projectModel) projectView.show() #end of student info into table view # QTableView Click Event self.qTableView = self.ui.table_studentList self.qTableView.clicked.connect(self.showInfo) # click and connection update self.ui.Btn_Update.clicked.connect(self.cont) # click and connection grade self.ui.Btn_Grade.clicked.connect(self.contGrade)
def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) self.ui = sm.Ui_MainWindow() self.ui.setupUi(self) self.ui.table_studentList # Call DB db = QSqlDatabase.addDatabase("QSQLITE") db.setDatabaseName("studentInformation001.db") db.open() # End of call DB # student info into table view projectModel = QSqlQueryModel() projectModel.setQuery( "SELECT schoolNumber, Name FROM Student ORDER BY schoolNumber ASC", db) projectView = self.ui.table_studentList projectView.setModel(projectModel) projectView.show() #end of student info into table view # QTableView Click Event self.qTableView = self.ui.table_studentList self.qTableView.clicked.connect(self.showInfo)
def get_linked_esu_list(self, usrn): """ function that selects all esus for a determined street :param usrn: the unique identifier of a certain street :return: list[esu_ids] all esu ids linked to a certain street or void in case a street does not have any linked esu """ # executing the query esus_query_model = QSqlQueryModel() esus_query_model.setQuery(self.queries[9].format(usrn)) while esus_query_model.canFetchMore(): esus_query_model.fetchMore() n_rows = esus_query_model.rowCount() # skip if no esus are linked if n_rows == 0: return else: i = 0 esus_list = [] # creating a list of ESUs Ids that are linked to the street while i <= n_rows - 1: model_index = esus_query_model.createIndex(i, 0) esu = model_index.data() esus_list.append(esu) i += 1 return esus_list
def __init__(self, parent=None): QDialog.__init__(self, parent) self.ui = sm.Ui_Dialog() self.ui.setupUi(self) self.ui.table_studentList # Call DB self.db = QSqlDatabase.addDatabase("QSQLITE") self.db.setDatabaseName("studentInformation001.db") self.db.open() # End of call DB # student info into table view projectModel = QSqlQueryModel() projectModel.setQuery("SELECT schoolNumber, Name FROM Student ORDER BY schoolNumber ASC",self.db) projectView = self.ui.table_studentList projectView.setModel(projectModel) projectView.show() #end of student info into table view # QTableView Click Event self.qTableView = self.ui.table_studentList self.qTableView.clicked.connect(self.showInfo) # click and connection update self.ui.Btn_Update.clicked.connect(self.cont) # click and connection grade self.ui.Btn_Grade.clicked.connect(self.contGrade)
def querymodel(self, sql, **mappings): query = self._query(sql, **mappings) if query.exec_(): model = QSqlQueryModel() model.setQuery(query) return model else: raise DatabaseException(query.lastError().text())
def updateArticles( self ): """ Actualizar la lista de articulos """ query = QSqlQuery() try: if not self.database.isOpen(): if not self.database.open(): raise UserWarning( u"No se pudo conectar con la " + "base de datos" ) self.updateArticleList( query ) self.editmodel.updateLines( query ) providers_model = QSqlQueryModel() providers_model.setQuery( """ SELECT idpersona, nombre FROM personas p WHERE tipopersona = 2 AND activo = 1 """ ) if not providers_model.rowCount() > 0: raise UserWarning( "No existen proveedores en el sistema" ) self.cbProvider.setModel( providers_model ) self.cbProvider.setModelColumn( 1 ) warehouse_model = QSqlQueryModel() warehouse_model.setQuery( """ SELECT idbodega, nombrebodega FROM bodegas b ORDER BY idbodega """ ) if not warehouse_model.rowCount() > 0: raise UserWarning( "No existen bodegas en el sistema" ) self.cbWarehouse.setModel( warehouse_model ) self.cbWarehouse.setModelColumn( 1 ) self.cbWarehouse.setCurrentIndex( -1 ) self.cbProvider.setCurrentIndex( -1 ) except UserWarning as inst: QMessageBox.warning( self, qApp.organizationName(), unicode( inst ) ) logging.error( query.lastError().text() ) logging.error( unicode( inst ) ) self.cancel() except Exception as inst: QMessageBox.critical( self, qApp.organizationName(), "Hubo un error fatal al tratar de actualizar la lista " \ + "de articulos, el sistema no puede recuperarse" \ + " y sus cambios se han perdido" ) logging.error( query.lastError().text() ) logging.critical( unicode( inst ) ) self.cancel()
def createXlsReport(self): homepath = expanduser('~') filePath = self.chooseSaveFile(os.path.join(homepath, 'report.xls'), 'xls') if not filePath: return excelWorkbook = xlwt.Workbook() invoice = excelWorkbook.add_sheet("ReportExample") cell_middle = xlwt.easyxf("align: vert centre, horz centre, wrap on") cell_left = xlwt.easyxf("align: vert centre, horz left") cell_middle_bold = xlwt.easyxf("font: bold on; align: vert centre, horz centre, wrap on") cell_middle_bold_borders = xlwt.easyxf( "font: bold on; border: left thin, top thin, right thin, bottom thin; align: vert centre, horz centre, wrap on") cell_string = xlwt.easyxf( "border: left thin, top thin, right thin, bottom thin; align: vert centre, horz left, wrap on") cell_underline = xlwt.easyxf("font: underline on; align: vert centre, horz left, wrap on") cell_left_with_borders = xlwt.easyxf( "border: left thin, top thin, right thin, bottom thin; align: vert centre, horz left, wrap on") cell_right_with_borders = xlwt.easyxf( "border: left thin, top thin, right thin, bottom thin; align: vert centre, horz right, wrap on") invoice.write_merge(1, 1, 0, 9, u"ПРИМЕР ОТЧЕТА №1 от %s" % datetime.datetime.now().strftime('%Y-%m-%d'), cell_middle_bold) invoice.write_merge(2, 2, 0, 9, u"Дополнительная строка %s от %s" % ('_' * 3, '_' * 10), cell_middle_bold) clientQuery = QSqlQueryModel() clientQuery.setQuery( "SELECT Surname, Name, Midname, birthdate, sex, snils FROM Client where id=%s" % self.clientId) invoice.write(4, 0, u'ФИО пациента:', cell_left) invoice.write(4, 1, unicode(clientQuery.record(0).value("Surname").toString() + " " + clientQuery.record(0).value("Name").toString() + " " + clientQuery.record(0).value("Midname").toString()), cell_left) invoice.write(5, 0, u'Дата рождения:', cell_left) invoice.write(5, 1, unicode(clientQuery.record(0).value('birthdate').toString()), cell_left) invoice.write(6, 0, u'СНИЛС:', cell_left) invoice.write(6, 1, unicode(clientQuery.record(0).value('snils').toString()), cell_left) invoice.write(7, 0, u'Пол', cell_left) invoice.write(7, 1, u'М' if 1 == clientQuery.record(0).value('sex').toInt() else u'Ж', cell_left) clientQuery.setQuery('''SELECT distinct s.* FROM Client c INNER join cure cr on cr.Client_id = c.id INNER join services s on s.id = cr.services_id where c.id = %d''' % self.clientId) invoice.write_merge(9, 9, 0, 9, u"Информация об оказанных услугах", cell_middle_bold) invoice.write(10, 0, u'№ п/п', cell_left_with_borders) invoice.write(10, 1, u'Код', cell_left_with_borders) invoice.write_merge(10, 10, 2, 9, u"Наименование услуги", cell_left_with_borders) for i in xrange(clientQuery.rowCount()): invoice.write(11 + i, 0, i + 1, cell_left_with_borders) invoice.write(11 + i, 1, unicode(clientQuery.record(i).value('code').toString()), cell_left_with_borders) invoice.write_merge(11 + i, 11 + i, 2, 9, unicode(clientQuery.record(i).value('Name').toString()), cell_left_with_borders) invoice.write(clientQuery.rowCount() + 12, 0, u'Дата печати:') invoice.write(clientQuery.rowCount() + 12, 1, datetime.datetime.now().strftime('%Y-%m-%d')) excelWorkbook.save(filePath) return
def querymodel(self, sql, **mappings): sql = sql.replace(r"\r\n", " ") query = self._query(sql, **mappings) print sql, mappings if query.exec_(): model = QSqlQueryModel() model.setQuery(query) return model else: raise DatabaseException(query.lastError().text())
def fill_tables(self, qtable, table_name): """ :param qtable: QTableView to show :param table_name: view or table name wich we want to charge """ sql = "SELECT * FROM " + self.controller.schema_name + "." + table_name sql += " WHERE node_id = '" + self.id + "'" model = QSqlQueryModel() model.setQuery(sql) qtable.setModel(model) qtable.show()
def loadAllData(self): self.items = [] model = QSqlQueryModel() model.setQuery('''SELECT s.code, s.name FROM services s ''') for i in xrange(model.rowCount()): code = model.record(i).value("code").toString() name = model.record(i).value("name").toString() item = [code + u": " + name] self.items.append(item) self.reset()
class MainWindow(QMainWindow) : def __init__(self): super(MainWindow, self).__init__(None) self.model = QSqlQueryModel(self) self.model.setQuery("select * from student") self.model.setHeaderData(0, Qt.Horizontal, self.tr("学号")) self.model.setHeaderData(1, Qt.Horizontal, self.tr("姓名")) self.model.setHeaderData(2, Qt.Horizontal, self.tr("课程")) self.view = QTableView(self) self.view.setModel(self.model) self.setCentralWidget(self.view)
def loading(self): db = QSqlDatabase.addDatabase("QSQLITE") save_path='database/' complete = os.path.join(save_path,"user.sqlite") db.setDatabaseName(complete) db.open() View = QSqlQueryModel() View.setQuery("select * from users",db) self.tableView = QtGui.QTableView() self.tableView.setModel(View) self.tableView.show()
def fill_table_by_query(self, qtable, query): """ :param qtable: QTableView to show :param query: query to set model """ model = QSqlQueryModel() model.setQuery(query) qtable.setModel(model) qtable.show() # Check for errors if model.lastError().isValid(): self.controller.show_warning(model.lastError().text())
def loadData(self, clientId): self.items = [] if clientId: model = QSqlQueryModel() model.setQuery('''SELECT s.code, s.name FROM Client c INNER JOIN cure cr on cr.Client_ID = c.id INNER JOIN services s on s.id = cr.Services_ID WHERE c.id = {0} '''.format(clientId)) for i in xrange(model.rowCount()): code = model.record(i).value("code").toString() name = model.record(i).value("name").toString() item = [code + u": " + name] self.items.append(item) self.items.append([u""]) self.reset()
def loading(self): save_path = 'database/' complete = os.path.join(save_path, "user") f = open(complete, "r") creator = f.read() f.close() print(creator) save_path = 'database/' comp = os.path.join(save_path, "user.sqlite") db = sqlite3.connect(comp) cur = db.cursor() f = unicode( cur.execute('SELECT Role FROM users where Username=(?)', (creator, )).fetchone()[0]) db.close() if (f == "Admin"): save_path = 'database/' complete = os.path.join(save_path, "user.sqlite") db = QSqlDatabase.addDatabase("QSQLITE") db.setDatabaseName(complete) db.open() View = QSqlQueryModel() View.setQuery("select * from Files", db) self.tableView = QtGui.QTableView() self.tableView.setModel(View) self.tableView.show() elif (f == 'User'): save_path = 'database/' save = os.path.join(save_path, "user.sqlite") db = sqlite3.connect(save) cur = db.cursor() f = """SELECT * FROM Files where File_creator=('%s')""" % ( creator) #This shit cost me a lot i will never forget complete = os.path.join(save_path, "user.sqlite") db = QSqlDatabase.addDatabase("QSQLITE") db.setDatabaseName(complete) db.open() View = QSqlQueryModel() View.setQuery(f, db) self.tableView = QtGui.QTableView() self.tableView.setModel(View) self.tableView.show()
class Cuenta( object ): def __init__( self, parent, fecha, account_id = 0 , code = "", description = "", monto = Decimal( 0 ), esdebe = 0 ): self.parentItem = parent self.id = account_id self.code = code self.description = description self.monto = monto self.esdebe = esdebe self.childItems = [] if self.id != 0: self.model = QSqlQueryModel() q = "CALL spBalance( %s )" % fecha.toString( "yyyyMMdd" ) self.model.setQuery( q ) modelo = self.model agregados = [] for i in range( modelo.rowCount() ): if modelo.index( i, IDCUENTA ).data().toInt()[0] not in agregados: c = CuentaPadre( self, modelo, modelo, i, agregados ) self.appendChild( c ) def appendChild( self, item ): self.childItems.append( item ) def child( self, row ): return self.childItems[row] def childCount( self ): return len( self.childItems ) def columnCount( self ): return 8 @property def acumulado( self ): total = self.monto for child in self.childItems: total += child.acumulado return total
class Users(QObject): def __init__(self, parent=None): super(Users, self).__init__(parent) self.model = QSqlQueryModel() self.sortProxyModels = {} self.init_model() self.init_proxy_models() def init_model(self): self.model.setQuery(u"SELECT concat_ws(' ', firstname, lastname, patrname) " u"AS FIO, " u"CONCAT_WS(', ', birthdate, TIMESTAMPDIFF(YEAR, birthdate, CURDATE())) " u"AS \"Birth date, age\", " u"(CASE WHEN sex=1 THEN 'М' WHEN sex=2 THEN 'Ж' ELSE 'Неопределен' END) " u"AS sex , " u"concat_ws(' ', test.ClientPolicy.serial, test.ClientPolicy.number) " u"AS 'Policy serial and number', " u"(SELECT name FROM test.rbDocumentType WHERE id = test.ClientDocument.documentType_id) " u"AS \"Document type\", " u"concat_ws(' ', test.ClientDocument.serial, test.ClientDocument.number) " u"AS \"Document serial and number\"" u"FROM test.Client " u"LEFT JOIN test.ClientPolicy ON test.Client.id=test.ClientPolicy.client_id " u"LEFT JOIN test.ClientDocument ON test.Client.id=test.ClientDocument.client_id") def init_proxy_model(self, name, column): proxy = QSortFilterProxyModel() proxy.setSourceModel(self.model) proxy.setFilterKeyColumn(column) proxy.setFilterCaseSensitivity(Qt.CaseInsensitive) self.model = proxy self.sortProxyModels[name] = proxy return proxy def init_proxy_models(self): for (name, settings) in config["filter_fields"].items(): self.init_proxy_model(name, settings["column"]) def apply_filer(self, text, filter_name): self.sortProxyModels[filter_name].setFilterFixedString(text)
def setQuery(self, str, db=None): if db == None: self.query = QSqlQuery(str) else: self.query = str QSqlQueryModel.setQuery(self, str) del self.data self.data = [] self.rCount = QSqlQueryModel.rowCount(self) if self.rCount > 10000: self.rCount = 10000 self.cCount = QSqlQueryModel.columnCount(self) for i in range(self.rCount ): row = [] for j in range(self.cCount): row.append(QSqlQueryModel.data(self, QSqlQueryModel.index(self, i, j))) self.data.append(row) self.clear() print self.rowCount(), self.columnCount()
def setQuery(self, str, db=None): if db == None: self.query = QSqlQuery(str) else: self.query = str QSqlQueryModel.setQuery(self, str) del self.data self.data = [] self.rCount = QSqlQueryModel.rowCount(self) if self.rCount > 10000: self.rCount = 10000 self.cCount = QSqlQueryModel.columnCount(self) for i in range(self.rCount): row = [] for j in range(self.cCount): row.append( QSqlQueryModel.data(self, QSqlQueryModel.index(self, i, j))) self.data.append(row) self.clear() print self.rowCount(), self.columnCount()
def executeQuery(self): """ Public slot to execute the entered query. """ model = QSqlQueryModel(self.table) model.setQuery( QSqlQuery(self.sqlEdit.toPlainText(), self.connections.currentDatabase())) self.table.setModel(model) if model.lastError().type() != QSqlError.NoError: self.emit(SIGNAL("statusMessage(QString)"), model.lastError().text()) elif model.query().isSelect(): self.emit(SIGNAL("statusMessage(QString)"), self.trUtf8("Query OK.")) else: self.emit(SIGNAL("statusMessage(QString)"), self.trUtf8("Query OK, number of affected rows: %1")\ .arg(model.query().numRowsAffected())) self.table.resizeColumnsToContents() self.updateActions()
def write_content(self, query_id, header_id, header_no_content_id, columns_name_id, include_footpaths=True, include_subtitle=False): """ format the content of the data coming from the db either in text or dialog format :param query_id: int reference to the query dictionary :param header_id: int reference to the header dictionary :param header_no_content_id: int reference to the header no content dictionary :param columns_name_id: int reference to the list of columns of the required table :param include_footpaths: bool value to include footpaths in type 3 streets query :param include_subtitle: bool indicates if the header has a subtitle :return: void """ # build a query model object query_model = QSqlQueryModel() if not include_footpaths: filtered_query = self.queries[2].replace( "AND (lnkESU_STREET.Currency_flag = 0)", "AND (lnkESU_STREET.Currency_flag = 0) AND " "(tblStreet.Description not like '%Footpath%')") query_model.setQuery(filtered_query) else: query_model.setQuery(self.queries[query_id]) while query_model.canFetchMore(): query_model.fetchMore() parent_model_index = QModelIndex() # if the path is not specified sends data to function creating a list if self.file_path is None: assert isinstance(columns_name_id, object) items_list = self.content_to_screen( content_list=None, query_model=query_model, columns_name_id=columns_name_id, no_content_id=header_no_content_id) return items_list
def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) self.ui = sm.Ui_MainWindow() self.ui.setupUi(self) self.ui.table_studentList # Call DB db = QSqlDatabase.addDatabase("QSQLITE") db.setDatabaseName("studentInformation001.db") db.open() # End of call DB # student info into table view projectModel = QSqlQueryModel() projectModel.setQuery("SELECT schoolNumber, Name FROM Student ORDER BY schoolNumber ASC",db) projectView = self.ui.table_studentList projectView.setModel(projectModel) projectView.show() #end of student info into table view # QTableView Click Event self.qTableView = self.ui.table_studentList self.qTableView.clicked.connect(self.showInfo)
class FrmArqueo( Ui_frmArqueo, Base ): ''' Esta clase implementa el formulario arqueo ''' web = "arqueos.php?doc=" def __init__( self, datos_sesion, parent, edit = False ): u''' @param datos_sesion: La información de la sesion de caja ''' super( FrmArqueo, self ).__init__( parent, True ) self.sesion = datos_sesion self.setWindowModality( Qt.WindowModal ) self.setWindowFlags( Qt.Dialog ) # self.status = False self.__dolar_proxy = ArqueoProxyModel() self.__cordoba_proxy = ArqueoProxyModel() self.editmodel = None # El modelo principal self.navmodel = QSqlQueryModel( self ) # El modelo que filtra a self.navmodel self.navproxymodel = QSortFilterProxyModel( self ) self.__details_proxymodel_d = QSortFilterProxyModel( self ) self.__details_proxymodel_c = QSortFilterProxyModel( self ) self.navproxymodel.setSourceModel( self.navmodel ) # Este es el modelo con los datos 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 ) #filtrar en dolares y en cordobas self.__details_proxymodel_d.setSourceModel( self.detailsproxymodel ) self.__details_proxymodel_d.setFilterKeyColumn( MONEDA ) self.__details_proxymodel_d.setFilterRegExp( "^%d$" % constantes.IDDOLARES ) self.__details_proxymodel_c.setSourceModel( self.detailsproxymodel ) self.__details_proxymodel_c.setFilterKeyColumn( MONEDA ) self.__details_proxymodel_c.setFilterRegExp( "^%d$" % constantes.IDCORDOBAS ) if edit: self.status = False self.newDocument() self.actionCancel.setVisible(False) self.tabWidget.setTabEnabled(1,False) else: self.status = True QTimer.singleShot( 0, self.loadModels ) def updateModels( self ): try: if not self.database.isOpen(): if not self.database.open(): raise UserWarning( "No se pudo abrir la base de datos" ) #TODO: Esta consulta tiene que mejorar para definir realmente quien es el que realiza el arqueo query = u""" SELECT d.iddocumento, d.fechacreacion , p.nombre AS 'Arqueador', FORMAT(SUM(IF(mc.idtipomovimiento = """ + str( constantes.IDPAGOEFECTIVO ) + """ AND mc.idtipomoneda = """ + str( constantes.IDCORDOBAS ) + """, mc.monto, 0)),4) AS 'efectivoc', FORMAT(SUM(IF(mc.idtipomovimiento = """ + str( constantes.IDPAGOEFECTIVO ) + """ AND mc.idtipomoneda = """ + str( constantes.IDDOLARES ) + """, mc.monto, 0)),4) AS 'efectivod', FORMAT(SUM(IF(mc.idtipomovimiento = """ + str( constantes.IDPAGOCHEQUE ) + """ AND mc.idtipomoneda = """ + str( constantes.IDCORDOBAS ) + """, mc.monto, 0)),4) AS 'chequec', FORMAT(SUM(IF(mc.idtipomovimiento = """ + str( constantes.IDPAGOCHEQUE ) + """ AND mc.idtipomoneda = """ + str( constantes.IDDOLARES ) + """, mc.monto, 0)),4) AS 'chequed', FORMAT(SUM(IF(mc.idtipomovimiento = """ + str( constantes.IDPAGODEPOSITO ) + """ AND mc.idtipomoneda = """ + str( constantes.IDCORDOBAS ) + """, mc.monto, 0)),4) AS 'depositoc', FORMAT(SUM(IF(mc.idtipomovimiento = """ + str( constantes.IDPAGODEPOSITO ) + """ AND mc.idtipomoneda = """ + str( constantes.IDDOLARES ) + """, mc.monto, 0)),4) AS 'depositod', FORMAT(SUM(IF(mc.idtipomovimiento = """ + str( constantes.IDPAGOTRANSFERENCIA ) + """ AND mc.idtipomoneda = """ + str( constantes.IDCORDOBAS ) + """, mc.monto, 0)),4) AS 'transferenciac', FORMAT(SUM(IF(mc.idtipomovimiento = """ + str( constantes.IDPAGOTRANSFERENCIA ) + """ AND mc.idtipomoneda = """ + str( constantes.IDDOLARES ) + """, mc.monto, 0)),4) AS 'transferenciad', FORMAT(SUM(IF(mc.idtipomovimiento = """ + str( constantes.IDPAGOTARJETA ) + """ AND mc.idtipomoneda = """ + str( constantes.IDCORDOBAS ) + """, mc.monto, 0)),4) AS 'tarjetac', FORMAT(SUM(IF(mc.idtipomovimiento = """ + str( constantes.IDPAGOTARJETA ) + """ AND mc.idtipomoneda = """ + str( constantes.IDDOLARES ) + """, mc.monto, 0)),4) AS 'tarjetad' FROM documentos d JOIN movimientoscaja mc ON mc.iddocumento = d.iddocumento JOIN tiposmoneda tm ON mc.idtipomoneda = tm.idtipomoneda JOIN personasxdocumento pxd ON pxd.iddocumento = d.iddocumento JOIN personas p ON p.idpersona = pxd.idpersona WHERE d.idtipodoc = %d GROUP BY d.iddocumento """ % ( constantes.IDARQUEO ) self.navmodel.setQuery( query ) self.detailsModel.setQuery( u""" SELECT l.cantidad AS 'Cantidad', CONCAT_WS(' ',tm.simbolo, CAST(de.valor AS CHAR)) as 'Denominación', FORMAT(l.cantidad * de.valor, 4) as 'Total', de.idtipomoneda, l.iddocumento FROM lineasarqueo l JOIN denominaciones de ON de.iddenominacion = l.iddenominacion JOIN tiposmoneda tm ON de.idtipomoneda = tm.idtipomoneda JOIN documentos d ON d.iddocumento = l.iddocumento JOIN tiposcambio tc ON d.idtipocambio = tc.idtc """ ) self.mapper.setSubmitPolicy( QDataWidgetMapper.ManualSubmit ) self.mapper.setModel( self.navproxymodel ) self.mapper.addMapping( self.dtPicker, FECHA ) self.mapper.addMapping( self.lblUserName, NOMBRE, "value" ) self.mapper.addMapping( self.sbCkC, CHEQUEC, "value" ) self.mapper.addMapping( self.sbCkD, CHEQUED, "value" ) self.mapper.addMapping( self.sbCardC, TARJETAC, "value" ) self.mapper.addMapping( self.sbCardD, TARJETAD, "value" ) self.mapper.addMapping( self.sbDepositC, DEPOSITOC, "value" ) self.mapper.addMapping( self.sbDepositD, DEPOSITOD, "value" ) self.mapper.addMapping( self.sbTransferC , TRANSFERENCIAC, "value" ) self.mapper.addMapping( self.sbTransferD , TRANSFERENCIAD, "value" ) except UserWarning as inst: logging.error( unicode( inst ) ) QMessageBox.critical( self, qApp.organizationName(), unicode( inst ) ) except Exception as inst: logging.critical( unicode( inst ) ) finally: if self.database.isOpen(): self.database.close() def updateDetailFilter( self, index ): self.detailsproxymodel.setFilterKeyColumn( IDDOCUMMENTOT ) self.detailsproxymodel.setFilterRegExp( self.navmodel.record( index ).value( IDDOCUMMENTO ).toString() ) self.tablenavigation.selectRow( self.mapper.currentIndex() ) def setControls( self, status ): """ @param status: false = editando true = navegando """ self.actionPrint.setVisible( status ) self.tablenavigation.setEnabled( status ) self.tabnavigation.setEnabled( status ) self.actionNew.setVisible( status ) self.actionPreview.setVisible( status ) self.actionCancel.setVisible( not status ) self.actionSave.setVisible( not status ) self.actionGoFirst.setVisible( status ) self.actionGoLast.setVisible( status ) self.actionGoNext.setVisible( status ) self.actionGoPrevious.setVisible( status ) self.sbCkD.setReadOnly( status ) self.sbCkC.setReadOnly( status ) self.sbCardD.setReadOnly( status ) self.sbCardC.setReadOnly( status ) self.sbDepositD.setReadOnly( status ) self.sbDepositC.setReadOnly( status ) self.sbTransferD.setReadOnly( status ) self.sbTransferC.setReadOnly( status ) self.txtObservations.setReadOnly( status ) self.tablenavigation.setColumnHidden( IDDOCUMMENTO, True ) if not self.status: self.tabledetailsC.setEditTriggers( QTableView.AllEditTriggers ) self.tabledetailsC.setColumnHidden( IDDOCUMMENTOT, False ) self.tabledetailsD.setEditTriggers( QTableView.AllEditTriggers ) self.tabledetailsD.setColumnHidden( IDDOCUMMENTOT, False ) self.tabWidget.setCurrentIndex( 0 ) self.tabledetailsC.setColumnHidden( IDDOCUMMENTOT, True ) self.tabledetailsC.setColumnHidden( IDDENOMINACION, True ) self.tabledetailsD.setColumnHidden( IDDOCUMMENTOT, True ) self.tabledetailsD.setColumnHidden( IDDENOMINACION, True ) # doublevalidator = QDoubleValidator(0, 99999999, 4, self) else: self.tabledetailsC.setModel( self.__details_proxymodel_c ) self.tabledetailsD.setModel( self.__details_proxymodel_d ) self.tablenavigation.setModel( self.navproxymodel ) self.tablenavigation.setColumnHidden( IDDOCUMMENTO, True ) self.tabledetailsC.setColumnHidden( IDDOCUMMENTOT, True ) self.tabledetailsC.setColumnHidden( IDDENOMINACION, True ) self.tabledetailsD.setColumnHidden( IDDOCUMMENTOT, True ) self.tabledetailsD.setColumnHidden( IDDENOMINACION, True ) self.tabledetailsC.setColumnHidden( MONEDA, True ) self.tabledetailsD.setColumnHidden( MONEDA, True ) def updateLabels( self ): self.lblCashC.setText( "%s / %s" % ( moneyfmt( self.editmodel.totalCashC, 4, "C$" ), moneyfmt( self.editmodel.expectedCashC, 4, "C$" ) ) ) self.lblCashD.setText( "%s / %s" % ( moneyfmt( self.editmodel.totalCashD, 4, "US$" ), moneyfmt( self.editmodel.expectedCashD, 4, "US$" ) ) ) self.lblCkC.setText( moneyfmt( self.editmodel.expectedCkC, 4, "C$" ) ) self.lblCkD.setText( moneyfmt( self.editmodel.expectedCkD, 4, "US$" ) ) self.lblCardC.setText( moneyfmt( self.editmodel.expectedCardC, 4, "C$" ) ) self.lblCardD.setText( moneyfmt( self.editmodel.expectedCardD, 4, "US$" ) ) self.lblDepositC.setText( moneyfmt( self.editmodel.expectedDepositC, 4, "C$" ) ) self.lblDepositD.setText( moneyfmt( self.editmodel.expectedDepositD, 4, "US$" ) ) self.lblTransferC.setText( moneyfmt( self.editmodel.expectedDepositC, 4, "C$" ) ) self.lblTransferD.setText( moneyfmt( self.editmodel.expectedDepositD, 4, "US$" ) ) def newDocument( self ): """ cargar todos los modelos para la edición """ query = QSqlQuery() try: 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" ) for window in self.parentWindow.findChild( QMdiArea ).subWindowList(): if window.widget(): raise UserWarning( u"Por favor cierre las otras pestañas" + u" de la aplicación antes de continuar" + " con el arqueo" ) self.editmodel = ArqueoModel( self.sesion ) self.editmodel.datetime.setDate( self.sesion.fecha ) self.editmodel.datetime.setTime( QTime.currentTime() ) self.__dolar_proxy.setSourceModel( self.editmodel ) self.__dolar_proxy.setFilterKeyColumn( MONEDA ) self.__dolar_proxy.setFilterRegExp( r"^%d$" % constantes.IDDOLARES ) self.__dolar_proxy.setDynamicSortFilter( True ) self.__cordoba_proxy.setSourceModel( self.editmodel ) self.__cordoba_proxy.setFilterKeyColumn( MONEDA ) self.__cordoba_proxy.setFilterRegExp( r"^%d$" % constantes.IDCORDOBAS ) self.__cordoba_proxy.setDynamicSortFilter( True ) self.tabledetailsC.setModel( self.__cordoba_proxy ) self.tabledetailsD.setModel( self.__dolar_proxy ) if not self.database.isOpen(): if not self.database.open(): raise UserWarning( "No se pudo conectar con la base de datos" ) #verificar si hay documentos pendientes de aprobación q = """ SELECT CONCAT_WS(' ', td.descripcion, d.ndocimpreso) FROM documentos sesion JOIN docpadrehijos dpd ON dpd.idpadre = sesion.iddocumento JOIN documentos d ON dpd.idhijo = d.iddocumento JOIN tiposdoc td ON td.idtipodoc = d.idtipodoc WHERE d.idestado NOT IN ( %d,%d) """ % ( constantes.CONFIRMADO, constantes.ANULADO ) if not query.exec_( q ): raise Exception( u"No se pudo ejecutar la consulta para "\ + "determinar si existen documentos " + "pendientes de aprobación" ) if not query.size() == 0: raise UserWarning( u"Existen documentos pendientes de "\ + "aprobación en la sesión" ) #Obtener los datos de la sesión q = """ CALL spConsecutivo( %d, NULL ) """ % constantes.IDARQUEO #query.prepare( q ) if not query.exec_( q ): raise Exception( u"No se pudo ejecutar la consulta para "\ + "obtener el numero del arqueo" ) if not query.size() > 0: raise Exception( u"La consulta para obtener el numero del "\ + "arqueo no devolvio ningún valor" ) query.first() self.editmodel.printedDocumentNumber = query.value( 0 ).toString() self.editmodel.exchangeRateId = self.sesion.tipoCambioId self.editmodel.exchangeRate = self.sesion.tipoCambioOficial self.editmodel.datetime.setDate( self.sesion.fecha ) q = """ CALL spTotalesSesion(%d); """ % self.sesion.sesionId if not query.exec_( q ): raise UserWarning( u"No se pudieron calcular los totales"\ + " de la sesión" ) while query.next(): if query.value( 0 ).toInt()[0] == constantes.IDPAGOEFECTIVO and query.value( 2 ).toInt()[0] == constantes.IDDOLARES: self.editmodel.expectedCashD = Decimal( query.value( 5 ).toString() ) elif query.value( 0 ).toInt()[0] == constantes.IDPAGOEFECTIVO and query.value( 2 ).toInt()[0] == constantes.IDCORDOBAS: self.editmodel.expectedCashC = Decimal( query.value( 5 ).toString() ) elif query.value( 0 ).toInt()[0] == constantes.IDPAGOCHEQUE and query.value( 2 ).toInt()[0] == constantes.IDDOLARES: self.editmodel.expectedCkD = Decimal( query.value( 5 ).toString() ) elif query.value( 0 ).toInt()[0] == constantes.IDPAGOCHEQUE and query.value( 2 ).toInt()[0] == constantes.IDCORDOBAS: self.editmodel.expectedCkC = Decimal( query.value( 5 ).toString() ) elif query.value( 0 ).toInt()[0] == constantes.IDPAGODEPOSITO and query.value( 2 ).toInt()[0] == constantes.IDDOLARES: self.editmodel.expectedDepositD = Decimal( query.value( 5 ).toString() ) elif query.value( 0 ).toInt()[0] == constantes.IDPAGODEPOSITO and query.value( 2 ).toInt()[0] == constantes.IDCORDOBAS: self.editmodel.expectedDepositC = Decimal( query.value( 5 ).toString() ) elif query.value( 0 ).toInt()[0] == constantes.IDPAGOTRANSFERENCIA and query.value( 2 ).toInt()[0] == constantes.IDDOLARES: self.editmodel.expectedTransferD = Decimal( query.value( 5 ).toString() ) elif query.value( 0 ).toInt()[0] == constantes.IDPAGOTRANSFERENCIA and query.value( 2 ).toInt()[0] == constantes.IDCORDOBAS: self.editmodel.expectedTransferC = Decimal( query.value( 5 ).toString() ) elif query.value( 0 ).toInt()[0] == constantes.IDPAGOTARJETA and query.value( 2 ).toInt()[0] == constantes.IDDOLARES: self.editmodel.expectedCardD = Decimal( query.value( 5 ).toString() ) elif query.value( 0 ).toInt()[0] == constantes.IDPAGOTARJETA and query.value( 2 ).toInt()[0] == constantes.IDCORDOBAS: self.editmodel.expectedCardC = Decimal( query.value( 5 ).toString() ) q = """ SELECT d.iddenominacion, CONCAT_WS( ' ',d.valor, m.moneda), d.valor, d.idtipomoneda, m.simbolo FROM denominaciones d JOIN tiposmoneda m ON d.idtipomoneda = m.idtipomoneda WHERE d.activo = 1 ORDER BY d.idtipomoneda, d.valor """ if not query.exec_( q ): raise UserWarning( "No se pudo recuperar la lista de " + "denominaciones" ) denominationsmodelC = SingleSelectionModel() denominationsmodelC.headers = ["Id", u"Denominación", "Valor", "Id Moneda", "Simbolo"] denominationsmodelD = SingleSelectionModel() denominationsmodelD.headers = denominationsmodelC.headers while query.next(): if query.value( 3 ).toInt()[0] == constantes.IDDOLARES: denominationsmodelD.items.append( [ query.value( 0 ).toInt()[0], #el id del tipo de denominacion query.value( 1 ).toString(), #La descripción de la denominación query.value( 2 ).toString(), # el valor de la denominación query.value( 3 ).toInt()[0], #El id del tipo de moneda query.value( 4 ).toString() #El simbolo de la moneda ] ) else: denominationsmodelC.items.append( [ query.value( 0 ).toInt()[0], #el id del tipo de denominacion query.value( 1 ).toString(), #La descripción de la denominación query.value( 2 ).toString() , # el valor de la denominación query.value( 3 ).toInt()[0], #El id del tipo de moneda query.value( 4 ).toString() #El simbolo de la moneda ] ) delegateC = ArqueoDelegate( denominationsmodelC ) self.tabledetailsC.setItemDelegate( delegateC ) delegateD = ArqueoDelegate( denominationsmodelD ) self.tabledetailsD.setItemDelegate( delegateD ) self.addLine() self.addLine() self.editmodel.setData( self.editmodel.index( 0, MONEDA ), constantes.IDDOLARES ) self.editmodel.setData( self.editmodel.index( 1, MONEDA ), constantes.IDCORDOBAS ) self.dtPicker.setDateTime( self.editmodel.datetime ) self.lblUserName.setText( self.user.fullname ) self.editmodel.dataChanged[QModelIndex, QModelIndex].connect( self.updateLabels ) self.tabledetailsC.setColumnWidth( DENOMINACION, 200 ) self.tabledetailsD.setColumnWidth( DENOMINACION, 200 ) self.updateLabels() self.status = False except UserWarning as inst: logging.error( unicode( inst ) ) logging.error( query.lastError().text() ) QMessageBox.critical( self, qApp.organizationName(), unicode( inst ) ) self.status = True except Exception as inst: logging.critical( unicode( inst ) ) logging.critical( query.lastError().text() ) QMessageBox.critical( self, qApp.organizationName(), "El sistema no pudo iniciar un nuevo arqueo" ) self.status = True finally: if self.database.isOpen(): self.database.close() @pyqtSlot( QDateTime ) def on_dtPicker_dateTimeChanged( self, datetime ): pass def cancel( self ): self.editmodel = None self.status = True self.navigate( 'last' ) def save( self ): """ Redefiniendo el metodo save de Base para mostrar advertencias si el arqueo no concuerda """ try: errors = [] if not self.editmodel.totalCashC == self.editmodel.expectedCashC: errors.append( u"El total de efectivo en cordobas del arqueo no coincide con el de la sesión" ) if not self.editmodel.totalCashD == self.editmodel.expectedCashD: errors.append( u"El total de efectivo en dolares del arqueo no coincide con el de la sesión" ) if not self.editmodel.totalCkD == self.editmodel.expectedCkD: errors.append( u"El total de cheques en dolares del arqueo no coincide con el de la sesión" ) if not self.editmodel.totalCkC == self.editmodel.expectedCkC: errors.append( u"El total de cheques en cordobas del arqueo no coincide con el de la sesión" ) if not self.editmodel.totalTransferD == self.editmodel.expectedTransferD: errors.append( u"El total de transferencias en dolares del arqueo no coincide con el de la sesión" ) if not self.editmodel.totalTransferC == self.editmodel.expectedTransferC: errors.append( u"El total de transferencias en cordobas del arqueo no coincide con el de la sesión" ) if not self.editmodel.totalDepositD == self.editmodel.expectedDepositD: errors.append( u"El total de depositos en dolares del arqueo no coincide con el de la sesión" ) if not self.editmodel.totalDepositC == self.editmodel.expectedDepositC: errors.append( u"El total de depositos en cordobas del arqueo no coincide con el de la sesión" ) if not self.editmodel.totalCardD == self.editmodel.expectedDepositD: errors.append( u"El total de pagos en tarjetas en dolares del arqueo no coincide con el de la sesión" ) if not self.editmodel.totalCardD == self.editmodel.expectedDepositC: errors.append( u"El total de pagos en tarjetas en cordobas del arqueo no coincide con el de la sesión" ) if len( errors ) > 0: raise UserWarning( "\n".join( errors ) ) dlgUser = dlgSmallUserLogin() if dlgUser.exec_() == QDialog.Accepted: if dlgUser.user.valid and dlgUser.user.hasRole( 'gerencia' ): self.editmodel.authorizationId = dlgUser.user.uid super( FrmArqueo, self ).save( False ) self.parentWindow.init() self.close() else: QMessageBox.warning( self, qApp.organizationName(), "No se pudo autorizar el arqueo" ) except UserWarning as inst: if not self.editmodel.observations == "": if QMessageBox.question( self, qApp.organizationName(), unicode( inst ) + u"\n¿Desea Continuar?", QMessageBox.Yes | QMessageBox.No ) == QMessageBox.Yes: dlgUser = dlgSmallUserLogin() if dlgUser.exec_() == QDialog.Accepted: if dlgUser.user.valid and dlgUser.user.hasRole( 'gerencia' ): self.editmodel.authorizationId = dlgUser.user.uid super( FrmArqueo, self ).save( False ) self.parentWindow.init() self.close() else: QMessageBox.warning( self, qApp.organizationName(), "No se pudo autorizar " + "el arqueo" ) else: QMessageBox.warning( self, qApp.organizationName(), unicode( inst )\ + u"\n Por favor especifique el motivo" + " de la diferencia" ) @property def printIdentifier( self ): return self.navmodel.record( self.mapper.currentIndex() ).value( "iddocumento" ).toString() def navigate( self, to ): """ Esta funcion se encarga de navegar entro los distintos documentos @param to: es una string que puede tomar los valores 'next' 'previous' 'first' 'last' """ if self.mapper.currentIndex != -1: row = self.mapper.currentIndex() if to == "next": row += 1 if row >= self.navproxymodel.rowCount(): row = self.navproxymodel.rowCount() - 1 self.mapper.setCurrentIndex( row ) elif to == "previous": if row <= 1: row = 0 else: row = row - 1 self.mapper.setCurrentIndex( row ) elif to == "first": self.mapper.toFirst() elif to == "last": self.mapper.toLast() else: self.mapper.toLast()() self.tabledetailsC.resizeColumnsToContents() self.tabledetailsC.horizontalHeader().setStretchLastSection( True ) self.tabledetailsD.resizeColumnsToContents() self.tabledetailsD.horizontalHeader().setStretchLastSection( True ) self.tablenavigation.selectRow( self.mapper.currentIndex() ) @pyqtSlot( float ) @if_edit_model def on_sbCkD_valueChanged( self, value ): self.editmodel.totalCkD = Decimal( str( value ) ) @pyqtSlot( float ) @if_edit_model def on_sbCkC_valueChanged( self, value ): self.editmodel.totalCkC = Decimal( str( value ) ) @pyqtSlot( float ) @if_edit_model def on_sbCardD_valueChanged( self, value ): self.editmodel.totalCardD = Decimal( str( value ) ) @pyqtSlot( float ) @if_edit_model def on_sbCardC_valueChanged( self, value ): self.editmodel.totalCardC = Decimal( str( value ) ) @pyqtSlot( float ) @if_edit_model def on_sbDepositD_valueChanged( self, value ): self.editmodel.totalDepositD = Decimal( str( value ) ) @pyqtSlot( float ) @if_edit_model def on_sbDepositC_valueChanged( self, value ): self.editmodel.totalDepositC = Decimal( str( value ) ) @pyqtSlot( float ) @if_edit_model def on_sbTransferD_valueChanged( self, value ): self.editmodel.totalTransferD = Decimal( str( value ) ) @pyqtSlot( float ) @if_edit_model def on_sbTransferC_valueChanged( self, value ): self.editmodel.totalTransferC = Decimal( str( value ) )
class Helferlein(QtGui.QMainWindow): def __init__(self): QtGui.QMainWindow.__init__(self) # Oberfläche abbilden: self.ui = uic.loadUi("ui_helferlein.ui") self.ui.setWindowIcon(QtGui.QIcon('helferlein.png')) #self.db = QSqlDatabase.addDatabase("QMYSQL") self.db = QSqlDatabase.addDatabase("QSQLITE3") self.db.setHostName("localhost") self.db.setDatabaseName("helferlein") self.user = "******" self.password = "******" if self.db.open(self.user, self.password): print "DB Verbindung" #self.init_db() else: print "Verbindung konnte nicht hergestellt werden" self.sql_model_namensliste = QSqlQueryModel(self) self.sql_model_fehlzeiten = QSqlQueryModel(self) self.ui.tableView_schuelernamen.setModel(self.sql_model_namensliste) self.ui.tableView_fehlzeiten.setModel(self.sql_model_fehlzeiten) # Argumente übergeben if len(sys.argv) > 1: self.filename = sys.argv[1] f = open(self.filename,'rb') self.schuelerliste = pickle.load(f) f.close() for schueler in self.schuelerliste.values(): self.ui.listWidget.addItem(schueler.name + ', ' + schueler.vorname) self.ui.listWidget.sortItems(0) else: self.filename = '' self.schuelerliste = {} # Grundeinstellungen: self.ui.dateEdit.setDate(QtCore.QDate.currentDate()) self.ui.dateEdit_2.setDate(QtCore.QDate.currentDate()) self.ui.dateEdit_3.setDate(QtCore.QDate.currentDate()) self.ui.dateEdit_4.setDate(QtCore.QDate.currentDate()) self.ui.comboBox_stufenwahl.currentIndexChanged.connect(self.stufenwahl) self.ui.show() # Connects: # Menü self.ui.actionStufe_importieren.triggered.connect(self.stufe_importieren) self.ui.action_ffnen.triggered.connect(self.datei_oeffnen) self.ui.actionSpeichern.triggered.connect(self.datei_speichern) self.ui.actionSpeichern_unter.triggered.connect(self.datei_speichern_unter) self.ui.actionSch_ler_l_schen.triggered.connect(self.schueler_loeschen) self.ui.actionSch_ler_hinzuf_gen.triggered.connect(self.schueler_anlegen) self.ui.actionKrankmeldungen.triggered.connect(self.zeige_krankmeldungen) self.ui.actionBeurlaubungen.triggered.connect(self.zeige_beurlaubungen) self.ui.actionKlausur_Attest.triggered.connect(self.zeige_klausur_attest) self.ui.actionDefizite_suchen.triggered.connect(self.suche_defizite) self.ui.actionKlausurplan_konvertieren.triggered.connect(self.klausurplan_konvertieren) self.ui.tableView_schuelernamen.activated.connect(self.schueler_auswahl) self.ui.tableView_schuelernamen.clicked.connect(self.schueler_auswahl) self.ui.lineEdit.textChanged.connect(self.suche) self.ui.pushButton_7.clicked.connect(self.heutiges_datum_setzen) # Krankmeldungen self.ui.pushButton.clicked.connect(self.krankmeldung_speichern) self.ui.lineEdit_2.returnPressed.connect(self.krankmeldung_speichern) self.ui.pushButton_4.clicked.connect(self.eintrag_loeschen_krank) self.ui.tableView_fehlzeiten.clicked.connect(self.krankmeldung_aufrufen) # Beurlaubungen self.ui.pushButton_2.clicked.connect(self.beurlaubung_speichern) self.ui.lineEdit_3.returnPressed.connect(self.beurlaubung_speichern) self.ui.pushButton_5.clicked.connect(self.eintrag_loeschen_beurlaubung) self.ui.tableWidget_2.cellClicked.connect(self.beurlaubung_aufrufen) # Bemerkungen self.ui.pushButton_3.clicked.connect(self.bemerkung_speichern) #self.ui.lineEdit_4.returnPressed.connect(self.bemerkung_speichern) self.ui.pushButton_6.clicked.connect(self.eintrag_loeschen_bemerkung) self.ui.tableWidget_3.cellClicked.connect(self.bemerkung_aufrufen) self.ui.calendarWidget.selectionChanged.connect(self.datum_geaendert) #self.ui.tableWidget.cellChanged.connect(self.zeile_geaendert_krank) # DB-Methoden ############################################################### def init_db(self): print "here" sql_query = QSqlQuery('''SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = 'helferlein';''', self.db) size = sql_query.size() print size if size == 0: print "db anlegen" sql_query = QSqlQuery("CREATE DATABASE helferlein;", self.db) print "tabelle schueler anlegen" sql_query = QSqlQuery('''CREATE TABLE SCHUELER ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, Name CHAR(100), Vorname CHAR(100), Stufe CHAR(2));''', self.db) print "tabelle fehlzeit anlegen" sql_query.prepare('''CREATE TABLE FEHLZEIT ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, schueler_id INT, Grund CHAR(100), Beginn CHAR(10), Ende CHAR(10), Stunden INT, ist_Beurlaubung INT, Attest INT, klausur_verpasst INT, Schuljahr CHAR(10));''') sql_query.exec_() def create_db(self): self.db.setDatabaseName(FILENAME_DB) ok = self.db.open() if ok: sql_query = QSqlQuery() # Menü-Methoden: def stufe_importieren(self): filename = QtGui.QFileDialog.getOpenFileName(self, u'CVS-Datei öffnen','.') namens_liste = [[col.strip() for col in row.split(";")] for row in codecs.open(filename, encoding="iso-8859-15")] sql_query = QSqlQuery() sql_query.prepare('''INSERT INTO SCHUELER(NAME, VORNAME, STUFE) VALUES(:name,:vorname,:stufe)''') for name, vorname, stufe in namens_liste: sql_query.bindValue(':name',name) sql_query.bindValue(':vorname', vorname) sql_query.bindValue(':stufe', stufe) sql_query.exec_() def datei_oeffnen(self): self.filename = QtGui.QFileDialog.getOpenFileName(self, u'Datei öffnen','.') f = open(self.filename,'rb') self.schuelerliste = pickle.load(f) f.close() self.ui.listWidget.clear() for schueler in self.schuelerliste.values(): self.ui.listWidget.addItem(schueler.name + ', ' + schueler.vorname) self.ui.listWidget.sortItems(0) def datei_speichern(self): f = open(self.filename,'wb') pickle.dump(self.schuelerliste,f) f.close() def datei_speichern_unter(self): filename = QtGui.QFileDialog.getSaveFileName(self, u'Namen der Datei angeben','.') f = open(filename,'wb') pickle.dump(self.schuelerliste,f) f.close() def schueler_loeschen(self): if self.ui.label_3.text(): name, vorname = self.ui.label_3.text().split(', ') reply = QtGui.QMessageBox.question(self, "Achtung!", "Soll %s, %s wirklich gelöscht werden?" % (name,vorname), QtGui.QMessageBox.Yes | QtGui.QMessageBox.No) if reply == QtGui.QMessageBox.Yes: del self.schuelerliste[(vorname,name)] self.ui.listWidget.clear() for schueler in self.schuelerliste.values(): self.ui.listWidget.addItem(schueler.name + ', ' + schueler.vorname) self.ui.listWidget.sortItems(0) self.datei_speichern() self.ui.label_3.setText("") self.ui.label_10.setText("") self.ui.label_16.setText("") else: MESSAGE = u"<p>Bitte erst einen Schüler aus der Liste auswählen</p>" reply = QtGui.QMessageBox.information(self, "Achtung!", MESSAGE) def schueler_anlegen(self): dialog_anlegen = Dialog_Schueler_Anlegen(self) dialog_anlegen.ui.setWindowTitle(u'Schüler/in hinzufügen') if dialog_anlegen.ui.exec_() == 1: name = dialog_anlegen.ui.lineEdit_name.text() vorname = dialog_anlegen.ui.lineEdit_vorname.text() stufe = dialog_anlegen.ui.spinBox_stufe.value() schueler = Schueler(vorname, name, stufe) if schueler not in self.schuelerliste: self.schuelerliste[(vorname, name)] = schueler self.ui.listWidget.clear() for schueler in self.schuelerliste.values(): self.ui.listWidget.addItem(schueler.name + ', ' + schueler.vorname) self.ui.listWidget.sortItems(0) self.datei_speichern() self.ui.label_3.setText("") self.ui.label_10.setText("") self.ui.label_16.setText("") # Fenster-Methoden: def stufenwahl(self, index): print "stufenwahl", index query = '''SELECT id, Name, Vorname FROM SCHUELER WHERE Stufe='{}' ORDER BY Name;'''.\ format(self.ui.comboBox_stufenwahl.itemText(index)) print query sql_query = QSqlQuery(query) self.sql_model_namensliste.setQuery(sql_query) sql_query.exec_() self.ui.tableView_schuelernamen.hideColumn(0) #don't show id def schueler_auswahl(self, index): self.schueler_id = index.sibling(index.row(),0).data().toString() name = index.sibling(index.row(),1).data().toString() vorname = index.sibling(index.row(),2).data().toString() self.ui.label_3.setText(u'{}, {}'.format(name, vorname)) self.ui.label_10.setText(u'{}, {}'.format(name, vorname)) self.ui.label_16.setText(u'{}, {}'.format(name, vorname)) self.tabelle_krank_aktualisieren() def heutiges_datum_setzen(self): self.ui.calendarWidget.setSelectedDate(QtCore.QDate.currentDate()) def tabelle_krank_aktualisieren(self): query_string = '''SELECT id, Beginn, Ende, Attest, klausur_verpasst as Klausur, Grund FROM FEHLZEIT WHERE FEHLZEIT.schueler_id={} AND ist_beurlaubung = '0'; '''.format(self.schueler_id) print query_string sql_query = QSqlQuery(query_string) self.sql_model_fehlzeiten.setQuery(sql_query) self.ui.tableView_fehlzeiten.hideColumn(0) #don't show id sql_query.exec_() self.ui.tableView_fehlzeiten.resizeColumnsToContents() self.ui.tableView_fehlzeiten.horizontalHeader().setStretchLastSection(True) def tabelle_beurlaubung_aktualisieren(self,schueler): self.ui.tableWidget_2.setRowCount(len(schueler.beurlaubungen.keys())) zeile = 0 for eintrag in sorted(schueler.beurlaubungen.keys(),reverse=True): liste = schueler.beurlaubungen[eintrag] liste0 = [eintrag.toString("dd.MM.yyyy"), liste[0].toString("dd.MM.yyyy"), str(liste[1]), liste[2]] for spalte in range(4): item = QtGui.QTableWidgetItem(liste0[spalte]) self.ui.tableWidget_2.setItem(zeile, spalte, item); zeile += 1 self.ui.tableWidget_2.resizeColumnsToContents() self.ui.tableWidget_2.horizontalHeader().setStretchLastSection(True) def tabelle_bemerkung_aktualisieren(self,schueler): self.ui.tableWidget_3.setRowCount(len(schueler.bemerkungen.keys())) zeile = 0 for eintrag in sorted(schueler.bemerkungen.keys(),reverse=True): aktennotiz = ('ja' if schueler.bemerkungen[eintrag][1] else 'nein') bemerkung = schueler.bemerkungen[eintrag][0] liste0 = [eintrag.toString("dd.MM.yyyy"),aktennotiz, bemerkung] for spalte in range(3): item = QtGui.QTableWidgetItem(liste0[spalte]) self.ui.tableWidget_3.setItem(zeile, spalte, item); zeile += 1 self.ui.tableWidget_3.resizeColumnsToContents() self.ui.tableWidget_3.horizontalHeader().setStretchLastSection(True) self.ui.plainTextEdit.clear() def ui_zuruecksetzen(self): self.ui.lineEdit.clear() self.ui.lineEdit_2.clear() self.ui.lineEdit_3.clear() #self.ui.lineEdit_4.clear() self.ui.plainTextEdit.clear() self.ui.checkBox.setChecked(False) self.ui.checkBox_2.setChecked(False) self.ui.checkBox_3.setChecked(False) self.ui.spinBox.setValue(0) self.ui.calendarWidget.setSelectedDate(QtCore.QDate.currentDate()) def suche(self,text): self.ui.listWidget.clear() for schueler in self.schuelerliste: if schueler[0].contains(text,0) or schueler[1].contains(text,0): s = self.schuelerliste[schueler] self.ui.listWidget.addItem(s.name + ', ' + s.vorname) self.ui.listWidget.sortItems(0) def datum_geaendert(self): datum_aktuell = self.ui.calendarWidget.selectedDate() self.ui.dateEdit.setDate(datum_aktuell) self.ui.dateEdit_2.setDate(datum_aktuell) self.ui.dateEdit_3.setDate(datum_aktuell) self.ui.dateEdit_4.setDate(datum_aktuell) def krankmeldung_speichern(self): self.schuljahr = '2013/14' datum_von = self.ui.dateEdit.date().toString("dd.MM.yyyy") datum_bis = self.ui.dateEdit_2.date().toString("dd.MM.yyyy") grund = (unicode(self.ui.lineEdit_2.text()) if self.ui.lineEdit_2.text() else u'-') attest = (u'ja' if self.ui.checkBox.isChecked() else u'nein') klausur = (u'ja' if self.ui.checkBox_2.isChecked() else u'nein') sql_query = QSqlQuery() query_string = '''INSERT INTO FEHLZEIT (schueler_id, Grund, Beginn, Ende, Attest, klausur_verpasst, ist_beurlaubung, schuljahr) VALUES({},'{}','{}','{}','{}','{}','0','{}');'''.format(self.schueler_id, grund, datum_von, datum_bis, attest, klausur, self.schuljahr) #print query_string sql_query.prepare(query_string) sql_query.exec_() self.ui_zuruecksetzen() self.tabelle_krank_aktualisieren() def eintrag_loeschen_krank(self): selected_items = self.ui.tableView_fehlzeiten.selectionModel().selection().indexes() if selected_items: index = selected_items[0] zeile = index.row() fehlzeit_id = index.sibling(zeile,0).data().toString() reply = QtGui.QMessageBox.question(self, "Achtung!", u"Soll die markierte Zeile wirklich gelöscht werden?", QtGui.QMessageBox.Yes | QtGui.QMessageBox.No) if reply == QtGui.QMessageBox.Yes: print "Zeile löschen", fehlzeit_id sql_query = QSqlQuery('''DELETE FROM FEHLZEIT WHERE id = {}'''.format(fehlzeit_id)) sql_query.exec_() self.tabelle_krank_aktualisieren() else: QtGui.QMessageBox.information(self, "Achtung!", "Bitte erst eine Zeile markieren!") def krankmeldung_aufrufen(self,index): zeile = index.row() sql_record = self.sql_model_fehlzeiten.record(zeile) beginn = sql_record.value('Beginn').toString() ende = sql_record.value('Ende').toString() attest = sql_record.value('Attest').toString() == 'ja' klausur = sql_record.value('Klausur').toString() == 'ja' grund = sql_record.value('Grund').toString() self.ui.dateEdit.setDate(QtCore.QDate.fromString(beginn,"dd.MM.yyyy")) self.ui.dateEdit_2.setDate(QtCore.QDate.fromString(ende,"dd.MM.yyyy")) self.ui.checkBox.setChecked(attest) self.ui.checkBox_2.setChecked(klausur) self.ui.lineEdit_2.setText(grund) def beurlaubung_speichern(self): name, vorname = self.ui.label_10.text().split(', ') schueler = self.schuelerliste[(vorname,name)] datum_von = self.ui.dateEdit_3.date() datum_bis = self.ui.dateEdit_4.date() grund = (self.ui.lineEdit_3.text() if self.ui.lineEdit_3.text() else u'-') anzahl_stunden = self.ui.spinBox.value() schueler.beurlaubungen[datum_von]=[datum_bis,anzahl_stunden,grund] self.ui_zuruecksetzen() self.tabelle_beurlaubung_aktualisieren() self.datei_speichern() def beurlaubung_aufrufen(self,zeile,spalte): self.ui.dateEdit_3.setDate(QtCore.QDate.fromString(self.ui.tableWidget_2.item(zeile,0).text(),"dd.MM.yyyy")) self.ui.dateEdit_4.setDate(QtCore.QDate.fromString(self.ui.tableWidget_2.item(zeile,1).text(),"dd.MM.yyyy")) self.ui.spinBox.setValue(int(self.ui.tableWidget_2.item(zeile,2).text())) self.ui.lineEdit_3.setText(self.ui.tableWidget_2.item(zeile,3).text()) def bemerkung_speichern(self): name, vorname = self.ui.label_16.text().split(', ') schueler = self.schuelerliste[(vorname,name)] datum = self.ui.calendarWidget.selectedDate() bemerkung = self.ui.plainTextEdit.document().toPlainText() if not bemerkung: QtGui.QMessageBox.information(self,u"Achtung!", u"Bitte erst eine Bemerkung eingeben!") else: schueler.bemerkungen[datum]=[bemerkung,self.ui.checkBox_3.isChecked()] self.tabelle_bemerkung_aktualisieren(schueler) self.datei_speichern() if self.ui.checkBox_3.isChecked(): printer = QtGui.QPrinter() printer.setPaperSize(QtGui.QPrinter.A4) kopfzeile = u'Aktennotiz von ' + vorname + ' ' + name + u' am ' + datum.toString("dd.MM.yyyy") + ':\n\n' #kopfzeile = u'<b>Aktennotiz von ' + vorname + ' ' + name + u' am ' + datum.toString("dd.MM.yyyy") + ':</b><br /><br />' doc = QtGui.QTextDocument(kopfzeile + bemerkung) #doc.setHtml(kopfzeile + bemerkung) doc.print_(printer) self.ui_zuruecksetzen() def bemerkung_aufrufen(self,zeile,spalte): #print zeile, spalte self.ui.calendarWidget.setSelectedDate(QtCore.QDate.fromString(self.ui.tableWidget_3.item(zeile,0).text(),"dd.MM.yyyy")) self.ui.plainTextEdit.setPlainText(self.ui.tableWidget_3.item(zeile,2).text()) if self.ui.tableWidget_3.item(zeile,1).text()=='ja': self.ui.checkBox_3.setChecked(True) else: self.ui.checkBox_3.setChecked(False) def eintrag_loeschen_beurlaubung(self): name, vorname = self.ui.label_10.text().split(', ') schueler = self.schuelerliste[(vorname,name)] i, ok = QtGui.QInputDialog.getInteger(self, u"Zeile löschen", u"Welche Zeile soll gelöscht werden?",1,1 ,len(schueler.beurlaubungen.keys()), 1) if ok: datum = QtCore.QDate.fromString(self.ui.tableWidget_2.item(i-1,0).text(),"dd.MM.yyyy") del schueler.beurlaubungen[datum] self.tabelle_beurlaubung_aktualisieren(schueler) self.datei_speichern() def eintrag_loeschen_bemerkung(self): name, vorname = self.ui.label_16.text().split(', ') schueler = self.schuelerliste[(vorname,name)] i, ok = QtGui.QInputDialog.getInteger(self, u"Zeile löschen", u"Welche Zeile soll gelöscht werden?",1,1 ,len(schueler.bemerkungen.keys()), 1) if ok: datum = QtCore.QDate.fromString(self.ui.tableWidget_3.item(i-1,0).text(),"dd.MM.yyyy") del schueler.bemerkungen[datum] self.tabelle_bemerkung_aktualisieren(schueler) self.datei_speichern() def zeile_geaendert_krank(self,zeile,spalte): print self.ui.tableWidget.item(zeile,spalte).text() if self.ui.tableWidget.item(zeile,spalte).text() != '': name, vorname = self.ui.label_3.text().split(', ') schueler = self.schuelerliste[(vorname,name)] datum = QtCore.QDate.fromString(self.ui.tableWidget.item(zeile,0).text(),"dd.MM.yyyy") datum_bis = QtCore.QDate.fromString(self.ui.tableWidget.item(zeile,1).text(),"dd.MM.yyyy") attest = self.ui.tableWidget.item(zeile,2).text() grund = self.ui.tableWidget.item(zeile,3).text() schueler.krankmeldungen[datum]=[datum_bis,attest,grund] self.datei_speichern() #Statistiken def zeige_krankmeldungen(self): dialog_krank = Dialog_Tabelle(self) dialog_krank.ui.setWindowTitle(u'Krankmeldungen') dialog_krank.ui.tableWidget.setRowCount(len(self.schuelerliste)) dialog_krank.ui.tableWidget.setColumnCount(2) dialog_krank.ui.tableWidget.setHorizontalHeaderLabels([u'Name, Vorname',u'Tage krank']) schueler_krank = [] for schueler in self.schuelerliste.values(): tage = 0 for datum in schueler.krankmeldungen.keys(): tage += datum.daysTo(schueler.krankmeldungen[datum][0])+1 schueler_krank.append([schueler.name+ ', ' + schueler.vorname,str(tage)]) zeile = 0 for eintrag in sorted(schueler_krank, key= lambda schueler : int(schueler[1]), reverse=True): for spalte in range(2): item = QtGui.QTableWidgetItem(eintrag[spalte]) if spalte == 1: item.setTextAlignment(4) dialog_krank.ui.tableWidget.setItem(zeile, spalte, item); zeile += 1 dialog_krank.ui.tableWidget.resizeColumnsToContents() dialog_krank.ui.tableWidget.resizeRowsToContents() dialog_krank.ui.tableWidget.horizontalHeader().setStretchLastSection(True) def zeige_beurlaubungen(self): dialog_krank = Dialog_Tabelle(self) dialog_krank.ui.setWindowTitle(u'Beurlaubungen') dialog_krank.ui.tableWidget.setRowCount(len(self.schuelerliste)) dialog_krank.ui.tableWidget.setColumnCount(2) dialog_krank.ui.tableWidget.setHorizontalHeaderLabels([u'Name, Vorname',u'Stunden beurlaubt']) schueler_beurlaubt = [] for schueler in self.schuelerliste.values(): stunden = 0 for datum in schueler.beurlaubungen: stunden += schueler.beurlaubungen[datum][1] schueler_beurlaubt.append([schueler.name+ ', ' + schueler.vorname,str(stunden)]) zeile = 0 for eintrag in sorted(schueler_beurlaubt, key= lambda schueler : int(schueler[1]), reverse=True): for spalte in range(2): item = QtGui.QTableWidgetItem(eintrag[spalte]) if spalte == 1: item.setTextAlignment(4) dialog_krank.ui.tableWidget.setItem(zeile, spalte, item); zeile += 1 dialog_krank.ui.tableWidget.resizeColumnsToContents() def zeige_klausur_attest(self): dialog_krank = Dialog_Tabelle(self) dialog_krank.ui.setWindowTitle(u'versäumte Klausuren') dialog_krank.ui.tableWidget.setRowCount(len(self.schuelerliste)) dialog_krank.ui.tableWidget.setColumnCount(3) def suche_defizite(self): MESSAGE = u"<p>Die Eingabedatei muss im CSV-Format (als Trennzeichen Komma) vorliegen.</p>" \ u"<p>Die Ausgabedatei wird in demselben Verzeichnis erzeugt, wo die Eingabedatei liegt.\ Sie hat den gleichen Namen mit dem Zusatz '_defizite'.\<p>Sollte etwas nicht funktionieren, frag Boris ;).</p>" reply = QtGui.QMessageBox.information(self, "Achtung!", MESSAGE) if reply == QtGui.QMessageBox.Ok: items = ("Noten", "Punkte") item, ok = QtGui.QInputDialog.getItem(self, "Abfrage", "Wie sind die Noten eingeben?\nAls...", items, 0, False) if ok and item: print item csv_ein = QtGui.QFileDialog.getOpenFileName(self, u'CSV-Datei öffnen','.') if csv_ein: finde_defizite(str(csv_ein), str(item)) def klausurplan_konvertieren(self): MESSAGE = u"<p>Die Eingabedatei muss im CSV-Format vorliegen\ Es dürfen keine Kommata in den Bemerkungen vorkommen!</p>"\ u"<p>Die Ausgabedatei wird in demselben Verzeichnis erzeugt, wo die Eingabedatei liegt.\ Sie hat den gleichen Namen mit dem Zusatz '_konvertiert'.\ Es öffnet sich nun ein Fenster, wo man die Eingabedatei auswählen kann.</p>"\ u"<p>Sollte etwas nicht funktionieren, frag Boris ;).</p>" reply = QtGui.QMessageBox.information(self, "Achtung!", MESSAGE) if reply == QtGui.QMessageBox.Ok: csv_ein = QtGui.QFileDialog.getOpenFileName(self, u'CSV-Datei öffnen','.') if csv_ein: konvertiere(str(csv_ein))
from PyQt4.QtSql import QSqlQueryModel, QSqlDatabase from PyQt4.QtGui import QApplication, QListView, QTableView import sys app = QApplication(sys.argv) db = QSqlDatabase.addDatabase("QMYSQL") db.setHostName("localhost") db.setDatabaseName("app") db.setUserName("root") db.setPassword("") db.open() projectModel = QSqlQueryModel() projectModel.setQuery("select name from customers", db) projectView = QTableView() projectView.setModel(projectModel) projectView.show() model = projectView.model() indexes = projectView.selectionModel().currentIndex().row() app.exec_()
def loading(self): save_path='database/' complete = os.path.join(save_path,"user") f=open(complete,"r") creator=f.read() f.close() ############so finally i came up with something########### #TOPSECRET=4 #SECRET=3 #CONFIDENTIAL=2 #UNCLASSIFIED=1 ############never under estimate your opponent############### print(creator) save_path='database/' comp = os.path.join(save_path,"user.sqlite") db = sqlite3.connect(comp) cur= db.cursor() f=unicode(cur.execute('SELECT Role FROM users where Username=(?)',(creator,)).fetchone()[0]) cl=unicode(cur.execute('SELECT Clearance FROM users where Username=(?)',(creator,)).fetchone()[0]) allow=unicode(cur.execute('SELECT access_auth FROM users where Username=(?)',(creator,)).fetchone()[0]) db.close() if(f=="Admin"): save_path='database/' complete = os.path.join(save_path,"user.sqlite") db = QSqlDatabase.addDatabase("QSQLITE") db.setDatabaseName(complete) db.open() View = QSqlQueryModel() View.setQuery("select * from Files",db) self.tableView = QtGui.QTableView() self.tableView.setModel(View) self.tableView.show() elif(f=='User'): if(allow=="Yes"): if(cl =="TOPSECRET"): save_path='database/' save = os.path.join(save_path,"user.sqlite") db = sqlite3.connect(save) cur= db.cursor() complete = os.path.join(save_path,"user.sqlite") db = QSqlDatabase.addDatabase("QSQLITE") db.setDatabaseName(complete) db.open() View = QSqlQueryModel() View.setQuery("SELECT * FROM files where Clearance in('TOPSECRET','SECRET','CONFIDENTIAL','UNCLASSIFIED')",db) self.tableView = QtGui.QTableView() self.tableView.setModel(View) self.tableView.show() elif(cl =="SECRET"): save_path='database/' save = os.path.join(save_path,"user.sqlite") db = sqlite3.connect(save) cur= db.cursor() complete = os.path.join(save_path,"user.sqlite") db = QSqlDatabase.addDatabase("QSQLITE") db.setDatabaseName(complete) db.open() View = QSqlQueryModel() View.setQuery("SELECT * FROM files where Clearance in('SECRET','CONFIDENTIAL','UNCLASSIFIED')",db) self.tableView = QtGui.QTableView() self.tableView.setModel(View) self.tableView.show() elif(cl =="CONFIDENTIAL"): save_path='database/' save = os.path.join(save_path,"user.sqlite") db = sqlite3.connect(save) cur= db.cursor() complete = os.path.join(save_path,"user.sqlite") db = QSqlDatabase.addDatabase("QSQLITE") db.setDatabaseName(complete) db.open() View = QSqlQueryModel() View.setQuery("SELECT * FROM files where Clearance in('CONFIDENTIAL','UNCLASSIFIED')",db) self.tableView = QtGui.QTableView() self.tableView.setModel(View) self.tableView.show() elif(cl =="UNCLASSIFIED"): save_path='database/' save = os.path.join(save_path,"user.sqlite") db = sqlite3.connect(save) cur= db.cursor() complete = os.path.join(save_path,"user.sqlite") db = QSqlDatabase.addDatabase("QSQLITE") db.setDatabaseName(complete) db.open() View = QSqlQueryModel() View.setQuery("SELECT * FROM files where Clearance in('UNCLASSIFIED')",db) self.tableView = QtGui.QTableView() self.tableView.setModel(View) self.tableView.show()
class FrmKardex( Ui_frmKardex, Base ): ''' Esta clase implementa la funcionalidad para los movimientos de entrada y salida de kardex, en ella el encargado de bodega da cuenta de cuando entra o sale algo de bodega ''' def __init__( self, tiposdoc, parent = None, edit = True ): ''' Constructor ''' super( FrmKardex, self ).__init__( parent ) self.tiposdoc = ",".join( [str( item ) for item in tiposdoc] ) self.edit = edit self.navigationmodel = QSqlQueryModel() self.detailsModel = QSqlQueryModel() self.navproxymodel = QSortFilterProxyModel() self.navproxymodel.setSourceModel( self.navigationmodel ) self.detailsproxymodel = QSortFilterProxyModel() self.detailsproxymodel.setSourceModel( self.detailsModel ) self.tabledetails.setModel( self.detailsproxymodel ) self.tablenavigation.setModel( self.navproxymodel ) self.editmodel = None QTimer.singleShot( 0, self.loadModels ) def updateModels( self ): try: if not self.database.isOpen(): if not self.database.open(): raise UserWarning( u"Existen problemas de conexión "\ + "con la base de datos" ) query = u""" SELECT d.iddocumento, CONCAT_WS(' ',tdc.descripcion, d.ndocimpreso) as 'Documento Referencia', kx.ndocimpreso as 'Numero Kardex', b.nombrebodega as 'Bodega', d.fechacreacion as 'Fecha', kx.observacion as 'Observacion Kardex', d.observacion as 'Observacion Doc', d.idbodega FROM documentos d JOIN tiposdoc tdc ON tdc.idtipodoc = d.idtipodoc JOIN bodegas b ON b.idbodega = d.idbodega JOIN docpadrehijos dpd ON dpd.idpadre = d.iddocumento JOIN documentos kx ON kx.iddocumento = dpd.idhijo AND kx.idtipodoc = %d WHERE d.idtipodoc IN (%s) GROUP BY d.iddocumento """ % ( constantes.IDKARDEX, self.tiposdoc ) self.navigationmodel.setQuery( query ) query = u""" SELECT axd.idarticulo, ad.descripcion as 'Articulo', axd.unidades as 'Unidades', IF(akx.unidades > 0, CONCAT('+',akx.unidades), IFNULL(akx.unidades,0)) as 'Ajuste', axd.iddocumento FROM articulosxdocumento axd JOIN vw_articulosdescritos ad ON ad.idarticulo = axd.idarticulo JOIN documentos d ON axd.iddocumento = d.iddocumento AND d.idtipodoc IN ( %s) JOIN docpadrehijos dph ON dph.idpadre = d.iddocumento JOIN documentos kardex ON kardex.iddocumento = dph.idhijo AND kardex.idtipodoc = %d LEFT JOIN articulosxdocumento akx ON akx.iddocumento = kardex.iddocumento GROUP BY ad.idarticulo, kardex.iddocumento """ % ( self.tiposdoc , constantes.IDKARDEX ) self.detailsModel.setQuery( query ) self.mapper.setModel( self.navproxymodel ) self.mapper.addMapping( self.txtParentPrintedDocumentNumber, NDOCIMPRESO ) self.mapper.addMapping( self.txtPrintedDocumentNumber, NKARDEX ) self.mapper.addMapping( self.dtPicker, FECHA ) self.mapper.addMapping( self.txtWarehouse, NOMBREBODEGA ) self.mapper.addMapping( self.txtKardexObservation, OBSERVACIONK, "plainText" ) self.mapper.addMapping( self.txtDocObservation, OBSERVACION, "plainText" ) # self.tabledetails.horizontalHeader().setStretchLastSection( True ) self.tabledetails.setColumnHidden(0,True) except UserWarning as inst: QMessageBox.critical( self, qApp.organizationName(), unicode( inst ) ) logging.error( inst ) except Exception as inst: logging.critical( inst ) def updateDetailFilter( self, index ): self.detailsproxymodel.setFilterKeyColumn( IDDOCUMENTOT ) self.detailsproxymodel.setFilterRegExp( "^" + self.navigationmodel.record( index ).value( IDDOCUMENTO ).toString() + "$" ) self.tablenavigation.selectRow( self.mapper.currentIndex() ) def cancel( self ): self.editmodel = None self.tabledetails.setModel( self.detailsproxymodel ) self.status = True @pyqtSlot() @if_edit_model def on_txtKardexObservation_textChanged( self ): self.editmodel.observations = self.txtKardexObservation.toPlainText() def setControls( self, status ): self.tabnavigation.setEnabled( status ) self.actionPrint.setVisible( status ) self.actionGoFirst.setVisible( status ) self.actionGoPrevious.setVisible( status ) self.actionGoNext.setVisible( status ) self.actionGoLast.setVisible( status ) self.actionNew.setVisible( status ) self.actionPreview.setVisible( status ) self.dtPicker.setReadOnly( status ) self.actionCancel.setVisible( not status ) self.actionSave.setVisible( not status ) self.tablenavigation.setColumnHidden( IDDOCUMENTO, True ) self.tablenavigation.setColumnHidden( OBSERVACION, True ) self.tablenavigation.setColumnHidden( OBSERVACIONK, True ) self.tablenavigation.setColumnHidden( BODEGA, True ) self.tabledetails.setColumnHidden( AJUSTE, True ) self.tabledetails.setColumnHidden( IDDOCUMENTOT, True ) if status: self.tabledetails.setEditTriggers( QAbstractItemView.NoEditTriggers ) else: self.tabledetails.setEditTriggers( QAbstractItemView.AllEditTriggers ) self.tabledetails.resizeColumnsToContents() # self.tabledetails.horizontalHeader().setStretchLastSection( True ) self.txtKardexObservation.setReadOnly( status ) # self.tabledetails.horizontalHeader().setStretchLastSection( True ) def newDocument( self ): """ Slot documentation goes here. """ query = QSqlQuery() try: if not self.database.isOpen(): if not self.database.open(): raise UserWarning( u"No se pudo establecer una conexión"\ + " con la base de datos" ) dlgdoc = dlgSelectDoc( self.tiposdoc ) if dlgdoc.exec_() == QDialog.Accepted: self.editmodel = KardexModel() row = dlgdoc.tblBills.selectionModel().currentIndex().row() self.editmodel.parentId = dlgdoc.filtermodel.index( row, 0 ).data().toInt()[0] self.editmodel.uid = self.user.uid self.editmodel.parentPrinted = dlgdoc.filtermodel.index( row, 1 ).data().toString() self.editmodel.warehouseId = dlgdoc.filtermodel.index( row, 4 ).data().toInt()[0] self.editmodel.warehouseName = dlgdoc.filtermodel.index( row, 2 ).data().toString() self.txtDocObservation.setPlainText( dlgdoc.filtermodel.index( row, 5 ) .data().toString() ) self.txtParentPrintedDocumentNumber.setText( self.editmodel.parentPrinted ) self.txtWarehouse.setText( self.editmodel.warehouseName ) if not query.prepare( """ SELECT axd.idarticulo, vw.descripcion, axd.unidades, cxa.valor FROM articulosxdocumento axd JOIN costosarticulo cxa ON cxa.idarticulo = axd.idarticulo AND cxa.activo = 1 JOIN vw_articulosdescritos vw ON vw.idarticulo = axd.idarticulo WHERE axd.iddocumento = %d """ % self.editmodel.parentId ): raise Exception( "No se pudo preparar la consulta para "\ + "obtener las lineas del documento" ) if not query.exec_(): raise Exception( "No se pudo ejecutar la consulta para"\ + " obtener las lineas del documento" ) if not query.size() > 0: raise Exception( "La consulta para las lineas del "\ + "documento no devolvio nada" ) while query.next(): linea = LineaKardex() linea.itemId = query.value( 0 ).toInt()[0] linea.itemDescription = query.value( 1 ).toString() linea.numdoc = query.value( 2 ).toInt()[0] linea.itemCost = Decimal( query.value( 3 ).toString() ) row = self.editmodel.rowCount() self.editmodel.insertRows( row ) self.editmodel.lines[row] = linea # Cargar el numero de kardex query = QSqlQuery( """ CALL spConsecutivo(%d,NULL); """ % constantes.IDKARDEX ) 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() self.txtPrintedDocumentNumber.setText( self.editmodel.printedDocumentNumber ) self.status = False self.tabnavigation.setEnabled( False ) self.tabWidget.setCurrentIndex( 0 ) self.tabledetails.setModel( self.editmodel ) delegate = KardexDelegate() self.tabledetails.setItemDelegate( delegate ) self.dtPicker.setDateTime( QDateTime.currentDateTime() ) self.editmodel.dataChanged[QModelIndex, QModelIndex].connect( self.updateLabels ) self.tabledetails.resizeColumnsToContents() except UserWarning as inst: QMessageBox.critical( self, qApp.organizationName(), unicode( inst ) ) logging.warning( inst ) self.cancel() except Exception as inst: QMessageBox.critical( self, qApp.organizationName(), "No se pudo iniciar el documento kardex" ) logging.critical( inst ) self.cancel() finally: if self.database.isOpen(): self.database.close() def updateLabels( self ): pass
class FrmOperations(QMainWindow, Ui_frmOperations): def __init__(self, parent=None): super(FrmOperations, self).__init__(parent) self.setupUi(self) self.__status = False self.database = QSqlDatabase.database() self.navmodel = QSqlQueryModel() self.navproxymodel = QSortFilterProxyModel() self.navproxymodel.setFilterKeyColumn(-1) self.navproxymodel.setFilterCaseSensitivity(Qt.CaseInsensitive) self.navproxymodel.setSourceModel(self.navmodel) self.detailsmodel = QSqlQueryModel() self.detailsproxymodel = QSortFilterProxyModel() self.detailsproxymodel.setSourceModel(self.detailsmodel) self.navproxymodel.setDynamicSortFilter(True) self.detailsproxymodel.setDynamicSortFilter(True) self.mapper = QDataWidgetMapper(self) self.mapper.setModel(self.navproxymodel) self.user = user.LoggedUser self.editModel = None self.tableNavigation.setModel(self.navproxymodel) self.tableDetails.setModel(self.detailsproxymodel) self.tableDetails.setColumnHidden(IDCUENTA, True) self.tableDetails.setColumnHidden(IDDOCUMENTOC, True) self.actionCancelar.setVisible(False) self.actionGuardar.setVisible(False) # self.actionGuardar.activated.connect( self.save ) self.tableNavigation.selectionModel().selectionChanged[QItemSelection, QItemSelection].connect( self.updateDetails ) QTimer.singleShot(0, self.updateModels) def updateModels(self): try: if not self.database.isOpen(): if not self.database.open(): raise UserWarning("No se pudo conectar con la base de datos") self.navmodel.setQuery( """ SELECT d.iddocumento, d.ndocimpreso as 'N Doc', d.fechacreacion as 'Fecha', c.descripcion as 'Concepto' FROM documentos d JOIN conceptos c ON c.idconcepto = d.idconcepto WHERE d.idtipodoc = %d ORDER BY d.iddocumento DESC """ % constantes.IDAJUSTECONTABLE ) self.detailsmodel.setQuery( """ SELECT cxd.idcuenta, cc.codigo as 'Codigo Cuenta', cc.descripcion as 'Nombre Cuenta', CONCAT('C$',FORMAT(cxd.monto,4)) as Monto, cxd.iddocumento FROM cuentasxdocumento cxd JOIN cuentascontables cc ON cxd.idcuenta = cc.idcuenta JOIN documentos d ON d.iddocumento = cxd.iddocumento WHERE d.idtipodoc = %d ORDER BY nlinea """ % constantes.IDAJUSTECONTABLE ) self.mapper.addMapping(self.dtPicker, FECHACREACION) self.mapper.addMapping(self.txtConcept, CONCEPTO) self.tableNavigation.selectionModel().setCurrentIndex( self.navproxymodel.index(0, 0), QItemSelectionModel.Select ) self.tableNavigation.setColumnHidden(IDDOCUMENTO, True) self.tableDetails.setColumnHidden(IDDOCUMENTOC, True) self.tableDetails.setColumnHidden(IDCUENTA, True) self.tableDetails.setColumnWidth(CODIGO, 240) self.tableDetails.setColumnWidth(DESCRIPCION, 250) self.tableNavigation.setColumnWidth(FECHACREACION, 200) self.tableNavigation.setColumnWidth(CONCEPTO, 250) except UserWarning as inst: logging.error(inst) QMessageBox.critical(self, qApp.organizationName(), unicode(inst)) except Exception as inst: logging.critical(inst) def updateDetails(self, selected, _deselected): if len(selected.indexes()) > 0: self.mapper.setCurrentModelIndex(selected.indexes()[0]) self.detailsproxymodel.setFilterKeyColumn(IDDOCUMENTOC) self.detailsproxymodel.setFilterRegExp(self.navproxymodel.data(selected.indexes()[0]).toString()) def setStatus(self, status): """ Cambiar el modo del formulario true = adding false = navigating @param status: El modo del formulario @type status:bool """ self.widget.setHidden(status) self.txtSearch.setEnabled(not status) self.actionNuevo.setVisible(not status) self.actionCancelar.setVisible(status) self.actionGuardar.setVisible(status) self.cbConcepts.setEnabled(status) self.tableDetails.setEditTriggers(QTableView.AllEditTriggers if status else QTableView.NoEditTriggers) self.tableNavigation.setEnabled(not status) self.tableDetails.setEditTriggers(QTableView.AllEditTriggers) # self.stackedWidget.setCurrentIndex( 0 if status else 1 ) self.stConcepts.setCurrentIndex(1 if status else 0) def getStatus(self): return self.__status status = property(getStatus, setStatus) @pyqtSlot() def on_actionCancelar_activated(self): self.status = False self.editModel = None self.tableDetails.setModel(self.detailsproxymodel) self.tableDetails.setColumnHidden(IDDOCUMENTOC, True) self.tableDetails.setColumnHidden(IDCUENTA, True) @pyqtSlot() def on_actionGuardar_activated(self): self.save() @pyqtSlot() def on_actionNuevo_activated(self): try: if not self.database.isOpen(): if not self.database.open(): raise UserWarning("No se pudo abrir la base de datos") self.editModel = AccountsSelectorModel() self.editModel.insertRow(1) delegate = AccountsSelectorDelegate( QSqlQuery( """ SELECT c.idcuenta, c.codigo, c.descripcion FROM cuentascontables c JOIN cuentascontables p ON c.padre = p.idcuenta AND p.padre != 1 """ ) ) self.dtPicker.setDateTime(QDateTime.currentDateTime()) self.dtPicker.setMaximumDateTime(QDateTime.currentDateTime()) self.conceptsmodel = QSqlQueryModel() q = """ SELECT idconcepto, descripcion FROM conceptos WHERE idtipodoc = %d and idconcepto <>%d """ % ( constantes.IDAJUSTECONTABLE, constantes.IDCONCEPTOBALANCEINICIAL, ) self.conceptsmodel.setQuery(q) if self.conceptsmodel.rowCount() < 1: raise UserWarning( "No existen conceptos para ajustes contables, por favor comuniquese con el administrador del sistema" ) self.cbConcepts.setModel(self.conceptsmodel) self.cbConcepts.setModelColumn(1) self.tableDetails.setModel(self.editModel) self.tableDetails.setColumnHidden(IDCUENTA, True) self.tableDetails.setColumnHidden(IDDOCUMENTOC, True) self.tableDetails.setItemDelegate(delegate) self.status = True self.tableDetails.resizeColumnsToContents() except UserWarning as inst: self.status = False QMessageBox.critical(self, qApp.organizationName(), unicode(inst)) logging.error(unicode(inst)) except Exception as inst: QMessageBox.critical(self, qApp.organizationName(), "Hubo un error al tratar de iniciar un nuevo ajuste") logging.critical(unicode(inst)) self.status = False @pyqtSlot("QString") def on_txtSearch_textChanged(self, text): self.navproxymodel.setFilterRegExp(text) def save(self): query = QSqlQuery() try: if not self.editModel.valid: raise UserWarning("El documento no es valido, no se puede guardar") if not self.database.isOpen(): if not self.database.open(): raise UserWarning("No se pudo conectar con la base de datos") if not self.database.transaction(): raise Exception(u"No se pudo comenzar la transacción") # Cargar el numero del asiento actual query.prepare( """ SELECT MAX(CAST(ndocimpreso AS SIGNED))+1 FROM documentos d WHERE idtipodoc=24 ; """ ) query.exec_() query.first() n = query.value(0).toString() if n == "0": n = "1" if not query.prepare( """ INSERT INTO documentos (ndocimpreso, fechacreacion, idconcepto, idtipodoc) VALUES (:ndocimpreso, :fechacreacion, :idconcepto, %d) """ % constantes.IDAJUSTECONTABLE ): raise Exception("No se pudo preparar la consulta para guardar el documento") query.bindValue(":ndocimpreso", n) query.bindValue(":fechacreacion", self.dtPicker.dateTime().toString("yyyyMMddhhmmss")) query.bindValue( ":idconcepto", self.conceptsmodel.record(self.cbConcepts.currentIndex()).value("idconcepto").toInt()[0] ) if not query.exec_(): raise Exception("No se pudo ejecutar la consulta para guardar el asiento") insertedId = query.lastInsertId().toInt()[0] if not query.prepare( """ INSERT INTO personasxdocumento (idpersona, iddocumento, idaccion) VALUES (:usuario, :documento, :idaccion) """ ): raise Exception("No se pudo preparar la consulta para insertar el usuario") query.bindValue(":usuario", self.user.uid) query.bindValue(":documento", insertedId) query.bindValue(":idaccion", constantes.ACCCREA) if not query.exec_(): raise Exception(u"No se pudo guardar la relación con el usuario") for lineid, line in enumerate(self.editModel.lines): if line.valid: line.save(insertedId, lineid + 1) if not self.database.commit(): raise Exception("No se pudo ejecutar la transaccion") self.tableDetails.setModel(self.detailsproxymodel) self.updateModels() self.status = False except UserWarning as inst: QMessageBox.critical(self, qApp.organizationName(), unicode(inst)) logging.error(inst) except Exception as inst: QMessageBox.critical(self, qApp.organizationName(), "Hubo un error al tratar de guardar su ajuste") self.database.rollback() logging.critical(inst) logging.critical(query.lastError().text()) finally: if self.database.isOpen(): self.database.close()
class tbFactura( QTabWidget ,Ui_tbFactura ): """ Implementacion de la interfaz grafica para facturas """ web = "facturas.php?doc=" DATE_FORMAT = "dd/MM/yyyy" def __init__( self ): ''' Constructor ''' super( tbFactura, self ).__init__( ) # ESTABLECER LA INTERFAZ AL FORMULARIO self.setupUi(self) # VALIDADOR DE MODO DE EDICION self.readOnly = True self.editmodel = None #ESTABLECER LA FECHA INICIAL , (establecida al dia de mañana) self.categoriesview.headers = ["Descripcion", "Precio", "Unidades","Existencia","","",""] # Crear el modelo para cargar catalogo de clientes self.clientesModel = QSqlQueryModel() # Crear lista de autocompletado para el combo de clientes self.clienteCompleter = QCompleter() # Modelo que carga el catalogo de productos self.existenciaModel = QSqlQueryModel() # Establecer todos los controles en modo de edicion self.setControls( False ) # Crear la conexion a la base de datos self.database = QSqlDatabase.database() self.vistaprevia = False # Cargar los modelos del modo de edicion self.updateEditModels() self.parent = self.parent() def newDocument( self ): """ activar todos los controles, llenar los modelos necesarios, crear el modelo FacturaModel, aniadir una linea a la tabla """ self.readOnly = False if not self.updateEditModels(): return self.status = False self.dtPicker.setDate( self.parentWindow.datosSesion.fecha ) def updateEditModels( self ): """ Este metodo actualiza los modelos usados en el modo edición """ resultado = False 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" ) self.clientesModel.setQuery( """ SELECT idpersona , nombre AS cliente FROM personas WHERE escliente = 1 """) self.cbcliente.setModel( self.clientesModel ) self.cbcliente.setModelColumn( 1 ) self.clienteCompleter.setCaseSensitivity( Qt.CaseInsensitive ) self.clienteCompleter.setModel( self.clientesModel ) self.clienteCompleter.setCompletionColumn( 1 ) self.cbcliente.setCompleter( self.clienteCompleter ) self.editmodel = FacturaModel( ) # Cargar el numero de la factura actual query = QSqlQuery( """ SELECT MAX(CAST( IFNULL(referencia,0) AS SIGNED)) FROM documentos d WHERE idtipodoc =%d; """ % constantes.IDFACTURA ) if not query.exec_(): raise Exception( "No se pudo obtener el numero de la factura" ) query.first() if query.size()==0: n =1 else: n = str(int(query.value(0)) + 1) self.editmodel.printedDocumentNumber = str(int(query.value(0)) + 1) self.lblnumero.setText(n) # if self.clientesModel.rowCount() == 0: # raise UserWarning( "No existen clientes en la"\ # + " base de datos" ) # return self.clienteCompleter.setModel(self.clientesModel) self.cbcliente.setModel(self.clientesModel) self.cbcliente.setCompleter(self.clienteCompleter) # #Crear el delegado con los articulo y verificar si existen articulos self.existenciaModel.setQuery( QSqlQuery( """ SELECT categoria, descripcion, precio, unidadesxcaja, -- cajas, 100 as cajas, idprecioproducto FROM vw_articulos -- WHERE existencia >0 """ ) ) self.categoriesview.update(""" SELECT categoria, descripcion, precio, unidadesxcaja, -- cajas, 100 as cajas, idprecioproducto FROM vw_articulos WHERE idprecioproducto IS NOT NULL -- WHERE existencia >0 """) self.categoriesview.expandAll() self.categoriesview.setColumnHidden(3,True) self.categoriesview.setColumnHidden(4,True) self.categoriesview.setColumnWidth(0,150) self.categoriesview.setColumnWidth(1,60) self.categoriesview.setColumnWidth(2,20) self.proxyexistenciaModel = SingleSelectionModel() self.proxyexistenciaModel.setSourceModel( self.existenciaModel ) # self.proxyexistenciaModel.setFilterKeyColumn( IDBODEGAEX ) if self.proxyexistenciaModel.rowCount() == 0: raise UserWarning( "No hay articulos en bodega" ) delegate = FacturaDelegate( self.proxyexistenciaModel ) self.tabledetails.setItemDelegate( delegate ) self.tabledetails.setModel( self.editmodel ) self.tabledetails.setColumnHidden(0,True) # self.editmodel.insertRow(1) self.editmodel.dataChanged[QModelIndex, QModelIndex].connect( self.updateLabels ) self.txtobservaciones.setPlainText( "" ) self.dtPicker.setDate(QDate.currentDate().addDays(1)) self.editmodel.fecha = QDate.currentDate().addDays(1) self.cbcliente.setCurrentIndex( -1 ) resultado = True except UserWarning as inst: logging.error( unicode( inst ) ) QMessageBox.critical( self, qApp.organizationName(), unicode( inst ) ) finally: if self.database.isOpen(): self.database.close() return resultado def addActionsToToolBar( self ): self.actionRefresh = self.createAction( text = "Actualizar", icon = QIcon.fromTheme( 'view-refresh', QIcon( ":/icons/res/view-refresh.png" ) ), slot = self.refresh, shortcut = Qt.Key_F5 ) self.toolBar.addActions( [ self.actionNew, self.actionRefresh, self.actionPreview, self.actionPrint, self.actionSave, self.actionCancel, ] ) self.toolBar.addSeparator() self.toolBar.addActions( [ self.actionGoFirst, self.actionGoPrevious, self.actionGoLast, self.actionGoNext, self.actionGoLast ] ) def refresh( self ): """ Actualizar los modelos de edición """ if not self.status: if QMessageBox.question( self, qApp.organizationName(), u"Se perderán todos los cambios en la factura. ¿Esta seguro que desea actualizar?", QMessageBox.Yes | QMessageBox.No ) == QMessageBox.No: return self.updateEditModels() else: if self.updateModels(): QMessageBox.information( None, "Factura", u"Los datos fueron actualizados con éxito" ) def printDocument1(self): html = u"" date = QDate.currentDate().toString(self.DATE_FORMAT) address = Qt.escape("Bario francisco mesa").replace(",","<br>") contact = Qt.escape("Luis Mejia") balance = 5000 html += ("<p align=right><img src=':/logo.png'></p>" "<p> align = right>Greasy hands ltd." "<br>New Lombard Street" "<br>London<br>WC13 4PX<br>%s</p>" "<p>%s</p><p>Dear %s, </p>" "<p>The balance of your account is %s.")% ( date, address, contact, QString("$ %L1").arg(float(balance),0,"f",2)) if balance <0 : html += ("<p><font color =red><b> Please remit the amount owing immediately.</b></font>") else: html += "We are delighted to have done business with you." html += ("</p><p> </p><p>" "<table border=1 cellpadding=2 cellspacing=2><tr><td colspan=3>Transaction</td></tr>") transactions = [ (QDate.currentDate(),500), (QDate.currentDate(),500), (QDate.currentDate(),-500), (QDate.currentDate(),500) ] for date, amount in transactions: color, status = "black", "Credit" if amount <0: color, status = "red", "Debid" html += ("<tr>" "<td align= right>%s</td>" "<td>%s</td><td align=right><font color=%s>%s</font></td></tr>" % ( date.toString(self.DATE_FORMAT), status,color, QString("$ %L1").arg(float(abs(amount)), 0, "f",2))) html += ("</table></p><p style='page-break-after=always;'>" "We hope to continue doing business with you</p>") pdialog = QPrintDialog() if pdialog.exec_() == QDialog.Accepted: printer = pdialog.printer() document = QTextDocument() document.setHtml(html) document.print_(printer) def printDocument2(self): dialog = QPrintDialog() if not dialog.exec_(): return self.printer = dialog.printer() headFormat = QTextBlockFormat() headFormat.setAlignment(Qt.AlignLeft) headFormat.setTextIndent( self.printer.pageRect().width()-216) bodyFormat = QTextBlockFormat() bodyFormat.setAlignment(Qt.AlignJustify) lastParaBodyFormat = QTextBlockFormat(bodyFormat) lastParaBodyFormat.setPageBreakPolicy(QTextFormat.PageBreak_AlwaysAfter) rightBodyFormat = QTextBlockFormat() rightBodyFormat.setAlignment(Qt.AlignRight) headCharFormat = QTextCharFormat() headCharFormat.setFont(QFont("Helvetica",10)) bodyCharFormat = QTextCharFormat() bodyCharFormat.setFont(QFont("Times",11)) redBodyCharFormat = QTextCharFormat(bodyCharFormat) redBodyCharFormat.setForeground(Qt.red) tableFormat = QTextTableFormat() tableFormat.setBorder(1) tableFormat.setCellPadding(2) document = QTextDocument() cursor = QTextCursor(document) mainFrame = cursor.currentFrame() page = 1 cursor.insertBlock(headFormat, headCharFormat) for text in ("Greasy Hands Ltd.", "New Lombard Street","London" , "WC13", QDate.currentDate().toString(self.DATE_FORMAT)): cursor.insertBlock(headFormat,headCharFormat) cursor.insertText(text) cursor.insertBlock(bodyFormat,bodyCharFormat) cursor.insertText("Barrio Francisco Meza") cursor.insertBlock(bodyFormat) cursor.insertBlock(bodyFormat,bodyCharFormat) cursor.insertText("Dear Lyuis") cursor.insertBlock(bodyFormat) cursor.insertBlock(bodyFormat,bodyCharFormat) cursor.insertText(QString("The balance of your account is $ %L1.").arg(float(500.987),0,"f",2)) cursor.insertBlock(bodyFormat,redBodyCharFormat) cursor.insertText("Please remit the amount") cursor.insertBlock(bodyFormat,bodyCharFormat) cursor.insertText("Transaction") transactions = [ (QDate.currentDate(),500), (QDate.currentDate(),500), (QDate.currentDate(),-500), (QDate.currentDate(),500) ] table = cursor.insertTable(len(transactions), 3, tableFormat) row = 0 for date, amount in transactions: cellCursor = table.cellAt(row,0).firstCursorPosition() cellCursor.setBlockFormat(rightBodyFormat) cellCursor.insertText(date.toString(self.DATE_FORMAT),bodyCharFormat) cellCursor = table.cellAt(row,1).firstCursorPosition() cellCursor.insertText("Credit",bodyCharFormat) cellCursor = table.cellAt(row,2).firstCursorPosition() cellCursor.setBlockFormat(rightBodyFormat) cellCursor.insertText(QString("The balance of your account is $ %L1.").arg(float(amount),0,"f",2),redBodyCharFormat) row += 1 cursor.setPosition(mainFrame.lastPosition()) cursor.insertBlock(bodyFormat,bodyCharFormat) cursor.insertText("We hope") document.print_(self.printer) def printDocument(self): dialog = QPrintDialog() if not dialog.exec_(): return self.printer = dialog.printer() self.imprimir(self.printer) self.document.load(self.editmodel) def preview(self): self.vistaprevia = True preview = frmImpresion(self) preview.exec_() def save( self ): """ Guardar el documento actual @rtype: bool """ result = False try: if not self.valid: return False if QMessageBox.question( self, qApp.organizationName(), u"¿Esta seguro que desea guardar la factura?", QMessageBox.Yes | QMessageBox.No ) == QMessageBox.Yes: if not self.database.isOpen(): if not self.database.open(): raise UserWarning( u"No se pudo conectar con la base de datos" ) self.editmodel.observaciones = self.txtobservaciones.toPlainText() if not self.editmodel.save(): raise UserWarning( "No se ha podido guardar la factura" ) QMessageBox.information( None, qApp.organizationName() , u"""El documento se ha guardado con éxito""" ) self.readOnly = True self.updateModels() # self.navigate( 'last' ) # self.status = True result = True 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 guardar la factura" ) finally: if self.database.isOpen(): self.database.close() return result # @pyqtSlot(QModelIndex) # def on_categoriesview_doubleClicked(self,index): @pyqtSlot(QModelIndex) def on_categoriesview_activated(self,index): articulo = self.categoriesview.model().asRecord(index) if len(articulo)>0: nuevo = True for i, line in enumerate(self.editmodel.lines): if line.itemId == articulo [5]: nuevo = False fila = i line = self.editmodel.lines[self.editmodel.rowCount()-1] if nuevo: fila = self.editmodel.rowCount() self.editmodel.insertRow(fila) self.parent.saveAct.setEnabled(True) linea = self.editmodel.lines[fila] linea.itemDescription = articulo[0] + " " + articulo [1] linea.itemPrice = Decimal(articulo[2]) linea.itemId = articulo[5] linea.quantityperbox = int(articulo[3]) self.editmodel.lines[fila].quantity += 1 self.editmodel.lines[fila].existencia = int(articulo[4]) - self.editmodel.lines[fila].quantity indice =self.editmodel.index( fila,2) self.editmodel.dataChanged.emit( indice, indice ) indice =self.editmodel.index( fila,3) self.editmodel.dataChanged.emit( indice, indice ) indice =self.editmodel.index( fila,5) self.editmodel.dataChanged.emit( indice, indice ) @pyqtSlot() def on_btneditar_clicked( self ): articulo = dlgArticulo(self) articulo.exec_() self.updateEditModels() @pyqtSlot( int ) def on_cbcliente_currentIndexChanged( self, index ): """ asignar proveedor al objeto self.editmodel """ if self.editmodel is not None: numero = self.clientesModel.record( index ).value( "idpersona" ) self.editmodel.clienteId = int(numero) if numero is not None else 0 @pyqtSlot( unicode ) def on_cbcliente_editTextChanged( self, text ): """ asignar proveedor al objeto self.editmodel """ if self.editmodel is not None: self.editmodel.cliente =str( text) @pyqtSlot( int ) def on_cbvendedor_currentIndexChanged( self, index ): """ asignar proveedor al objeto self.editmodel """ self.editmodel.vendedorId = self.vendedoresModel.record( index ).value( "idpersona" ).toInt()[0] @pyqtSlot( QDate) def on_dtPicker_dateChanged( self, date ): if self.editmodel is not None: self.editmodel.fecha = date @pyqtSlot( bool ) def on_rbcontado_toggled( self, on ): """ Asignar las observaciones al objeto editmodel """ self.editmodel.escontado = 1 if on else 0 def on_txtSearch_textChanged( self, text ): """ Cambiar el filtro de busqueda """ self.filtermodel.setFilterRegExp( text ) def setControls( self, status ): """ @param status: false = editando true = navegando """ # self.actionPrint.setVisible( status ) self.readOnly = status self.txtobservaciones.setReadOnly( status ) # self.actionPreview.setVisible( status ) # self.actionAnular.setVisible( status ) # self.toolBar.setVisible(status) # self.lblnfac.setText( self.editmodel.printedDocumentNumber ) self.swcliente.setCurrentIndex( 0 ) self.lbltotal.setText( "C$ 0.00" ) self.tabledetails.setEditTriggers( QAbstractItemView.AllEditTriggers ) # self.lblanulado.setHidden( True ) self.tabledetails.horizontalHeader().setStretchLastSection(True) self.tabledetails.setColumnHidden( IDARTICULO, True ) self.tabledetails.setColumnHidden( IDDOCUMENTOT, True ) def updateLabels( self ): self.lbltotal.setText( moneyfmt( self.editmodel.total, 2, "C$ " ) ) @property def valid( self ): """ Un documento es valido cuando self.printedDocumentNumber != "" self.providerId !=0 self.validLines >0 self.ivaId !=0 self.uid != 0 self.warehouseId != 0 """ if int( self.editmodel.clienteId) == 0 and self.editmodel.cliente == "": QMessageBox.warning( self, qApp.organizationName(), "Por favor elija el cliente" ) self.cbcliente.setFocus() elif self.editmodel.rowCount() == 0: QMessageBox.warning( self, qApp.organizationName(), "Por favor agregue algun articulo a la factura" ) else: return True return False def imprimir(self,printer): leftMargin = 72 widthCol = 100 arialFont = QFont("Helvetica",16,3) fuente =QFontMetrics(arialFont) arialLineHeight = fuente.height() fondo = QPixmap(":/images/res/fondo.png") painter = QPainter(printer) pageRect = printer.pageRect() page = 1 painter.save() if self.vistaprevia: painter.drawPixmap(0, 0, 530, 830, fondo) painter.setFont(arialFont) y = 180 x = 35 painter.drawText(x,y,self.editmodel.fecha.toString("dd MM yy")) y = 210 x = 85 painter.drawText(x,y, self.editmodel.cliente) painter.setFont(arialFont) cajasFont = QFont("Helvetica",10,2) x = -5 y = 295 painter.setFont(cajasFont) painter.drawText(x,y - arialLineHeight - 1,"Cajas") for row in self.editmodel.lines: painter.setFont(cajasFont) x = 2 painter.drawText(x,y,row.cantidad()) painter.setFont(arialFont) total = moneyfmt(row.total,2,"") x = 470 - fuente.width(total) painter.drawText(x,y,total) x =310 painter.drawText(x,y,moneyfmt(row.itemPrice,2,"")) x = 30 painter.drawText(x,y,row.unidades()) x = 80 painter.drawText(x,y,row.itemDescription) y+= arialLineHeight total = moneyfmt(self.editmodel.total,2,"") y= 690 x = 470 - fuente.width(total) painter.drawText(x,y,total) painter.setPen(Qt.black) # printer.newPage() painter.restore()
class SearchPlus(QObject): def __init__(self, iface, srid, controller): """ Constructor """ self.iface = iface self.srid = srid self.controller = controller self.schema_name = self.controller.schema_name self.project_type = self.controller.get_project_type() self.feature_cat = {} # Create dialog self.dlg = SearchPlusDockWidget(self.iface.mainWindow()) # Load configuration data from tables if not self.load_config_data(): self.enabled = False return sql = ("SELECT value FROM " + self.controller.schema_name + ".config_param_system WHERE parameter='street_field_expl'") self.street_field_expl = self.controller.get_row(sql) if not self.street_field_expl: message = "Param street_field_expl not found" self.controller.show_warning(message) return sql = ("SELECT value FROM " + self.controller.schema_name + ".config_param_system WHERE parameter='portal_field_postal'") portal_field_postal = self.controller.get_row(sql) if not portal_field_postal: message = "Param portal_field_postal not found" self.controller.show_warning(message) return # Set signals self.dlg.address_exploitation.currentIndexChanged.connect(partial(self.address_fill_postal_code, self.dlg.address_postal_code)) self.dlg.address_exploitation.currentIndexChanged.connect(partial(self.address_populate, self.dlg.address_street, 'street_layer', 'street_field_code', 'street_field_name')) self.dlg.address_exploitation.currentIndexChanged.connect(partial(self.address_get_numbers, self.dlg.address_exploitation, self.street_field_expl[0], False)) self.dlg.address_postal_code.currentIndexChanged.connect(partial(self.address_get_numbers, self.dlg.address_postal_code, portal_field_postal[0], False)) self.dlg.address_street.activated.connect(partial(self.address_get_numbers, self.dlg.address_street, self.params['portal_field_code'], True)) self.dlg.address_number.activated.connect(partial(self.address_zoom_portal)) self.dlg.network_geom_type.activated.connect(partial(self.network_geom_type_changed)) self.dlg.network_code.activated.connect(partial(self.network_zoom, self.dlg.network_code, self.dlg.network_geom_type)) self.dlg.network_code.editTextChanged.connect(partial(self.filter_by_list, self.dlg.network_code)) self.dlg.hydrometer_connec.activated.connect(partial(self.hydrometer_get_hydrometers)) self.dlg.hydrometer_id.activated.connect(partial(self.hydrometer_zoom, self.params['hydrometer_urban_propierties_field_code'], self.dlg.hydrometer_connec)) self.dlg.hydrometer_id.editTextChanged.connect(partial(self.filter_by_list, self.dlg.hydrometer_id)) self.dlg.workcat_id.activated.connect(partial(self.workcat_open_table_items)) self.enabled = True def workcat_populate(self, combo): """ Fill @combo """ sql = ("SELECT DISTINCT(workcat_id) FROM " + self.controller.schema_name + ".arc" " WHERE workcat_id LIKE '%%' or workcat_id is NULL" " UNION" " SELECT DISTINCT(workcat_id) FROM " + self.controller.schema_name + ".connec" " WHERE workcat_id LIKE '%%' or workcat_id is NULL" " UNION" " SELECT DISTINCT(workcat_id) FROM " + self.controller.schema_name + ".node" " WHERE workcat_id LIKE '%%' or workcat_id is NULL") if self.project_type == 'ud': sql += (" UNION" " SELECT DISTINCT(workcat_id) FROM " + self.controller.schema_name + ".gully" " WHERE workcat_id LIKE '%%' or workcat_id is NULL") rows = self.controller.get_rows(sql) utils_giswater.fillComboBox(combo, rows) return rows def workcat_open_table_items(self): """ Create the view and open the dialog with his content """ self.workcat_id = utils_giswater.getWidgetText(self.dlg.workcat_id) if self.workcat_id == "null": return False self.items_dialog = ListItems() utils_giswater.setDialog(self.items_dialog) self.tbl_psm = self.items_dialog.findChild(QTableView, "tbl_psm") self.tbl_psm.setSelectionBehavior(QAbstractItemView.SelectRows) self.items_dialog.btn_accept.pressed.connect(partial(self.workcat_zoom)) self.items_dialog.btn_cancel.pressed.connect(self.items_dialog.close) self.items_dialog.txt_name.textChanged.connect(partial(self.workcat_filter_by_text, self.tbl_psm, self.items_dialog.txt_name)) self.workcat_fill_table(self.workcat_id) self.items_dialog.exec_() def workcat_zoom(self): """ Zoom feature with the code set in 'network_code' of the layer set in 'network_geom_type' """ # Get selected code from combo element = self.tbl_psm.selectionModel().selectedRows() if len(element) == 0: message = "Any record selected" self.controller.show_warning(message) return row = element[0].row() feature_id = self.tbl_psm.model().record(row).value(2) # Get selected layer geom_type = self.tbl_psm.model().record(row).value('feature_type').lower() fieldname = geom_type + "_id" self.items_dialog.close() # Check if the expression is valid aux = fieldname + " = '" + str(feature_id) + "'" expr = QgsExpression(aux) if expr.hasParserError(): message = expr.parserErrorString() + ": " + aux self.controller.show_warning(message) return for value in self.feature_cat.itervalues(): if value.type.lower() == geom_type: layer = self.controller.get_layer_by_layername(value.layername) if layer: it = layer.getFeatures(QgsFeatureRequest(expr)) ids = [i.id() for i in it] layer.selectByIds(ids) # If any feature found, zoom it and exit function if layer.selectedFeatureCount() > 0: self.workcat_open_custom_form(layer, expr) self.zoom_to_selected_features(layer) return def workcat_open_custom_form(self, layer, expr): """ Open custom form from selected layer """ it = layer.getFeatures(QgsFeatureRequest(expr)) features = [i for i in it] if features: self.iface.openFeatureForm(layer, features[0]) def workcat_fill_table(self, workcat_id): """ Fill table @widget filtering query by @workcat_id """ result_select = utils_giswater.getWidgetText(self.items_dialog.txt_name) if result_select != 'null': expr = " feature_id LIKE '%" + result_select + "%'" # Refresh model with selected filter self.controller.log_info(expr) self.tbl_psm.model().setFilter(expr) self.tbl_psm.model().select() return # Define SQL sql = ("SELECT 'NODE' as feature_type, nodecat_id AS featurecat_id, node_id AS feature_id, code, name as state" " FROM " + self.schema_name + ".v_edit_node JOIN " + self.schema_name + ".value_state ON id = state" " WHERE workcat_id = '" + str(workcat_id) + "'" " UNION" " SELECT 'ARC', arccat_id, arc_id, code, name" " FROM " + self.schema_name + ".v_edit_arc JOIN " + self.schema_name + ".value_state ON id = state" " WHERE workcat_id = '" + str(workcat_id) + "'" " UNION" " SELECT 'ELEMENT', elementcat_id, element_id, code, name" " FROM " + self.schema_name + ".v_edit_element JOIN " + self.schema_name + ".value_state ON id = state" " WHERE workcat_id = '" + str(workcat_id) + "'" " UNION" " SELECT 'CONNEC', connecat_id, connec_id, code, name" " FROM " + self.schema_name + ".v_edit_connec JOIN " + self.schema_name + ".value_state ON id = state" " WHERE workcat_id = '" + str(workcat_id) + "'") # Set model self.model = QSqlQueryModel() self.model.setQuery(sql) # Check for errors if self.model.lastError().isValid(): self.controller.show_warning(self.model.lastError().text()) # Attach model to table view self.tbl_psm.setModel(self.model) def workcat_filter_by_text(self, table, widget_txt): result_select = utils_giswater.getWidgetText(widget_txt) if result_select != 'null': expr = " feature_id LIKE '%" + result_select + "%'" # Refresh model with selected filter table.model().setFilter(expr) table.model().select() else: self.workcat_fill_table(self.workcat_id) def address_fill_postal_code(self, combo): """ Fill @combo """ # Get exploitation code: 'expl_id' elem = self.dlg.address_exploitation.itemData(self.dlg.address_exploitation.currentIndex()) code = elem[0] # Get postcodes related with selected 'expl_id' sql = "SELECT DISTINCT(postcode) FROM " + self.controller.schema_name + ".ext_address" if code != -1: sql += " WHERE "+self.street_field_expl[0]+"= '" + str(code) + "'" sql += " ORDER BY postcode" rows = self.controller.get_rows(sql) if not rows: return False records = [(-1, '', '')] for row in rows: field_code = row[0] elem = [field_code, field_code, None] records.append(elem) # Fill combo combo.blockSignals(True) combo.clear() records_sorted = sorted(records, key=operator.itemgetter(1)) for i in range(len(records_sorted)): record = records_sorted[i] combo.addItem(str(record[1]), record) combo.blockSignals(False) return True def load_config_data(self): """ Load configuration data from tables """ self.params = {} sql = "SELECT parameter, value FROM " + self.controller.schema_name + ".config_param_system" sql += " WHERE context = 'searchplus' ORDER BY parameter" rows = self.controller.get_rows(sql) if rows: for row in rows: self.params[row['parameter']] = str(row['value']) return True else: self.controller.log_warning("Parameters related with 'searchplus' not set in table 'config_param_system'") return False # Get scale zoom self.scale_zoom = 2500 sql = "SELECT value FROM " + self.schema_name + ".config_param_system" sql += " WHERE parameter = 'scale_zoom'" row = self.controller.get_row(sql) if row: self.scale_zoom = row['value'] def dock_dialog(self): """ Dock dialog into left dock widget area """ # Get path of .ui file ui_path = os.path.join(self.controller.plugin_dir, 'search', 'ui', 'search_plus_dialog.ui') if not os.path.exists(ui_path): self.controller.show_warning("File not found", parameter=ui_path) return False # Make it dockable in left dock widget area self.dock = uic.loadUi(ui_path) self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.dlg) self.dlg.setFixedHeight(162) # Set his backgroundcolor p = self.dlg.palette() self.dlg.setAutoFillBackground(True) p.setColor(self.dlg.backgroundRole(), Qt.white) self.dlg.setPalette(p) return True def get_layers(self): """ Iterate over all layers to get the ones set in config file """ # Check if we have any layer loaded layers = self.iface.legendInterface().layers() if len(layers) == 0: return # Iterate over all layers to get the ones specified parameters '*_layer' self.layers = {} for cur_layer in layers: layer_source = self.controller.get_layer_source(cur_layer) uri_table = layer_source['table'] if uri_table is not None: if self.params['expl_layer'] == uri_table: self.layers['expl_layer'] = cur_layer if self.params['street_layer'] == uri_table: self.layers['street_layer'] = cur_layer if self.params['portal_layer'] == uri_table: self.layers['portal_layer'] = cur_layer if self.params['hydrometer_layer'] == uri_table: self.layers['hydrometer_layer'] = cur_layer if self.params['hydrometer_urban_propierties_layer'] == uri_table: self.layers['hydrometer_urban_propierties_layer'] = cur_layer if self.params['network_layer_arc'] == uri_table: self.layers['network_layer_arc'] = cur_layer if self.params['network_layer_connec'] == uri_table: self.layers['network_layer_connec'] = cur_layer if self.params['network_layer_element'] == uri_table: self.layers['network_layer_element'] = cur_layer if self.params['network_layer_gully'] == uri_table: self.layers['network_layer_gully'] = cur_layer if self.params['network_layer_node'] == uri_table: self.layers['network_layer_node'] = cur_layer def populate_dialog(self): """ Populate the interface with values get from layers """ if not self.enabled: return False # Get layers and full extent self.get_layers() # Tab 'WorkCat' self.dlg.workcat_items_list.setVisible(False) status = self.workcat_populate(self.dlg.workcat_id) if not status: self.dlg.tab_main.removeTab(3) # Tab 'Address' status = self.address_populate(self.dlg.address_exploitation, 'expl_layer', 'expl_field_code', 'expl_field_name') if not status: self.dlg.tab_main.removeTab(2) else: # Get project variable 'expl_id' expl_id = QgsExpressionContextUtils.projectScope().variable(str(self.street_field_expl[0])) if expl_id is not None: self.controller.log_info(expl_id) # Set SQL to get 'expl_name' sql = "SELECT " + self.params['expl_field_name'] + " FROM " + self.controller.schema_name + "." + self.params['expl_layer'] sql += " WHERE " + self.params['expl_field_code'] + " = " + str(expl_id) row = self.controller.get_row(sql) if row: utils_giswater.setSelectedItem(self.dlg.address_exploitation, row[0]) # Tab 'Hydrometer' self.populate_combo('hydrometer_urban_propierties_layer', self.dlg.hydrometer_connec, self.params['hydrometer_field_urban_propierties_code']) status = self.populate_combo('hydrometer_layer', self.dlg.hydrometer_id, self.params['hydrometer_field_urban_propierties_code'], self.params['hydrometer_field_code']) if not status: self.dlg.tab_main.removeTab(1) # Tab 'Network' self.network_code_create_lists() status = self.network_geom_type_populate() if not status: self.dlg.tab_main.removeTab(0) return True def network_code_create_lists(self): """ Create one list for each geom type and other one with all geom types """ self.list_arc = [] self.list_connec = [] self.list_element = [] self.list_gully = [] self.list_node = [] self.list_all = [] # Check which layers are available and get its list of codes if 'network_layer_arc' in self.layers: self.list_arc = self.network_code_layer('network_layer_arc') if 'network_layer_connec' in self.layers: self.list_connec = self.network_code_layer('network_layer_connec') if 'network_layer_element' in self.layers: self.list_element = self.network_code_layer('network_layer_element') if 'network_layer_gully' in self.layers: self.list_gully = self.network_code_layer('network_layer_gully') if 'network_layer_node' in self.layers: self.list_node = self.network_code_layer('network_layer_node') try: self.list_all = self.list_arc + self.list_connec + self.list_element + self.list_gully + self.list_node self.list_all = sorted(set(self.list_all)) self.set_model_by_list(self.list_all, self.dlg.network_code) except: pass return True def network_code_layer(self, layername): """ Get codes of selected layer and add them to the combo 'network_code' """ viewname = self.params[layername] feature_type = viewname.split("_") if len(feature_type) < 3: return field_id = str(feature_type[2]).lower() field_type = "" if self.project_type == 'ws': if str(feature_type[2]) == "arc": feature_type[2] = "cat_arc" field_type = feature_type[2] + "type_id" elif self.project_type == 'ud': field_type = feature_type[2] + "_type" sql = ("SELECT DISTINCT(" + str(field_id) + "_id), " + str(field_type) + "" " FROM " + self.controller.schema_name + "." + viewname + "" " WHERE " + str(field_id) + "_id IS NOT NULL" " ORDER BY " + str(field_id) + "_id") rows = self.controller.get_rows(sql) if not rows: return False list_codes = [''] for row in rows: list_codes.append(row[0] + " " + row[1]) return list_codes def network_geom_type_populate(self): """ Populate combo 'network_geom_type' """ # Add null value self.dlg.network_geom_type.clear() self.dlg.network_geom_type.addItem('') # Check which layers are available if 'network_layer_arc' in self.layers: self.dlg.network_geom_type.addItem(self.controller.tr('Arc')) if 'network_layer_connec' in self.layers: self.dlg.network_geom_type.addItem(self.controller.tr('Connec')) if 'network_layer_element' in self.layers: self.dlg.network_geom_type.addItem(self.controller.tr('Element')) if 'network_layer_gully' in self.layers: self.dlg.network_geom_type.addItem(self.controller.tr('Gully')) if 'network_layer_node' in self.layers: self.dlg.network_geom_type.addItem(self.controller.tr('Node')) return self.dlg.network_geom_type > 0 def network_geom_type_changed(self): """ Get 'geom_type' to filter 'code' values """ geom_type = utils_giswater.getWidgetText(self.dlg.network_geom_type) list_codes = [] if geom_type == self.controller.tr('Arc'): list_codes = self.list_arc elif geom_type == self.controller.tr('Connec'): list_codes = self.list_connec elif geom_type == self.controller.tr('Element'): list_codes = self.list_element elif geom_type == self.controller.tr('Gully'): list_codes = self.list_gully elif geom_type == self.controller.tr('Node'): list_codes = self.list_node else: list_codes = self.list_all self.set_model_by_list(list_codes, self.dlg.network_code) return True def set_model_by_list(self, string_list, widget): model = QStringListModel() model.setStringList(string_list) self.proxy_model = QSortFilterProxyModel() self.proxy_model.setSourceModel(model) self.proxy_model.setFilterKeyColumn(0) proxy_model_aux = QSortFilterProxyModel() proxy_model_aux.setSourceModel(model) proxy_model_aux.setFilterKeyColumn(0) widget.setModel(proxy_model_aux) widget.setModelColumn(0) completer = QCompleter() completer.setModel(self.proxy_model) completer.setCompletionColumn(0) completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion) widget.setCompleter(completer) def filter_by_list(self, widget): self.proxy_model.setFilterFixedString(widget.currentText()) def network_zoom(self, network_code, network_geom_type): """ Zoom feature with the code set in 'network_code' of the layer set in 'network_geom_type' """ # Get selected code from combo element = utils_giswater.getWidgetText(network_code) if element == 'null': return # Split element. [0]: feature_id, [1]: cat_feature_id row = element.split(' ', 1) feature_id = str(row[0]) cat_feature_id = str(row[1]) # Get selected layer geom_type = utils_giswater.getWidgetText(network_geom_type).lower() if geom_type == "null": sql = ("SELECT feature_type FROM " + self.controller.schema_name + ".cat_feature" " WHERE id = '" + cat_feature_id + "'") row = self.controller.get_row(sql) if not row: return geom_type = row[0].lower() fieldname = geom_type + "_id" # Check if the expression is valid aux = fieldname + " = '" + feature_id + "'" expr = QgsExpression(aux) if expr.hasParserError(): message = expr.parserErrorString() + ": " + aux self.controller.show_warning(message) return for value in self.feature_cat.itervalues(): if value.type.lower() == geom_type: layer = self.controller.get_layer_by_layername(value.layername) if layer: it = layer.getFeatures(QgsFeatureRequest(expr)) ids = [i.id() for i in it] layer.selectByIds(ids) # If any feature found, zoom it and exit function if layer.selectedFeatureCount() > 0: self.zoom_to_selected_features(layer) return def hydrometer_get_hydrometers(self): """ Populate hydrometers depending on selected connec """ # Get selected connec selected = utils_giswater.getWidgetText(self.dlg.hydrometer_connec) # If any conenc selected, get again all hydrometers if selected == 'null': self.populate_combo('hydrometer_layer', self.dlg.hydrometer_id, self.params['hydrometer_field_urban_propierties_code'], self.params['hydrometer_field_code']) return # Get connec_id elem = self.dlg.hydrometer_connec.itemData(self.dlg.hydrometer_connec.currentIndex()) code = elem[0] # to know the index see the query that populate the combo records = [[-1, '']] # Set filter expression layer = self.layers['hydrometer_layer'] idx_field_code = layer.fieldNameIndex(self.params['hydrometer_field_urban_propierties_code']) idx_field_number = layer.fieldNameIndex(self.params['hydrometer_field_code']) aux = self.params['hydrometer_field_urban_propierties_code'] + " = '" + str(code) + "'" # Check filter and existence of fields expr = QgsExpression(aux) if expr.hasParserError(): message = expr.parserErrorString() + ": " + aux self.controller.show_warning(message) return if idx_field_code == -1: message = "Field '{}' not found in layer '{}'. Open '{}' and check parameter '{}'" \ .format(self.params['hydrometer_field_urban_propierties_code'], layer.name(), self.setting_file, 'hydrometer_field_urban_propierties_code') self.controller.show_warning(message) return if idx_field_number == -1: message = "Field '{}' not found in layer '{}'. Open '{}' and check parameter '{}'" \ .format(self.params['hydrometer_field_code'], layer.name(), self.setting_file, 'hydrometer_field_code') self.controller.show_warning(message) return # Get a featureIterator from an expression: # Get features from the iterator and do something it = layer.getFeatures(QgsFeatureRequest(expr)) for feature in it: attrs = feature.attributes() field_number = attrs[idx_field_number] if not type(field_number) is QPyNullVariant: elem = [code, field_number] records.append(elem) # Fill hydrometers records_sorted = sorted(records, key=operator.itemgetter(1)) self.dlg.hydrometer_id.blockSignals(True) self.dlg.hydrometer_id.clear() hydrometer_list = [] #hydrometer_list.append('') for record in records_sorted: self.dlg.hydrometer_id.addItem(str(record[1]), record) if record[1] != '': hydrometer_list.append(str(record[1])) self.set_model_by_list(hydrometer_list, self.dlg.hydrometer_id) self.hydrometer_zoom(self.params['hydrometer_urban_propierties_field_code'], self.dlg.hydrometer_connec) self.dlg.hydrometer_id.blockSignals(False) def hydrometer_zoom(self, fieldname, combo): """ Zoom to layer set in parameter 'hydrometer_urban_propierties_layer' """ expr = self.generic_zoom(fieldname, combo) if expr is None: return # Build a list of feature id's from the expression and select them try: layer = self.layers['hydrometer_urban_propierties_layer'] except KeyError as e: self.controller.show_warning(str(e)) return False it = layer.getFeatures(QgsFeatureRequest(expr)) ids = [i.id() for i in it] layer.selectByIds(ids) # Zoom to selected feature of the layer self.zoom_to_selected_features(layer) # Toggles 'Show feature count' self.show_feature_count() def address_populate(self, combo, layername, field_code, field_name): """ Populate @combo """ # Check if we have this search option available if layername not in self.layers: return False # Get features layer = self.layers[layername] records = [(-1, '', '')] idx_field_code = layer.fieldNameIndex(self.params[field_code]) idx_field_name = layer.fieldNameIndex(self.params[field_name]) it = layer.getFeatures() if layername == 'street_layer': # Get 'expl_id' field_expl_id = self.street_field_expl[0] elem = self.dlg.address_exploitation.itemData(self.dlg.address_exploitation.currentIndex()) expl_id = elem[0] records = [[-1, '']] # Set filter expression aux = self.street_field_expl[0] + " = '" + str(expl_id) + "'" # Check filter and existence of fields expr = QgsExpression(aux) if expr.hasParserError(): message = expr.parserErrorString() + ": " + aux self.controller.show_warning(message) return it = layer.getFeatures(QgsFeatureRequest(expr)) # Iterate over features for feature in it: geom = feature.geometry() attrs = feature.attributes() value_code = attrs[idx_field_code] value_name = attrs[idx_field_name] if not type(value_code) is QPyNullVariant and geom is not None: elem = [value_code, value_name, geom.exportToWkt()] else: elem = [value_code, value_name, None] records.append(elem) # Fill combo combo.blockSignals(True) combo.clear() records_sorted = sorted(records, key = operator.itemgetter(1)) for record in records_sorted: combo.addItem(str(record[1]), record) combo.blockSignals(False) return True def address_get_numbers(self, combo, field_code, fill_combo=False): """ Populate civic numbers depending on value of selected @combo. Build an expression with @field_code """ # Get selected street selected = utils_giswater.getWidgetText(combo) if selected == 'null': return # Get street code elem = combo.itemData(combo.currentIndex()) code = elem[0] # to know the index see the query that populate the combo records = [[-1, '']] # Set filter expression layer = self.layers['portal_layer'] idx_field_code = layer.fieldNameIndex(field_code) idx_field_number = layer.fieldNameIndex(self.params['portal_field_number']) aux = field_code + " = '" + str(code) + "'" # Check filter and existence of fields expr = QgsExpression(aux) if expr.hasParserError(): message = expr.parserErrorString() + ": " + aux self.controller.show_warning(message) return if idx_field_code == -1: message = "Field '{}' not found in layer '{}'. Open '{}' and check parameter '{}'" \ .format(self.params['portal_field_code'], layer.name(), self.setting_file, 'portal_field_code') self.controller.show_warning(message) return if idx_field_number == -1: message = "Field '{}' not found in layer '{}'. Open '{}' and check parameter '{}'" \ .format(self.params['portal_field_number'], layer.name(), self.setting_file, 'portal_field_number') self.controller.show_warning(message) return self.dlg.address_number.blockSignals(True) self.dlg.address_number.clear() if fill_combo: it = layer.getFeatures(QgsFeatureRequest(expr)) for feature in it: attrs = feature.attributes() field_number = attrs[idx_field_number] if not type(field_number) is QPyNullVariant: elem = [code, field_number] records.append(elem) # Fill numbers combo records_sorted = sorted(records, key=operator.itemgetter(1)) for record in records_sorted: self.dlg.address_number.addItem(str(record[1]), record) self.dlg.address_number.blockSignals(False) # Get a featureIterator from an expression: # Select featureswith the ids obtained it = layer.getFeatures(QgsFeatureRequest(expr)) ids = [i.id() for i in it] layer.selectByIds(ids) # Zoom to selected feature of the layer self.zoom_to_selected_features(layer) def address_zoom_portal(self): """ Show street data on the canvas when selected street and number in street tab """ # Get selected street street = utils_giswater.getWidgetText(self.dlg.address_street) civic = utils_giswater.getWidgetText(self.dlg.address_number) if street == 'null' or civic == 'null': return # Get selected portal elem = self.dlg.address_number.itemData(self.dlg.address_number.currentIndex()) if not elem: # that means that user has edited manually the combo but the element # does not correspond to any combo element message = 'Element {} does not exist'.format(civic) self.controller.show_warning(message) return # select this feature in order to copy to memory layer aux = self.params['portal_field_code'] + " = '" + str(elem[0]) + "' AND " + self.params['portal_field_number'] + " = '" + str(elem[1]) + "'" expr = QgsExpression(aux) if expr.hasParserError(): message = expr.parserErrorString() + ": " + aux self.controller.show_warning(message) return # Get a featureIterator from an expression # Build a list of feature Ids from the previous result # Select featureswith the ids obtained layer = self.layers['portal_layer'] it = self.layers['portal_layer'].getFeatures(QgsFeatureRequest(expr)) ids = [i.id() for i in it] layer.selectByIds(ids) # Zoom to selected feature of the layer self.zoom_to_selected_features(self.layers['portal_layer']) # Toggles 'Show feature count' self.show_feature_count() def generic_zoom(self, fieldname, combo, field_index=0): """ Get selected element from the combo, and returns a feature request expression """ # Get selected element from combo element = utils_giswater.getWidgetText(combo) if element == 'null': return None elem = combo.itemData(combo.currentIndex()) if not elem: # that means that user has edited manually the combo but the element # does not correspond to any combo element message = 'Element {} does not exist'.format(element) self.controller.show_warning(message) return None # Check if the expression is valid aux = fieldname + " = '" + str(elem[field_index]) + "'" expr = QgsExpression(aux) if expr.hasParserError(): message = expr.parserErrorString() + ": " + aux self.controller.show_warning(message) return return expr def populate_combo(self, parameter, combo, fieldname, fieldname_2=None): """ Populate selected combo from features of selected layer """ # Check if we have this search option available if not parameter in self.layers: return False # Fields management layer = self.layers[parameter] records = [] idx_field = layer.fieldNameIndex(fieldname) if idx_field == -1: message = "Field '{}' not found in the layer specified in parameter '{}'".format(fieldname, parameter) self.controller.show_warning(message) return False idx_field_2 = idx_field if fieldname_2 is not None: idx_field_2 = layer.fieldNameIndex(fieldname_2) if idx_field_2 == -1: message = "Field '{}' not found in the layer specified in parameter '{}'".format(fieldname_2, parameter) self.controller.show_warning(message) return False # Iterate over all features to get distinct records list_elements = [] for feature in layer.getFeatures(): attrs = feature.attributes() field = attrs[idx_field] field_2 = attrs[idx_field_2] if not type(field) is QPyNullVariant: if field not in list_elements: elem = [field, field_2] list_elements.append(field) records.append(elem) # Fill combo box combo.blockSignals(True) combo.clear() records_sorted = sorted(records, key=operator.itemgetter(1)) combo.addItem('', '') hydrometer_list = [] hydrometer_list.append('') for i in range(len(records_sorted)): record = records_sorted[i] combo.addItem(str(record[1]), record) if record[1] != '': hydrometer_list.append(record[1]) self.set_model_by_list(hydrometer_list, self.dlg.hydrometer_id) combo.blockSignals(False) return True def show_feature_count(self): """ Toggles 'Show Feature Count' of all the layers in the root path of the TOC """ root = QgsProject.instance().layerTreeRoot() for child in root.children(): if isinstance(child, QgsLayerTreeLayer): child.setCustomProperty("showFeatureCount", True) def zoom_to_selected_features(self, layer): """ Zoom to selected features of the @layer """ if not layer: return self.iface.setActiveLayer(layer) self.iface.actionZoomToSelected().trigger() scale = self.iface.mapCanvas().scale() if int(scale) < int(self.scale_zoom): self.iface.mapCanvas().zoomScale(float(self.scale_zoom)) def unload(self): """ Removes dialog """ if self.dlg: self.dlg.deleteLater() del self.dlg
def check_start_end(self, tol): # set the feature counter to 0 count = 0 # initialises two virtual objects points (start and end point) start_point = self.start_point end_point = self.end_point # uses the qgis python api to access the ESU Graphic Layer esu_layer = self.esu_layer # runs the query number 8 to retrieve all streets from the Database streets_model = QSqlQueryModel() streets_model.setQuery(self.queries[8]) while streets_model.canFetchMore(): streets_model.fetchMore() n_columns = streets_model.columnCount() n_rows = streets_model.rowCount() i = 0 j = 0 # first loop start (for each street): start_end_content = [] while i <= n_rows - 1: self.progress_win.setLabelText("Checking start-end Coordinates...") # initialises the state of the checks booleans both to false start_ok = False end_ok = False col_info = [] while j <= n_columns - 1: model_index = streets_model.createIndex(i, j) if j == 0: data = model_index.data() col_info.append(data) if j == 1: data = model_index.data() col_info.append(data) if j == 2: data = model_index.data() col_info.append(data) if j >= 3: data = model_index.data() col_info.append(data) j += 1 usrn = col_info[0] ref_type = col_info[2] desc = col_info[1] start_point.set(float(col_info[3]), float(col_info[4])) end_point.set(float(col_info[5]), float(col_info[6])) # filter the layer "ESU Graphic" for the ESUs Ids returned from the list # deal just with the arcs part of multi arcs street esus_list = self.get_linked_esu_list(usrn) feat_filter = self.build_layer_filter(esus_list) feat_request = QgsFeatureRequest() feat_request.setFilterExpression(feat_filter) # second loop starts (for each arc (ESU) composing the street) # iterate through all filtered features and their proximity with the start and end of the street features = self.esu_layer.getFeatures(feat_request) features.rewind() # iterates through features for feat in features: # check start end points for each of the only if none of the start end points of # a ESU on each street is not already matched if (start_ok is not True) or (end_ok is not True): result = self.start_end_proximity(start_point, end_point, feat, tol) # both dist are ok if result == 3: start_ok = True end_ok = True # just end dist is ok elif result == 2: end_ok = True # just start dist is ok elif result == 1: start_ok = True else: break # in case of problems if not start_ok or not end_ok: count += 1 start_end_item = [str(col_info[0]) + ","] # handles the creation of the report on a text file if not start_ok and not end_ok: start_end_item.append("(both),") if not start_ok and end_ok: start_end_item.append("(start),") if start_ok and not end_ok: start_end_item.append("(end),") start_end_item.append(str(ref_type) + ",") start_end_item.append(str(desc) + "\n") start_end_content.append(start_end_item) j = 0 i += 1 if count == 0: self.progress_win.setValue(7) return else: start_end_content.insert(0, self.column_names[5]) self.progress_win.setValue(7) return self.content_to_screen(content_list=start_end_content, query_model=None, columns_name_id=None, no_content_id=8)
from PyQt4.QtSql import QSqlQueryModel, QSqlDatabase, QSqlQuery from PyQt4.QtGui import QTableView, QApplication import sys app = QApplication(sys.argv) db = QSqlDatabase.addDatabase("QSQLITE") db.setDatabaseName("Photogeniks.db") db.open() projectModel = QSqlQueryModel() projectModel.setQuery("SELECT * from Student", db) projectView = QTableView() projectView.setModel(projectModel) projectView.show() app.exec_()
from PyQt4.QtSql import QSqlQueryModel,QSqlDatabase from PyQt4.QtGui import QApplication,QListView,QTableView import sys app = QApplication(sys.argv) db = QSqlDatabase.addDatabase("QMYSQL") db.setHostName("localhost") db.setDatabaseName("app") db.setUserName("root") db.setPassword("") db.open() projectModel = QSqlQueryModel() projectModel.setQuery("select name from customers",db) projectView = QTableView() projectView.setModel(projectModel) projectView.show() model = projectView.model() indexes = projectView.selectionModel().currentIndex().row() app.exec_()
except Exception, e: import traceback QMessageBox.critical( None, "Error", u"<h2>%s</h2></pre>%s</pre>" % (type(e), traceback.format_exc())) sys.exit() query = QSqlQuery(''' SELECT CONCAT(UC.nombre_uc, '(' ,UC.id_UC,')'), UC.id FROM UC WHERE UC.co_id = %(co_id)d ''' % {'co_id': 1}) print "Error?", query.lastError().databaseText() model = QSqlQueryModel() model.setQuery(query) combo_box = QComboBoxModelQuery() combo_box.setMinimumWidth(400) def prueba(index): print "-------------------------------------------------------------" print index print "El id es", combo_box.get_col_value(0),\ combo_box.get_col_value() print "Conexion", combo_box.connect(combo_box, SIGNAL('currentIndexChanged(int)'), prueba) combo_box.setWindowTitle("Texto") combo_box.setModel(model)
class DlgSelectInvoice( QDialog ): def __init__( self, parent = None ): super( DlgSelectInvoice, self ).__init__( parent ) self.billsmodel = QSqlQueryModel() query = """ SELECT * FROM ( SELECT factura.iddocumento, CONCAT_WS(' ', tdc.descripcion, factura.ndocimpreso) AS 'Numero de Factura', factura.fechacreacion AS 'Fecha', p.nombre AS 'Cliente', -SUM(axd.unidades) - IFNULL(( SELECT SUM(axddev.unidades) FROM documentos devoluciones JOIN docpadrehijos dpddev ON devoluciones.iddocumento = dpddev.idhijo JOIN articulosxdocumento axddev ON axddev.iddocumento = devoluciones.iddocumento WHERE devoluciones.idtipodoc = %d AND dpddev.idpadre = factura.iddocumento GROUP BY dpddev.idpadre ),0) as unittotal, p.idpersona, ca.valorcosto, ca.idcostoagregado, tc.tasa, tc.idtc, b.nombrebodega AS 'Bodega', b.idbodega FROM documentos factura JOIN bodegas b ON factura.idbodega = b.idbodega JOIN tiposdoc tdc ON tdc.idtipodoc = factura.idtipodoc JOIN articulosxdocumento axd ON axd.iddocumento = factura.iddocumento AND factura.idtipodoc = %d JOIN tiposcambio tc ON tc.idtc = factura.idtipocambio JOIN personasxdocumento pxd ON pxd.iddocumento = factura.iddocumento JOIN personas p ON pxd.idpersona = p.idpersona AND p.tipopersona=%d LEFT JOIN costosxdocumento cxd ON cxd.iddocumento = factura.iddocumento LEFT JOIN costosagregados ca ON cxd.idcostoagregado = ca.idcostoagregado JOIN ( SELECT dpdk.idpadre FROM documentos kardex JOIN docpadrehijos dpdk ON kardex.iddocumento = dpdk.idhijo WHERE kardex.idtipodoc = %d ) as kardex ON kardex.idpadre = factura.iddocumento GROUP BY factura.iddocumento ) as tbl WHERE unittotal > 0 """ % ( constantes.IDNC, constantes.IDFACTURA, constantes.CLIENTE, constantes.IDKARDEX ) self.billsmodel.setQuery( query ) self.setWindowTitle( "Seleccione la factura para la devolucion" ) self.filtermodel = QSortFilterProxyModel() self.filtermodel.setSourceModel( self.billsmodel ) self.filtermodel.setFilterCaseSensitivity( Qt.CaseInsensitive ) self.filtermodel.setFilterKeyColumn( -1 ) iddoc, _ndocimpreso, _fechacreacion, _nombre, total, idpersona, valorcosto, idcosto, tasacambio, idcambio, _nombrebodega, idbodega = range( 12 ) self.tblBills = QTableView() self.tblBills.setSelectionMode( QAbstractItemView.SingleSelection ) self.tblBills.setSelectionBehavior( QAbstractItemView.SelectRows ) self.tblBills.selectRow( 0 ) self.tblBills.setModel( self.filtermodel ) self.tblBills.setColumnHidden( iddoc, True ) self.tblBills.setColumnHidden( idpersona, True ) self.tblBills.setColumnHidden( total, True ) self.tblBills.setColumnHidden( valorcosto, True ) self.tblBills.setColumnHidden( idcosto, True ) self.tblBills.setColumnHidden( idcambio, True ) self.tblBills.setColumnHidden( tasacambio, True ) self.tblBills.setColumnHidden( idbodega, True ) self.tblBills.horizontalHeader().setStretchLastSection( True ) self.tblBills.resizeColumnsToContents() buttonbox = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel ) self.txtSearch = QLineEdit() formlayout = QFormLayout() formlayout.addRow( "&Buscar", self.txtSearch ) layout = QVBoxLayout() layout.addWidget( self.tblBills ) layout.addLayout( formlayout ) layout.addWidget( buttonbox ) self.setLayout( layout ) self.setMinimumWidth( 400 ) buttonbox.accepted.connect( self.accept ) buttonbox.rejected.connect( self.reject ) self.txtSearch.textChanged[unicode].connect( self.updateFilter ) #FIXME: Que pasa cuando no hay facturas? # def exec_( self ): # if self.billsmodel.rowCount() == 0: # QMessageBox.critical( None, # self.trUtf8( "Llantera Esquipulas: Inventario" ), # self.trUtf8( """No hay facturas a las cuales hacer devoluciones""" ), # QMessageBox.StandardButtons( \ # QMessageBox.Ok ) ) # self.reject() # else: # QDialog.exec_( self ) def updateFilter( self, str ): self.filtermodel.setFilterWildcard( str )
class SearchPanelDelegate( QStyledItemDelegate ): def __init__( self, query, showTable = False ): QStyledItemDelegate.__init__( self ) self.accounts = QSqlQueryModel() self.accounts.setQuery( query ) self.proxymodel = QSortFilterProxyModel() self.proxymodel.setFilterKeyColumn( 0 ) self.proxymodel.setSourceModel( self.accounts ) self.showTable = showTable self.filtrados = [] def createEditor( self, parent, _option, index ): if index.column() in ( CODCUENTA, NCUENTA ): value = index.model().index( index.row(), 0 ).data().toString() self.removeFromFilter( value ) self.proxymodel.setFilterRegExp( self.filter() ) sp = SearchPanel( self.proxymodel, parent, self.showTable ) sp.setColumn( index.column() ) return sp elif index.column() == MONTO: doublespinbox = QDoubleSpinBox( parent ) doublespinbox.setMinimum( -1000000 ) doublespinbox.setMaximum( 1000000 ) doublespinbox.setDecimals( 4 ) return doublespinbox def removeFromFilter( self, value ): try: self.filtrados.remove( value ) return True except: return False def filter( self ): filtro = "|^".join( self.filtrados ) if filtro != "": filtro = "[^" + filtro + "]" return filtro def setEditorData( self, editor, index ): data = index.data() if index.column() in ( CODCUENTA, NCUENTA ): i = editor.findText( data if type( data ) != QVariant else data.toString() ) if i == -1: i = 0 editor.setCurrentIndex( i ) elif index.column() == MONTO: editor.setValue( index.model().data( index, Qt.EditRole ) if index.model().data( index, Qt.EditRole ) != "" else 0 ) else: QStyledItemDelegate.setEditorData( self, editor, index ) def setModelData( self, editor, model, index ): if index.column() in ( NCUENTA, CODCUENTA ): if self.proxymodel.rowCount() > 0: fila = editor.currentIndex() modelo = self.proxymodel model.setData( index, [ modelo.index( fila , 0 ).data(), modelo.index( fila, 1 ).data(), modelo.index( fila, 2 ).data() ] ) self.filtrados.append( modelo.index( fila , 0 ).data().toString() ) self.proxymodel.setFilterRegExp( self.filter() ) else: QStyledItemDelegate.setModelData( self, editor, model, index ) def sizeHint( self, option, index ): u""" El tamaño sugerido de los datos en el modelo """ fm = option.fontMetrics if index.column() == CODCUENTA: return QSize( 130, fm.height() ) if index.column() == NCUENTA: return QSize( 250, fm.height() ) if index.column() == MONTO: return QSize( 80, fm.height() ) return QStyledItemDelegate.sizeHint( self, option, index )
def results_to_txt_row(self, vals, sql, mode): query_model = QSqlQueryModel() query_model.setQuery(sql) model_index = QModelIndex() row_count = query_model.rowCount(model_index) if row_count < 1: self.file.write(self.no_content) else: query = QSqlQuery(self.db) query.exec_(sql) rec = query.record() if mode == "streets": avals = [ rec.indexOf(vals[0]), rec.indexOf(vals[1]), rec.indexOf(vals[2]), rec.indexOf(vals[3]), rec.indexOf(vals[4]), rec.indexOf(vals[5]), rec.indexOf(vals[6]), rec.indexOf(vals[7]), rec.indexOf(vals[8]), rec.indexOf(vals[9]), rec.indexOf(vals[10]), rec.indexOf(vals[11]) ] n = 0 # write content headers = self.headers[0] while n <= len(headers) - 1: if n == len(headers) - 1: self.file.write(str(headers[n]) + "\n") else: self.file.write(str(headers[n]) + " ") n += 1 while query.next(): line = [ query.value(avals[0]), query.value(avals[1]), query.value(avals[2]), query.value(avals[3]), query.value(avals[4]), query.value(avals[5]), query.value(avals[6]), query.value(avals[7]), query.value(avals[8]), query.value(avals[9]), query.value(avals[10]), query.value(avals[11]) ] self.file.write( str(line[0]) + " , " + str(line[1]) + " , " + str(line[2]) + " , " + str(line[3]) + " , " + str(line[4]) + " , " + str(line[5]) + " , " + self.format_dates(str(line[6])) + " , " + self.format_dates(str(line[7])) + " , " + self.format_dates(str(line[8])) + " , " + self.format_dates(str(line[9])) + " , " + str(line[10]) + " " + str(line[11]) + "\n") else: avals = [ rec.indexOf(vals[0]), rec.indexOf(vals[1]), rec.indexOf(vals[2]), rec.indexOf(vals[3]), rec.indexOf(vals[4]), rec.indexOf(vals[5]), rec.indexOf(vals[6]), rec.indexOf(vals[7]) ] m = 0 headers = self.headers[1] while m <= len(headers) - 1: if m == len(headers) - 1: self.file.write(str(headers[m]) + "\n") else: self.file.write(str(headers[m]) + " ") m += 1 while query.next(): line = [ query.value(avals[0]), query.value(avals[1]), query.value(avals[2]), query.value(avals[3]), query.value(avals[4]), query.value(avals[5]), query.value(avals[6]), query.value(avals[7]) ] self.file.write( str(line[0]) + " , " + str(line[1]) + " , " + str(line[2]) + " , " + str(line[3]) + " , " + str(line[4]) + " , " + str(line[5]) + " , " + str(line[6]) + " , " + str(line[7]) + "\n")
class dlgPersona( QDialog, Ui_dlgPersona ): def __init__( self ,tipopersona, parent ): ''' Constructor ''' super( dlgPersona, self ).__init__( parent ) self.setupUi(self) # self.tableview.addActions( ( self.actionEdit, self.actionNew ) ) self.idtipopersona = tipopersona self.table = "" self.backmodel = QSqlQueryModel() self.database = parent.database self.filtermodel = QSortFilterProxyModel( self ) self.filtermodel.setSourceModel( self.backmodel ) self.filtermodel.setDynamicSortFilter( True ) self.filtermodel.setFilterKeyColumn( -1 ) self.filtermodel.setFilterCaseSensitivity( Qt.CaseInsensitive ) self.paisesModel = QSqlQueryModel() self.cbpais.setModel( self.paisesModel ) self.cbpais.setCurrentIndex( -1 ) self.cbpais.setFocus() self.cbpais.setModelColumn( 1 ) self.paisescompleter = QCompleter() self.paisescompleter.setCaseSensitivity( Qt.CaseInsensitive ) self.paisescompleter.setModel( self.paisesModel ) self.paisescompleter.setCompletionColumn( 1 ) self.cbpais.setCompleter( self.paisescompleter ) self.proveedoresModel = QSqlQueryModel() self.cbproveedor.setModel( self.proveedoresModel ) self.cbproveedor.setCurrentIndex( -1 ) self.cbproveedor.setFocus() self.cbproveedor.setModelColumn( 1 ) self.proveedorcompleter = QCompleter() self.proveedorcompleter.setCaseSensitivity( Qt.CaseInsensitive ) self.proveedorcompleter.setModel( self.proveedoresModel ) self.proveedorcompleter.setCompletionColumn( 1 ) self.cbproveedor.setCompleter( self.proveedorcompleter ) # self.tableview.setModel(self.filtermodel) self.cbsexo.setCurrentIndex(-1) self.txtnombre.setFocus() self.setReadOnly(True) QTimer.singleShot( 0, self.updateModels ) @pyqtSlot( "QString" ) def on_txtSearch_textChanged( self, text ): """ Cambiar el filtro de busqueda """ self.filtermodel.setFilterRegExp( text ) def setReadOnly(self,status): self.txtSearch.setText("") self.txtnombre.setText("") self.txtempresa.setText("") self.txttelefono.setText("") self.txtcorreo.setText("") self.cbpais.setCurrentIndex(-1) self.txtnombre.setFocus() if status: self.editmodel = None self.swpanel.setCurrentIndex(0) else: self.editmodel = PersonaModel(self.database,self.idtipopersona) self.swpanel.setCurrentIndex(1) # # if status: # self.tableview.setEditTriggers( QAbstractItemView.AllEditTriggers ) ## self.tableview.edit( self.tableview.selectionModel().currentIndex() ) # else: # self.tableview.setEditTriggers( QAbstractItemView.NoEditTriggers ) # # self.actionNew.setVisible( status ) # self.actionEdit.setVisible( status ) # self.actionDelete.setVisible( status ) # self.actionCancel.setVisible( not status ) # self.actionSave.setVisible(not status ) # self.backmodel.readOnly = status def updateModels( self ): """ Actualizar los modelos, despues de toda operacion que cambie la base de datos se tienen que actualizar los modelos """ try: if not self.database.isOpen(): if not self.database.open(): raise UserWarning( u"No se pudo conectar con la base de datos" ) self.backmodel.setQuery(""" SELECT d.idpersona as Id, d.Nombre, d.Telefono, d.Correo, p.nombre as Pais FROM personas d JOIN paises p ON p.idpais = d.idpais WHERE idaccion = %d""" %self.idtipopersona ) self.tableview.setModel( self.filtermodel ) self.tableview.setColumnHidden(0,True) # self.tableview.setColumnWidth(0,200) # self.tableview.set self.paisesModel.setQuery( """ SELECT idpais , nombre FROM paises """ ) if self.paisesModel.rowCount() == 0: raise UserWarning( "No existen paises en la"\ + " base de datos" ) self.cbpais.setModel( self.paisesModel ) self.cbpais.setCurrentIndex( -1 ) self.cbpais.setModelColumn( 1 ) self.paisescompleter.setCaseSensitivity( Qt.CaseInsensitive ) self.paisescompleter.setModel( self.paisesModel ) self.paisescompleter.setCompletionColumn( 1 ) self.cbpais.setCompleter( self.paisescompleter ) self.proveedoresModel.setQuery( """ SELECT idproveedor, nombre FROM proveedores p where p.idproveedor not in (select origen from proveedores where origen is not null);""" ) if self.proveedoresModel.rowCount() == 0: raise UserWarning( "No existen proveedores en la"\ + " base de datos" ) self.cbproveedor.setModel( self.proveedoresModel ) self.cbproveedor.setCurrentIndex( -1 ) self.cbproveedor.setFocus() self.cbproveedor.setModelColumn( 1 ) self.proveedorcompleter.setCaseSensitivity( Qt.CaseInsensitive ) self.proveedorcompleter.setModel( self.proveedoresModel ) self.proveedorcompleter.setCompletionColumn( 1 ) self.cbproveedor.setCompleter( self.proveedorcompleter ) self.cbproveedor.setModel( self.proveedoresModel ) self.cbproveedor.setCurrentIndex(-1) self.database.close() except Exception as inst: print( unicode( inst ) ) return False finally: if self.database.isOpen(): self.database.close() return True @pyqtSlot() def on_btnadd_clicked(self): self.setReadOnly(False) @pyqtSlot() def on_btnagregar_pais_clicked(self): paisdialog = DlgPais(self) paisdialog.exec_() self.updateModels() @pyqtSlot() def on_btncancelar_clicked(self): self.setReadOnly(True) @pyqtSlot( int ) def on_cbproveedor_currentIndexChanged( self, index ): """ asignar la concepto al objeto self.editmodel """ if self.editmodel is not None: self.editmodel.idproveedor = self.proveedoresModel.record( index ).value( "idproveedor" ).toInt()[0] @pyqtSlot( int ) def on_cbpais_currentIndexChanged( self, index ): """ asignar la concepto al objeto self.editmodel """ if self.editmodel is not None: self.editmodel.idpais = self.paisesModel.record( index ).value( "idpais" ).toInt()[0] @pyqtSlot() def on_btnguardar_clicked(self): self.editmodel.nombre = self.txtnombre.text() self.editmodel.telefono = self.txttelefono.text() self.editmodel.correo = self.txtcorreo.text() self.editmodel.empresa = self.txtempresa.text() self.editmodel.eshombre = self.cbsexo.currentIndex() self.editmodel.descuento = self.txtdescuento.value() if self.editmodel.valid(): if self.editmodel.save(): QMessageBox.information(None,"Guardar", self.editmodel.mensaje) self.setReadOnly(True) self.updateModels() else: QMessageBox.critical(None,"Guardar", self.editmodel.mensaje) else: QMessageBox.critical(None,"Guardar", self.editmodel.mensaje) @pyqtSlot( int ) def on_cbproveedor_currentIndexChanged( self, index ): """ asignar la concepto al objeto self.editmodel """ if self.editmodel is not None: self.editmodel.idproveedor = self.proveedoresModel.record( index ).value( "idproveedor" ).toInt()[0]
class FrmPago( Ui_frmPago, Base ): """ Implementacion de la interfaz grafica para entrada compra """ web = "recibos.php?doc=" def __init__( self , sesion, parent ): ''' Constructor @param sesion: Los datos de la sesión actual de caja @param parent: La ventana padre del formulario @type sesion: DatosSesion ''' super( FrmPago, self ).__init__( parent, True ) self.setWindowModality( Qt.WindowModal ) self.setWindowFlags( Qt.Dialog ) self.sesion = sesion self.tabledetails = None self.editmodel = None self.groupcuentas.setVisible( False ) self.actionSave.setVisible( False ) self.actionCancel.setVisible( False ) #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # El modelo principal self.navmodel = QSqlQueryModel( 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 con los detalles self.detailsmodel = QSqlQueryModel( self ) # Este es el filtro del modelo anterior self.detailsproxymodel = QSortFilterProxyModel( self ) self.sbtotalc.setValue( 0 ) self.sbtotald.setValue( 0 ) self.conceptosModel = QSqlQueryModel() QTimer.singleShot( 0, self.loadModels ) def cancel( self ): """ Aca se cancela la edicion del documento """ self.status = True def newDocument( self ): """ activar todos los controles, llenar los modelos necesarios, crear el modelo Pago, aniadir una linea a la tabla """ 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" ) query = QSqlQuery() try: # Rellenar el combobox de las CONCEPTOS self.conceptosModel.setQuery( """ SELECT idconcepto, descripcion FROM conceptos c WHERE idtipodoc = %d; """ % constantes.IDPAGO ) if self.conceptosModel.rowCount() == 0: raise UserWarning( u"No existen conceptos en la base de "\ + "datos para los pagos" ) self.beneficiariosModel = QSqlQueryModel() self.beneficiariosModel.setQuery( """ SELECT s.idpersona, s.nombre FROM personas s WHERE s.tipopersona <> %d ORDER BY s.nombre """ % constantes.AUTOR ) if self.beneficiariosModel.rowCount() == 0: raise UserWarning( u"No existen personas en la base de datos" ) # Rellenar el combobox de las retenciones self.retencionModel = QSqlQueryModel() self.retencionModel.setQuery( """ SELECT idcostoagregado, FORMAT(valorcosto,0) as tasa FROM costosagregados WHERE idtipocosto IN (%d,%d) AND activo=1 ORDER BY valorcosto desc; """ % ( constantes.RETENCIONPROFESIONALES, constantes.RETENCIONFUENTE ) ) if self.retencionModel.rowCount() == 0: raise UserWarning( u"No existe ninguna tasa de retención en "\ + "la base de datos" ) query = QSqlQuery( """ SELECT SUM(IF(m.idtipomoneda = %d,m.monto,0)) as totalC, SUM(IF(m.idtipomoneda = %d,m.monto,0)) as totalD FROM movimientoscaja m JOIN documentos d ON d.iddocumento = m.iddocumento WHERE d.idcaja = %d AND m.idtipomovimiento=%d ; """ % ( constantes.IDCORDOBAS, constantes.IDDOLARES, self.sesion.cajaId, constantes.IDPAGOEFECTIVO ) ) if not query.exec_(): raise UserWarning( u"No pudo obtenerse de la base de datos la cantidad de dinero en caja" ) query.first() maxCordoba = Decimal( query.value( 0 ).toString() ) maxDolar = Decimal( query.value( 1 ).toString() ) if maxCordoba <= 0 and maxDolar <= 0: raise UserWarning( u"No hay Efectivo en Caja" ) query = QSqlQuery( "SELECT fnCONSECUTIVO(%d,null);" % constantes.IDPAGO ) if not query.exec_(): raise UserWarning( u"No pudo obtenerse el número del comprobante" ) query.first() ndoc = query.value( 0 ).toString() self.lblnpago.setText( ndoc ) self.txttipocambio.setText( moneyfmt( self.sesion.tipoCambioBanco, 4 ) ) self.cbtasaret.setModel( self.retencionModel ) self.cbtasaret.setModelColumn( 1 ) self.cbtasaret.setCurrentIndex( -1 ) self.retencionId = 0 self.cbbeneficiario.setModel( self.beneficiariosModel ) self.cbbeneficiario.setCurrentIndex( -1 ) self.cbbeneficiario.setModelColumn( 1 ) completer = QCompleter() completer.setCaseSensitivity( Qt.CaseInsensitive ) completer.setModel( self.beneficiariosModel ) completer.setCompletionColumn( 1 ) self.cbconcepto.setModel( self.conceptosModel ) self.cbconcepto.setCurrentIndex( -1 ) self.cbconcepto.setModelColumn( 1 ) completerconcepto = QCompleter() completerconcepto.setCaseSensitivity( Qt.CaseInsensitive ) completerconcepto.setModel( self.conceptosModel ) completerconcepto.setCompletionColumn( 1 ) self.editmodel = PagoModel( self.sesion ) self.editmodel.docImpreso = ndoc self.editmodel.maxCordoba = maxCordoba self.editmodel.maxDolar = maxDolar self.sbtotalc.setToolTip( "Max= " + moneyfmt( maxCordoba, 4, 'C$' ) ) self.sbtotald.setToolTip( "Max= " + moneyfmt( maxDolar, 4, 'US$' ) ) self.sbtotalc.setMaximum( maxCordoba ) self.sbtotald.setMaximum( maxDolar ) query = QSqlQuery( """ SELECT idcostoagregado, valorcosto FROM costosagregados c WHERE idtipocosto = %d AND activo = 1; """ % constantes.IVA ) if not query.exec_(): raise UserWarning( u"No pudo obtenerse la tasa de IVA" ) query.first() self.editmodel.ivaId = query.value( 0 ).toInt()[0] self.editmodel.ivaTasa = Decimal( query.value( 1 ).toString() ) self.ckiva.setToolTip( query.value( 1 ).toString() + '%' ) self.status = False except UserWarning as inst: QMessageBox.critical( self, qApp.organizationName(), unicode( inst ) ) logging.error( unicode( inst ) ) logging.error( 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() @property def printIdentifier( self ): return self.navmodel.record( self.mapper.currentIndex() ).value( "iddocumento" ).toString() def save( self ): """ Slot documentation goes here. """ if self.valid: if QMessageBox.question( self, qApp.organizationName(), u"¿Esta seguro que desea guardar el pago?", QMessageBox.Yes | QMessageBox.No ) == QMessageBox.Yes: if not QSqlDatabase.database().isOpen(): QSqlDatabase.database().open() self.editmodel.observaciones = self.txtobservaciones.toPlainText() if self.editmodel.save(): QMessageBox.information( None, self.trUtf8( qApp.organizationName() ), self.trUtf8( u"""El pago se ha guardado con éxito""" ) ) self.editmodel = None self.updateModels() self.navigate( 'last' ) self.status = True else: QMessageBox.critical( None, self.trUtf8( qApp.organizationName() ), self.trUtf8( """Ha ocurrido un error al guardar el pago""" ) ) if QSqlDatabase.database().isOpen(): QSqlDatabase.database().close() @property def valid( self ): mensaje = "Ocurrio un Error al guardar" if self.editmodel.beneficiarioId == 0: mensaje = "Por favor elija el beneficiario" self.cbbeneficiario.setFocus() elif self.editmodel.conceptoId == 0: mensaje = "Por favor elija el concepto del pago" self.cbconcepto.setFocus() elif self.editmodel.totalD == 0 and self.editmodel.totalC == 0: mensaje = "Por favor escriba el monto del pago" if self.editmodel.maxCordoba > 0 : self.sbtotalc.setFocus() else: self.sbtotald.setFocus() else: return True QMessageBox.information( None, "Guardar Pago", mensaje ) return False @pyqtSlot( int ) @if_edit_model def on_cbbeneficiario_currentIndexChanged( self, index ): """ asignar proveedor al objeto self.editmodel """ self.editmodel.beneficiarioId = self.beneficiariosModel.record( index ).value( "idpersona" ).toInt()[0] if index != -1 else - 1 # self.tableabonos.setEnabled( index != -1 ) # self.frbotones.setEnabled( index != -1 ) # self.abonoeditmodel.removeRows( 0, self.tablefacturas, self.abonoeditmodel.rowCount() ) # self.abonoeditmodel.idbeneficiario = self.datosRecibo.beneficiarioId # self.updateFacturasFilter() self.updateLabels() @pyqtSlot( int ) @if_edit_model def on_cbconcepto_currentIndexChanged( self, index ): """ asignar la concepto al objeto self.editmodel """ self.editmodel.conceptoId = self.conceptosModel.record( index ).value( "idconcepto" ).toInt()[0] @pyqtSlot( int ) @if_edit_model def on_cbtasaret_currentIndexChanged( self, index ): """ asignar la retencion al objeto self.editmodel """ self.editmodel.retencionId = self.retencionModel.record( index ).value( "idcostoagregado" ).toInt()[0] value = self.retencionModel.record( index ).value( "tasa" ).toString() self.editmodel.retencionTasa = Decimal( value if value != "" else 0 ) self.updateLabels() # MANEJO EL EVENTO DE SELECCION EN EL RADIOBUTTON @pyqtSlot( bool ) @if_edit_model def on_ckretener_toggled( self, on ): """ """ self.editmodel.aplicarRet = on self.cbtasaret.setEnabled( on ) self.cbtasaret.setCurrentIndex( -1 ) @pyqtSlot( bool ) @if_edit_model def on_ckiva_toggled( self, on ): """ """ self.editmodel.aplicarIva = on self.updateLabels() @pyqtSlot( QDateTime ) def on_dtPicker_dateTimeChanged( self, datetime ): pass @pyqtSlot( float ) @if_edit_model def on_sbtotalc_valueChanged ( self, value ): self.editmodel.totalC = Decimal( str( value ) ) self.updateLabels() @pyqtSlot( float ) @if_edit_model def on_sbtotald_valueChanged ( self, value ): self.editmodel.totalD = Decimal( str( value ) ) self.updateLabels() def setControls( self, status ): """ @param status: false = editando true = navegando """ self.actionPrint.setVisible( status ) self.dtPicker.setReadOnly( True ) # self.ckretener.setEnabled( ( not status ) ) self.txtobservaciones.setReadOnly( 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.ckretener.setEnabled( False ) self.ckiva.setEnabled( not status ) self.sbtotalc.setReadOnly( status ) self.sbtotald.setReadOnly( status ) # self.txtretencion.setReadOnly(status) if status: self.editmodel = None # self.frbotones.setVisible( False ) self.tablenavigation.setModel( self.navproxymodel ) # self.tabledetails.setModel( self.detailsproxymodel ) # self.tableabonos.setModel( self.abonosproxymodel ) # self.tabledetails.setColumnHidden( IDPAGO, True ) # self.tabledetails.setColumnHidden( IDMONEDA, True ) # self.tabledetails.setColumnHidden( IDDOCUMENTOT, True ) # self.swbeneficiario.setCurrentIndex( 1 ) self.swconcepto.setCurrentIndex( 1 ) self.swtasaret.setCurrentIndex( 1 ) # self.tabledetails.setEditTriggers( QAbstractItemView.NoEditTriggers ) # self.tableabonos.setEditTriggers( QAbstractItemView.NoEditTriggers ) else: self.tabWidget.setCurrentIndex( 0 ) self.dtPicker.setDate( self.sesion.fecha ) self.cbbeneficiario.setCurrentIndex( -1 ) self.swbeneficiario.setCurrentIndex( 0 ) self.swconcepto.setCurrentIndex( 0 ) self.swtasaret.setCurrentIndex( 0 ) self.txtobservaciones.setPlainText( "" ) self.sbtotalc.setValue( 0 ) self.sbtotald.setValue( 0 ) self.lbltotal.setText( "US$ 0.0000" ) self.lblretencion.setText( "US$ 0.0000" ) self.lbltotalpago.setText( "US$ 0.0000" ) self.cbbeneficiario.setFocus() self.ckretener.setChecked( False ) # self.tabledetails.setEditTriggers( QAbstractItemView.EditKeyPressed | QAbstractItemView.AnyKeyPressed | QAbstractItemView.DoubleClicked ) # self.tableabonos.setEditTriggers( QAbstractItemView.EditKeyPressed | QAbstractItemView.AnyKeyPressed | QAbstractItemView.DoubleClicked ) # self.tableabonos.setColumnHidden(IDDOCUMENTO,True) # # self.tabledetails.setColumnWidth(DESCRIPCION,250) # self.tabledetails.setColumnWidth(MONTO,150) # self.tabledetails.setColumnWidth(MONTODOLAR,150) # self.tabledetails.setColumnWidth(REFERENCIA,150) # def updateDetailFilter( self, index ): record = self.navmodel.record( index ) self.dtPicker.setDate( QDate.fromString( record.value( "Fecha" ).toString(), "dd/MM/yyyy" ) ) valor = Decimal( record.value( "totalc" ).toString() ) self.sbtotalc.setMaximum( valor ) self.sbtotalc.setValue( valor ) valor = Decimal( record.value( "totald" ).toString() ) self.sbtotald.setMaximum( valor ) self.sbtotald.setValue( valor ) self.tablenavigation.selectRow( self.mapper.currentIndex() ) def updateLabels( self ): """ """ self.ckretener.setEnabled( self.editmodel.tieneRetencion ) retencion = self.editmodel.retencionCordoba self.lblretencion.setText( moneyfmt( retencion / self.sesion.tipoCambioBanco, 4, "US$ " ) ) self.lblretencion.setToolTip( moneyfmt( retencion, 4, "C$ " ) ) self.lbltotal.setText( moneyfmt( self.editmodel.totalDolar, 4, "US$ " ) ) self.lbltotal.setToolTip( moneyfmt( self.editmodel.totalCordoba, 4, "C$ " ) ) total = self.editmodel.totalCordoba - retencion self.lbltotalpago.setText( moneyfmt( total / self.sesion.tipoCambioBanco , 4, "US$ " ) ) self.lbltotalpago.setToolTip( moneyfmt( total, 4, "C$ " ) ) def updateModels( self ): """ Recargar todos los modelos """ try: if not self.database.isOpen(): if not self.database.open(): raise UserWarning( u"No se pudo conectar con la base de datos" ) query = """ SELECT pago.iddocumento, pago.ndocimpreso as 'No. Comprobante', pago.Fecha, pago.nombre as Beneficiario, pago.Concepto, CONCAT('US$',FORMAT(pago.total,4)), IF(SUM(IF(ca.idtipocosto=1,1,0))>0,1,0) as coniva, IF(SUM(IF(ca.idtipocosto in (8,9),1,0))>0,1,0) as conret, SUM(IF(ca.idtipocosto in (8,9),ca.valorcosto,0)) as tasaret, SUM(IF(mc.idtipomoneda =1,-mc.monto,0)) as totalc, SUM(IF(mc.idtipomoneda =2,-mc.monto,0)) as totald, CONCAT('US$',FORMAT(ROUND(pago.total + (pago.total / (1 +SUM(IF(ca.idtipocosto=1,ca.valorcosto/100,0))) ) * SUM(IF(ca.idtipocosto in (8,9),ca.valorcosto/100,0)),4),4)) as total, -- pago.total / (1 +SUM(IF(ca.idtipocosto=1,ca.valorcosto/100,0))) as subtotal, CONCAT('US$',FORMAT(ROUND((pago.total / (1 +SUM(IF(ca.idtipocosto=1,ca.valorcosto/100,0))) ) * SUM(IF(ca.idtipocosto in (8,9),ca.valorcosto/100,0)),4),4)) as retencion, pago.observacion, pago.tasa FROM costosagregados ca JOIN costosxdocumento cxd ON ca.idcostoagregado = cxd.idcostoagregado JOIN movimientoscaja mc ON mc.iddocumento = cxd.iddocumento JOIN ( SELECT d.iddocumento, d.ndocimpreso, GROUP_CONCAT(IF(pxd.idaccion=2,p.nombre,'') SEPARATOR '') as nombre, DATE_FORMAT(d.fechacreacion,'%d/%m/%Y') AS fecha, d.observacion, con.descripcion as concepto, tc.tasa, d.total FROM documentos d JOIN conceptos con ON con.idconcepto = d.idconcepto JOIN personasxdocumento pxd ON pxd.iddocumento = d.iddocumento JOIN personas p ON p.idpersona = pxd.idpersona JOIN tiposcambio tc ON tc.idtc=d.idtipocambio WHERE d.idtipodoc=30 GROUP BY d.iddocumento ) pago on pago.iddocumento = cxd.iddocumento GROUP BY pago.iddocumento ; """ # % ( constantes.IDCORDOBAS, constantes.IDDOLARES, constantes.IVA, constantes.IVA, constantes.RETENCIONFUENTE, constantes.RETENCIONPROFESIONALES, constantes.PROVEEDOR, '%d/%m/%Y', constantes.IDPAGO ) self.navmodel.setQuery( query ) self.navproxymodel = QSortFilterProxyModel( self ) self.navproxymodel.setSourceModel( self.navmodel ) self.navproxymodel.setFilterKeyColumn( -1 ) self.navproxymodel.setFilterCaseSensitivity ( Qt.CaseInsensitive ) # Este es el modelo con los datos de la tabla para navegar #FIXME: Se el simbolo de la moneda deberia de salir desde la tabla tiposmoneda self.detailsmodel.setQuery( """ SELECT p.iddocumento, CONCAT(tp.descripcion, ' ' , tm.moneda) as 'Tipo de Pago', p.refexterna as 'No. Referencia', b.descripcion as Banco, CONCAT(tm.simbolo,' ',FORMAT(monto,4)) as 'Monto', CONCAT('US$ ',FORMAT(monto / IF(p.idtipomoneda=2,1,IFNULL(tc.tasaBanco,tc.tasa)),4)) as 'Monto US$' FROM movimientoscaja p JOIN documentos d ON d.iddocumento=p.iddocumento AND d.idtipodoc=18 JOIN tiposcambio tc ON tc.idtc=d.idtipocambio JOIN tiposmoneda tm ON tm.idtipomoneda=p.idtipomoneda JOIN tiposmovimientocaja tp ON tp.idtipomovimiento=p.idtipomovimiento LEFT JOIN bancos b ON b.idbanco = p.idbanco ORDER BY p.nlinea ; """ ) # Este es el filtro del modelo anterior self.detailsproxymodel = QSortFilterProxyModel( self ) self.detailsproxymodel.setSourceModel( self.detailsmodel ) self.detailsproxymodel.setFilterKeyColumn( IDDOCUMENTO ) self.detailsproxymodel.setFilterRegExp( '^0$' ) # ESTE ES EL MODELO CON LOS DATOS DE Los ABONOS PARA NAVEGAR self.abonosmodel = QSqlQueryModel( self ) self.abonosmodel.setQuery( """ SELECT d.idhijo as idrecibo, padre.ndocimpreso as 'No. Factura', CONCAT('US$ ',FORMAT(d.monto,4)) as 'Saldo' FROM docpadrehijos d JOIN documentos padre ON d.idpadre=padre.iddocumento WHERE padre.idtipodoc=%d and d.monto is not null ORDER BY d.nlinea ; """ % constantes.IDFACTURA ) # Este es el filtro del modelo anterior # self.abonosproxymodel.setSourceModel( self.abonosmodel ) # 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.lblnpago, NDOCIMPRESO , "text" ) # self.mapper.addMapping( self.txtretencion, NRETENCION , "text" ) self.mapper.addMapping( self.txtobservaciones, OBSERVACION ) # self.mapper.addMapping( self.dtPicker, FECHA ) self.mapper.addMapping( self.txtbeneficiario, NOMBREBENEFICIARIO, "text" ) self.mapper.addMapping( self.txtconcepto, CONCEPTO, "text" ) self.mapper.addMapping( self.txttasaret, TASARETENCION, "text" ) self.mapper.addMapping( self.lbltotalpago, TOTALPAGADO, "text" ) self.mapper.addMapping( self.lbltotal, TOTAL, "text" ) self.mapper.addMapping( self.lblretencion, TOTALRETENCION, "text" ) self.mapper.addMapping( self.ckretener, CONRETENCION, "checked" ) self.mapper.addMapping( self.ckiva, CONIVA, "checked" ) # self.mapper.addMapping( self.sbtotalc, TOTALC, "value" ) self.tablenavigation.setColumnHidden( IDDOCUMENTO, True ) self.tablenavigation.setColumnHidden( TOTALRETENCION, True ) self.tablenavigation.setColumnHidden( CONRETENCION, True ) 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 obtener los datos" ) finally: if self.database.isOpen(): self.database.close()
def loadtree(self, geom, epsg, pid, profilename, buffervalue): epsg = self.xuni(epsg) pid = self.xuni(pid) profilename = self.xuni(profilename) # Create profile model if self.parent.dbmeta.isOpen(): # Create model for treeview model = QtGui.QStandardItemModel() model.setHorizontalHeaderLabels(['Identification']) # Find treeview widget from dialog view = self.twResult view.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) view.clicked.connect(self.on_viewClicked) # Set model and looks for treeview view.setModel(model) view.setUniformRowHeights(True) view.setAlternatingRowColors(True) view.header().setStretchLastSection(True) view.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers) # Fetch profile data from database profilemodel = QSqlQueryModel() profilemodel.setQuery( 'select * from "' + self.parent.config['db_schema'] + '"."profiles_layers_view" where pid = ' + str(pid), self.parent.dbmeta) # Create root item profile = QtGui.QStandardItem( tr(u'{} ({} layers)').format(profilename, profilemodel.rowCount())) # Get profile link (if it can be retrieved (no of layers > 0) if profilemodel.rowCount() > 0: profile.setData( u'p|' + self.xuni(profilemodel.record(0).value('profile_link')) + u'|||') else: profile.setData(u'p||||') # Create root item model.appendRow(profile) # rowcounter layers with non-zero conflicts nextRow = 0 # Iterate through layers in selected profile..... for i in range(profilemodel.rowCount()): # Fetch record nr. i r = profilemodel.record(i) # Rowcount default (-1 --> db not open) rc = -1 # Open or reconnect database for layer dbl = self.parent.connectDatabase('c' + str(r.value('cid')), r.value('servertypename'), r.value('host'), r.value('port'), r.value('username'), r.value('password'), r.value('database'), r.value('serverconnection')) if not dbl is None: # Create wkt string for layer query # (it has to be converted for each layer - they might have different projections) wkt = self.parent.cnvobj2wkt(geom, epsg, r.value('epsg')) # Fetch layerdata from database layermodel = QSqlQueryModel() # Generate SQL statement sel1 = r.value('sql_detail').format( r.value('profilename'), r.value('layername'), r.value('compoundid'), r.value('linkid'), r.value('geomid'), r.value('schemaname'), r.value('tablename')) sel2 = r.value('sql_filter').format( wkt, r.value('epsg'), buffervalue, r.value('geomid')) sel = sel1 + u' where ' + sel2 # Execute SQL and create layermodel content layermodel.setQuery(sel, dbl) rc = layermodel.rowCount() # Create stub QStandardItem for layer lName = QtGui.QStandardItem( tr(u'{} ({} overlaps)').format(r.value('layername'), rc)) lName.setData(u'l|' + self.xuni(r.value('layerlink')) + u'|' + self.xuni(r.value('qlr_file')) + u'||') for j in range(rc): # Fetch record nr. j q = layermodel.record(j) # Append data to lName item li = QtGui.QStandardItem(q.value('layerid')) li.setData(u'i|' + self.xuni(q.value('link')) + '|' + self.xuni(r.value('qlr_file')) + '|' + self.xuni(q.value('wkt_geom')) + '|' + self.xuni(r.value('epsg'))) lName.appendRow(li) #Append layerinfo to profile item if rc > 0: lName.setBackground(QtGui.QColor(255, 230, 230)) lName.sortChildren(0) profile.insertRow(nextRow, lName) nextRow = nextRow + 1 elif rc == 0: profile.appendRow(lName) else: pass # db not found view.expandToDepth(0)
model.select() model.setHeaderData(0, QtCore.Qt.Horizontal, "ID") model.setHeaderData(1, QtCore.Qt.Horizontal, "First name") model.setHeaderData(2, QtCore.Qt.Horizontal, "Last name") def createView(title, model): view = QtGui.QTableView() view.setModel(model) view.setWindowTitle(title) return view if __name__ == '__main__': query = QtSql.QSqlQuery() app = QtGui.QApplication(sys.argv) db = QtSql.QSqlDatabase.addDatabase('QSQLITE') db.setDatabaseName('fichadas.db') model = QtSql.QSqlTableModel() delrow = -1 initializeModel(model) projectModel = QSqlQueryModel() projectModel.setQuery("select * from empleados",db) projectView = QTableView() projectView.setModel(projectModel) form = Form() form.show() sys.exit(app.exec_())
class DlgAnular( QDialog ): def __init__( self , numero, parent = None ): super( DlgAnular, self ).__init__( parent ) self.cboConceptos = QComboBox( self ) self.cboConceptos.setObjectName( "cboConceptos" ) self.txtObservaciones = QPlainTextEdit( self ) self.txtObservaciones.setObjectName( "txtObservaciones" ) self.setupUi() #QtCore.QMetaObject.connectSlotsByName(self) self.conceptosmodel = QSqlQueryModel() self.conceptosmodel.setQuery( """ SELECT idconcepto,descripcion FROM conceptos c WHERE idtipodoc = %d ; """ % constantes.IDANULACION ) self.cboConceptos.setModel( self.conceptosmodel ) self.cboConceptos.setCurrentIndex( -1 ) self.cboConceptos.setModelColumn( 1 ) self.numero = numero self.lblnfactura2.setText( str( self.numero ) ) def setupUi( self ): self.setObjectName( "frmAnulaciones" ) self.setWindowTitle( "Seleccione la factura a anular" ) self.resize( 485, 300 ) gridLayout = QGridLayout( self ) gridLayout.setObjectName( "gridLayout" ) lblnfactura = QLabel( self ) lblnfactura.setObjectName( "lblnfactura" ) lblnfactura.setText( "# Factura" ) gridLayout.addWidget( lblnfactura, 0, 0, 1, 1 ) self.lblnfactura2 = QLabel( self ) self.lblnfactura2.setFrameShape( QFrame.Box ) self.lblnfactura2.setText( "" ) self.lblnfactura2.setObjectName( "lblnfactura2" ) gridLayout.addWidget( self.lblnfactura2, 0, 1, 1, 1 ) lblconcepto = QLabel( self ) lblconcepto.setObjectName( "lblconcepto" ) lblconcepto.setText( "Concepto" ) gridLayout.addWidget( lblconcepto, 1, 0, 1, 1 ) gridLayout.addWidget( self.cboConceptos, 1, 1, 1, 1 ) lblobservaciones = QLabel( self ) lblobservaciones.setObjectName( "lblobservaciones" ) lblobservaciones.setText( "Observaciones" ) gridLayout.addWidget( lblobservaciones, 2, 0, 1, 1 ) gridLayout.addWidget( self.txtObservaciones, 3, 1, 1, 1 ) buttonBox = QDialogButtonBox( self ) buttonBox.setOrientation( Qt.Horizontal ) buttonBox.setStandardButtons( QDialogButtonBox.Cancel | QDialogButtonBox.Ok ) buttonBox.setObjectName( "buttonBox" ) gridLayout.addWidget( buttonBox, 4, 0, 1, 2 ) buttonBox.accepted.connect( self.accept ) buttonBox.rejected.connect( self.reject )
class ChooseMTModelDialog(QDialog, Ui_Dialog): """ Class documentation goes here. """ def __init__(self, parent=None, datamodel=None): """ Constructor """ QDialog.__init__(self, parent) self.setupUi(self) self.model = QSqlQueryModel() self.selTableView.setModel(self.model) self.database = datamodel.getQSqlDatabase() self.updateModel() self.selTableView.hideColumn(0) self.selTableView.hideColumn(5) self.selTableView.hideColumn(6) # Change status and keep the column. QObject.connect( datamodel, SIGNAL("modelInstalled()"), self.on_datamodel_modelInstalled) def updateModel(self): self.model.setQuery( 'SELECT ID, name, srclang, trglang, status, path, mosesini ' 'FROM models ' 'WHERE status = "READY" AND deleted != "True"', self.database) def on_datamodel_recordUpdated(self, bRecord): """Deal with the selection changed problem.""" try: if bRecord: current = self.selTableView.currentIndex() if current and current.row() != -1: self.curSelection = current.row() else: self.curSelection = None else: if self.curSelection is not None: self.selTableView.selectRow(self.curSelection) except Exception as e: print >> sys.stderr, str(e) def on_datamodel_modelInstalled(self): self.updateModel() @pyqtSignature("") def on_buttonBox_accepted(self): """ Slot documentation goes here. """ current = self.selTableView.currentIndex() if not current: doAlert("Please choose a model to start.") return record = self.model.record(current.row()) self.ID = record.value("ID").toString() self.modelName = record.value("name").toString() self.srcLang = record.value('srclang').toString() self.trgLang = record.value('trglang').toString() self.path = record.value("path").toString() self.mosesini = record.value("mosesini").toString() self.accept()
class FrmRecibo( Ui_frmRecibo, Base ): """ Implementacion de la interfaz grafica para entrada compra """ web = "recibos.php?doc=" def __init__( self, parent = None ): ''' Constructor ''' super( FrmRecibo, self ).__init__( parent ) # las acciones deberian de estar ocultas self.frbotones.setVisible( False ) self.actionSave.setVisible( False ) self.actionCancel.setVisible( False ) #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # El modelo principal self.navmodel = QSqlQueryModel( self ) # El modelo que filtra a self.navmodel self.navproxymodel = RONavigationModel( self ) self.navproxymodel.setSourceModel( self.navmodel ) #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # Este es el modelo con los datos de la con los detalles self.detailsmodel = QSqlQueryModel( self ) # Este es el filtro del modelo anterior self.detailsproxymodel = QSortFilterProxyModel( self ) #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # Este es el modelo con los datos de la con los detalles self.abonosmodel = QSqlQueryModel( self ) # Este es el filtro del modelo anterior self.abonosproxymodel = QSortFilterProxyModel( self ) self.abonosproxymodel.setSourceModel( self.abonosmodel ) self.facturasmodel = QSqlQueryModel( self ) self.facturasproxymodel = ROFacturasModel( self ) self.facturasproxymodel.setSourceModel( self.facturasmodel ) #inicializando el documento self.editmodel = None self.datosRecibo = None self.status = True QTimer.singleShot( 0, self.loadModels ) def agregarFactura( self, i, n ): # modelo = cindex.model() modelo = self.facturasproxymodel self.abonoeditmodel.insertRows( i ) self.abonoeditmodel.lines[i].idFac = modelo.index( n, 0 ).data() self.abonoeditmodel.lines[i].nFac = modelo.index( n, 1 ).data() monto = Decimal( modelo.data( modelo.index( n, 2 ), Qt.EditRole ).toString() ) self.abonoeditmodel.lines[i].tasaIva = Decimal( modelo.data( modelo.index( n, 3 ), Qt.EditRole ).toString() ) self.abonoeditmodel.lines[i].monto = monto # self.abonoeditmodel.lines[i].setMonto( monto) self.abonoeditmodel.lines[i].nlinea = n self.abonoeditmodel.lines[i].totalFac = monto self.tablefacturas.setRowHidden( n, True ) def cancel( self ): """ Aca se cancela la edicion del documento """ self.status = True @property def printIdentifier( self ): return self.navmodel.record( self.mapper.currentIndex() ).value( "iddocumento" ).toString() def newDocument( self ): """ activar todos los controles, llenar los modelos necesarios, crear el modelo EntradaCompraModel, aniadir una linea a la tabla """ try: 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" ) self.facturasmodel.setQuery( """ SELECT s.iddocumento, s.ndocimpreso, s.Saldo, s.tasaiva, s.idpersona FROM vw_saldofacturas s WHERE s.saldo>0 and s.idestado = %d ; """ % constantes.CONFIRMADO ) self.tablefacturas.setModel( self.facturasproxymodel ) self.tablefacturas.setColumnHidden( IDDOCUMENTO, True ) # self.tablefacturas.setColumnHidden( 3, True ) # Rellenar el combobox de los CLLIENTES self.clientesModel = QSqlQueryModel() self.clientesModel.setQuery( """ SELECT s.idpersona, s.nombre FROM vw_saldofacturas s WHERE s.idestado = %d GROUP BY s.idpersona HAVING SUM(s.saldo)>0 ORDER BY s.nombre """ % constantes.CONFIRMADO ) #Verificar si existen clientes morosos if self.clientesModel.rowCount() == 0: raise UserWarning( "No existen clientes morosos" ) # Rellenar el combobox de las CONCEPTOS self.conceptosModel = QSqlQueryModel() self.conceptosModel.setQuery( """ SELECT idconcepto, descripcion FROM conceptos c WHERE idtipodoc = %d; """ % constantes.IDRECIBO ) if self.conceptosModel.rowCount() == 0: raise UserWarning( "No existen conceptos para los recibos,"\ + " por favor cree uno" ) self.cbcliente.setModel( self.clientesModel ) self.cbcliente.setCurrentIndex( -1 ) self.cbcliente.setModelColumn( 1 ) completer = QCompleter() completer.setCaseSensitivity( Qt.CaseInsensitive ) completer.setModel( self.clientesModel ) completer.setCompletionColumn( 1 ) self.cbconcepto.setModel( self.conceptosModel ) self.cbconcepto.setCurrentIndex( -1 ) self.cbconcepto.setModelColumn( 1 ) completerconcepto = QCompleter() completerconcepto.setCaseSensitivity( Qt.CaseInsensitive ) completerconcepto.setModel( self.conceptosModel ) completerconcepto.setCompletionColumn( 1 ) self.datosRecibo = DatosRecibo( self.parentWindow.datosSesion ) self.editmodel = ReciboModel( self.datosRecibo.lineas, self.datosRecibo.datosSesion.tipoCambioBanco ) self.abonoeditmodel = AbonoModel( self.datosRecibo.lineasAbonos ) self.datosRecibo.cargarRetenciones( self.cbtasaret ) if self.datosRecibo.retencionModel.rowCount() == 0: raise UserWarning( u"No existe ninguna tasa de retención."\ + " Por favor contacte al administrador"\ + " del sistema" ) # Asigno el modelo del recibo self.datosRecibo.cargarNumeros( self ) self.tablefacturas.setSelectionMode( QAbstractItemView.SingleSelection ) self.tablefacturas.setSelectionBehavior( QAbstractItemView.SelectRows ) self.tableabonos.setModel( self.abonoeditmodel ) self.tabledetails.setModel( self.editmodel ) # ASIGNO EL DELEGADO A LA TABLA DE LOS PAGO delegate = ReciboDelegate() self.tabledetails.setItemDelegate( delegate ) # ASIGNO EL DELEGADO A LA TABLA DE LOS ABONOS delegado = AbonoDelegate() self.tableabonos.setItemDelegate( delegado ) self.status = False self.frbotones.setVisible( True ) self.updateFacturasFilter() self.abonoeditmodel.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 tratar de obtener los datos" ) finally: if self.database.isOpen(): self.database.close() def save( self ): """ Slot documentation goes here. """ # self.datosRecibo.lineasAbonos =self.abonoeditmodel.lines # self.datosRecibo.lineas = self.editmodel.lines self.datosRecibo.observaciones = self.txtobservaciones.toPlainText() if self.datosRecibo.valid( self ): if QMessageBox.question( self, qApp.organizationName(), u"¿Esta seguro que desea guardar el recibo?", QMessageBox.Yes | QMessageBox.No ) == QMessageBox.Yes: if not QSqlDatabase.database().isOpen(): QSqlDatabase.database().open() if self.datosRecibo.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""" ) if self.database.isOpen(): self.database.close() @pyqtSlot( bool ) def on_btnadd_clicked( self, _on ): """ Asignar el contenido al objeto documeto """ cindex = self.tablefacturas.currentIndex() if not cindex.model() is None: if not self.tablefacturas.isRowHidden( cindex.row() ): i = self.abonoeditmodel.rowCount() self.agregarFactura( i, cindex.row() ) self.updateLabels() @pyqtSlot( bool ) def on_btnaddall_clicked( self, _on ): """ Asignar el contenido al objeto documeto """ i = self.abonoeditmodel.rowCount() for n in range( self.facturasproxymodel.rowCount() ): if not self.tablefacturas.isRowHidden( n ): self.agregarFactura( i, n ) i = i + 1 self.updateLabels() @pyqtSlot( bool ) def on_btnremove_clicked( self, _on ): """ Asignar el contenido al objeto documeto """ r = self.tableabonos.currentIndex().row() if self.abonoeditmodel.rowCount() > 0 and r > -1: self.abonoeditmodel.removeRows( r, self.tablefacturas ) self.updateLabels() @pyqtSlot( bool ) def on_btnremoveall_clicked( self, _on ): """ Asignar el contenido al objeto documeto """ rows = self.abonoeditmodel.rowCount() if rows > 0: self.abonoeditmodel.removeRows( 0, self.tablefacturas, rows ) self.updateLabels() @pyqtSlot( int ) @if_edit_model def on_cbcliente_currentIndexChanged( self, index ): """ asignar proveedor al objeto self.editmodel """ self.datosRecibo.clienteId = self.clientesModel.record( index ).value( "idpersona" ).toInt()[0] if index != -1 else - 1 self.tableabonos.setEnabled( index != -1 ) self.frbotones.setEnabled( index != -1 ) self.abonoeditmodel.removeRows( 0, self.tablefacturas, self.abonoeditmodel.rowCount() ) self.abonoeditmodel.idcliente = self.datosRecibo.clienteId self.updateFacturasFilter() self.updateLabels() @pyqtSlot( int ) @if_edit_model def on_cbconcepto_currentIndexChanged( self, index ): """ asignar la concepto al objeto self.editmodel """ self.datosRecibo.conceptoId = self.conceptosModel.record( index ).value( "idconcepto" ).toInt()[0] @pyqtSlot( int ) def on_cbtasaret_currentIndexChanged( self, index ): """ asignar la retencion al objeto self.editmodel """ self.datosRecibo.tasaRetencionCambio( self, index ) if self.ckretener.isEnabled(): self.updateLabels() # MANEJO EL EVENTO DE SELECCION EN EL RADIOBUTTON @pyqtSlot( bool ) @if_edit_model def on_ckretener_toggled( self, on ): """ """ self.datosRecibo.aplicarRet = on self.cbtasaret.setEnabled( on ) self.cbtasaret.setCurrentIndex( -1 ) @pyqtSlot( QDateTime ) def on_dtPicker_dateTimeChanged( self, datetime ): pass def removeLine( self ): """ Funcion usada para borrar lineas de la tabla """ index = self.tabledetails.currentIndex() if not index.isValid(): return row = index.row() self.tabledetails.removeRows( row ) self.updateLabels() def setControls( self, status ): """ @param status: false = editando true = navegando """ self.actionPrint.setVisible( status ) self.dtPicker.setReadOnly( True ) # self.ckretener.setEnabled( ( not status ) ) self.txtobservaciones.setReadOnly( 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.ckretener.setEnabled( False ) if status: self.editmodel = None self.frbotones.setVisible( False ) self.tablenavigation.setModel( self.navproxymodel ) self.tabledetails.setModel( self.detailsproxymodel ) self.tableabonos.setModel( self.abonosproxymodel ) self.tabledetails.setColumnHidden( IDPAGO, True ) self.tabledetails.setColumnHidden( IDMONEDA, True ) self.tabledetails.setColumnHidden( IDDOCUMENTOT, True ) self.swcliente.setCurrentIndex( 1 ) self.swconcepto.setCurrentIndex( 1 ) self.swtasaret.setCurrentIndex( 1 ) self.tabledetails.setEditTriggers( QAbstractItemView.NoEditTriggers ) self.tableabonos.setEditTriggers( QAbstractItemView.NoEditTriggers ) else: self.tabWidget.setCurrentIndex( 0 ) self.dtPicker.setDate( self.parentWindow.datosSesion.fecha ) self.swcliente.setCurrentIndex( 0 ) self.swconcepto.setCurrentIndex( 0 ) self.swtasaret.setCurrentIndex( 0 ) self.txtobservaciones.setPlainText( "" ) self.lbltotalreten.setText( "US$ 0.0000" ) self.lbltotal.setText( "US$ 0.0000" ) self.lbltotalrecibo.setText( "US$ 0.0000" ) self.cbcliente.setFocus() self.ckretener.setChecked( False ) self.tabledetails.setEditTriggers( QAbstractItemView.EditKeyPressed | QAbstractItemView.AnyKeyPressed | QAbstractItemView.DoubleClicked ) self.tableabonos.setEditTriggers( QAbstractItemView.EditKeyPressed | QAbstractItemView.AnyKeyPressed | QAbstractItemView.DoubleClicked ) self.cbcliente.setCurrentIndex( -1 ) self.tableabonos.setColumnHidden( IDDOCUMENTO, True ) self.tabledetails.setColumnWidth( DESCRIPCION, 250 ) self.tabledetails.setColumnWidth( MONTO, 150 ) self.tabledetails.setColumnWidth( MONTODOLAR, 150 ) self.tabledetails.setColumnWidth( REFERENCIA, 150 ) def updateDetailFilter( self, index ): self.detailsproxymodel.setFilterKeyColumn( IDDOCUMENTOT ) iddoc = self.navmodel.record( index ).value( "iddocumento" ).toString() self.detailsproxymodel.setFilterRegExp( iddoc ) self.tablenavigation.selectRow( self.mapper.currentIndex() ) # FILTRO DE LOS ABONOS self.abonosproxymodel.setFilterKeyColumn( IDDOCUMENTOT ) self.abonosproxymodel.setFilterRegExp( iddoc ) self.tabledetails.resizeColumnsToContents() def updateFacturasFilter( self ): self.facturasproxymodel.setFilterKeyColumn( IDCLIENTE ) self.facturasproxymodel.setFilterRegExp( "^" + str( self.datosRecibo.clienteId ) + "$" ) def updateLabels( self ): #Asingar el total al modelo totalAbono = self.abonoeditmodel.total retener = self.datosRecibo.retencionValida if self.cbtasaret.currentIndex() > -1 or ( not self.ckretener.isEnabled() ): self.ckretener.setChecked( retener ) self.ckretener.setEnabled( retener ) self.cbtasaret.setEnabled( retener ) ret = self.datosRecibo.obtenerRetencion self.editmodel.asignarTotal( totalAbono - ret ) tasa = self.datosRecibo.datosSesion.tipoCambioBanco self.lbltotal.setText( moneyfmt( totalAbono, 4, "US$ " ) ) self.lbltotal.setToolTip( moneyfmt( totalAbono * tasa, 4, "C$ " ) ) self.lbltotalreten.setText( moneyfmt( ret, 4, "US$ " ) ) self.lbltotalreten.setToolTip( moneyfmt( ret * tasa, 4, "C$ " ) ) self.lbltotalrecibo.setText( moneyfmt( totalAbono - ret, 4, "US$ " ) ) self.lbltotalrecibo.setToolTip( moneyfmt( ( totalAbono - ret ) * tasa, 4, "C$ " ) ) def updateModels( self ): """ Recargar todos los modelos """ try: if not QSqlDatabase.database().isOpen(): QSqlDatabase.database().open() # El modelo principal query = """ SELECT padre.iddocumento, DATE(padre.fechacreacion) as 'Fecha', padre.ndocimpreso as 'No. Recibo', p.nombre as 'Cliente', padre.total + IFNULL(hijo.total,0) as 'Total', c.descripcion as 'En cocepto de', IF(hijo.ndocimpreso IS NULL,'-',hijo.ndocimpreso) as 'No. Retencion', IF(ca.valorcosto IS NULL, '-',CONCAT(CAST(ca.valorcosto AS CHAR),'%s')) as 'Retencion', IFNULL(hijo.total,'-') as 'Total Ret C$', padre.total as 'Total Pagado', padre.observacion , IF(hijo.iddocumento IS NULL, 0,1) as 'Con Retencion', GROUP_CONCAT('(',fac.iddocumento, ')' SEPARATOR '') as idfacturas FROM documentos padre JOIN docpadrehijos phfac ON phfac.idhijo = padre.iddocumento JOIN documentos fac ON phfac.idpadre = fac.iddocumento AND fac.idtipodoc = %d JOIN personasxdocumento pxd ON pxd.iddocumento = padre.iddocumento JOIN personas p ON p.idpersona = pxd.idpersona JOIN conceptos c ON c.idconcepto=padre.idconcepto LEFT JOIN costosxdocumento cd ON cd.iddocumento=padre.iddocumento LEFT JOIN costosagregados ca ON ca.idcostoagregado=cd.idcostoagregado LEFT JOIN docpadrehijos ph ON padre.iddocumento=ph.idpadre LEFT JOIN documentos hijo ON hijo.iddocumento=ph.idhijo WHERE padre.idtipodoc=%d AND p.tipopersona=%d GROUP BY padre.iddocumento ORDER BY padre.iddocumento; """ % ( '%', constantes.IDFACTURA, constantes.IDRECIBO, constantes.CLIENTE ) self.navmodel.setQuery( query ) # Proxy model que se utilizara desde el formulario de facturacion SOLAMENTE self.remoteProxyModel = QSortFilterProxyModel() self.remoteProxyModel.setSourceModel( self.navmodel ) self.remoteProxyModel.setFilterKeyColumn( IDFACTURAS ) self.remoteProxyModel.setFilterRegExp( '' ) self.navproxymodel = RONavigationModel( self ) self.navproxymodel.setSourceModel( self.remoteProxyModel ) self.navproxymodel.setFilterKeyColumn( -1 ) self.navproxymodel.setFilterCaseSensitivity ( Qt.CaseInsensitive ) # Este es el modelo con los datos de la tabla para navegar #FIXME: Se el simbolo de la moneda deberia de salir desde la tabla tiposmoneda self.detailsmodel.setQuery( """ SELECT p.iddocumento, CONCAT(tp.descripcion, ' ' , tm.moneda) as 'Tipo de Pago', p.refexterna as 'No. Referencia', b.descripcion as Banco, CONCAT(tm.simbolo,' ',FORMAT(monto,4)) as 'Monto', CONCAT('US$ ',FORMAT(monto / IF(p.idtipomoneda=2,1,IFNULL(tc.tasaBanco,tc.tasa)),4)) as 'Monto US$' FROM movimientoscaja p JOIN documentos d ON d.iddocumento=p.iddocumento AND d.idtipodoc=18 JOIN tiposcambio tc ON tc.idtc=d.idtipocambio JOIN tiposmoneda tm ON tm.idtipomoneda=p.idtipomoneda JOIN tiposmovimientocaja tp ON tp.idtipomovimiento=p.idtipomovimiento LEFT JOIN bancos b ON b.idbanco = p.idbanco ORDER BY p.nlinea ; """ ) # Este es el filtro del modelo anterior self.detailsproxymodel = QSortFilterProxyModel( self ) self.detailsproxymodel.setSourceModel( self.detailsmodel ) self.detailsproxymodel.setFilterKeyColumn( IDDOCUMENTOT ) self.detailsproxymodel.setFilterRegExp( '^0$' ) # ESTE ES EL MODELO CON LOS DATOS DE Los ABONOS PARA NAVEGAR self.abonosmodel = QSqlQueryModel( self ) self.abonosmodel.setQuery( """ SELECT d.idhijo as idrecibo, padre.ndocimpreso as 'No. Factura', CONCAT('US$ ',FORMAT(d.monto,4)) as 'Saldo' FROM docpadrehijos d JOIN documentos padre ON d.idpadre=padre.iddocumento WHERE padre.idtipodoc=%d and d.monto is not null ORDER BY d.nlinea ; """ % constantes.IDFACTURA ) # Este es el filtro del modelo anterior self.abonosproxymodel.setSourceModel( self.abonosmodel ) # 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.lblnrec, NDOCIMPRESO , "text" ) self.mapper.addMapping( self.lblnreten, NRETENCION , "text" ) self.mapper.addMapping( self.txtobservaciones, OBSERVACION ) self.mapper.addMapping( self.dtPicker, FECHA ) self.mapper.addMapping( self.txtcliente, NOMBRECLIENTE, "text" ) self.mapper.addMapping( self.txtconcepto, CONCEPTO, "text" ) self.mapper.addMapping( self.lbltotalreten, TOTALRETENCION, "text" ) self.mapper.addMapping( self.txttasaret, TASARETENCION, "text" ) self.mapper.addMapping( self.lbltotal, TOTAL, "text" ) self.mapper.addMapping( self.lbltotalrecibo, TOTALPAGADO, "text" ) self.mapper.addMapping( self.ckretener, CONRETENCION, "checked" ) self.tablenavigation.setColumnHidden( 0, True ) self.tablenavigation.setColumnHidden( TOTALRETENCION, True ) self.tablenavigation.setColumnHidden( CONRETENCION, True ) # self.tabledetails.resizeColumnsToContents() except Exception as inst: pass finally: if QSqlDatabase.database().isOpen(): QSqlDatabase.database().close()
class dlgSelectDoc( QDialog ): def __init__( self, tiposdoc, parent = None ): super( dlgSelectDoc, self ).__init__( parent ) self.setupUi() self.model = QSqlQueryModel() query = u""" SELECT d.iddocumento, CONCAT_WS(' ', tdc.descripcion, d.ndocimpreso) as 'Documento', b.nombrebodega as 'Bodega', d.fechacreacion as 'Fecha', b.idbodega, d.observacion FROM documentos d JOIN tiposdoc tdc ON tdc.idtipodoc = d.idtipodoc JOIN bodegas b ON b.idbodega = d.idbodega LEFT JOIN docpadrehijos dpd ON dpd.idpadre = d.iddocumento LEFT JOIN documentos h ON h.iddocumento = dpd.idhijo AND h.idtipodoc = %d WHERE d.idtipodoc IN (%s) AND d.idestado = %d GROUP BY d.iddocumento HAVING SUM(h.idtipodoc) IS NULL """ % ( constantes.IDKARDEX , tiposdoc, constantes.CONFIRMADO ) self.model.setQuery( query ) self.setWindowTitle( u"Seleccione el documento con los artículos" ) self.filtermodel = QSortFilterProxyModel() self.filtermodel.setSourceModel( self.model ) self.filtermodel.setFilterCaseSensitivity( Qt.CaseInsensitive ) self.filtermodel.setFilterKeyColumn( -1 ) self.tblBills.setModel( self.filtermodel ) # self.tblBills.horizontalHeader().setStretchLastSection( True ) iddoc, _ndocimpreso, _bodega, _fecha, idbodega, observacion = range( 6 ) self.tblBills.setColumnHidden( iddoc, True ) self.tblBills.setColumnHidden( idbodega, True ) self.tblBills.setColumnHidden( observacion, True ) self.tblBills.resizeColumnsToContents() self.buttonbox.accepted.connect( self.accept ) self.buttonbox.rejected.connect( self.reject ) self.txt_search.textChanged[unicode].connect( self.update_filter ) def setupUi( self ): self.tblBills = QTableView() self.tblBills.setSelectionMode( QAbstractItemView.SingleSelection ) self.tblBills.setSelectionBehavior( QAbstractItemView.SelectRows ) self.tblBills.selectRow( 0 ) self.buttonbox = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel ) self.txt_search = QLineEdit() formlayout = QFormLayout() formlayout.addRow( "&Buscar", self.txt_search ) layout = QVBoxLayout() layout.addWidget( self.tblBills ) layout.addLayout( formlayout ) layout.addWidget( self.buttonbox ) self.setLayout( layout ) self.setMinimumWidth( 450 ) def update_filter( self, text ): self.filtermodel.setFilterWildcard( text )
class DatosRecibo( object ): def __init__( self, datosSesion ): object.__init__( self ) self.__documentType = 18 self.clienteId = 0 self.observaciones = "" self.aplicarRet = True self.lineas = [] self.lineasAbonos = [] self.numeroImpreso = '' self.conceptoId = 0 self.datosSesion = datosSesion self.retencionId = 0 self.retencionTasa = Decimal( 0 ) self.retencionNumeroImpreso = '' @property def total( self ): """ """ tmpsubtotal = sum( [linea.monto for linea in self.lineasAbonos] ) return tmpsubtotal if tmpsubtotal > 0 else Decimal( 0 ) @property def subtotal( self ): """ """ tmpsubtotal = sum( [linea.subMonto for linea in self.lineasAbonos] ) return tmpsubtotal if tmpsubtotal > 0 else Decimal( 0 ) @property def totalPagado( self ): """ """ return self.total - self.obtenerRetencion def valid( self, recibo ): """ Un documento es valido cuando self.printedDocumentNumber != "" self.providerId !=0 self.validLines >0 self.__idIVA !=0 self.uid != 0 self.warehouseId != 0 """ if int( self.clienteId ) == 0: try: recibo.cbcliente.setFocus() except: pass QMessageBox.information( None, "Guardar Recibo", "No existe un cliente seleccionado" ) elif int( self.conceptoId ) == 0: try: recibo.cbconcepto.setFocus() except: pass QMessageBox.information( None, "Guardar Recibo", "No hay un concepto" ) elif self.aplicarRet and int( self.retencionId ) == 0: recibo.cbtasaret.setFocus() QMessageBox.information( None, "Guardar Recibo", "No hay tasa de retencion" ) elif self.datosSesion.tipoCambioBanco == 0: QMessageBox.information( None, "Guardar Recibo", "no hay un tipo de cambio para la fecha" + self.datosSesion.fecha ) elif int( self.datosSesion.usuarioId ) == 0: raise Exception( "No hay un usuario" ) elif self.printedDocumentNumber == "": raise Exception( "No existe numero de doc impreso" ) else: foo = 0 for line in self.lineas: foo += 1 if not line.valid: recibo.tabledetails.selectRow( foo - 1 ) QMessageBox.information( None, "Guardar Recibo", u"La linea " + str( foo ) + u" de los pagos esta incompleta. " + line.error ) return False if len( self.lineasAbonos ) == 0: QMessageBox.information( None, "Guardar Recibo", u"Por favor elija al menos una factura a la que se realizará el abono" ) return False foo = 0 for line in self.lineasAbonos: foo += 1 if not line.valid: QMessageBox.information( None, "Guardar Recibo", u"La linea " + str( foo ) + u" de las facturas abonadas no es válida" ) return False return True return False @property def retencionValida( self ): subtotal = self.subtotal subtotalC = subtotal * self.datosSesion.tipoCambioBanco return subtotalC > 1000 @property def obtenerRetencion( self ): if self.aplicarRet: if not self.retencionValida: self.aplicarRet = False self.retencionId = 0 return Decimal( 0 ) else: return ( self.subtotal * ( self.retencionTasa / Decimal( 100 ) ) ) else: return Decimal( 0 ) @property def obtenerGanancia( self ): total = self.total retencion = self.obtenerRetencion return Decimal( str( round( ( total + retencion ) * ( self.datosSesion.tipoCambioBanco - self.datosSesion.tipoCambioOficial ), 4 ) ) ) @property def validLines( self ): """ la cantidad de lineas validas que hay en el documento """ foo = 0 for line in self.lineas: if line.valid:foo += 1 return foo def save( self, sinFactura = True ): """ Este metodo guarda el documento actual en la base de datos """ if not self.valid: raise Exception( "El documento a salvar no es valido" ) query = QSqlQuery() try: if sinFactura: if not QSqlDatabase.database().transaction(): raise Exception( u"No se pudo comenzar la transacción" ) fechaCreacion = self.datosSesion.fecha.toString( 'yyyyMMdd' ) + QDateTime.currentDateTime().toString( "hhmmss" ) #INSERTAR RECIBO query.prepare( """ INSERT INTO documentos (ndocimpreso,fechacreacion,idtipodoc, observacion,total,idtipocambio,idconcepto,idcaja) VALUES ( :ndocimpreso,:fechacreacion,:idtipodoc,:observacion,:total,:idtc,:concepto,:caja) """ ) query.bindValue( ":ndocimpreso", self.printedDocumentNumber ) query.bindValue( ":fechacreacion", fechaCreacion ) query.bindValue( ":idtipodoc", self.__documentType ) query.bindValue( ":observacion", self.observaciones ) totalPagado = self.totalPagado query.bindValue( ":total", totalPagado.to_eng_string() ) query.bindValue( ":idtc", self.datosSesion.tipoCambioId ) query.bindValue( ":concepto", self.conceptoId ) query.bindValue( ":caja", self.datosSesion.cajaId ) if not query.exec_(): raise Exception( "No se pudo insertar el recibo" ) insertedId = query.lastInsertId().toString() #INSERTAR LA RELACION CON LA SESION DE CAJA query.prepare( """ INSERT INTO docpadrehijos (idpadre,idhijo) VALUES (:idsesion,:idrecibo) """ ) query.bindValue( ":idsesion", self.datosSesion.sesionId ) query.bindValue( ":idrecibo", insertedId ) if not query.exec_(): raise Exception( "No se Inserto la relacion entre la sesion de caja y el recibo" ) #INSERTAR LA RELACION CON El USUARIO y EL CLIENTE query.prepare( "INSERT INTO personasxdocumento (iddocumento,idpersona,idaccion) VALUES" + "(" + insertedId + ",:iduser,:autor)," "(" + insertedId + ",:idcliente,:cliente)" ) query.bindValue( ":iduser", self.datosSesion.usuarioId ) query.bindValue( ":autor", constantes.AUTOR ) query.bindValue( ":idcliente", self.clienteId ) query.bindValue( ":usuario", constantes.CLIENTE ) if not query.exec_(): raise Exception( "No se Inserto la relacion entre el recibo y las personas" ) #INSERTAR LOS TIPOS DE PAGO if len( self.lineas ) == 0: raise Exception( "Deben existir pagos" ) i = 1 for linea in self.lineas: # print insertedId + "-" + str(linea.pagoId) + "-" + str(linea.monedaId) linea.save( insertedId, i ) i = i + 1 #INSERTAR los abonos i = 0 if len( self.lineasAbonos ) == 0: raise Exception( "Deben existir abonos" ) for l in self.lineasAbonos: l.save( insertedId, i ) i = i + 1 #VERIFICO SI se aplicara la retencion if self.aplicarRet : #INSERTAR EL DOCUMENTO RETENCION CON EL TOTAL EN NEGATIVO, PORQUE ESTA SALIENDO DE CAJA query.prepare( """ INSERT INTO documentos (ndocimpreso,fechacreacion,idtipodoc,total,idtipocambio,idconcepto) VALUES ( :ndocimpreso,:fechacreacion,:idtipodoc,:total,:idtc,:concepto) """ ) query.bindValue( ":ndocimpreso", self.retencionNumeroImpreso ) query.bindValue( ":fechacreacion", fechaCreacion ) query.bindValue( ":idtipodoc", constantes.IDRETENCION ) query.bindValue( ":total", self.obtenerRetencion.to_eng_string() ) query.bindValue( ":idtc", self.datosSesion.tipoCambioId ) query.bindValue( ":concepto", self.conceptoId ) if not query.exec_(): raise Exception( "No se Inserto la retencion" ) idret = query.lastInsertId().toString() query.prepare( "INSERT INTO docpadrehijos (idpadre,idhijo) VALUES" + "(:idsesion," + idret + ")," + "(:idrecibo," + idret + ")" ) query.bindValue( ":idsesion", self.datosSesion.sesionId ) query.bindValue( ":idrecibo", insertedId ) if not query.exec_(): raise Exception( "No se Inserto la relacion entre la retencion y el recibo" ) # INSERTAR EL ID DEL COSTO RETENCION query.prepare( """ INSERT INTO costosxdocumento (iddocumento, idcostoagregado) VALUES( :iddocumento, :idcostoagregado ) """ ) query.bindValue( ":iddocumento", insertedId ) query.bindValue( ":idcostoagregado", self.retencionId ) if not query.exec_(): raise Exception( "el costo Retencion NO SE INSERTO" ) #manejar las cuentas contables tasa = self.datosSesion.tipoCambioOficial movAbonoDeCliente( insertedId, self.total * tasa, self.obtenerRetencion * tasa, self.obtenerGanancia ) if sinFactura: if not QSqlDatabase.database().commit(): raise Exception( "No se pudo hacer commit" ) except Exception as inst: QSqlDatabase.database().rollback() return False return True def cargarRetenciones( self, cbtasaret ): # Rellenar el combobox de las retenciones self.retencionModel = QSqlQueryModel() self.retencionModel.setQuery( """ SELECT idcostoagregado, FORMAT(valorcosto,0) as tasa FROM costosagregados WHERE (idtipocosto=%d OR idtipocosto =%d) AND activo=1 ORDER BY valorcosto desc; """ % ( constantes.RETENCIONPROFESIONALES, constantes.RETENCIONFUENTE ) ) cbtasaret.setModel( self.retencionModel ) cbtasaret.setModelColumn( 1 ) cbtasaret.setCurrentIndex( -1 ) self.retencionId = 0 def cargarNumeros( self, recibo ): # Cargar el numero de el Recibo actual idrec = str( constantes.IDRECIBO ) idret = str( constantes.IDRETENCION ) query = QSqlQuery( "CALL spConsecutivo(" + idrec + ",null)" ) if not query.exec_(): print( query.lastError().text() ) query.first() n = query.value( 0 ).toString() recibo.lblnrec.setText( n ) self.printedDocumentNumber = n query = QSqlQuery( "CALL spConsecutivo(" + idret + ",null)" ) if not query.exec_(): print( query.lastError().text() ) query.first() n = query.value( 0 ).toString() recibo.lblnreten.setText( n ) self.retencionNumeroImpreso = n def tasaRetencionCambio( self, _recibo, index ): self.retencionId = self.retencionModel.record( index ).value( "idcostoagregado" ).toInt()[0] value = self.retencionModel.record( index ).value( "tasa" ).toString() self.retencionTasa = Decimal( value if value != "" else 0 )
class MainWin(QMainWindow): """ Esta ventana guarda las tabs """ def __init__(self, netmanager, clipboard, parent=None): super(MainWin, self).__init__(parent) self.setWindowTitle("Eilat Browser " + netmanager.name) self.netmanager = netmanager self.clipboard = clipboard self.tab_widget = QTabWidget(self) self.tab_widget.tabBar().setMovable(True) self.setCentralWidget(self.tab_widget) self.tab_widget.setTabsClosable(True) database = QSqlDatabase("QPSQL") database.open("pguser", "pguser") query = QSqlQuery( "select concat(host, path) h, count(*) c from reply " + "where status between 200 and 399 " + "and is_bookmarkable(path) " + "and host not in (select host from filtro) " + "group by h " + "order by c desc", database) self.model = QSqlQueryModel() self.model.setQuery(query) self.tab_widget.tabCloseRequested.connect(self.del_tab) def new_tab_from_clipboard(): """ One-use callback for QShortcut. Reads the content of the PRIMARY clipboard and navigates to it on a new tab. """ url = unicode(self.clipboard.text(QClipboard.Selection)).strip() self.add_tab(url) set_shortcuts([("Ctrl+T", self, self.add_tab), ("Y", self, new_tab_from_clipboard), ("Ctrl+W", self, self.del_tab), ("N", self, partial(self.inc_tab, -1)), ("Ctrl+PgUp", self, partial(self.inc_tab, -1)), ("M", self, self.inc_tab), ("Ctrl+PgDown", self, self.inc_tab), ("Ctrl+Q", self, QApplication.closeAllWindows)]) # aux. action (en register_actions) def inc_tab(self, incby=1): """ Takes the current tab index, modifies wrapping around, and sets as current. Afterwards the active tab has focus on its webkit area. """ if self.tab_widget.count() < 2: return idx = self.tab_widget.currentIndex() idx += incby if idx < 0: idx = self.tab_widget.count() - 1 elif idx >= self.tab_widget.count(): idx = 0 self.tab_widget.setCurrentIndex(idx) self.tab_widget.currentWidget().webkit.setFocus() # action y connect en llamada en constructor def del_tab(self, idx=None): """ Closes a tab. If 'idx' is set, it was called by a tabCloseRequested signal. If not, it was called by a keyboard action and closes the currently active tab. Afterwards the active tab has focus on its webkit area. It closes the window when deleting the last active tab. """ if idx is None: idx = self.tab_widget.currentIndex() self.tab_widget.widget(idx).webkit.stop() self.tab_widget.widget(idx).deleteLater() self.tab_widget.removeTab(idx) if len(self.tab_widget) == 0: self.close() else: self.tab_widget.currentWidget().webkit.setFocus() # action (en register_actions) # externo en eilat.py, crea la primera tab def add_tab(self, url=None): """ Creates a new tab, either empty or navegating to the url. Sets itself as the active tab. If navegating to an url it gives focus to the webkit area. Otherwise, the address bar is focused. """ tab = WebTab(browser=self, parent=self.tab_widget) self.tab_widget.addTab(tab, "New tab") self.tab_widget.setCurrentWidget(tab) if url: tab.navigate(url) else: tab.address_bar.setFocus()
class ChooseMTModelDialog(QDialog, Ui_Dialog): """ Class documentation goes here. """ def __init__(self, parent=None, datamodel=None): """ Constructor """ QDialog.__init__(self, parent) self.setupUi(self) self.model = QSqlQueryModel() self.selTableView.setModel(self.model) self.database = datamodel.getQSqlDatabase() self.updateModel() self.selTableView.hideColumn(0) self.selTableView.hideColumn(5) self.selTableView.hideColumn(6) # Change status and keep the column. QObject.connect(datamodel, SIGNAL("modelInstalled()"), self.on_datamodel_modelInstalled) def updateModel(self): self.model.setQuery( 'SELECT ID, name, srclang, trglang, status, path, mosesini ' 'FROM models ' 'WHERE status = "READY" AND deleted != "True"', self.database) def on_datamodel_recordUpdated(self, bRecord): """Deal with the selection changed problem.""" try: if bRecord: current = self.selTableView.currentIndex() if current and current.row() != -1: self.curSelection = current.row() else: self.curSelection = None else: if self.curSelection is not None: self.selTableView.selectRow(self.curSelection) except Exception as e: print >> sys.stderr, str(e) def on_datamodel_modelInstalled(self): self.updateModel() @pyqtSignature("") def on_buttonBox_accepted(self): """ Slot documentation goes here. """ current = self.selTableView.currentIndex() if not current: doAlert("Please choose a model to start.") return record = self.model.record(current.row()) self.ID = record.value("ID").toString() self.modelName = record.value("name").toString() self.srcLang = record.value('srclang').toString() self.trgLang = record.value('trglang').toString() self.path = record.value("path").toString() self.mosesini = record.value("mosesini").toString() self.accept()
class MainWin(QMainWindow): """ Esta ventana guarda las tabs """ def __init__(self, netmanager, clipboard, parent = None): super(MainWin, self).__init__(parent) self.setWindowTitle("Eilat Browser " + netmanager.name) self.netmanager = netmanager self.clipboard = clipboard self.tab_widget = QTabWidget(self) self.tab_widget.tabBar().setMovable(True) self.setCentralWidget(self.tab_widget) self.tab_widget.setTabsClosable(True) database = QSqlDatabase("QPSQL") database.open("pguser", "pguser") query = QSqlQuery( "select concat(host, path) h, count(*) c from reply " + "where status between 200 and 399 " + "and is_bookmarkable(path) " + "and host not in (select host from filtro) " + "group by h " + "order by c desc", database) self.model = QSqlQueryModel() self.model.setQuery(query) self.tab_widget.tabCloseRequested.connect(self.del_tab) def new_tab_from_clipboard(): """ One-use callback for QShortcut. Reads the content of the PRIMARY clipboard and navigates to it on a new tab. """ url = unicode(self.clipboard.text(QClipboard.Selection)).strip() self.add_tab(url) set_shortcuts([ ("Ctrl+T", self, self.add_tab), ("Y", self, new_tab_from_clipboard), ("Ctrl+W", self, self.del_tab), ("N", self, partial(self.inc_tab, -1)), ("Ctrl+PgUp", self, partial(self.inc_tab, -1)), ("M", self, self.inc_tab), ("Ctrl+PgDown", self, self.inc_tab), ("Ctrl+Q", self, QApplication.closeAllWindows) ]) # aux. action (en register_actions) def inc_tab(self, incby = 1): """ Takes the current tab index, modifies wrapping around, and sets as current. Afterwards the active tab has focus on its webkit area. """ if self.tab_widget.count() < 2: return idx = self.tab_widget.currentIndex() idx += incby if idx < 0: idx = self.tab_widget.count()-1 elif idx >= self.tab_widget.count(): idx = 0 self.tab_widget.setCurrentIndex(idx) self.tab_widget.currentWidget().webkit.setFocus() # action y connect en llamada en constructor def del_tab(self, idx = None): """ Closes a tab. If 'idx' is set, it was called by a tabCloseRequested signal. If not, it was called by a keyboard action and closes the currently active tab. Afterwards the active tab has focus on its webkit area. It closes the window when deleting the last active tab. """ if idx is None: idx = self.tab_widget.currentIndex() self.tab_widget.widget(idx).webkit.stop() self.tab_widget.widget(idx).deleteLater() self.tab_widget.removeTab(idx) if len(self.tab_widget) == 0: self.close() else: self.tab_widget.currentWidget().webkit.setFocus() # action (en register_actions) # externo en eilat.py, crea la primera tab def add_tab(self, url = None): """ Creates a new tab, either empty or navegating to the url. Sets itself as the active tab. If navegating to an url it gives focus to the webkit area. Otherwise, the address bar is focused. """ tab = WebTab( browser = self, parent = self.tab_widget) self.tab_widget.addTab(tab, "New tab") self.tab_widget.setCurrentWidget(tab) if url: tab.navigate(url) else: tab.address_bar.setFocus()
class FrmFactura( Base, Ui_frmFactura ): """ Implementacion de la interfaz grafica para facturas """ web = "facturas.php?doc=" def __init__( self, parent ): ''' Constructor ''' super( FrmFactura, self ).__init__( parent ) self.readOnly = True self.recibo = None self.clientesModel = QSqlQueryModel() # las acciones deberian de estar ocultas self.actionSave.setVisible( False ) self.actionCancel.setVisible( False ) # El modelo principal self.navmodel = QSqlQueryModel( 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 los datos de la con los detalles self.detailsmodel = QSqlQueryModel( self ) self.detailsproxymodel = QSortFilterProxyModel( self ) self.detailsproxymodel.setSourceModel( self.detailsmodel ) #inicializando el documento self.editmodel = None self.lblanulado.setHidden( True ) self.toolBar.removeAction( self.actionAnular ) self.toolBar.addAction( self.actionAnular ) self.recibo = None self.cargarRecibos() self.existenciaModel = QSqlQueryModel() self.vendedoresModel = QSqlQueryModel() self.bodegasModel = QSqlQueryModel() self.anulable = 2 """ @ivar: Si la factura actual se puede anular o no @type: int """ self.tabledetails.setOrder( 1, 3 ) self.completer = QCompleter() self.completerVendedor = QCompleter() QTimer.singleShot( 0, self.loadModels ) def cargarRecibos( self ): self.recibo = FrmRecibo( self ) #dlgRecibo( self, True ) self.recibo.setWindowModality( Qt.WindowModal ) self.recibo.setWindowFlags( Qt.Dialog ) self.recibo.actionNew.setVisible( False ) def cancel( self ): """ Aca se cancela la edición del documento """ self.editmodel = None self.tablenavigation.setModel( self.navproxymodel ) self.tabledetails.setModel( self.detailsproxymodel ) self.readOnly = True self.status = True def newDocument( self ): """ activar todos los controles, llenar los modelos necesarios, crear el modelo FacturaModel, aniadir una linea a la tabla """ self.readOnly = False if not self.updateEditModels(): return self.status = False self.dtPicker.setDate( self.parentWindow.datosSesion.fecha ) def updateEditModels( self ): """ Este metodo actualiza los modelos usados en el modo edición """ resultado = False 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" ) self.editmodel = FacturaModel( self.parentWindow.datosSesion ) # Cargar el numero de la factura actual query = QSqlQuery( """ SELECT fnConsecutivo(%d,NULL); """ % constantes.IDFACTURA ) if not query.exec_(): raise Exception( "No se pudo obtener el numero de la factura" ) query.first() n = query.value( 0 ).toString() self.editmodel.printedDocumentNumber = n self.clientesModel.setQuery( """ SELECT idpersona , nombre AS cliente FROM personas WHERE tipopersona = %d """ % constantes.CLIENTE ) if self.clientesModel.rowCount() == 0: raise UserWarning( "No existen clientes en la"\ + " base de datos" ) return # Rellenar el combobox de los vendedores self.vendedoresModel.setQuery( """ SELECT idpersona, nombre AS Vendedor FROM personas WHERE tipopersona = %d """ % constantes.VENDEDOR ) #Verificar si existen clientes if self.vendedoresModel.rowCount() == 0: raise UserWarning( "No existen vendedores en la "\ + "base de datos" ) #Crear el delegado con los articulo y verificar si existen articulos self.existenciaModel.setQuery( QSqlQuery( """ SELECT idarticulo, descripcion, precio, ROUND(costo,4) as costo, Existencia, idbodega FROM vw_articulosenbodegas WHERE existencia >0 """ ) ) self.proxyexistenciaModel = SingleSelectionModel() self.proxyexistenciaModel.setSourceModel( self.existenciaModel ) self.proxyexistenciaModel.setFilterKeyColumn( IDBODEGAEX ) if self.proxyexistenciaModel.rowCount() == 0: raise UserWarning( "No hay articulos en bodega" ) delegate = FacturaDelegate( self.proxyexistenciaModel ) # Rellenar el combobox de las BODEGAS self.bodegasModel.setQuery( """ SELECT b.idbodega, b.nombrebodega as Bodega FROM bodegas b JOIN documentos d ON b.idbodega=d.idbodega JOIN docpadrehijos ph ON ph.idpadre =d.iddocumento JOIN documentos k ON ph.idhijo = k.iddocumento AND k.idtipodoc = %d JOIN articulosxdocumento ad ON ad.iddocumento=d.iddocumento GROUP BY b.idbodega HAVING SUM(ad.unidades)>0 """ % constantes.IDKARDEX ) #Verificar si existen bodegas if self.bodegasModel.rowCount() == 0: raise UserWarning( "No existe ninguna bodega "\ + "en la base de datos" ) #Verificar IVA query = QSqlQuery( """ SELECT idcostoagregado, valorcosto FROM costosagregados c WHERE idtipocosto = 1 AND activo = 1 ORDER BY idtipocosto; """ ) query.exec_() if not query.size() == 1: raise UserWarning( "No fue posible obtener el "\ + "porcentaje del IVA" ) query.first() self.editmodel.ivaId = query.value( 0 ).toInt()[0] self.lbltasaiva.setText( ( '0' if self.editmodel.bodegaId != 1 else str( self.editmodel.ivaTasa ) ) + '%' ) self.editmodel.ivaTasa = Decimal( query.value( 1 ).toString() ) self.tabledetails.setItemDelegate( delegate ) self.cbcliente.setModel( self.clientesModel ) self.cbcliente.setCurrentIndex( -1 ) self.cbcliente.setFocus() self.cbcliente.setModelColumn( 1 ) self.completer.setCaseSensitivity( Qt.CaseInsensitive ) self.completer.setModel( self.clientesModel ) self.completer.setCompletionColumn( 1 ) self.cbcliente.setCompleter( self.completer ) self.cbbodega.setModel( self.bodegasModel ) self.cbbodega.setCurrentIndex( -1 ) self.cbbodega.setModelColumn( 1 ) self.completerbodega = QCompleter() self.completerbodega.setCaseSensitivity( Qt.CaseInsensitive ) self.completerbodega.setModel( self.bodegasModel ) self.completerbodega.setCompletionColumn( 1 ) self.cbbodega.setCompleter( self.completerbodega ) self.cbvendedor.setModel( self.vendedoresModel ) self.cbvendedor.setCurrentIndex( -1 ) self.cbvendedor.setModelColumn( 1 ) self.completerVendedor.setCaseSensitivity( Qt.CaseInsensitive ) self.completerVendedor.setModel( self.vendedoresModel ) self.completerVendedor.setCompletionColumn( 1 ) self.cbvendedor.setCompleter( self.completerVendedor ) self.tabledetails.setModel( self.editmodel ) self.addLine() self.editmodel.dataChanged[QModelIndex, QModelIndex].connect( self.updateLabels ) self.rbcontado.setChecked( True ) self.txtobservaciones.setPlainText( "" ) resultado = True except UserWarning as inst: logging.error( unicode( inst ) ) QMessageBox.critical( self, qApp.organizationName(), unicode( inst ) ) finally: if self.database.isOpen(): self.database.close() return resultado @property def printIdentifier( self ): return self.navmodel.record( self.mapper.currentIndex() ).value( "iddocumento" ).toString() def addActionsToToolBar( self ): self.actionRefresh = self.createAction( text = "Actualizar", icon = QIcon.fromTheme( 'view-refresh', QIcon( ":/icons/res/view-refresh.png" ) ), slot = self.refresh, shortcut = Qt.Key_F5 ) self.toolBar.addActions( [ self.actionNew, self.actionRefresh, self.actionPreview, self.actionPrint, self.actionSave, self.actionCancel, ] ) self.toolBar.addSeparator() self.toolBar.addActions( [ self.actionGoFirst, self.actionGoPrevious, self.actionGoLast, self.actionGoNext, self.actionGoLast ] ) def refresh( self ): """ Actualizar los modelos de edición """ if not self.status: if QMessageBox.question( self, qApp.organizationName(), u"Se perderán todos los cambios en la factura. ¿Esta seguro que desea actualizar?", QMessageBox.Yes | QMessageBox.No ) == QMessageBox.No: return self.updateEditModels() else: if self.updateModels(): QMessageBox.information( None, "Factura", u"Los datos fueron actualizados con éxito" ) def save( self ): """ Guardar el documento actual @rtype: bool """ result = False try: if not self.valid: return False if self.editmodel.escontado: recibo = DlgRecibo( self ) if recibo.datosRecibo.retencionValida: if recibo.datosRecibo.retencionModel.rowCount() == 0: raise UserWarning( "No es posible crear un recibo "\ + "porque no existen retenciones en la base de datos" ) else: recibo.ckretener.setChecked( False ) recibo.ckretener.setEnabled( False ) if recibo.exec_() == QDialog.Rejected: return else: credito = DlgCredito( self ) if not credito.exec_() == QDialog.Accepted: return self.editmodel.fechaTope = credito.dtFechaTope.date() self.editmodel.multa = Decimal( str( credito.sbTaxRate.value() ) ) if QMessageBox.question( self, qApp.organizationName(), u"¿Esta seguro que desea guardar la factura?", QMessageBox.Yes | QMessageBox.No ) == QMessageBox.Yes: if not self.database.isOpen(): if not self.database.open(): raise UserWarning( u"No se pudo conectar con la base de datos" ) self.editmodel.observaciones = self.txtobservaciones.toPlainText() if self.editmodel.escontado: recibo.datosRecibo.observaciones = recibo.txtobservaciones.toPlainText() if not self.editmodel.save( recibo.datosRecibo if self.editmodel.escontado else None ): raise UserWarning( "No se ha podido guardar la factura" ) QMessageBox.information( None, qApp.organizationName() , u"""El documento se ha guardado con éxito""" ) self.editmodel = None self.readOnly = True self.updateModels() self.cargarRecibos() self.navigate( 'last' ) self.status = True result = True 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 guardar la factura" ) finally: if self.database.isOpen(): self.database.close() return result #FIXME: Hay demasiados if y cosas por el estilo en esta función...deberia de #hacerse un refactor @pyqtSlot() def on_actionAnular_activated( self ): if self.anulable == 2: QMessageBox.warning( self, qApp.organizationName(), u"La factura no puede anularse. Solo las"\ + " facturas confirmadas o en proceso de "\ + "autorización pueden anularse" ) elif self.anulable == 3: QMessageBox.warning( self, qApp.organizationName(), u"La factura no puede anularse porque no "\ + "es del día de hoy" ) elif self.anulable == 4: QMessageBox.warning( self, qApp.organizationName(), u"La factura no puede anularse porque tiene"\ + " abonos" ) elif self.anulable == 5: QMessageBox.warning( self, qApp.organizationName(), u"La factura no puede anularse porque tiene"\ + " devoluciones" ) elif self.anulable == 1: currentIndex = self.mapper.currentIndex() record = self.navmodel.record( currentIndex ) doc = record.value( "iddocumento" ).toInt()[0] estado = record.value( "idestado" ).toInt()[0] total = record.value( "totalfac" ).toString() bodega = record.value( IDBODEGA ).toInt()[0] if total != "": total = Decimal( total ) query = QSqlQuery() try: if not self.database.isOpen(): if not self.database.open(): raise Exception( "NO se pudo abrir la Base de datos" ) if estado == 3: if QMessageBox.question( self, qApp.organizationName(), u"Esta factura no fue confirmada,"\ + " ¿Desea eliminarla?", QMessageBox.Yes | QMessageBox.No ) == QMessageBox.Yes: query = QSqlQuery() query.prepare( "CALL spEliminarFactura(:doc)" ) query.bindValue( ":doc", doc ) if not query.exec_(): raise Exception( "No se pudo eliminar el la factura" ) QMessageBox.information( self, qApp.organizationName(), "La factura fue eliminada correctamente" ) self.updateModels() else: if QMessageBox.question( self, qApp.organizationName(), u"¿Esta seguro que desea anular la factura?", QMessageBox.Yes | QMessageBox.No ) == QMessageBox.Yes: nfac = self.navmodel.record( self.mapper.currentIndex() ).value( "No. Factura" ).toString() anulardialog = DlgAnular( nfac ) if anulardialog.conceptosmodel.rowCount() == 0: QMessageBox.warning( self, qApp.organizationName(), u"No existen conceptos para la anulación" ) else: if anulardialog.exec_() == QDialog.Accepted: if anulardialog.cboConceptos.currentIndex() == -1 and anulardialog.txtObservaciones.toPlainText() == "": QMessageBox.critical( self, qApp.organizationName(), "No ingreso los datos correctos", QMessageBox.Ok ) else: if not self.database.transaction(): raise Exception( "No se pudo comenzar la transacción" ) #Cambiar estado Anulado=1 para documento query.prepare( "UPDATE documentos d SET idestado=%d where iddocumento=%d LIMIT 1" % ( constantes.ANULACIONPENDIENTE, doc ) ) if not query.exec_(): raise Exception( "No se logro cambiar el estado a el documento" ) #Insertar documento anulacion if not query.prepare( """ INSERT INTO documentos(ndocimpreso,total,fechacreacion,idtipodoc,observacion,idestado, idbodega) VALUES(:ndocimpreso,:total,NOW(),:idtipodoc,:observacion,:idestado, :idbodega)""" ): raise Exception( query.lastError().text() ) query.bindValue( ":ndocimpreso", nfac ) query.bindValue( ":total", str( total ) ) # query.bindValue( ":fechacreacion", QDateTime.currentDateTime().toString('yyyyMMddhhmmss') ) query.bindValue( ":idtipodoc", constantes.IDANULACION ) query.bindValue( ":observacion", anulardialog.txtObservaciones.toPlainText() ) query.bindValue( ":idestado", constantes.PENDIENTE ) query.bindValue( ":idbodega", bodega ) if not query.exec_(): raise Exception( "No se pudo insertar el documento Anulacion" ) insertedId = query.lastInsertId().toString() if not query.prepare( "INSERT INTO docpadrehijos (idpadre,idhijo) VALUES" + "(:idfac," + insertedId + ")" ): # "(:usuario," + insertedId + ",0)," # "(:supervisor," + insertedId + ",1)"): raise Exception( query.lastError().text() + "No se preparo la relacion de la anulacion con la factura" ) query.bindValue( ":idfac", doc ) if not query.exec_(): raise Exception( "No se pudo insertar la relacion de la Anulacion con la factura" ) if not query.prepare( "INSERT INTO personasxdocumento (idpersona,iddocumento,idaccion) VALUES" \ + "(:usuario," + insertedId + ",:accion)" ): raise Exception( "No se inserto el usuario y autoriza" ) query.bindValue( ":usuario", self.parentWindow.datosSesion.usuarioId ) query.bindValue ( ":accion", constantes.AUTOR ) if not query.exec_(): raise Exception( "No se pudo Insertar la relacion de la anulacion con el usuario" ) if not self.database.commit(): raise Exception( "No se hizo el commit para la Anulacion" ) QMessageBox.information( self, qApp.organizationName(), "Factura anulada Correctamente", QMessageBox.Ok ) self.updateModels() except Exception as inst: logging.error( unicode( inst ) ) logging.error( query.lastError().text() ) QMessageBox.critical( self, qApp.organizationName(), unicode( inst ) ) self.database.rollback() except Exception as inst: logging.critical( unicode( inst ) ) logging.critical( query.lastError().text() ) QMessageBox.critical( self, qApp.organizationName(), "Hubo un error al intentar anular "\ + "la factura" ) self.database.rollback() finally: if self.database.isOpen(): self.database.close() @pyqtSlot() def on_actionRecibo_activated( self ): index = self.mapper.currentIndex() record = self.navmodel.record( index ) self.recibo.remoteProxyModel.setFilterRegExp( "(%s)" % record.value( "iddocumento" ).toString() ) if self.recibo.remoteProxyModel.rowCount() > 0: self.recibo.mapper.setCurrentIndex( 1 ) if self.recibo.remoteProxyModel.rowCount() != 0: self.recibo.mapper.setCurrentIndex( 0 ) self.recibo.show() @pyqtSlot( int ) def on_cboFiltro_currentIndexChanged( self, index ): """ asignar la bodega al objeto self.editmodel """ self.navproxymodel.setFilterKeyColumn( ANULADO ) if index == 0: self.navproxymodel.setFilterRegExp( "" ) else: self.navproxymodel.setFilterRegExp( "^%d$" % index ) @pyqtSlot( int ) @if_edit_model def on_cbbodega_currentIndexChanged( self, index ): """ asignar la bodega al objeto self.editmodel """ if self.editmodel.rowCount() > 0 and self.editmodel.lines[0].itemDescription != "": self.editmodel.removeRows( 0, self.editmodel.rowCount() ) self.editmodel.bodegaId = self.bodegasModel.record( index ).value( "idbodega" ).toInt()[0] self.proxyexistenciaModel.setFilterRegExp( '^%d$' % self.editmodel.bodegaId ) self.tabledetails.setColumnHidden( IDARTICULO, True ) self.updateLabels() @pyqtSlot( int ) @if_edit_model def on_cbcliente_currentIndexChanged( self, index ): """ asignar proveedor al objeto self.editmodel """ self.editmodel.clienteId = self.clientesModel.record( index ).value( "idpersona" ).toInt()[0] @pyqtSlot( int ) @if_edit_model def on_cbvendedor_currentIndexChanged( self, index ): """ asignar proveedor al objeto self.editmodel """ self.editmodel.vendedorId = self.vendedoresModel.record( index ).value( "idpersona" ).toInt()[0] @pyqtSlot( QDateTime ) def on_dtPicker_dateTimeChanged( self, datetime ): pass @pyqtSlot( bool ) @if_edit_model def on_rbcontado_toggled( self, on ): """ Asignar las observaciones al objeto editmodel """ self.editmodel.escontado = 1 if on else 0 def setControls( self, status ): """ @param status: false = editando true = navegando """ self.actionPrint.setVisible( status ) self.readOnly = status self.txtobservaciones.setReadOnly( status ) self.rbcontado.setEnabled( ( not status ) ) self.rbcredito.setEnabled( 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.actionAnular.setVisible( status ) self.actionRecibo.setVisible( status ) if status: self.navigate( 'last' ) self.swcliente.setCurrentIndex( 1 ) self.swbodega.setCurrentIndex( 1 ) self.swvendedor.setCurrentIndex( 1 ) self.tabledetails.setEditTriggers( QAbstractItemView.NoEditTriggers ) self.tabledetails.removeAction( self.actionDeleteRow ) self.tablenavigation.setColumnHidden( IDDOCUMENTO, True ) self.tablenavigation.setColumnHidden( OBSERVACION, True ) self.tablenavigation.setColumnHidden( SUBTOTAL, True ) self.tablenavigation.setColumnHidden( IVA, True ) self.tablenavigation.setColumnHidden( TASAIVA, True ) self.tablenavigation.setColumnHidden( TASA, True ) self.tablenavigation.setColumnHidden( ESCONTADO, True ) self.tablenavigation.setColumnHidden( ANULADO, True ) self.tablenavigation.setColumnHidden( TOTALFAC, True ) self.tablenavigation.setColumnHidden( IDBODEGA, True ) self.tablenavigation.setColumnHidden( ANULABLE, True ) else: # self.btnrecibo.setHidden( True ) self.tabWidget.setCurrentIndex( 0 ) self.lblnfac.setText( self.editmodel.printedDocumentNumber ) self.swcliente.setCurrentIndex( 0 ) self.swbodega.setCurrentIndex( 0 ) self.swvendedor.setCurrentIndex( 0 ) self.lblsubtotal.setText( "0.0000" ) self.lbliva.setText( "0.0000" ) self.lbltotal.setText( "0.0000" ) self.tabledetails.setEditTriggers( QAbstractItemView.AllEditTriggers ) self.lblanulado.setHidden( True ) self.tabledetails.addAction( self.actionDeleteRow ) # self.tabledetails.horizontalHeader().setStretchLastSection(True) self.tabledetails.setColumnHidden( IDARTICULO, True ) self.tabledetails.setColumnHidden( IDDOCUMENTOT, True ) def updateDetailFilter( self, index ): record = self.navmodel.record( index ) self.lbltasaiva.setText( record.value( "tasaiva" ).toString() + '%' ) self.lblanulado.setHidden( record.value( "idestado" ).toInt()[0] != constantes.ANULADO ) self.anulable = record.value( ANULABLE ).toInt()[0] # self.actionAnular.setEnabled() escontado = record.value( "escontado" ).toBool() if escontado: self.rbcontado.setChecked( True ) else: self.rbcredito.setChecked( True ) # self.recibo.setHidden(True) self.detailsproxymodel.setFilterKeyColumn( IDDOCUMENTOT ) self.detailsproxymodel.setFilterRegExp( record.value( "iddocumento" ).toString() ) self.tablenavigation.selectRow( self.mapper.currentIndex() ) def updateLabels( self ): self.lblsubtotal.setText( moneyfmt( self.editmodel.subtotal, 4, "US$ " ) ) self.lbliva.setText( moneyfmt( self.editmodel.IVA, 4, "US$ " ) ) self.lbltotal.setText( moneyfmt( self.editmodel.total, 4, "US$ " ) ) self.lbltasaiva.setText( str( self.editmodel.ivaTasa ) + '%' ) self.tabledetails.resizeColumnsToContents() def updateModels( self ): """ Recargar todos los modelos """ resultado = False try: 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" ) # El modelo principal query = """ SELECT d.iddocumento, d.ndocimpreso as 'No. Factura', GROUP_CONCAT(IF(pxd.idaccion=%d,p.nombre,"") SEPARATOR '') as Cliente, GROUP_CONCAT(IF(pxd.idaccion=%d,p.nombre,"") SEPARATOR '') as Vendedor, CONCAT('US$ ',FORMAT(ROUND(d.total / (1+ IF(valorcosto IS NULL,0,valorcosto/100)),4),4)) as subtotal, CONCAT('US$ ',FORMAT(d.total- ROUND(d.total / (1+ IF(valorcosto IS NULL,0,valorcosto/100)),4),4)) as iva, CONCAT('US$ ',FORMAT(d.Total,4)) as Total, d.observacion, d.fechacreacion as Fecha, b.nombrebodega as Bodega, tc.tasa as 'Tipo de Cambio Oficial', valorcosto as tasaiva, ed.descripcion as Estado, d.idestado, d.escontado, d.total as totalfac, fnFacturaAnulable(d.iddocumento,d.idtipodoc,%d,%d,%d,%d) as anulable, b.idbodega FROM documentos d JOIN estadosdocumento ed ON ed.idestado = d.idestado JOIN bodegas b ON b.idbodega=d.idbodega JOIN tiposcambio tc ON tc.idtc=d.idtipocambio JOIN personasxdocumento pxd ON pxd.iddocumento=d.iddocumento JOIN personas p ON p.idpersona=pxd.idpersona LEFT JOIN costosxdocumento cd ON cd.iddocumento=d.iddocumento LEFT JOIN costosagregados ca ON ca.idcostoagregado=cd.idcostoagregado WHERE d.idtipodoc=%d GROUP BY d.iddocumento ORDER BY CAST(IF(ndocimpreso='S/N',0,d.ndocimpreso) AS SIGNED) ; """ % ( constantes.CLIENTE, constantes.VENDEDOR, constantes.IDRECIBO, constantes.IDNC, constantes.CONFIRMADO, constantes.PENDIENTE, constantes.IDFACTURA ) self.navmodel.setQuery( query ) # Este es el modelo con los datos de la tabla para navegar self.detailsmodel.setQuery( u""" SELECT ad.idarticulo, ad.descripcion as 'Descripción', -a.unidades as Unidades, CONCAT('US$ ',FORMAT(a.precioventa,4)) as 'Precio Unit.', CONCAT('US$ ',FORMAT(-a.unidades*a.precioventa,4)) as 'Total', a.iddocumento FROM articulosxdocumento a JOIN vw_articulosdescritos ad on a.idarticulo=ad.idarticulo WHERE a.precioventa IS NOT NULL ; """ ) # 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.lblnfac, NDOCIMPRESO , "text" ) self.mapper.addMapping( self.txtobservaciones, OBSERVACION ) self.mapper.addMapping( self.txtcliente, CLIENTE, "text" ) self.mapper.addMapping( self.txtvendedor, VENDEDOR, "text" ) self.mapper.addMapping( self.txtbodega, BODEGA, "text" ) self.mapper.addMapping( self.lbltotal, TOTAL, "text" ) self.mapper.addMapping( self.lblsubtotal, SUBTOTAL, "text" ) self.mapper.addMapping( self.lbliva, IVA, "text" ) self.mapper.addMapping( self.dtPicker, FECHA ) # asignar los modelos a sus tablas self.tablenavigation.setModel( self.navproxymodel ) self.tabledetails.setModel( self.detailsproxymodel ) resultado = True except UserWarning as inst: logging.error( unicode( inst ) ) QMessageBox.critical( self, qApp.organizationName(), unicode( inst ) ) self.status = True except Exception as inst: logging.critical( unicode( inst ) ) QMessageBox.critical( self, qApp.organizationName(), u"Hubo un error al actualizar los datos" ) self.status = True finally: if self.database.isOpen(): self.database.close() return resultado @property def valid( self ): """ Un documento es valido cuando self.printedDocumentNumber != "" self.providerId !=0 self.validLines >0 self.ivaId !=0 self.uid != 0 self.warehouseId != 0 """ if int( self.editmodel.datosSesion.usuarioId ) == 0: raise Exception( "No existe el usuario" ) elif int( self.editmodel.clienteId ) == 0: QMessageBox.warning( self, qApp.organizationName(), "Por favor elija el cliente" ) self.cbcliente.setFocus() elif int( self.editmodel.vendedorId ) == 0: QMessageBox.warning( self, qApp.organizationName(), "Por favor elija el vendedor" ) self.cbvendedor.setFocus() elif int( self.editmodel.bodegaId ) == 0: QMessageBox.warning( self, qApp.organizationName(), "Por favor elija la bodega" ) self.cbbodega.setFocus() elif int( self.editmodel.validLines ) == 0: QMessageBox.warning( self, qApp.organizationName(), "Por favor complete la información de los artículos comprados" ) else: return True return False
class FrmPersona( Ui_frmPersona, Base ): def __init__( self, tipo, rol, parent ): super( FrmPersona, self ).__init__( parent, True ) self.tabledetails = None self.setWindowModality( Qt.WindowModal ) self.setWindowFlags( Qt.Dialog ) self.tipo = tipo self.rol = rol self.lbltitulo.setText( u"<B>Datos del %s</B>" % rol ) self.editmodel = None # self.parent = parent self.navmodel = QSqlQueryModel() self.navproxymodel = QSortFilterProxyModel() self.navproxymodel.setFilterKeyColumn( -1 ) self.navproxymodel.setSourceModel( self.navmodel ) self.navproxymodel.setFilterCaseSensitivity( Qt.CaseInsensitive ) self.tablenavigation.setModel( self.navproxymodel ) self.actionPreview.setVisible( False ) self.actionPrint.setVisible( False ) self.updateModels() self.status = True def updateDetailFilter( self, index ): self.actionEditar.setEnabled( self.navproxymodel.rowCount() > 0 ) if self.navmodel.record( index ).value( "activo" ).toBool(): self.rbactivo.setChecked( True ) else: self.rbinactivo.setChecked( True ) def updateModels( self ): try: if not self.database.isOpen(): if not self.database.open(): raise UserWarning( "No se pudo abrir la base de datos" ) #TODO: Esta consulta tiene que mejorar para definir realmente quien es el que realiza el arqueo query = u""" SELECT tipopersona, idpersona, Nombre, direccion as 'Dirección', telefono as 'Teléfono', email as 'E-mail', ruc as Ruc, activo FROM personas p WHERE tipopersona =%d """ % self.tipo self.navmodel.setQuery( query ) self.navproxymodel.setSourceModel( self.navmodel ) self.actionEditar.setEnabled( self.navproxymodel.rowCount() > 0 ) self.tablenavigation.setModel( self.navproxymodel ) self.mapper.setSubmitPolicy( QDataWidgetMapper.ManualSubmit ) self.mapper.setModel( self.navproxymodel ) self.mapper.addMapping( self.txtnombre, NOMBRE ) self.mapper.addMapping( self.txtdireccion, DIRECCION ) self.mapper.addMapping( self.txttelefono, TELEFONO ) self.mapper.addMapping( self.txtcorreo, CORREO ) self.mapper.addMapping( self.txtruc, RUC ) self.tablenavigation.setColumnHidden( TIPO, True ) self.tablenavigation.setColumnHidden( ID, True ) self.tablenavigation.setColumnHidden( ACTIVO, True ) self.tablenavigation.setColumnWidth( NOMBRE, 200 ) self.navigate( 'last' ) # self.mapper.setCurrentIndex( index.row() ) except UserWarning as inst: logging.error( inst ) QMessageBox.critical( self, qApp.organizationName(), unicode( inst ) ) except Exception as inst: logging.critical( inst ) finally: if self.database.isOpen(): self.database.close() def save( self ): editado = self.status == 2 titulo = "Guardar los cambios" if editado else "Crear un nuevo %s" % self.rol if self.txtnombre.text() == "": self.txtnombre.setFocus() QMessageBox.warning( None, titulo, "Por favor escriba el nombre del %s" % self.rol ) return False if QMessageBox.question( None, titulo, u"¿Está seguro que desea guardar los cambios?" if editado else u"¿Está seguro que desea crear al %s?" % self.rol , QMessageBox.Yes | QMessageBox.No ) == QMessageBox.No: return False try: if not self.database.isOpen(): if not self.database.open(): raise UserWarning( u"No se pudo conectar con la base de datos" ) query = QSqlQuery() pos = self.mapper.currentIndex() if editado: query.prepare( """ UPDATE personas SET direccion =:dir, telefono=:tel, email=:correo, ruc=:ruc, tipopersona = :tipo, activo=:activo WHERE idpersona = :idpersona LIMIT 1; """ ) query.bindValue( ":idpersona", self.navmodel.record( self.mapper.currentIndex() ).value( "idpersona" ).toInt()[0] ) else: query.prepare( """ INSERT INTO personas(nombre,fechaingreso,direccion,telefono,email,ruc,tipopersona,activo) VALUES (:nombre,NOW(),:dir,:tel,:correo,:ruc,:tipo,:activo) """ ) query.bindValue( ":nombre", self.txtnombre.text() ) query.bindValue( ":dir", self.txtdireccion.text() ) query.bindValue( ":tel", self.txttelefono.text() ) query.bindValue( ":correo", self.txtcorreo.text() ) query.bindValue( ":ruc", self.txtruc.text() ) query.bindValue( ":tipo", self.tipo ) query.bindValue( ":activo", 1 if self.rbactivo.isChecked() else 0 ) if not query.exec_(): raise Exception( query.lastError().text() ) QMessageBox.information( None, titulo, "Los cambios fueron guardados" if editado else "El %s fue creado exitosamente" % self.rol ) self.updateModels() self.status = True result = True if editado: self.mapper.setCurrentIndex( pos ) except UserWarning as inst: logging.error( unicode( inst ) ) logging.error( query.lastError().text() ) QMessageBox.critical( self, titulo, unicode( inst ) ) result = False except Exception as inst: logging.critical( unicode( inst ) ) logging.critical( query.lastError().text() ) QMessageBox.critical( self, titulo, "El %s no pudo ser creado" % self.rol ) result = False finally: if self.database.isOpen(): self.database.close() return result def cancel( self ): self.editmodel = None self.status = True self.navigate( 'last' ) def addActionsToToolBar( self ): self.actionEditar = self.createAction( text = "Editar", tip = u"Editar la persona", icon = QIcon.fromTheme( 'document-edit', QIcon( ":/icons/res/document-edit.png" ) ), slot = functools.partial( self._setStatus, 2 ) ) self.toolBar.addActions( [ self.actionEditar ] ) super( FrmPersona, self ).addActionsToToolBar() def setControls( self, status ): if status == 2 and self.navproxymodel.rowCount() == 0: return if status == False: self.txtnombre.setText( "" ) self.txtnombre.setFocus() self.txtdireccion.setText( "" ) self.txtcorreo.setText( "" ) self.txtruc.setText( "" ) self.txttelefono.setText( "" ) self.rbactivo.setChecked( True ) self.txtnombre.setReadOnly( False ) elif status == True: self.tablenavigation.setFocus() self.txtnombre.setReadOnly( True ) else: self.txtdireccion.setFocus() status = False self.tabWidget.setCurrentIndex( 0 if status == False else 1 ) self.rbactivo.setEnabled( not status ) self.rbinactivo.setEnabled( not status ) self.tablenavigation.setEnabled( status ) self.tabnavigation.setEnabled( status ) self.actionNew.setVisible( status ) self.actionCancel.setVisible( not status ) self.actionSave.setVisible( not status ) self.actionEditar.setVisible( status ) self.actionGoFirst.setVisible( status ) self.actionGoLast.setVisible( status ) self.actionGoNext.setVisible( status ) self.actionGoPrevious.setVisible( status ) self.txtcorreo.setReadOnly( status ) self.txtdireccion.setReadOnly( status ) self.txtruc.setReadOnly( status ) self.txttelefono.setReadOnly( status ) def newDocument( self ): self.status = False @pyqtSlot( int ) def on_cbnombre_currentIndexChanged( self, index ): """ asignar proveedor al objeto self.editmodel """ index = self.combomodel.mapToSource( self.combomodel.index( index, 0 ) ) index = index.row() self.personaId = self.personasModel.record( index ).value( "idpersona" ).toInt()[0] self.txtcorreo.setText( self.personasModel.record( index ).value( "email" ).toString() ) self.txtdireccion.setText( self.personasModel.record( index ).value( "direccion" ).toString() ) self.txtruc.setText( self.personasModel.record( index ).value( "ruc" ).toString() ) self.txttelefono.setText( self.personasModel.record( index ).value( "telefono" ).toString() ) @pyqtSlot( unicode ) def on_txtSearch_textChanged( self, searchstring ): """ Cambiar el filtro para el navigation model @param searchstring: Es el contenido por el cual se va a filtrar el modelo de navegación @type searchstring: string """ self.navproxymodel.setFilterFixedString( searchstring )
class FrmArticlesNew( QDialog, Ui_frmArticlesNew ): ''' classdocs ''' def __init__( self, parent = None ): ''' Constructor ''' super( FrmArticlesNew, self ).__init__( parent ) self.user = user.LoggedUser self.setupUi( self ) self.catmodel = CategoriesModel() self.catproxymodel = TreeFilterProxyModel() self.catproxymodel.setSourceModel( self.catmodel ) self.catproxymodel.setFilterKeyColumn( 0 ) self.catproxymodel.setFilterCaseSensitivity( Qt.CaseInsensitive ) self.catvalid = False self.cat_id = 0 self.brand_id = 0 self.isc = Decimal( 0 ) self.dai = Decimal( 0 ) self.comission = Decimal( 0 ) self.profit = Decimal( 0 ) self.categoriesview.setModel( self.catproxymodel ) self.categoriesview.setColumnHidden( 1, True ) self.categoriesview.resizeColumnToContents( 0 ) self.brandsmodel = QSqlQueryModel() self.cargarMarcas() self.brandsproxymodel = QSortFilterProxyModel() self.brandsproxymodel.setSourceModel( self.brandsmodel ) self.brandsproxymodel.setFilterKeyColumn( 1 ) self.brandsproxymodel.setFilterCaseSensitivity( Qt.CaseInsensitive ) self.brandsview.setModel( self.brandsproxymodel ) self.brandsview.setModelColumn( 1 ) self.buttonBox.rejected.connect( self.reject ) self.categoriesview.selectionModel().selectionChanged[QItemSelection, QItemSelection].connect( self.update_category ) self.brandsview.selectionModel().selectionChanged[QItemSelection, QItemSelection].connect( self.updateBrand ) def cargarMarcas( self ): if not QSqlDatabase.database().isOpen(): if not QSqlDatabase.database().open(): raise Exception( "No se pudo abrir la base de datos" ) self.brandsmodel.setQuery( """ SELECT idmarca, nombre FROM marcas """ ) if QSqlDatabase.database().isOpen(): QSqlDatabase.database().close() @pyqtSlot() def on_buttonBox_accepted( self ): if self.valid: if QMessageBox.question( self, qApp.organizationName(), u"¿Esta seguro que desea añadir el producto?", QMessageBox.Ok | QMessageBox.Cancel ) == QMessageBox.Ok: if not self.save(): QMessageBox.critical( self, qApp.organizationName(), u"Lo sentimos pero no se ha"\ + " podido guardar el articulo" ) else: super( FrmArticlesNew, self ).accept() else: QMessageBox.warning( self, qApp.organizationName(), u"Lo sentimos pero los datos no son"\ + " validos, recuerde elegir una subcategoria"\ + " y una marca" ) def save( self ): """ Guardar el nuevo articulo en la base de datos """ query = QSqlQuery() result = False try: if not QSqlDatabase.database().isOpen(): if not QSqlDatabase.open(): raise UserWarning( u"No se pudo conectar con la"\ + " base de datos" ) query.prepare( """ CALL spAgregarArticulos( :activo, :marca, :subcategoria, :dai, :isc, :comision, :ganancia ) """ ) query.bindValue( ":activo", 1 ) query.bindValue( ":marca", self.brand_id ) query.bindValue( ":subcategoria", self.cat_id ) query.bindValue( ":dai", str( self.dai ) ) query.bindValue( ":isc", str( self.isc ) ) query.bindValue( ":comision", str( self.comission ) ) query.bindValue( ":ganancia", str( self.profit ) ) if not query.exec_(): raise Exception( "No se pudo ejecutar la consulta" ) result = True except UserWarning as inst: logging.error( query.lastError().text() ) logging.error( unicode( inst ) ) except Exception as inst: logging.critical( query.lastError().text() ) logging.critical( unicode( inst ) ) return result @pyqtSlot( unicode ) def on_txtCategorySearch_textChanged( self, text ): self.catproxymodel.setFilterFixedString( text ) @pyqtSlot( unicode ) def on_txtBrandSearch_textChanged( self, text ): self.brandsproxymodel.setFilterFixedString( text ) @property def valid( self ): return self.catvalid and self.brand_id != 0 @pyqtSlot() def on_btnAgregarMarca_pressed( self ): marca = ["", True] marca_descripcion = "" while marca_descripcion == "" and marca[1] == True: marca = QInputDialog.getText( self, "Agregar Marca", "Ingrese la Marca" ) marca_descripcion = marca[0].strip() if marca_descripcion != "": proxy = self.brandsproxymodel proxy.setFilterRegExp( "^" + marca_descripcion + "$" ) if proxy.rowCount() > 0: QMessageBox.information( None, "Crear Marca", "La marca %s ya existe" % marca_descripcion ) marca = ["", True] marca_descripcion = "" self.brandsproxymodel.setFilterRegExp( "" ) if marca[1]: if QMessageBox.question( self, qApp.organizationName(), u"¿Está seguro que desea crear la marca %s ?" % marca_descripcion, QMessageBox.Yes | QMessageBox.No ) == QMessageBox.Yes: if not QSqlDatabase.database().isOpen(): if not QSqlDatabase.database().open(): raise Exception( "No se pudo abrir la base de datos" ) query = QSqlQuery() query.prepare( "INSERT INTO marcas(nombre) VALUES (:marca)" ) query.bindValue( ":marca", marca_descripcion ) if not query.exec_(): logging.error( query.lastError().text() ) QMessageBox.warning( None, "Error al crear la marca", "No se pudo insertar la marca" ) else: self.cargarMarcas() @pyqtSlot( float ) def on_sbDAI_valueChanged( self, value ): try: self.dai = Decimal( str( value ) ) except ValueError: self.dai = 0 @pyqtSlot( float ) def on_sbISC_valueChanged( self, value ): try: self.isc = Decimal( str( value ) ) except ValueError: self.isc = 0 @pyqtSlot( float ) def on_sbComission_valueChanged( self, value ): try: self.comission = Decimal( str( value ) ) except ValueError: self.comission = 0 @pyqtSlot( float ) def on_sbProfit_valueChanged( self, value ): try: self.profit = Decimal( str( value ) ) except ValueError: self.profit = 0 def updateBrand( self, selected, _deselected ): if self.brandsproxymodel.rowCount() >= 0: self.brand_id = self.brandsproxymodel.index( selected.indexes()[0].row(), 0 ).data().toInt()[0] def update_category( self, selected, _deselected ): try: row = selected.indexes()[0].row() parent = selected.indexes()[0].parent() self.catvalid = parent.data().toString() != "" self.cat_id = self.catproxymodel.data( self.catproxymodel.index( row, 1, parent ), Qt.DisplayRole ) except IndexError: pass
class DlgPais(QDialog, Ui_DlgPais): def __init__(self, parent): ''' Constructor ''' super(DlgPais, self).__init__(parent) self.setupUi(self) self.table = "" self.backmodel = QSqlQueryModel() self.database = parent.database self.filtermodel = QSortFilterProxyModel(self) self.filtermodel.setSourceModel(self.backmodel) self.filtermodel.setDynamicSortFilter(True) self.filtermodel.setFilterKeyColumn(-1) self.filtermodel.setFilterCaseSensitivity(Qt.CaseInsensitive) # self.tableview.setModel(self.filtermodel) self.setReadOnly(True) QTimer.singleShot(0, self.updateModels) @pyqtSlot("QString") def on_txtSearch_textChanged(self, text): """ Cambiar el filtro de busqueda """ self.filtermodel.setFilterRegExp(text) def setReadOnly(self, status): self.txtSearch.setText("") if status: self.editmodel = None self.swpanel.setCurrentIndex(0) self.txtnombre.setText("") self.txtcodigo.setText("") else: self.editmodel = PaisModel(self.database) self.swpanel.setCurrentIndex(1) # # if status: # self.tableview.setEditTriggers( QAbstractItemView.AllEditTriggers ) ## self.tableview.edit( self.tableview.selectionModel().currentIndex() ) # else: # self.tableview.setEditTriggers( QAbstractItemView.NoEditTriggers ) # # self.actionNew.setVisible( status ) # self.actionEdit.setVisible( status ) # self.actionDelete.setVisible( status ) # self.actionCancel.setVisible( not status ) # self.actionSave.setVisible(not status ) # self.backmodel.readOnly = status def updateModels(self): """ Actualizar los modelos, despues de toda operacion que cambie la base de datos se tienen que actualizar los modelos """ try: if not self.database.isOpen(): if not self.database.open(): raise UserWarning( u"No se pudo conectar con la base de datos") self.backmodel.setQuery( "Select codigoarea as 'Codigo Area' , nombre as Pais from paises" ) self.tableview.setModel(self.filtermodel) # self.tableview.setColumnHidden(0,True) # self.tableview.setColumnWidth(0,200) # self.tableview.set self.database.close() except: return False finally: if self.database.isOpen(): self.database.close() return True @pyqtSlot() def on_btnadd_clicked(self): self.setReadOnly(False) @pyqtSlot() def on_btncancelar_clicked(self): self.setReadOnly(True) @pyqtSlot() def on_btnguardar_clicked(self): self.editmodel.nombre = self.txtnombre.text() self.editmodel.codigo = self.txtcodigo.text() if self.editmodel.valid(): if self.editmodel.save(): QMessageBox.information(None, "Guardar", self.editmodel.mensaje) self.setReadOnly(True) self.updateModels() else: QMessageBox.critical(None, "Guardar", self.editmodel.mensaje) else: QMessageBox.critical(None, "Guardar", self.editmodel.mensaje)
class SrwrLookup: def __init__(self, iface, db, srwr_lu_dia): self.iface = iface self.db = db self.srwr_lu_dia = srwr_lu_dia self.connect_buttons() self.items_model = None self.data_model = None self.queries = { 0: """SELECT designation_code, (designation_code || ' : ' || designation_text) AS 'display' FROM tlkpSPEC_DES ORDER BY designation_code""", 1: """SELECT reinstatement_code, (reinstatement_code || ' : ' || description) AS 'display' FROM tlkpREINS_CAT ORDER BY reinstatement_code""", 2: """SELECT road_status_ref, (road_status_ref || ' : ' || Description) AS 'display' FROM tlkpROAD_STATUS ORDER BY road_status_ref""" } self.tables = { 0: "tlkpSPEC_DES", 1: "tlkpREINS_CAT", 2: "tlkpROAD_STATUS" } self.columns = { 0: "designation_code", 1: "reinstatement_code", 2: "road_status_ref" } self.amend_queries = { 0: """UPDATE tlkpSPEC_DES SET designation_text = '{0}' WHERE designation_code = {1} """, 1: """UPDATE tlkpREINS_CAT SET description = '{0}' WHERE reinstatement_code = {1} """, 2: """UPDATE tlkpROAD_STATUS SET Description = '{0}' WHERE road_status_ref = {1}""" } self.changes_made = False # Setup initial view self.srwr_lu_dia.ui.desRadioButton.setChecked(True) self.populate_list(0) def connect_buttons(self): """ events handler for buttons in the form :return: object """ self.srwr_lu_dia.ui.addButton.clicked.connect(self.add_lookup) self.srwr_lu_dia.ui.removeButton.clicked.connect(self.remove_lookup) self.srwr_lu_dia.ui.amendButton.clicked.connect(self.amend_lookup) self.srwr_lu_dia.ui.closeButton.clicked.connect(self.close_browser) self.srwr_lu_dia.ui.desRadioButton.pressed.connect( lambda: self.populate_list(0)) self.srwr_lu_dia.ui.reinsRadioButton.pressed.connect( lambda: self.populate_list(1)) self.srwr_lu_dia.ui.statRadioButton.pressed.connect( lambda: self.populate_list(2)) self.srwr_lu_dia.ui.itemsListView.pressed.connect( lambda: self.selection_handler()) def close_browser(self): # close the dialog window if self.changes_made: changes_made_msg_box = QMessageBox( QMessageBox.Information, " ", "SRWR lookup tables updated.\n\n" "Restart roadNet to populate menus with new values.", QMessageBox.Ok, None) changes_made_msg_box.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowTitleHint) changes_made_msg_box.exec_() self.srwr_lu_dia.close() def populate_list(self, table_id): """ populate the list view on initialisation and when radio buttons are toggled, this view is just for show because QSqlQueryModel class does not handle editing but data need to be displayed as concatenated strings, this is not allowed in a QSqlTableModel class :param table_id: the id passed from the radio button :return: void """ self.srwr_lu_dia.ui.typeDescLineEdit.clear() self.items_model = QSqlQueryModel() self.items_model.setQuery(self.queries[table_id], self.db) while self.items_model.canFetchMore(): self.items_model.fetchMore() self.srwr_lu_dia.ui.typeNoSpinBox.setValue(0) self.srwr_lu_dia.ui.itemsListView.setModel(self.items_model) self.srwr_lu_dia.ui.itemsListView.setModelColumn(1) self.create_data_model(table_id) def create_data_model(self, table_id): """ create an object from the QSqlTableModel class used to data modifications to send to the database :param table_id: the id passed from the radio button :return: void """ self.data_model = QSqlTableModel(db=self.db) self.data_model.setTable(self.tables[table_id]) self.data_model.setEditStrategy(QSqlTableModel.OnManualSubmit) self.data_model.setSort(2, Qt.AscendingOrder) self.data_model.select() while self.data_model.canFetchMore(): self.data_model.fetchMore() def add_lookup(self): """ get the max value each table model and increment of 1 add a record to the database when the add button is pressed with the incremented value :return: void """ ui = self.srwr_lu_dia.ui if ui.desRadioButton.isChecked(): table_id = 0 table = self.tables[table_id] ref_col = self.columns[0] elif ui.reinsRadioButton.isChecked(): table_id = 1 table = self.tables[table_id] ref_col = self.columns[1] elif ui.statRadioButton.isChecked(): table_id = 2 table = self.tables[table_id] ref_col = self.columns[2] # format text and numbers add_desc = str(ui.typeDescLineEdit.text()).strip() add_desc.replace("'", "''") add_code = ui.typeNoSpinBox.value() if add_desc == "" or add_code is None: desc_error_msg_box = QMessageBox( QMessageBox.Warning, " ", "You must enter the code AND description", QMessageBox.Ok, None) desc_error_msg_box.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowTitleHint) desc_error_msg_box.exec_() return # avoid duplicate insertion on double click on 'Add' button sel_model = ui.itemsListView.selectionModel() if sel_model.selectedIndexes(): # extracts just the id from the string sel_items = sel_model.selectedIndexes()[0] item_data = str(sel_items.data()) p = re.compile("([0-9]{1,3})(?=\s:)") src = p.search(item_data) item_id = int(src.group(1)) if item_id == add_code: dups_error_msg_box = QMessageBox( QMessageBox.Warning, " ", "Cannot add duplicate values", QMessageBox.Ok, None) dups_error_msg_box.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowTitleHint) dups_error_msg_box.exec_() return # Avoid duplicate insertion by checking database sql_find_duplicates = """SELECT {0} FROM {1} WHERE {0} IS '{2}'""".format( ref_col, table, add_code) if config.DEBUG_MODE: print( 'DEBUG_MODE: find_duplicates: {}'.format(sql_find_duplicates)) query = QSqlQuery(sql_find_duplicates, self.db) if query.first(): # False unless value already found in table dup_values_msg_box = QMessageBox(QMessageBox.Warning, " ", "Cannot add duplicate values", QMessageBox.Ok, None) dup_values_msg_box.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowTitleHint) dup_values_msg_box.exec_() return # create the record to insert data_model_idx = self.data_model.createIndex( self.data_model.rowCount() - 1, 0) insert_record = self.data_model.record(self.items_model.rowCount()) insert_record.setValue(1, add_code) insert_record.setValue(2, add_desc) insert_record.setValue(3, str("")) insert_record.setValue(4, str("")) self.data_model.insertRecord(self.items_model.rowCount(), insert_record) if self.data_model.submitAll(): # clear the line input and selects the newly created value on the list ui.typeDescLineEdit.clear() ui.typeNoSpinBox.setValue(1) self.populate_list(table_id) index = ui.itemsListView.model().createIndex( self.items_model.rowCount() - 1, 1) ui.itemsListView.setCurrentIndex(index) self.changes_made = True else: db_error_msg_box = QMessageBox( QMessageBox.Warning, " ", "Error: {}".format(self.data_model.lastError().text()), QMessageBox.Ok, None) db_error_msg_box.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowTitleHint) db_error_msg_box.exec_() return def selection_handler(self, table_id=None): """ Populate the typeNoSpinBox and typeDescLineEdit with data from the selected row in the list. The data are extracted from the string value itself, without reference to the original model. :return void: """ # print all selected list items to the text box sel_model = self.srwr_lu_dia.ui.itemsListView.selectionModel() sel_items = sel_model.selectedIndexes()[0] item_data = str(sel_items.data()) # split text from the code number p = re.compile("\:(.*)") src = p.search(item_data) item_text = str(src.group(1)[1:]) p = re.compile("([0-9]{1,3})(?=\s:)") src = p.search(item_data) item_id = int(src.group(1)) self.srwr_lu_dia.ui.typeNoSpinBox.setValue(item_id) self.srwr_lu_dia.ui.typeDescLineEdit.setText(item_text) def remove_lookup(self): """ this function deletes selected items from the list view and db, only if the lookups are not used, in this case it prevents the removal displaying the list of the streets that use the lookup :return: void """ ui = self.srwr_lu_dia.ui if ui.desRadioButton.isChecked(): table_id = 0 table = self.tables[table_id] ref_col = self.columns[0] sql_usrns = "SELECT usrn FROM tblSPEC_DES WHERE " \ "(designation_code = {0} AND currency_flag=0);" \ .format(str(ui.typeNoSpinBox.value())) elif ui.reinsRadioButton.isChecked(): table_id = 1 table = self.tables[table_id] ref_col = self.columns[1] sql_usrns = "SELECT usrn FROM tblREINS_CAT WHERE " \ "(reinstatement_code = {0} AND currency_flag=0);" \ .format(str(ui.typeNoSpinBox.value())) elif ui.statRadioButton.isChecked(): table_id = 2 table = self.tables[table_id] ref_col = self.columns[2] sql_usrns = "SELECT usrn FROM tblMaint WHERE " \ "(road_status_ref = {0} AND currency_flag=0);" \ .format(str(ui.typeNoSpinBox.value())) data_model = self.data_model item_text = ui.typeDescLineEdit.text() item_ref = ui.typeNoSpinBox.value() selection_model = ui.itemsListView.selectionModel() try: item_to_remove = selection_model.selectedIndexes()[0] except IndexError: # Throws if nothing selected return # prevent deleting the default lookup just for designation and road status if table_id == 0 or table_id == 2: if item_text == "-none-" or item_ref == 0: # not_remove_message = self.srwr_lu_dia.ui.removeButton remove_error_msg_box = QMessageBox( QMessageBox.Warning, " ", "This item cannot be removed", QMessageBox.Ok, None) remove_error_msg_box.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowTitleHint) remove_error_msg_box.exec_() return # Check for USRNs that use this item query = QSqlQuery(sql_usrns, self.db) usrns = [] while query.next(): usrns.append(str(query.value(0))) if len(usrns) > 0: # Create a message message = ("This item cannot be deleted because is used by the " "following streets: \n") usrns_string = ', '.join(usrns[:20]) if len(usrns) > 20: usrns_string += ' and more...' long_message = message + usrns_string # Display warning message in box, then exit item_not_deletable_msg_box = QMessageBox(QMessageBox.Warning, " ", long_message, QMessageBox.Ok, None) item_not_deletable_msg_box.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowTitleHint) item_not_deletable_msg_box.exec_() return # Remove selected row and clear the line edit sql_remove_item = """DELETE FROM {} WHERE {} IS {};""".format(table, ref_col, item_ref) if config.DEBUG_MODE: print('DEBUG_MODE: remove_item: {}'.format(sql_remove_item)) query = QSqlQuery(sql_remove_item, self.db) # Query is excuted here ui.typeDescLineEdit.clear() # Check the delete was successful if query.numRowsAffected > 0: # Repopulate table and select previous item in list self.populate_list(table_id) if item_to_remove.row() == 0: index = ui.itemsListView.model().createIndex(0, 1) else: index = ui.itemsListView.model().createIndex( item_to_remove.row() - 1, 1) ui.itemsListView.setCurrentIndex(index) self.selection_handler(table_id) self.changes_made = True else: db_error_msg_box = QMessageBox( QMessageBox.Warning, " ", "Error: {}".format(data_model.lastError.text(), QMessageBox.Ok, None)) db_error_msg_box.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowTitleHint) db_error_msg_box.exec_() return def amend_lookup(self): """ change the value of existing lookup items, this time are used db queries :return: void """ table_id = None if self.srwr_lu_dia.ui.typeDescLineEdit.text() == "": return item_id = self.srwr_lu_dia.ui.typeNoSpinBox.value() selection_model = self.srwr_lu_dia.ui.itemsListView.selectionModel() selection_indexes = selection_model.selectedIndexes() # if nothing is selects exit the function if not selection_indexes: return selection_index = selection_indexes[0] if selection_index.data() == "0 : -none-": # if the selected value is -none- fire an alert not_edit_msg_box = QMessageBox(QMessageBox.Warning, " ", "This item cannot be edited", QMessageBox.Ok, None) not_edit_msg_box.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowTitleHint) not_edit_msg_box.exec_() return # changes the values directly onto the db des_radio_btn = self.srwr_lu_dia.ui.desRadioButton reins_radio_btn = self.srwr_lu_dia.ui.reinsRadioButton stat_radio_btn = self.srwr_lu_dia.ui.statRadioButton amend_query = QSqlQuery(self.db) if des_radio_btn.isChecked(): table_id = 0 format_query = self.amend_queries[0].format( self.srwr_lu_dia.ui.typeDescLineEdit.text(), item_id) if not amend_query.exec_(format_query): db_error_msg_box = QMessageBox( QMessageBox.Warning, " ", "Error: {}".format(amend_query.lastError().text()), QMessageBox.Ok, None) db_error_msg_box.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowTitleHint) db_error_msg_box.exec_() if reins_radio_btn.isChecked(): table_id = 1 format_query = self.amend_queries[1].format( self.srwr_lu_dia.ui.typeDescLineEdit.text(), item_id) if not amend_query.exec_(format_query): db_error_msg_box = QMessageBox( QMessageBox.Warning, " ", "Error: {}".format(amend_query.lastError().text()), QMessageBox.Ok, None) db_error_msg_box.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowTitleHint) db_error_msg_box.exec_() if stat_radio_btn.isChecked(): table_id = 2 format_query = self.amend_queries[2].format( self.srwr_lu_dia.ui.typeDescLineEdit.text(), item_id) if not amend_query.exec_(format_query): db_error_msg_box = QMessageBox( QMessageBox.Warning, " ", "Error: {}".format(amend_query.lastError().text()), QMessageBox.Ok, None) db_error_msg_box.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowTitleHint) db_error_msg_box.exec_() # closes the query and repopulate the list self.changes_made = True amend_query.clear() self.populate_list(table_id)
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
class tbFactura(QTabWidget, Ui_tbFactura): """ Implementacion de la interfaz grafica para facturas """ web = "facturas.php?doc=" DATE_FORMAT = "dd/MM/yyyy" def __init__(self): ''' Constructor ''' super(tbFactura, self).__init__() # ESTABLECER LA INTERFAZ AL FORMULARIO self.setupUi(self) # VALIDADOR DE MODO DE EDICION self.readOnly = True self.editmodel = None #ESTABLECER LA FECHA INICIAL , (establecida al dia de mañana) self.categoriesview.headers = [ "Descripcion", "Precio", "Unidades", "Existencia", "", "", "" ] # Crear el modelo para cargar catalogo de clientes self.clientesModel = QSqlQueryModel() # Crear lista de autocompletado para el combo de clientes self.clienteCompleter = QCompleter() # Modelo que carga el catalogo de productos self.existenciaModel = QSqlQueryModel() # Establecer todos los controles en modo de edicion self.setControls(False) # Crear la conexion a la base de datos self.database = QSqlDatabase.database() self.vistaprevia = False # Cargar los modelos del modo de edicion self.updateEditModels() self.parent = self.parent() def newDocument(self): """ activar todos los controles, llenar los modelos necesarios, crear el modelo FacturaModel, aniadir una linea a la tabla """ self.readOnly = False if not self.updateEditModels(): return self.status = False self.dtPicker.setDate(self.parentWindow.datosSesion.fecha) def updateEditModels(self): """ Este metodo actualiza los modelos usados en el modo edición """ resultado = False 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" ) self.clientesModel.setQuery(""" SELECT idpersona , nombre AS cliente FROM personas WHERE escliente = 1 """) self.cbcliente.setModel(self.clientesModel) self.cbcliente.setModelColumn(1) self.clienteCompleter.setCaseSensitivity(Qt.CaseInsensitive) self.clienteCompleter.setModel(self.clientesModel) self.clienteCompleter.setCompletionColumn(1) self.cbcliente.setCompleter(self.clienteCompleter) self.editmodel = FacturaModel() # Cargar el numero de la factura actual query = QSqlQuery(""" SELECT MAX(CAST( IFNULL(referencia,0) AS SIGNED)) FROM documentos d WHERE idtipodoc =%d; """ % constantes.IDFACTURA) if not query.exec_(): raise Exception("No se pudo obtener el numero de la factura") query.first() if query.size() == 0: n = 1 else: n = str(int(query.value(0)) + 1) self.editmodel.printedDocumentNumber = str( int(query.value(0)) + 1) self.lblnumero.setText(n) # if self.clientesModel.rowCount() == 0: # raise UserWarning( "No existen clientes en la"\ # + " base de datos" ) # return self.clienteCompleter.setModel(self.clientesModel) self.cbcliente.setModel(self.clientesModel) self.cbcliente.setCompleter(self.clienteCompleter) # #Crear el delegado con los articulo y verificar si existen articulos self.existenciaModel.setQuery( QSqlQuery(""" SELECT categoria, descripcion, precio, unidadesxcaja, -- cajas, 100 as cajas, idprecioproducto FROM vw_articulos -- WHERE existencia >0 """)) self.categoriesview.update(""" SELECT categoria, descripcion, precio, unidadesxcaja, -- cajas, 100 as cajas, idprecioproducto FROM vw_articulos WHERE idprecioproducto IS NOT NULL -- WHERE existencia >0 """) self.categoriesview.expandAll() self.categoriesview.setColumnHidden(3, True) self.categoriesview.setColumnHidden(4, True) self.categoriesview.setColumnWidth(0, 150) self.categoriesview.setColumnWidth(1, 60) self.categoriesview.setColumnWidth(2, 20) self.proxyexistenciaModel = SingleSelectionModel() self.proxyexistenciaModel.setSourceModel(self.existenciaModel) # self.proxyexistenciaModel.setFilterKeyColumn( IDBODEGAEX ) if self.proxyexistenciaModel.rowCount() == 0: raise UserWarning("No hay articulos en bodega") delegate = FacturaDelegate(self.proxyexistenciaModel) self.tabledetails.setItemDelegate(delegate) self.tabledetails.setModel(self.editmodel) self.tabledetails.setColumnHidden(0, True) # self.editmodel.insertRow(1) self.editmodel.dataChanged[QModelIndex, QModelIndex].connect(self.updateLabels) self.txtobservaciones.setPlainText("") self.dtPicker.setDate(QDate.currentDate().addDays(1)) self.editmodel.fecha = QDate.currentDate().addDays(1) self.cbcliente.setCurrentIndex(-1) resultado = True except UserWarning as inst: logging.error(unicode(inst)) QMessageBox.critical(self, qApp.organizationName(), unicode(inst)) finally: if self.database.isOpen(): self.database.close() return resultado def addActionsToToolBar(self): self.actionRefresh = self.createAction( text="Actualizar", icon=QIcon.fromTheme('view-refresh', QIcon(":/icons/res/view-refresh.png")), slot=self.refresh, shortcut=Qt.Key_F5) self.toolBar.addActions([ self.actionNew, self.actionRefresh, self.actionPreview, self.actionPrint, self.actionSave, self.actionCancel, ]) self.toolBar.addSeparator() self.toolBar.addActions([ self.actionGoFirst, self.actionGoPrevious, self.actionGoLast, self.actionGoNext, self.actionGoLast ]) def refresh(self): """ Actualizar los modelos de edición """ if not self.status: if QMessageBox.question( self, qApp.organizationName(), u"Se perderán todos los cambios en la factura. ¿Esta seguro que desea actualizar?", QMessageBox.Yes | QMessageBox.No) == QMessageBox.No: return self.updateEditModels() else: if self.updateModels(): QMessageBox.information( None, "Factura", u"Los datos fueron actualizados con éxito") def printDocument1(self): html = u"" date = QDate.currentDate().toString(self.DATE_FORMAT) address = Qt.escape("Bario francisco mesa").replace(",", "<br>") contact = Qt.escape("Luis Mejia") balance = 5000 html += ("<p align=right><img src=':/logo.png'></p>" "<p> align = right>Greasy hands ltd." "<br>New Lombard Street" "<br>London<br>WC13 4PX<br>%s</p>" "<p>%s</p><p>Dear %s, </p>" "<p>The balance of your account is %s.") % ( date, address, contact, QString("$ %L1").arg( float(balance), 0, "f", 2)) if balance < 0: html += ( "<p><font color =red><b> Please remit the amount owing immediately.</b></font>" ) else: html += "We are delighted to have done business with you." html += ( "</p><p> </p><p>" "<table border=1 cellpadding=2 cellspacing=2><tr><td colspan=3>Transaction</td></tr>" ) transactions = [(QDate.currentDate(), 500), (QDate.currentDate(), 500), (QDate.currentDate(), -500), (QDate.currentDate(), 500)] for date, amount in transactions: color, status = "black", "Credit" if amount < 0: color, status = "red", "Debid" html += ( "<tr>" "<td align= right>%s</td>" "<td>%s</td><td align=right><font color=%s>%s</font></td></tr>" % (date.toString(self.DATE_FORMAT), status, color, QString("$ %L1").arg(float(abs(amount)), 0, "f", 2))) html += ("</table></p><p style='page-break-after=always;'>" "We hope to continue doing business with you</p>") pdialog = QPrintDialog() if pdialog.exec_() == QDialog.Accepted: printer = pdialog.printer() document = QTextDocument() document.setHtml(html) document.print_(printer) def printDocument2(self): dialog = QPrintDialog() if not dialog.exec_(): return self.printer = dialog.printer() headFormat = QTextBlockFormat() headFormat.setAlignment(Qt.AlignLeft) headFormat.setTextIndent(self.printer.pageRect().width() - 216) bodyFormat = QTextBlockFormat() bodyFormat.setAlignment(Qt.AlignJustify) lastParaBodyFormat = QTextBlockFormat(bodyFormat) lastParaBodyFormat.setPageBreakPolicy( QTextFormat.PageBreak_AlwaysAfter) rightBodyFormat = QTextBlockFormat() rightBodyFormat.setAlignment(Qt.AlignRight) headCharFormat = QTextCharFormat() headCharFormat.setFont(QFont("Helvetica", 10)) bodyCharFormat = QTextCharFormat() bodyCharFormat.setFont(QFont("Times", 11)) redBodyCharFormat = QTextCharFormat(bodyCharFormat) redBodyCharFormat.setForeground(Qt.red) tableFormat = QTextTableFormat() tableFormat.setBorder(1) tableFormat.setCellPadding(2) document = QTextDocument() cursor = QTextCursor(document) mainFrame = cursor.currentFrame() page = 1 cursor.insertBlock(headFormat, headCharFormat) for text in ("Greasy Hands Ltd.", "New Lombard Street", "London", "WC13", QDate.currentDate().toString(self.DATE_FORMAT)): cursor.insertBlock(headFormat, headCharFormat) cursor.insertText(text) cursor.insertBlock(bodyFormat, bodyCharFormat) cursor.insertText("Barrio Francisco Meza") cursor.insertBlock(bodyFormat) cursor.insertBlock(bodyFormat, bodyCharFormat) cursor.insertText("Dear Lyuis") cursor.insertBlock(bodyFormat) cursor.insertBlock(bodyFormat, bodyCharFormat) cursor.insertText( QString("The balance of your account is $ %L1.").arg( float(500.987), 0, "f", 2)) cursor.insertBlock(bodyFormat, redBodyCharFormat) cursor.insertText("Please remit the amount") cursor.insertBlock(bodyFormat, bodyCharFormat) cursor.insertText("Transaction") transactions = [(QDate.currentDate(), 500), (QDate.currentDate(), 500), (QDate.currentDate(), -500), (QDate.currentDate(), 500)] table = cursor.insertTable(len(transactions), 3, tableFormat) row = 0 for date, amount in transactions: cellCursor = table.cellAt(row, 0).firstCursorPosition() cellCursor.setBlockFormat(rightBodyFormat) cellCursor.insertText(date.toString(self.DATE_FORMAT), bodyCharFormat) cellCursor = table.cellAt(row, 1).firstCursorPosition() cellCursor.insertText("Credit", bodyCharFormat) cellCursor = table.cellAt(row, 2).firstCursorPosition() cellCursor.setBlockFormat(rightBodyFormat) cellCursor.insertText( QString("The balance of your account is $ %L1.").arg( float(amount), 0, "f", 2), redBodyCharFormat) row += 1 cursor.setPosition(mainFrame.lastPosition()) cursor.insertBlock(bodyFormat, bodyCharFormat) cursor.insertText("We hope") document.print_(self.printer) def printDocument(self): dialog = QPrintDialog() if not dialog.exec_(): return self.printer = dialog.printer() self.imprimir(self.printer) self.document.load(self.editmodel) def preview(self): self.vistaprevia = True preview = frmImpresion(self) preview.exec_() def save(self): """ Guardar el documento actual @rtype: bool """ result = False try: if not self.valid: return False if QMessageBox.question( self, qApp.organizationName(), u"¿Esta seguro que desea guardar la factura?", QMessageBox.Yes | QMessageBox.No) == QMessageBox.Yes: if not self.database.isOpen(): if not self.database.open(): raise UserWarning( u"No se pudo conectar con la base de datos") self.editmodel.observaciones = self.txtobservaciones.toPlainText( ) if not self.editmodel.save(): raise UserWarning("No se ha podido guardar la factura") QMessageBox.information( None, qApp.organizationName(), u"""El documento se ha guardado con éxito""") self.readOnly = True self.updateModels() # self.navigate( 'last' ) # self.status = True result = True 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 guardar la factura") finally: if self.database.isOpen(): self.database.close() return result # @pyqtSlot(QModelIndex) # def on_categoriesview_doubleClicked(self,index): @pyqtSlot(QModelIndex) def on_categoriesview_activated(self, index): articulo = self.categoriesview.model().asRecord(index) if len(articulo) > 0: nuevo = True for i, line in enumerate(self.editmodel.lines): if line.itemId == articulo[5]: nuevo = False fila = i line = self.editmodel.lines[self.editmodel.rowCount() - 1] if nuevo: fila = self.editmodel.rowCount() self.editmodel.insertRow(fila) self.parent.saveAct.setEnabled(True) linea = self.editmodel.lines[fila] linea.itemDescription = articulo[0] + " " + articulo[1] linea.itemPrice = Decimal(articulo[2]) linea.itemId = articulo[5] linea.quantityperbox = int(articulo[3]) self.editmodel.lines[fila].quantity += 1 self.editmodel.lines[fila].existencia = int( articulo[4]) - self.editmodel.lines[fila].quantity indice = self.editmodel.index(fila, 2) self.editmodel.dataChanged.emit(indice, indice) indice = self.editmodel.index(fila, 3) self.editmodel.dataChanged.emit(indice, indice) indice = self.editmodel.index(fila, 5) self.editmodel.dataChanged.emit(indice, indice) @pyqtSlot() def on_btneditar_clicked(self): articulo = dlgArticulo(self) articulo.exec_() self.updateEditModels() @pyqtSlot(int) def on_cbcliente_currentIndexChanged(self, index): """ asignar proveedor al objeto self.editmodel """ if self.editmodel is not None: numero = self.clientesModel.record(index).value("idpersona") self.editmodel.clienteId = int(numero) if numero is not None else 0 @pyqtSlot(unicode) def on_cbcliente_editTextChanged(self, text): """ asignar proveedor al objeto self.editmodel """ if self.editmodel is not None: self.editmodel.cliente = str(text) @pyqtSlot(int) def on_cbvendedor_currentIndexChanged(self, index): """ asignar proveedor al objeto self.editmodel """ self.editmodel.vendedorId = self.vendedoresModel.record(index).value( "idpersona").toInt()[0] @pyqtSlot(QDate) def on_dtPicker_dateChanged(self, date): if self.editmodel is not None: self.editmodel.fecha = date @pyqtSlot(bool) def on_rbcontado_toggled(self, on): """ Asignar las observaciones al objeto editmodel """ self.editmodel.escontado = 1 if on else 0 def on_txtSearch_textChanged(self, text): """ Cambiar el filtro de busqueda """ self.filtermodel.setFilterRegExp(text) def setControls(self, status): """ @param status: false = editando true = navegando """ # self.actionPrint.setVisible( status ) self.readOnly = status self.txtobservaciones.setReadOnly(status) # self.actionPreview.setVisible( status ) # self.actionAnular.setVisible( status ) # self.toolBar.setVisible(status) # self.lblnfac.setText( self.editmodel.printedDocumentNumber ) self.swcliente.setCurrentIndex(0) self.lbltotal.setText("C$ 0.00") self.tabledetails.setEditTriggers(QAbstractItemView.AllEditTriggers) # self.lblanulado.setHidden( True ) self.tabledetails.horizontalHeader().setStretchLastSection(True) self.tabledetails.setColumnHidden(IDARTICULO, True) self.tabledetails.setColumnHidden(IDDOCUMENTOT, True) def updateLabels(self): self.lbltotal.setText(moneyfmt(self.editmodel.total, 2, "C$ ")) @property def valid(self): """ Un documento es valido cuando self.printedDocumentNumber != "" self.providerId !=0 self.validLines >0 self.ivaId !=0 self.uid != 0 self.warehouseId != 0 """ if int(self.editmodel.clienteId) == 0 and self.editmodel.cliente == "": QMessageBox.warning(self, qApp.organizationName(), "Por favor elija el cliente") self.cbcliente.setFocus() elif self.editmodel.rowCount() == 0: QMessageBox.warning( self, qApp.organizationName(), "Por favor agregue algun articulo a la factura") else: return True return False def imprimir(self, printer): leftMargin = 72 widthCol = 100 arialFont = QFont("Helvetica", 16, 3) fuente = QFontMetrics(arialFont) arialLineHeight = fuente.height() fondo = QPixmap(":/images/res/fondo.png") painter = QPainter(printer) pageRect = printer.pageRect() page = 1 painter.save() if self.vistaprevia: painter.drawPixmap(0, 0, 530, 830, fondo) painter.setFont(arialFont) y = 180 x = 35 painter.drawText(x, y, self.editmodel.fecha.toString("dd MM yy")) y = 210 x = 85 painter.drawText(x, y, self.editmodel.cliente) painter.setFont(arialFont) cajasFont = QFont("Helvetica", 10, 2) x = -5 y = 295 painter.setFont(cajasFont) painter.drawText(x, y - arialLineHeight - 1, "Cajas") for row in self.editmodel.lines: painter.setFont(cajasFont) x = 2 painter.drawText(x, y, row.cantidad()) painter.setFont(arialFont) total = moneyfmt(row.total, 2, "") x = 470 - fuente.width(total) painter.drawText(x, y, total) x = 310 painter.drawText(x, y, moneyfmt(row.itemPrice, 2, "")) x = 30 painter.drawText(x, y, row.unidades()) x = 80 painter.drawText(x, y, row.itemDescription) y += arialLineHeight total = moneyfmt(self.editmodel.total, 2, "") y = 690 x = 470 - fuente.width(total) painter.drawText(x, y, total) painter.setPen(Qt.black) # printer.newPage() painter.restore()