Example #1
0
 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()
Example #2
0
    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()  
Example #3
0
    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)
Example #4
0
    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
Example #6
0
    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)
Example #7
0
 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()) 
Example #8
0
 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())
Example #9
0
    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()
Example #10
0
    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
Example #11
0
 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())
Example #12
0
 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()) 
Example #13
0
 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()
Example #14
0
 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()
Example #17
0
    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())
Example #18
0
 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()
Example #20
0
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
Example #21
0
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)
Example #22
0
 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()
Example #23
0
 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
Example #26
0
    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)
Example #27
0
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))
Example #29
0
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_()
Example #30
0
    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()
Example #31
0
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
Example #32
0
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()
Example #33
0
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>&nbsp;</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()
Example #34
0
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)
Example #36
0
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_()

Example #38
0
    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)
Example #39
0
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")
Example #42
0
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]
Example #43
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()
Example #44
0
    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)
Example #45
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_())
Example #46
0
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 )
Example #47
0
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()
Example #48
0
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()
Example #49
0
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 )
Example #50
0
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 )
Example #51
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()
Example #52
0
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()
Example #53
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()
Example #54
0
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
Example #55
0
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 )
Example #56
0
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
Example #57
0
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)
Example #58
0
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)
Example #59
0
class FrmDevolucion( Ui_frmDevoluciones, Base ):
    """
    Formulario para crear nuevas devoluciones
    """
    web = "devoluciones.php?doc="
    def __init__( self, parent = None ):
        """
        Constructor
        """
        super( FrmDevolucion, self ).__init__( parent )



        self.editmodel = None

        self.status = True

#        las acciones deberian de estar ocultas


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



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



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

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

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


        try:

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

            self.navmodel.setQuery( query )

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




            #        Este objeto mapea una fila del modelo self.navproxymodel a los controles

            self.mapper.setSubmitPolicy( QDataWidgetMapper.ManualSubmit )
            self.mapper.setModel( self.navproxymodel )
            self.mapper.addMapping( self.txtDocumentNumber, NDOCIMPRESO )
            self.mapper.addMapping( self.txtObservations, OBSERVACION )
            self.mapper.addMapping( self.dtPicker, FECHA )
            self.mapper.addMapping( self.txtClient, CLIENTE, "text" )
            self.mapper.addMapping( self.txtBill, FACTURA, "text" )
            self.mapper.addMapping( self.lblTotal, TOTAL, "text" )
            self.mapper.addMapping( self.lblSubtotal, SUBTOTAL, "text" )
            #self.mapper.addMapping( self.lblCost, COSTO, "text" )
            self.mapper.addMapping( self.lblTaxes, IMPUESTOS, "text" )
            self.mapper.addMapping( self.txtConcept, CONCEPTO, "text" )
            self.mapper.addMapping( self.txtWarehouse, NOMBREBODEGA, "text" )

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

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


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

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

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

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

    def setControls( self, status ):
        """
        En esta funcion cambio el estado enabled de todos los items en el formulario
        @param status: false = editando        true = navegando
        """
        self.actionPrint.setVisible( status )
        self.actionSave.setVisible( not status )
        self.actionCancel.setVisible( not status )
        self.tabnavigation.setEnabled( status )
        self.actionNew.setVisible( status )
        self.actionGoFirst.setVisible( status )
        self.actionGoPrevious.setVisible( status )
        self.actionGoNext.setVisible( status )
        self.actionGoLast.setVisible( status )
        self.actionPreview.setVisible( status )
        #self.txtDocumentNumber.setReadOnly( status )
        self.txtObservations.setReadOnly( status )
        self.dtPicker.setReadOnly( status )

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

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

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

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

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

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


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

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

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

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


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

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

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

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

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


                self.editmodel.uid = self.user.uid


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



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

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


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

                    self.editmodel.lines[row] = linea


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


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

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

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


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

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

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

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

    def cancel( self ):
        self.editmodel = None

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

        self.txtBill.setText( "" )
        self.txtClient.setText( "" )
        self.txtDocumentNumber.setText( "" )
        self.txtWarehouse.setText( "" )
        self.tabWidget.setCurrentIndex( 1 )
        self.status = True
Example #60
0
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>&nbsp;</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()