Exemple #1
0
    def localizar(self, parent=None):

        localizar = LocalizarDialog(db=self.db,
                                    campos=self.localizar_campos,
                                    tabela=self.view_busca,
                                    colunas=self.colunas_busca,
                                    filtro=self.filtro_adicional,
                                    parent=parent)

        localizar.retorno_dados.connect(self.receber_dados)
        modal = localizar.exec()

        return modal if modal > 0 else None
Exemple #2
0
    def __init__(self, db=None, window_list=None, parent=None, **kwargs):
        super(AjusteEstoque, self).__init__(parent=parent, **kwargs)
        self.setupUi(self)
        self.db = db
        self.window_list = window_list
        self.setWindowFlags(Qt.Dialog)

        self.buttonBox_confirmar.button(QDialogButtonBox.Ok).clicked.connect(
            self.confirmar_ajuste)
        self.buttonBox_confirmar.button(
            QDialogButtonBox.Cancel).clicked.connect(self.cancelar)

        self.buttonBox_confirmar.button(
            QDialogButtonBox.Ok).setText("Confirmar")
        self.buttonBox_confirmar.button(
            QDialogButtonBox.Cancel).setText("Cancelar")

        self.pushButton_historico.clicked.connect(self.abrir_historico)

        validador_regex_id = QRegExpValidator(QRegExp("[0-9]{1,9}"))
        self.lineEdit_mercadoria_id.setValidator(validador_regex_id)

        self.lineEdit_mercadoria_id.editingFinished.connect(
            self.busca_mercadoria)
        self.toolButton_mercadoria.clicked.connect(
            lambda: self.busca_mercadoria(force=True))

        self.dialog_localizar = LocalizarDialog(db=self.db, parent=self)

        self.lineEdit_mercadoria_id.setStyleSheet("\nborder: 0.5px solid red")

        find_icon = QIcon(os.path.join('Resources', 'icons', 'search.png'))
        self.toolButton_mercadoria.setIcon(find_icon)
        clock_icon = QIcon(os.path.join('Resources', 'icons', 'clock.png'))
        self.pushButton_historico.setIcon(clock_icon)

        self.spinBox_quantidade.setRange(1, 999)

        help=\
'''Aqui é possível realizar lançamentos de entrada/saída, de forma manual,
para operações que ocorrem sem um pedido.

ENTRADA: Serão adicionados itens sem vínculo com pedido de entrada.
SAÍDA: Apenas itens fechados podem ser retirados do estoque.'''

        self.adiciona_help(texto=help)

        self.show()
Exemple #3
0
    def __init__(self, db, child=None, parent=None, **kwargs):
        super(FiltroPadrao, self).__init__(parent)
        self.setupUi(self)
        self.db = db
        self.parent = parent

        self.setWindowIcon(
            QIcon(os.path.join('Resources', 'icons', 'filter.png')))

        self.child = child(db=self.db,
                           parent=self.widget,
                           filtro_padrao=self,
                           **kwargs)
        self.child.setWindowFlags(Qt.Widget)
        self.child.move(0, 0)
        self.child.show()

        self.setMinimumHeight(self.child.height() + 60)
        self.setMinimumWidth(self.child.width() + 20)
        self.setMaximumHeight(self.child.height() + 60)
        self.setMaximumWidth(self.child.width() + 20)

        self.buttonBox.button(QDialogButtonBox.Ok).clicked.connect(
            self.confirma)
        self.buttonBox.button(QDialogButtonBox.Cancel).clicked.connect(
            self.cancela)
        self.buttonBox.button(QDialogButtonBox.Ok).setDefault(True)

        self.dialog_localizar = LocalizarDialog(db=self.db, parent=self)

        self.translate_ui()

        self.show()
Exemple #4
0
    def __init__(self, db=None, window_list=None, parent=None, **kwargs):
        super(CadastroMercadoria, self).__init__(parent=parent, **kwargs)
        ### Padrão
        self.parent_window = self
        self.setupUi(self)

        self.db = db
        self.window_list = window_list
        self.modo_edicao = False

        self.frame_menu.setDisabled(False)
        self.frame_contents.setDisabled(True)
        self.frame_buttons.setDisabled(True)

        self.pushButton_cadastrar.clicked.connect(self.cadastrar)
        self.pushButton_editar.clicked.connect(self.editar)
        self.pushButton_excluir.clicked.connect(self.excluir)
        self.pushButton_localizar.clicked.connect(self.localizar)

        self.buttonBox.button(QDialogButtonBox.Ok).clicked.connect(self.confirma)
        self.buttonBox.button(QDialogButtonBox.Cancel).clicked.connect(self.cancela)
        ### Fim padrão

        self.campos_obrigatorios = dict([
            ('Código', self.lineEdit_codigo)
            , ('Descrição', self.lineEdit_descricao)
            , ('Fabricante', self.comboBox_fabricante)
            , ('Valor de Venda', self.lineEdit_valor_venda)
        ])

        self.filtro_adicional = None
        self.view_busca = 'vw_mercadoria'

        self.checkBox_ativo.setChecked(True)

        self.tipo = 'MERCADORIA' if kwargs.get('tipo') \
            is None else kwargs.get('tipo')

        self.configura_tipo()

        self.label_tipo.setText(self.tipo)
        self.setWindowTitle('SOAD - Cadastrar ' + self.tipo.capitalize())

        # Define se ativa o botão editar e excluir
        self.pushButton_editar.setDisabled(True)
        self.pushButton_excluir.setDisabled(True)
        self.lineEdit_id.textChanged[str].connect(
            self.define_permite_editar)

        # Validadores de tipos de dados
        validador_double = QDoubleValidator(bottom=0.000001, top=1000000.00, decimals=6)
        validador_regex_id = QRegExpValidator(QRegExp("[0-9]{1,9}"))
        validador_regex_codigo = QRegExpValidator(QRegExp("([A-z][0-9])*\w+"))

        self.lineEdit_insumo_id.setValidator(validador_regex_id)
        self.lineEdit_quantidade_insumo.setValidator(validador_double)
        self.lineEdit_quantidade_embalagem.setValidator(validador_double)
        self.lineEdit_valor_venda.setValidator(validador_double)
        self.lineEdit_codigo.setValidator(validador_regex_codigo)

        self.lineEdit_descricao.editingFinished.connect(
            lambda: self.lineEdit_descricao.setText(
                self.lineEdit_descricao.text().upper()
            )
        )

        self.lineEdit_codigo.editingFinished.connect(
            lambda: self.lineEdit_codigo.setText(
                self.lineEdit_codigo.text().upper()
            )
        )

        self.checkBox_permite_venda.toggled.connect(
            self.permite_venda_toggled
        )

        # Busca registros
        self.lineEdit_insumo_id.editingFinished.connect(self.busca_insumo)
        self.toolButton_insumo.clicked.connect(lambda: self.busca_insumo(force=True))

        self.unidades_medida = dict()

        # Cadastro de fabricante
        self.fabricantes = set()
        self.lineEdit_fabricante.setVisible(False)
        self.toolButton_addFabricante.clicked.connect(
            self.cadastrar_fabricante)

        self.lineEdit_fabricante.textChanged[str].connect(
            lambda: self.toolButton_addFabricante.setText('Cancelar')
            if self.lineEdit_fabricante.text() == ''
            else self.toolButton_addFabricante.setText('Salvar')
        )
        self.toolButton_addFabricante.setText('+')

        self.dialog_localizar = LocalizarDialog(db=self.db)

        self.define_icones()

        find_icon = QIcon(os.path.join('Resources', 'icons', 'search.png'))
        self.toolButton_insumo.setIcon(find_icon)

        self.adiciona_help(self.help)

        self.popular_dados_padrao()

        self.id_registro = kwargs.get('id_registro')
        if self.id_registro:
            self.atualizar_interface(self.id_registro)
        self.show()
Exemple #5
0
class CadastroMercadoria(CadastroPadrao, Ui_CadastroMercadoria):

    def __init__(self, db=None, window_list=None, parent=None, **kwargs):
        super(CadastroMercadoria, self).__init__(parent=parent, **kwargs)
        ### Padrão
        self.parent_window = self
        self.setupUi(self)

        self.db = db
        self.window_list = window_list
        self.modo_edicao = False

        self.frame_menu.setDisabled(False)
        self.frame_contents.setDisabled(True)
        self.frame_buttons.setDisabled(True)

        self.pushButton_cadastrar.clicked.connect(self.cadastrar)
        self.pushButton_editar.clicked.connect(self.editar)
        self.pushButton_excluir.clicked.connect(self.excluir)
        self.pushButton_localizar.clicked.connect(self.localizar)

        self.buttonBox.button(QDialogButtonBox.Ok).clicked.connect(self.confirma)
        self.buttonBox.button(QDialogButtonBox.Cancel).clicked.connect(self.cancela)
        ### Fim padrão

        self.campos_obrigatorios = dict([
            ('Código', self.lineEdit_codigo)
            , ('Descrição', self.lineEdit_descricao)
            , ('Fabricante', self.comboBox_fabricante)
            , ('Valor de Venda', self.lineEdit_valor_venda)
        ])

        self.filtro_adicional = None
        self.view_busca = 'vw_mercadoria'

        self.checkBox_ativo.setChecked(True)

        self.tipo = 'MERCADORIA' if kwargs.get('tipo') \
            is None else kwargs.get('tipo')

        self.configura_tipo()

        self.label_tipo.setText(self.tipo)
        self.setWindowTitle('SOAD - Cadastrar ' + self.tipo.capitalize())

        # Define se ativa o botão editar e excluir
        self.pushButton_editar.setDisabled(True)
        self.pushButton_excluir.setDisabled(True)
        self.lineEdit_id.textChanged[str].connect(
            self.define_permite_editar)

        # Validadores de tipos de dados
        validador_double = QDoubleValidator(bottom=0.000001, top=1000000.00, decimals=6)
        validador_regex_id = QRegExpValidator(QRegExp("[0-9]{1,9}"))
        validador_regex_codigo = QRegExpValidator(QRegExp("([A-z][0-9])*\w+"))

        self.lineEdit_insumo_id.setValidator(validador_regex_id)
        self.lineEdit_quantidade_insumo.setValidator(validador_double)
        self.lineEdit_quantidade_embalagem.setValidator(validador_double)
        self.lineEdit_valor_venda.setValidator(validador_double)
        self.lineEdit_codigo.setValidator(validador_regex_codigo)

        self.lineEdit_descricao.editingFinished.connect(
            lambda: self.lineEdit_descricao.setText(
                self.lineEdit_descricao.text().upper()
            )
        )

        self.lineEdit_codigo.editingFinished.connect(
            lambda: self.lineEdit_codigo.setText(
                self.lineEdit_codigo.text().upper()
            )
        )

        self.checkBox_permite_venda.toggled.connect(
            self.permite_venda_toggled
        )

        # Busca registros
        self.lineEdit_insumo_id.editingFinished.connect(self.busca_insumo)
        self.toolButton_insumo.clicked.connect(lambda: self.busca_insumo(force=True))

        self.unidades_medida = dict()

        # Cadastro de fabricante
        self.fabricantes = set()
        self.lineEdit_fabricante.setVisible(False)
        self.toolButton_addFabricante.clicked.connect(
            self.cadastrar_fabricante)

        self.lineEdit_fabricante.textChanged[str].connect(
            lambda: self.toolButton_addFabricante.setText('Cancelar')
            if self.lineEdit_fabricante.text() == ''
            else self.toolButton_addFabricante.setText('Salvar')
        )
        self.toolButton_addFabricante.setText('+')

        self.dialog_localizar = LocalizarDialog(db=self.db)

        self.define_icones()

        find_icon = QIcon(os.path.join('Resources', 'icons', 'search.png'))
        self.toolButton_insumo.setIcon(find_icon)

        self.adiciona_help(self.help)

        self.popular_dados_padrao()

        self.id_registro = kwargs.get('id_registro')
        if self.id_registro:
            self.atualizar_interface(self.id_registro)
        self.show()

    def cadastrar(self):
        super(CadastroMercadoria, self).cadastrar()
        self.limpar_dados()
        self.checkBox_permite_venda.setChecked(self.tipo == 'MERCADORIA')
        self.checkBox_ativo.setChecked(True)
        self.lineEdit_valor_venda.setText('0,00')

    def excluir(self, validar=True):

        self.dados = {
            "metodo": "prc_delete_mercadoria",
            "schema": "soad",
            "params": {
                "mercadoria_id": self.lineEdit_id.text()
            }
        }

        retorno = super(CadastroMercadoria, self).excluir()

        if retorno[0]:
            dialog = StatusDialog(status='OK'
                                  , mensagem='Mercadoria excluída com sucesso.'
                                  , parent=self.parent_window)
            self.limpar_dados()
        else:
            dialog = StatusDialog(status='ALERTA'
                                  , mensagem='Não foi possível excluir a mercadoria.'
                                  , exception=retorno
                                  , parent=self.parent_window)
        dialog.exec()

    def limpar_dados(self):
        super(CadastroMercadoria, self).limpar_dados()
        # mercadoria
        self.lineEdit_codigo.clear()
        self.lineEdit_descricao.clear()
        self.checkBox_permite_venda.setChecked(False)
        self.checkBox_ativo.setChecked(False)
        self.comboBox_fabricante.setCurrentIndex(0)
        self.lineEdit_valor_venda.clear()

        # insumo
        self.lineEdit_quantidade_embalagem.clear()
        self.comboBox_unidade_medida_embalagem.setCurrentIndex(0)

        # casco
        self.lineEdit_insumo_fabricante.clear()
        self.lineEdit_insumo_id.clear()
        self.lineEdit_insumo.clear()
        self.lineEdit_insumo_fabricante.clear()
        self.lineEdit_quantidade_insumo.clear()
        self.comboBox_unidade_medida_insumo.setCurrentIndex(0)

    def localizar(self, parent=None):

        self.localizar_campos = {
            'id_mercadoria': 'ID'
            , "codigo": 'Código'
            , "descricao": self.tipo.capitalize()
            , "marca": "Fabricante"
        }

        self.colunas_busca = {
            'id_mercadoria': 'ID'
            , "codigo": 'Código'
            , "descricao": self.tipo.capitalize()
            , "marca": "Fabricante"
        }

        self.filtro_adicional = "tipo_mercadoria=$$" + self.tipo.capitalize() + "$$"

        retorno = super(CadastroMercadoria, self).localizar(parent=self)

        if retorno is not None:
            self.atualizar_interface(retorno)

    def confirma(self):

        if self.valida_obrigatorios() != 'OK':
            return

        unidade_medida = self.comboBox_unidade_medida_insumo.currentText() \
                         if self.tipo == 'CASCO' \
                         else self.comboBox_unidade_medida_embalagem.currentText()

        mercadoria = Mercadoria(
            mercadoria_id=self.lineEdit_id.text()
            , codigo=self.lineEdit_codigo.text()
            , descricao=self.lineEdit_descricao.text()
            , fabricante=self.comboBox_fabricante.currentText()
            , valor_venda=self.lineEdit_valor_venda.text().replace(',', '.')
            , ativo=self.checkBox_ativo.isChecked()
            , permite_venda=self.checkBox_permite_venda.isChecked()
            , tipo_mercadoria=self.tipo
            , unidade_medida_id=self.unidades_medida.get(unidade_medida)

            # Insumo
            , quantidade_embalagem=self.lineEdit_quantidade_embalagem.text().replace(',', '.')
            , colorido=self.radioButton_cor.isChecked()
            # Casco
            , insumo_id=self.lineEdit_insumo_id.text()
            , quantidade_insumo=self.lineEdit_quantidade_insumo.text().replace(',', '.')
        )

        self.dados = {
            "metodo": "fnc_insert_update_mercadoria",
            "schema": "soad",
            "params": mercadoria.to_dict()
        }

        retorno = super(CadastroMercadoria, self).confirma()

        if retorno[0]:
            mercadoria_id = retorno[1]['p_retorno_json']['mercadoria_id']
            self.atualizar_interface(mercadoria_id)

        else:
            return

    def cancela(self):
        if super(CadastroMercadoria, self).cancela():
            self.limpar_dados()
            self.atualizar_interface(self.ultimo_id)

    def atualizar_interface(self, mercadoria_id):

        self.limpar_dados()

        if not mercadoria_id or mercadoria_id == '':
            return

        dados = self.db.get_registro(
            "fnc_get_mercadoria"
            , "mercadoria_id"
            , mercadoria_id
        )

        if dados[0]:
            dados = dados[1][0]['json_mercadoria']
            self.popular_interface(dados)

        else:
            dialog = StatusDialog(
                status='ERRO'
                , exception=dados
                , mensagem='Erro ao buscar dados.'
                , parent=self
            )
            dialog.exec()

    def popular_interface(self, dados):

        mercadoria = dados

        tipo = str(mercadoria['tipo']).upper()
        self.tipo = tipo
        self.configura_tipo()

        if tipo == 'MERCADORIA':
            mercadoria = Mercadoria(
                mercadoria_id=mercadoria['id_mercadoria']
                , codigo=mercadoria['codigo']
                , descricao=mercadoria['descricao']
                , fabricante=mercadoria['marca']
                , valor_venda=mercadoria['valor_venda']
                , ativo=mercadoria['ativo']
                , permite_venda=mercadoria['permite_venda']
                , tipo_mercadoria=tipo
            )

        elif tipo == 'INSUMO':
            mercadoria = Mercadoria(
                mercadoria_id=mercadoria['id_mercadoria']
                , codigo=mercadoria['codigo']
                , descricao=mercadoria['descricao']
                , fabricante=mercadoria['marca']
                , valor_venda=mercadoria['valor_venda']
                , ativo=mercadoria['ativo']
                , permite_venda=mercadoria['permite_venda']
                , tipo_mercadoria=tipo
                , unidade_medida_id=mercadoria['unidade_medida_id']
                , quantidade_embalagem=mercadoria['quantidade_embalagem']
                , colorido=mercadoria['colorido']
            )

            if mercadoria.colorido:
                self.radioButton_cor.setChecked(True)
            else:
                self.radioButton_pb.setChecked(True)

            self.lineEdit_quantidade_embalagem.setText(
                str(mercadoria.quantidade_embalagem).replace('', '')
            )

            for key in self.unidades_medida:
                if self.unidades_medida[key] == mercadoria.unidade_medida_id:
                    self.comboBox_unidade_medida_embalagem.setCurrentText(key)
                    break

        elif tipo == 'CASCO':
            mercadoria = Mercadoria(
                mercadoria_id=mercadoria['id_mercadoria']
                , codigo=mercadoria['codigo']
                , descricao=mercadoria['descricao']
                , fabricante=mercadoria['marca']
                , valor_venda=mercadoria['valor_venda']
                , ativo=mercadoria['ativo']
                , permite_venda=mercadoria['permite_venda']
                , tipo_mercadoria=tipo
                , unidade_medida_id=mercadoria['unidade_medida_id']
                , quantidade_insumo=mercadoria['quantidade_insumo']
                , insumo_id=mercadoria['insumo_id']
            )

            self.lineEdit_quantidade_insumo.setText(
                str(mercadoria.quantidade_insumo).replace('', '')
            )

            for key in self.unidades_medida:
                if self.unidades_medida[key] == mercadoria.unidade_medida_id:
                    self.comboBox_unidade_medida_insumo.setCurrentText(key)
                    break

            self.lineEdit_insumo_id.setText(
                str(mercadoria.insumo_id)
            )

            self.busca_insumo()

        else:
            logging.debug('[CadastroMercadoria] Tipo desconhecido: ' + self.tipo)
            return

        self.lineEdit_id.setText(
            str(mercadoria.mercadoria_id)
        )

        self.label_tipo.setText(mercadoria.tipo)
        self.lineEdit_codigo.setText(mercadoria.codigo)
        self.checkBox_ativo.setChecked(mercadoria.ativo)
        self.checkBox_permite_venda.setChecked(mercadoria.permite_venda)
        self.lineEdit_descricao.setText(mercadoria.descricao)
        self.comboBox_fabricante.setCurrentText(mercadoria.fabricante)

        self.lineEdit_valor_venda.setText(
            str(mercadoria.valor_venda).replace('.', ',')
        )

    def popular_dados_padrao(self):
        self.permite_venda_toggled()

        ### Fabricantes
        self.comboBox_fabricante.clear()
        items = self.db.busca_registro("vw_fabricante", "fabricante")

        if items[0]:
            items = items[1][0]['fnc_buscar_registro']

            if items:
                for item in items:
                    self.fabricantes.add(item['fabricante'])

                self.comboBox_fabricante.addItems(list(self.fabricantes))

        else:
            dialog = StatusDialog(status='ALERTA'
                                  , mensagem="Não foi possível buscar os fabricantes"
                                  , exception=items[1]
                                  , parent=self.parent_window)
            dialog.exec()

        ### Unidades de medida
        self.comboBox_unidade_medida_insumo.clear()
        self.comboBox_unidade_medida_embalagem.clear()

        items = self.db.busca_registro("unidade_medida", "id_unidade_medida")

        if items[0]:
            items = items[1][0]['fnc_buscar_registro']

            for item in items:
                self.unidades_medida[item['abreviacao']] = item['id_unidade_medida']

            self.comboBox_unidade_medida_embalagem.addItems(
                list(self.unidades_medida.keys())
            )
            self.comboBox_unidade_medida_insumo.addItems(
                list(self.unidades_medida.keys())
            )

    def busca_insumo(self, force=False):

        insumo = None
        tabela = 'vw_insumo'
        campo = 'id_insumo'
        lineEdit_id = self.lineEdit_insumo_id
        lineEdit_descricao = self.lineEdit_insumo
        lineEdit_marca = self.lineEdit_insumo_fabricante

        valor = lineEdit_id.text().replace(' ', '')

        if valor != '':

            insumo = self.db.busca_registro(tabela, campo, valor, '=')[1][0]['fnc_buscar_registro']

            logging.debug('[CadastroMercadoria] ' + str(insumo))
            if insumo is not None:
                insumo = insumo[0]

        if not force:
            return False

        if insumo is None or force:

            localizar_campos = {
                campo: 'ID'
                , "codigo": 'Código'
                , "descricao": 'Insumo'
                , "marca": "Fabricante"
            }

            colunas_busca = {
                campo: 'ID'
                , "codigo": 'Código'
                , "descricao": 'Insumo'
                , "marca": "Fabricante"
            }

            self.dialog_localizar.define_tabela(tabela)
            self.dialog_localizar.define_campos(localizar_campos)
            self.dialog_localizar.define_colunas(colunas_busca)

            self.dialog_localizar.define_valor_padrao(localizar_campos[campo], lineEdit_id.text())

            mercadoria_id = self.dialog_localizar.exec()

            if mercadoria_id == 0:
                return False

            insumo = self.db.busca_registro(tabela, campo, str(mercadoria_id), '=')[1][0]['fnc_buscar_registro']

            if insumo is not None:
                insumo = insumo[0]

        if insumo:
            lineEdit_id.setText(str(insumo['id_insumo']))
            lineEdit_descricao.setText(insumo['descricao'])
            lineEdit_marca.setText(insumo['marca'])
            return True

        else:
            lineEdit_id.clear()
            lineEdit_descricao.clear()
            lineEdit_marca.clear()
            return False

    def cadastrar_fabricante(self):

        pressed = self.toolButton_addFabricante.isChecked()

        self.comboBox_fabricante.setVisible(not pressed)
        self.lineEdit_fabricante.setVisible(pressed)

        if pressed:
            self.toolButton_addFabricante.setText('Cancelar')
            self.lineEdit_fabricante.setFocus()
            self.buttonBox.button(QDialogButtonBox.Ok).setDisabled(True)

        else:
            texto = self.lineEdit_fabricante.text().upper()
            if texto != '':
                self.fabricantes.add(texto)
                self.comboBox_fabricante.clear()
                self.comboBox_fabricante.addItems(list(self.fabricantes))
                self.comboBox_fabricante.setCurrentText(texto)
                logging.info('[CadastroMercadoria] Adicionado fornecedor: ' + texto)

            self.lineEdit_fabricante.clear()
            self.comboBox_fabricante.setFocus()
            self.buttonBox.button(QDialogButtonBox.Ok).setDisabled(False)
            self.toolButton_addFabricante.setText('+')

    def permite_venda_toggled(self):
        if self.checkBox_permite_venda.isChecked():
            self.lineEdit_valor_venda.setDisabled(False)
        else:
            self.lineEdit_valor_venda.setDisabled(True)
            self.lineEdit_valor_venda.setText('0,00')

    def configura_tipo(self):
        self.tipo = 'MERCADORIA' if not self.tipo else self.tipo
        if self.tipo == 'MERCADORIA':
            self.tipo = 'MERCADORIA'
            self.stackedWidget.setVisible(False)
            self.checkBox_permite_venda.setChecked(True)
            self.help = '''Aqui são cadastradas as mercadorias comuns.'''

        elif self.tipo == 'CASCO':
            self.campos_obrigatorios['Insumo'] = self.lineEdit_insumo_id
            self.campos_obrigatorios['Quantidade'] = self.lineEdit_quantidade_insumo
            self.campos_obrigatorios['Un. Medida (Insumo)'] = self.comboBox_unidade_medida_insumo
            self.stackedWidget.setVisible(True)
            self.page_insumo.setVisible(False)
            self.stackedWidget.setCurrentWidget(self.page_casco)
            self.help = '''Os cascos cadastrados podem ser utilizados em remanufaturas.'''

        elif self.tipo == 'INSUMO':
            self.campos_obrigatorios['Quantidade Embalagem'] = self.lineEdit_quantidade_embalagem
            self.campos_obrigatorios['Un. Medida (Embalagem)'] = self.comboBox_unidade_medida_embalagem
            self.stackedWidget.setVisible(True)
            self.page_casco.setVisible(False)
            self.stackedWidget.setCurrentWidget(self.page_insumo)
            self.help = '''Os insumos cadastrados podem ser utilizados em remanufaturas.'''

        else:
            dialog = StatusDialog(
                status='ERRO'
                , mensagem='TIPO DE MERCADORIA INVÁLIDO'
                , parent=self.parent_window)
            dialog.exec()
            return

        self.help = self.help + '''\nMercadorias inativas não podem ser utilizadas.\n Mercadorias que não permitem venda só podem ser utilizadas em remanufaturas.'''
    def __init__(self, db=None, window_list=None, parent=None, **kwargs):
        super(RegistroRemanufatura, self).__init__(parent, **kwargs)
        ### Padrão
        self.parent_window = self
        self.setupUi(self)

        self.db = db
        self.window_list = window_list
        self.modo_edicao = True

        # Configurações

        self.campos_obrigatorios = dict([
            ('Casco', self.lineEdit_casco_id)
            , ('Insumo', self.lineEdit_insumo_id)
            , ('Quantidade', self.spinBox_quantidade)
        ])

        ## Monta QTableWidget

        self.remanufaturas = list()

        self.colunas_remanufaturas = {
            "remanufatura_id": "ID"
            , "codigo": "Código"
            , "casco_id": "Casco"
            , "insumo_id": "Insumo"
            , "situacao": "Situação"
            , "log": "Log"
        }

        self.col_remanufatura_id = 0
        self.col_codigo = 1
        self.col_casco_id = 2
        self.col_insumo_id = 3
        self.col_situacao = 4
        self.col_log = 5

        self.colunas_descricao = list(self.colunas_remanufaturas.values())
        self.colunas_chave = list(self.colunas_remanufaturas.keys())

        self.label_situacao.setVisible(False)

        self.tableWidget_remanufaturas.setRowCount(len(self.remanufaturas))
        self.tableWidget_remanufaturas.setColumnCount(len(self.colunas_descricao))
        self.tableWidget_remanufaturas.setHorizontalHeaderLabels(self.colunas_descricao)
        self.tableWidget_remanufaturas.verticalHeader().setVisible(False)
        self.tableWidget_remanufaturas.horizontalHeader().setVisible(True)

        ### Fim monta tableWidget

        # Imagens

        self.color_ink = QImage(os.path.join("Resources", "icons", "color_ink.png")).smoothScaled(90, 90)
        self.bw_ink = QImage(os.path.join("Resources", "icons", "bw_ink.png")).smoothScaled(90, 90)
        self.open_box = QImage(os.path.join("Resources", "icons", "open_box.png")).smoothScaled(80, 80)
        self.closed_box = QImage(os.path.join("Resources", "icons", "closed_box.png")).smoothScaled(80, 80)
        self.vazio = QImage(os.path.join("Resources", "icons", "vazio.png")).smoothScaled(80, 80)
        self.icone_esvaziar = QIcon(os.path.join("Resources", "icons", "delete.png"))
        self.icone_realizar = QIcon(os.path.join("Resources", "icons", "ok.png"))
        self.icone_limpar = QIcon(os.path.join("Resources", "icons", "clean.png"))

        find_icon = QIcon(os.path.join('Resources', 'icons', 'search.png'))
        self.toolButton_insumo.setIcon(find_icon)
        self.toolButton_casco.setIcon(find_icon)

        self.pushButton_esvaziar.setIcon(self.icone_esvaziar)
        self.pushButton_realizar.setIcon(self.icone_realizar)
        self.pushButton_limpar.setIcon(self.icone_limpar)

        self.label_tinta.setText('')

        self.formFrame_item_lote.setVisible(False)

        # Validadores
        validador_regex_id = QRegExpValidator(QRegExp("[0-9]{1,9}"))
        self.lineEdit_casco_id.setValidator(validador_regex_id)
        self.lineEdit_insumo_id.setValidator(validador_regex_id)

        # Conectar botões

        self.pushButton_limpar.setDisabled(True)
        self.pushButton_realizar.setDisabled(True)

        self.tableWidget_remanufaturas.itemPressed.connect(self.ativar_botoes)

        self.buttonBox_remanufatura.button(
            QDialogButtonBox.Ok).clicked.connect(self.gerar_remanufaturas)

        self.buttonBox_remanufatura.button(
            QDialogButtonBox.Reset).clicked.connect(self.limpar_formulario)

        self.pushButton_realizar.clicked.connect(
            lambda: self.realizar_remanufaturas(apenas_selecionados=True)
        )

        self.pushButton_limpar.clicked.connect(
            lambda: self.limpar_tabela(apenas_selecionados=True)
        )

        self.pushButton_esvaziar.clicked.connect(
            lambda: self.esvaziar_embalagem(
                int(self.label_item_lote_id.text() if self.label_item_lote_id.text() != '' else None)
            )
        )

        self.checkBox_selecionar_tudo.toggled.connect(self.selecionar_todas)

        self.lineEdit_insumo_id.editingFinished.connect(
            lambda: self.busca_mercadoria(tipo='INSUMO')
        )

        self.lineEdit_casco_id.editingFinished.connect(
            lambda: self.busca_mercadoria(tipo='CASCO')
        )

        self.toolButton_insumo.clicked.connect(
            lambda: self.busca_mercadoria(tipo='INSUMO', force=True)
        )

        self.toolButton_casco.clicked.connect(
            lambda: self.busca_mercadoria(tipo='CASCO', force=True)
        )

        self.tableWidget_remanufaturas.setColumnHidden(0, True)
        self.dialog_localizar = LocalizarDialog(db=self.db, parent=self)

        self.pushButton_esvaziar.setVisible(False)

        self.help = \
'''Para registrar remanufaturas deve-se informar o casco e o insumo.
Se tiver estoque do insumo disponível a remanufatura poderá ser realizada.
Remanufaturas realizadas podem ser utilizadas em pedidos de venda.
'''
        self.adiciona_help(self.help)

        self.translate_ui()

        self.id_registro = kwargs.get('id_registro')
        if self.id_registro:
            self.visualizar_remanufatura(self.id_registro)
        else:
            self.marca_obrigatorios()
        self.show()
class RegistroRemanufatura(CadastroPadrao, Ui_RegistroRemanufatura):

    def __init__(self, db=None, window_list=None, parent=None, **kwargs):
        super(RegistroRemanufatura, self).__init__(parent, **kwargs)
        ### Padrão
        self.parent_window = self
        self.setupUi(self)

        self.db = db
        self.window_list = window_list
        self.modo_edicao = True

        # Configurações

        self.campos_obrigatorios = dict([
            ('Casco', self.lineEdit_casco_id)
            , ('Insumo', self.lineEdit_insumo_id)
            , ('Quantidade', self.spinBox_quantidade)
        ])

        ## Monta QTableWidget

        self.remanufaturas = list()

        self.colunas_remanufaturas = {
            "remanufatura_id": "ID"
            , "codigo": "Código"
            , "casco_id": "Casco"
            , "insumo_id": "Insumo"
            , "situacao": "Situação"
            , "log": "Log"
        }

        self.col_remanufatura_id = 0
        self.col_codigo = 1
        self.col_casco_id = 2
        self.col_insumo_id = 3
        self.col_situacao = 4
        self.col_log = 5

        self.colunas_descricao = list(self.colunas_remanufaturas.values())
        self.colunas_chave = list(self.colunas_remanufaturas.keys())

        self.label_situacao.setVisible(False)

        self.tableWidget_remanufaturas.setRowCount(len(self.remanufaturas))
        self.tableWidget_remanufaturas.setColumnCount(len(self.colunas_descricao))
        self.tableWidget_remanufaturas.setHorizontalHeaderLabels(self.colunas_descricao)
        self.tableWidget_remanufaturas.verticalHeader().setVisible(False)
        self.tableWidget_remanufaturas.horizontalHeader().setVisible(True)

        ### Fim monta tableWidget

        # Imagens

        self.color_ink = QImage(os.path.join("Resources", "icons", "color_ink.png")).smoothScaled(90, 90)
        self.bw_ink = QImage(os.path.join("Resources", "icons", "bw_ink.png")).smoothScaled(90, 90)
        self.open_box = QImage(os.path.join("Resources", "icons", "open_box.png")).smoothScaled(80, 80)
        self.closed_box = QImage(os.path.join("Resources", "icons", "closed_box.png")).smoothScaled(80, 80)
        self.vazio = QImage(os.path.join("Resources", "icons", "vazio.png")).smoothScaled(80, 80)
        self.icone_esvaziar = QIcon(os.path.join("Resources", "icons", "delete.png"))
        self.icone_realizar = QIcon(os.path.join("Resources", "icons", "ok.png"))
        self.icone_limpar = QIcon(os.path.join("Resources", "icons", "clean.png"))

        find_icon = QIcon(os.path.join('Resources', 'icons', 'search.png'))
        self.toolButton_insumo.setIcon(find_icon)
        self.toolButton_casco.setIcon(find_icon)

        self.pushButton_esvaziar.setIcon(self.icone_esvaziar)
        self.pushButton_realizar.setIcon(self.icone_realizar)
        self.pushButton_limpar.setIcon(self.icone_limpar)

        self.label_tinta.setText('')

        self.formFrame_item_lote.setVisible(False)

        # Validadores
        validador_regex_id = QRegExpValidator(QRegExp("[0-9]{1,9}"))
        self.lineEdit_casco_id.setValidator(validador_regex_id)
        self.lineEdit_insumo_id.setValidator(validador_regex_id)

        # Conectar botões

        self.pushButton_limpar.setDisabled(True)
        self.pushButton_realizar.setDisabled(True)

        self.tableWidget_remanufaturas.itemPressed.connect(self.ativar_botoes)

        self.buttonBox_remanufatura.button(
            QDialogButtonBox.Ok).clicked.connect(self.gerar_remanufaturas)

        self.buttonBox_remanufatura.button(
            QDialogButtonBox.Reset).clicked.connect(self.limpar_formulario)

        self.pushButton_realizar.clicked.connect(
            lambda: self.realizar_remanufaturas(apenas_selecionados=True)
        )

        self.pushButton_limpar.clicked.connect(
            lambda: self.limpar_tabela(apenas_selecionados=True)
        )

        self.pushButton_esvaziar.clicked.connect(
            lambda: self.esvaziar_embalagem(
                int(self.label_item_lote_id.text() if self.label_item_lote_id.text() != '' else None)
            )
        )

        self.checkBox_selecionar_tudo.toggled.connect(self.selecionar_todas)

        self.lineEdit_insumo_id.editingFinished.connect(
            lambda: self.busca_mercadoria(tipo='INSUMO')
        )

        self.lineEdit_casco_id.editingFinished.connect(
            lambda: self.busca_mercadoria(tipo='CASCO')
        )

        self.toolButton_insumo.clicked.connect(
            lambda: self.busca_mercadoria(tipo='INSUMO', force=True)
        )

        self.toolButton_casco.clicked.connect(
            lambda: self.busca_mercadoria(tipo='CASCO', force=True)
        )

        self.tableWidget_remanufaturas.setColumnHidden(0, True)
        self.dialog_localizar = LocalizarDialog(db=self.db, parent=self)

        self.pushButton_esvaziar.setVisible(False)

        self.help = \
'''Para registrar remanufaturas deve-se informar o casco e o insumo.
Se tiver estoque do insumo disponível a remanufatura poderá ser realizada.
Remanufaturas realizadas podem ser utilizadas em pedidos de venda.
'''
        self.adiciona_help(self.help)

        self.translate_ui()

        self.id_registro = kwargs.get('id_registro')
        if self.id_registro:
            self.visualizar_remanufatura(self.id_registro)
        else:
            self.marca_obrigatorios()
        self.show()

    def gerar_remanufaturas(self):

        if self.valida_obrigatorios() != 'OK':
            return

        self.lineEdit_insumo_id.setDisabled(True)
        self.lineEdit_casco_id.setDisabled(True)

        self.toolButton_insumo.setDisabled(True)
        self.toolButton_casco.setDisabled(True)

        casco_id = self.lineEdit_casco_id.text()
        insumo_id = self.lineEdit_insumo_id.text()
        quantidade = self.spinBox_quantidade.text()
        realizar = False

        dados = {
            "metodo": "fnc_gerar_remanufatura",
            "schema": "soad",
            "params": {
                "casco_id": casco_id,
                "insumo_id": insumo_id,
                "quantidade": quantidade,
                "realizar": realizar
            }
        }

        # pega ids das remanufturas geradas
        retorno = self.db.call_procedure(self.db.schema, dados)

        remanufaturas = list(dict())

        if retorno[0]:

            remanufaturas_ids = retorno[1][0]['p_retorno_json']
            remanufaturas_ids = remanufaturas_ids['remanufaturas_ids']

            for remanufatura_id in remanufaturas_ids:
                remanufaturas.append(
                    Remanufatura(
                        remanufatura_id=remanufatura_id
                        , casco_id=casco_id
                        , insumo_id=insumo_id
                        , situacao='CADASTRADA' if not realizar
                        else 'REALIZADA'
                    )
                )

            if self.localiza_item_lote(remanufaturas_ids[0]):
                self.popular_tabela(remanufaturas)

        else:
            dialog = StatusDialog(
                status='ERRO'
                , exception=retorno
                , mensagem='Erro ao buscar dados.'
                , parent=self
            )
            dialog.exec()

    def popular_tabela(self, itens=None):

        self.tableWidget_remanufaturas.setRowCount(0)
        self.checkBox_selecionar_tudo.setChecked(False)

        if itens is not None:
            self.remanufaturas = self.remanufaturas + itens

        self.tableWidget_remanufaturas.setRowCount(len(self.remanufaturas))

        if len(self.remanufaturas) > 0:

            row = 0
            for remanufatura in self.remanufaturas:

                col = 0
                for coluna in self.colunas_remanufaturas:
                    valor = remanufatura.to_dict()[coluna]
                    item = QTableWidgetItem(str(valor))
                    self.tableWidget_remanufaturas.setItem(row, col, item)

                    if remanufatura.situacao != 'CADASTRADA':
                        item.setSelected(False)
                        item.setFlags(Qt.NoItemFlags)

                    col = col + 1
                row = row + 1

        self.tableWidget_remanufaturas.setColumnHidden(0, True)

        self.ativar_botoes()

    def limpar_formulario(self):
        # limpa os campos de cadastro da remanufatura

        dialog = ConfirmDialog(parent=self)
        dialog.definir_mensagem(
            mensagem='Tem certeza que deseja limpar as remanufaturas? Remanufaturas não realizadas serão descartadas.'
        )

        if dialog.exec():

            self.selecionar_todas(nao_valida_checkbox=True)
            self.limpar_tabela(apenas_selecionados=False)

            self.lineEdit_insumo_id.clear()
            self.lineEdit_insumo.clear()
            self.lineEdit_marca_insumo.clear()
            self.lineEdit_casco_id.clear()
            self.lineEdit_casco.clear()
            self.lineEdit_marca_casco.clear()
            self.spinBox_quantidade.setValue(1)
            self.lineEdit_insumo_id.setDisabled(False)
            self.lineEdit_casco_id.setDisabled(False)
            self.toolButton_insumo.setDisabled(False)
            self.toolButton_casco.setDisabled(False)
            self.toolButton_insumo.setDisabled(False)
            self.toolButton_casco.setDisabled(False)
            self.frameFormLayout_remanufatura.setDisabled(False)

            self.label_medida.setText('0,00g')

    def limpar_tabela(self, apenas_selecionados=False):
        # remove todas as remanufaturas selecionadas da lista (excluir do banco)

        if self.id_registro:
            dialog = ConfirmDialog(parent=self)
            dialog.definir_mensagem("Tem certeza que deseja excluir essa remanufatura? Essa ação não pode ser desfeita.")
            if not dialog.exec():
                return

        if not apenas_selecionados:
            self.selecionar_todas(nao_valida_checkbox=True)

        items = self.tableWidget_remanufaturas.selectedItems()
        remover = list()

        if not len(items) > 0:
            return

        linhas = list()
        for item in items:
            linhas.append(item.row())
        linhas = list(dict.fromkeys(linhas))

        for linha in linhas:

            id_remanufatura = self.get_id_by_row(linha)

            for remanufatura in self.remanufaturas:
                if remanufatura.remanufatura_id == int(id_remanufatura) \
                        and remanufatura.situacao == 'CADASTRADA':
                    remover.append(remanufatura)

        remover_ids = list()

        for rem in remover:
            remover_ids.append(rem.remanufatura_id)

        dados = {
            "metodo": "prc_delete_remanufatura"
            , "schema": "soad"
            , "params": {
                "remanufatura_id": json.dumps(remover_ids)
            }
        }

        retorno = self.db.call_procedure(self.db.schema, dados)

        if retorno[0]:

            manter = list()
            for remanufatura in self.remanufaturas:
                if remanufatura not in remover:
                    manter.append(remanufatura)
            self.remanufaturas = manter

        else:
            dialog = StatusDialog(
                status='ALERTA'
                , mensagem='Não foi possível remover todas as remanufaturas.'
                , exception=retorno
                , parent=self
            )
            dialog.exec()
        self.popular_tabela()

        if self.id_registro:
            dialog = StatusDialog(
                status='OK'
                , mensagem='Remanufatura removida com sucesso.'
                , parent=self
            )
            dialog.exec()
            self.close()

    def realizar_remanufaturas(self, apenas_selecionados=True):
        # chama o procedimento de realizar remanufatura para
        # todas as remanufaturas selecionadas na lista

        if self.label_situacao.text() == 'CADASTRADA' and self.id_registro:
            if not self.localiza_item_lote(remanufatura_id=self.id_registro, novo=True):
                return

        if not apenas_selecionados:
            self.selecionar_todas(nao_valida_checkbox=True)
            logging.debug('[RegistroRemanufatura] Realizando todas remanufaturas.')
        else:
            logging.debug('[RegistroRemanufatura] Realizando remanufaturas selecionadas.')

        items = self.tableWidget_remanufaturas.selectedItems()

        linhas = list()
        for item in items:
            linhas.append(item.row())
        linhas = list(dict.fromkeys(linhas))

        for linha in linhas:

            id_remanufatura = self.get_id_by_row(linha)

            logging.debug('[RegistroRemanufatura] Selecionados: ' + str(id_remanufatura))

            dados = {
                "metodo": "fnc_realizar_remanufatura"
                , "schema": "soad"
                , "params": {
                    "remanufatura_id": int(id_remanufatura)
                }
            }

            retorno = self.db.call_procedure(self.db.schema, dados)
            logging.info('[RegistroRemanufatura] Executado procedimento para realizar remanufatura.')

            if retorno[0]:

                atualiza = self.db.busca_registro(
                    'vw_remanufatura'
                    , 'id_remanufatura'
                    , id_remanufatura
                    , '='
                )

                logging.info('[RegistroRemanufatura] Executado procedimento para buscar remanufatura.')

                if atualiza[0]:

                    registro = atualiza[1][0]['fnc_buscar_registro'][0]

                    self.localiza_item_lote(remanufatura_id=id_remanufatura)

                    for remanufatura in self.remanufaturas:
                        if remanufatura.remanufatura_id == int(id_remanufatura):
                            remanufatura.situacao = registro['situacao_remanufatura']
                            remanufatura.codigo = registro['codigo']

                            self.tableWidget_remanufaturas.item(
                                linha, self.col_situacao).setText(remanufatura.situacao)

                            self.tableWidget_remanufaturas.item(
                                linha, self.col_codigo).setText(remanufatura.codigo)

                            self.tableWidget_remanufaturas.item(
                                linha, self.col_log).setText('')

                else:
                    self.tableWidget_remanufaturas.item(str(linha), self.col_log).setText(str(atualiza[1][0]))
                    logging.debug('[RegistroRemanufatura] Não foi possível atualizar os dados da remanufatura:')
                    logging.debug('exception> ' + str(atualiza[1]) + '\nsql> ' + str(atualiza[2]))

            else:
                self.tableWidget_remanufaturas.item(str(linha), self.col_log).setText(str(retorno[1][0]))
                logging.debug('[RegistroRemanufatura] Não foi possível realizar a remanufatura:')
                logging.debug('exception> ' + str(retorno[1]) + '\nsql> ' + str(retorno[2]))

        self.popular_tabela()

    def get_id_by_row(self, row_id):
        return self.tableWidget_remanufaturas.item(int(row_id), int(self.col_remanufatura_id)).text()

    def selecionar_todas(self, nao_valida_checkbox=False):
        # seleciona todas as remanufaturas com situacao == 'CADASTRADA'
        if self.checkBox_selecionar_tudo.isChecked() or nao_valida_checkbox:
            self.tableWidget_remanufaturas.selectAll()
            self.ativar_botoes()
            logging.debug('[RegistroRemanufatura] Selecionado todas as remanufaturas.')

        else:
            for item in self.tableWidget_remanufaturas.selectedItems():
                item.setSelected(False)
            logging.debug('[RegistroRemanufatura] Deselecionado todas as remanufaturas.')

    def busca_mercadoria(self, tipo, force=False):
        # Busca insumo e casco e preenche os campos

        mercadoria = None

        if tipo == 'CASCO':
            tabela = 'vw_casco'
            campo = 'id_casco'
            lineEdit_id = self.lineEdit_casco_id
            lineEdit_descricao = self.lineEdit_casco
            lineEdit_marca = self.lineEdit_marca_casco

        elif tipo == 'INSUMO':
            tabela = 'vw_insumo'
            campo = 'id_insumo'
            lineEdit_id = self.lineEdit_insumo_id
            lineEdit_descricao = self.lineEdit_insumo
            lineEdit_marca = self.lineEdit_marca_insumo

        else:
            logging.debug("[RegistroRemanufatura] Tipo inválido: " + tipo)
            return False

        valor = lineEdit_id.text().replace(' ', '')

        if valor != '':

            mercadoria = self.db.busca_registro(tabela, campo, valor, '=')[1][0]['fnc_buscar_registro']

            logging.debug('[RegistroRemanufatura] ' + str(mercadoria))
            if mercadoria is not None:
                mercadoria = mercadoria[0]

        else:
            if not force:
                return False

        if mercadoria is None or force:

            localizar_campos = {
                campo: 'ID',
                "codigo": 'Código',
                "descricao": tipo.capitalize(),
                'marca': "Marca"
            }

            colunas_busca = {
                campo: 'ID',
                "codigo": 'Código',
                "descricao": tipo.capitalize(),
                'marca': "Marca"
            }

            self.dialog_localizar.define_tabela(tabela)
            self.dialog_localizar.define_campos(localizar_campos)
            self.dialog_localizar.define_colunas(colunas_busca)

            self.dialog_localizar.define_valor_padrao(localizar_campos[campo], lineEdit_id.text())

            mercadoria_id = self.dialog_localizar.exec()

            if mercadoria_id == 0:
                return False

            mercadoria = self.db.busca_registro(
                tabela
                , campo
                , str(mercadoria_id)
                , '='
            )[1][0]['fnc_buscar_registro']

            if mercadoria is not None:
                mercadoria = mercadoria[0]

        if mercadoria:
            lineEdit_id.setText(str(mercadoria[campo]))
            lineEdit_descricao.setText(mercadoria['descricao'])
            lineEdit_marca.setText(mercadoria['marca'])

            if tipo == 'CASCO':
                self.lineEdit_insumo_id.setText(str(mercadoria['id_insumo']))
                self.lineEdit_insumo_id.editingFinished.emit()
                self.buttonBox_remanufatura.setFocus()

                medida = str(mercadoria['quantidade_insumo']) + str(mercadoria['unidade_medida_insumo'])
                self.label_medida.setText(medida)

            if tipo == 'INSUMO':
                if bool(mercadoria['colorido']):
                    self.label_tinta.setPixmap(QPixmap.fromImage(self.color_ink))
                else:
                    self.label_tinta.setPixmap(QPixmap.fromImage(self.bw_ink))
            return True

        else:
            lineEdit_id.clear()
            lineEdit_descricao.clear()
            lineEdit_marca.clear()
            return False

    def localiza_item_lote(self, remanufatura_id, novo=True):

        if novo:
            dados = {
                "metodo": "fnc_realizar_remanufatura"
                , "schema": "soad"
                , "params": {
                    "remanufatura_id": remanufatura_id
                    , "simular": True
                }
            }

            retorno = self.db.call_procedure(self.db.schema, dados)

        else:
            dados = {
                "metodo": "fnc_get_item_lote_remanufatura"
                , "schema": "soad"
                , "params": {
                    "remanufatura_id": remanufatura_id
                }
            }

            retorno = self.db.call_procedure(self.db.schema, dados)

        logging.info('[RegistroRemanufatura] Localizando item lote.')

        if retorno[0]:
            retorno = retorno[1][0]
            id_item_lote = retorno['p_retorno_json']['p_item_lote_id']

            if id_item_lote is not None:

                registro = self.db.busca_registro(
                    'vw_item_lote'
                    , 'id_item_lote'
                    , str(id_item_lote)
                    , '='
                )

                if registro[0]:

                    registro = registro[1][0]['fnc_buscar_registro'][0]

                    self.posiciona_item_lote(registro)
                    logging.info('[RegistroRemanufatura] Item lote localizado.')

                    return True
            else:
                logging.info('[RegistroRemanufatura] Item lote não localizado.')

        else:
            dialog = StatusDialog(
                status='ALERTA'
                , exception=retorno
                , mensagem=' Não foi possível inserir remanufatura.'
                , parent=self
            )
            dialog.exec()
            logging.info('[RegistroRemanufatura] Não foi possível identificar insumo em estoque.')
            self.lineEdit_insumo_id.setDisabled(False)
            self.lineEdit_casco_id.setDisabled(False)
            self.frameFormLayout_remanufatura.setDisabled(False)
            return False

    def posiciona_item_lote(self, dados):

        self.formFrame_item_lote.setVisible(True)

        item_lote = dados

        self.label_item_lote_descricao.setText(
            item_lote['codigo_mercadoria'] + ' - ' + item_lote['descricao']
        )

        self.label_item_lote_fabricante.setText(item_lote['marca'])

        ### datas
        data = str(item_lote['data_cadastro']).split('T')[0]
        data = data if data != 'None' else None
        if data is None:
            self.dateEdit_entrada.setDisabled(True)
        else:
            self.dateEdit_entrada.setDisabled(False)
            self.dateEdit_entrada.setDate(
                QDate.fromString(
                    data, 'yyyy-MM-dd')

            )

        data = str(item_lote['data_abertura']).split('T')[0]
        data = data if data != 'None' else None
        if data is None:
            self.dateEdit_abertura.setDisabled(True)
        else:
            self.dateEdit_abertura.setDisabled(False)
            self.dateEdit_abertura.setDate(
                QDate.fromString(
                    data, 'yyyy-MM-dd')
            )

        data = str(item_lote['data_validade']).split('T')[0]
        data = data if data != 'None' else None
        if data is None:
            self.dateEdit_validade.setDisabled(True)
        else:
            self.dateEdit_validade.setDisabled(False)
            self.dateEdit_validade.setDate(
                QDate.fromString(
                    data, 'yyyy-MM-dd')
            )

        self.label_item_lote_lote_id.setText(str(item_lote['id_lote']))

        self.label_item_lote_id.setText(str(item_lote['id_item_lote']))

        quantidade_remanufatura = item_lote['quantidade_remanufaturas']
        quantidade_remanufatura = '0' if quantidade_remanufatura is None else str(quantidade_remanufatura)
        self.label_item_lote_quantidade_remanufaturas.setText(quantidade_remanufatura)

        aberto = item_lote['aberto']
        self.label_item_lote_aberto.setText(
            'Sim' if aberto else 'Não'
        )

        self.label_icone_item_lote.setPixmap(
            QPixmap.fromImage(self.open_box if aberto else self.closed_box)
        )

        vazio = True if int(item_lote['quantidade_item']) == 0 else False
        self.label_item_lote_vazio.setText('Sim' if vazio else 'Não')

        if vazio:
            self.label_icone_item_lote.setPixmap(
                QPixmap.fromImage(self.vazio))
            self.pushButton_esvaziar.setDisabled(True)
        else:
            self.pushButton_esvaziar.setVisible(True)
            self.pushButton_esvaziar.setDisabled(False)
        self.ativar_botoes()

    def esvaziar_embalagem(self, item_lote_id):
        # Marca lote sendo utilizado para recargas como vazio
        if item_lote_id is None:
            logging.info('[RegistroRemanufatura] Nenhum item lote selecionado para esvaziar.')
            return

        dialog = ConfirmDialog(parent=self)
        dialog.definir_mensagem(
            "Tem certeza que deseja marcar essa embalagem como 'Vazia'?\nEssa ação não pode ser desfeita.")

        if dialog.exec():

            dados = {
                "metodo": "prc_esvaziar_item_lote"
                , "schema": "soad"
                , "params": {
                    "item_lote_id": str(item_lote_id)
                }
            }

            retorno = self.db.call_procedure(self.db.schema, dados)
            logging.info('[RegistroRemanufatura] Executado procedimento para esvaziar lote.')

            if retorno[0]:
                if retorno[1][0]['p_retorno'] == 100:
                    self.label_icone_item_lote.setPixmap(QPixmap.fromImage(self.vazio))
                    self.pushButton_esvaziar.setDisabled(True)
                    self.label_item_lote_vazio.setText('Sim')
                self.ativar_botoes()
            else:
                dialog = StatusDialog(
                    status='ALERTA'
                    , exception=retorno
                    , mensagem='Não foi possível esvaziar o insumo.'
                    , parent=self
                )
                dialog.exec()

    def ativar_botoes(self):
        disabled = True
        disabled = disabled and len(self.tableWidget_remanufaturas.selectedIndexes()) <= 0
        self.pushButton_limpar.setDisabled(disabled)

        disabled = disabled or self.label_item_lote_vazio.text() == 'Sim'
        self.pushButton_realizar.setDisabled(disabled)

    def fechar(self):
        if self.modo_edicao:

            if self.id_registro:
                return True

            if self.tableWidget_remanufaturas.rowCount() > 0:
                dialog = ConfirmDialog(parent=self)
                dialog.definir_mensagem("Tem certeza que deseja fechar? As remanufaturas CADASTRADAS serão perdidas.")
                fechar = dialog.exec()
            else:
                fechar = True
        else:
            fechar = True

        if fechar:
            self.limpar_tabela(apenas_selecionados=False)

        return fechar

    def visualizar_remanufatura(self, id_remanufatura):

        self.vazio = self.vazio.smoothScaled(100, 100)
        self.open_box = self.open_box.smoothScaled(100, 100)
        self.closed_box = self.closed_box.smoothScaled(100, 100)

        self.setMaximumWidth(self.minimumWidth())
        self.setMaximumHeight(self.minimumHeight())

        horizontalLayout_visualizacao = QHBoxLayout()
        self.verticalLayout_insumo.removeWidget(self.frame_insumo)
        self.verticalLayout_insumo.removeWidget(self.frame_insumo_item)
        self.verticalLayout_groupBox_insumo.removeItem(self.verticalLayout_insumo)

        self.verticalLayout_groupBox_insumo.addItem(horizontalLayout_visualizacao)
        horizontalLayout_visualizacao.addWidget(self.frame_insumo)
        horizontalLayout_visualizacao.addWidget(self.frame_insumo_item)

        self.lineEdit_casco_id.setDisabled(True)
        self.lineEdit_insumo_id.setDisabled(True)
        self.groupBox_remanufaturas.setVisible(False)
        self.buttonBox_remanufatura.setVisible(False)
        self.spinBox_quantidade.setVisible(False)
        self.label_situacao.setVisible(True)
        self.buscar_remanufatura(remanufatura_id=id_remanufatura)
        # Manipular botões

        self.pushButton_limpar.setText('Remover remanufatura')
        self.pushButton_realizar.setText('Realizar remanufatura')

        self.toolButton_casco.setVisible(False)
        self.toolButton_insumo.setVisible(False)

        situacao = self.label_situacao.text()

        if situacao == 'CADASTRADA':
            self.pushButton_realizar.setDisabled(False)
            self.pushButton_limpar.setDisabled(False)

        else:
            self.pushButton_esvaziar.setVisible(False)
            self.pushButton_realizar.setVisible(False)
            self.pushButton_limpar.setVisible(False)

    def buscar_remanufatura(self, remanufatura_id):

        remanufatura = None

        tabela = 'vw_remanufatura'
        campo = 'id_remanufatura'

        if remanufatura_id != '':

            remanufatura = self.db.busca_registro(tabela, campo, str(remanufatura_id), '=')[1][0]['fnc_buscar_registro']

            logging.debug('[RegistroRemanufatura] ' + str(remanufatura))
            if remanufatura is not None:
                remanufatura = remanufatura[0]

                print(remanufatura['id_pedido'])

                self.label_pedido_id.setText(
                    "Venda N°: " + str(remanufatura['id_pedido']) if remanufatura['id_pedido'] is not None
                    else 'Nenhuma venda vínculada'
                )

                remanufaturas = list(dict())

                remanufaturas.append(
                    Remanufatura(
                        remanufatura_id=remanufatura_id
                        , casco_id=int(remanufatura['id_casco'])
                        , insumo_id=int(remanufatura['id_insumo'])
                        , situacao=remanufatura['situacao_remanufatura']
                    )
                )

                self.popular_tabela(remanufaturas)
                self.localiza_item_lote(remanufatura_id=remanufatura_id, novo=False)
                self.selecionar_todas(nao_valida_checkbox=True)

        if remanufatura:
            self.lineEdit_codigo.setText(str(remanufatura['codigo']))
            self.lineEdit_casco_id.setText(str(remanufatura['id_casco']))
            self.lineEdit_casco_id.editingFinished.emit()

            self.lineEdit_insumo_id.setText(str(remanufatura['id_insumo']))
            self.lineEdit_insumo_id.editingFinished.emit()

            self.label_situacao.setText(str(remanufatura['situacao_remanufatura']))
            return True

        else:
            return False

    def translate_ui(self):
        self.buttonBox_remanufatura.button(QDialogButtonBox.Ok).setText('Registrar')
        self.buttonBox_remanufatura.button(QDialogButtonBox.Reset).setText('Limpar')
    def __init__(self, db=None, window_list=None, parent=None, **kwargs):
        super(CadastroPedido, self).__init__(parent, **kwargs)
        ### Padrão
        self.parent_window = self
        self.setupUi(self)

        self.db = db
        self.window_list = window_list
        self.modo_edicao = False

        self.frame_menu.setDisabled(False)
        self.frame_contents.setDisabled(True)
        self.frame_buttons.setDisabled(True)

        self.pushButton_cadastrar.clicked.connect(self.cadastrar)
        self.pushButton_editar.clicked.connect(self.editar)
        self.pushButton_excluir.clicked.connect(self.excluir)
        self.pushButton_localizar.clicked.connect(self.localizar)
        self.pushButton_imprimir.clicked.connect(self.imprimir_pedido)

        self.buttonBox.button(QDialogButtonBox.Ok).clicked.connect(self.confirma)
        self.buttonBox.button(QDialogButtonBox.Cancel).clicked.connect(self.cancela)
        ### Fim padrão

        self.label_tinta.setText('')
        self.color_ink = QImage(os.path.join("Resources", "icons", "color_ink.png")).smoothScaled(45, 45)
        self.bw_ink = QImage(os.path.join("Resources", "icons", "bw_ink.png")).smoothScaled(45, 45)
        self.label_tinta.setPixmap(QPixmap.fromImage(self.bw_ink))

        self.icone_cancelar = QIcon(os.path.join('Resources', 'icons', 'cancel.png'))
        self.icone_alerta = QIcon(os.path.join('Resources', 'icons', 'warning.png'))
        self.icone_estornar = QIcon(os.path.join('Resources', 'icons', 'undo.png'))

        # Compra ou venda
        self.tipo_pedido = kwargs.get('tipo')

        self.configura_tipo()

        self.filtro_adicional = None
        self.setWindowTitle('SOAD - Registrar ' + self.tipo_pedido.capitalize())

        # buttonBox items
        self.buttonBox_item.button(QDialogButtonBox.Save).clicked.connect(self.salva_item)
        self.buttonBox_item.button(QDialogButtonBox.Reset).clicked.connect(self.limpar_item)

        self.lineEdit_valor_total_item.textChanged[str].connect(self.valida_valores)
        self.lineEdit_casco_id.textChanged[str].connect(self.valida_valores)
        self.lineEdit_insumo_id.textChanged[str].connect(self.valida_valores)
        self.lineEdit_mercadoria_id.textChanged[str].connect(self.valida_valores)
        self.lineEdit_quantidade.textChanged[str].connect(self.valida_valores)
        self.lineEdit_valor_unitario.textChanged[str].connect(self.valida_valores)

        self.tableWidget_items.itemDoubleClicked.connect(self.posicionar_item)

        self.pushButton_movimentar.clicked.connect(
            lambda: self.movimentar(self.lineEdit_id.text())
        )

        self.pushButton_remover_item.setDisabled(True)

        self.tableWidget_items.itemClicked.connect(
            lambda: self.pushButton_remover_item.setDisabled(
                len(self.tableWidget_items.selectedIndexes()) <= 0
            )
        )

        self.pushButton_remover_item.clicked.connect(self.apagar_item)

        # campos obrigatorios:
        self.campos_obrigatorios = dict([
            ('Documento', self.lineEdit_documento)
            , ('Casco', self.lineEdit_casco_id)
            , ('Mercadoria', self.lineEdit_mercadoria_id)
            , ('Insumo', self.lineEdit_insumo_id)
            , ('Quantidade', self.lineEdit_quantidade)
            , ('Valor Unitário', self.lineEdit_valor_unitario)
            , ('Valor Total Item', self.lineEdit_valor_total_item)
        ])

        # Radio Button item
        self.radioButton_remanufatura.toggled.connect(self.define_tipo)

        # Define se ativa o botão editar e excluir
        self.pushButton_editar.setDisabled(True)
        self.pushButton_excluir.setDisabled(True)
        self.lineEdit_id.textChanged[str].connect(self.define_permite_editar)

        self.pushButton_excluir.setText('Cancelar Pedido')
        self.pushButton_excluir.setIcon(self.icone_cancelar)

        self.pushButton_movimentar.setDisabled(True)

        # Validadores de tipos de dados
        validador_double = QDoubleValidator(bottom=0.000001, top=1000000.00, decimals=6)
        validador_integer = QIntValidator(bottom=1, top=1000000)
        validador_regex_doc = QRegExpValidator(QRegExp("[0-9]{1,14}"))
        validador_regex_id = QRegExpValidator(QRegExp("[0-9]{1,9}"))

        self.lineEdit_quantidade.setValidator(validador_regex_doc)
        self.lineEdit_valor_unitario.setValidator(validador_double)

        self.lineEdit_mercadoria_id.setValidator(validador_regex_id)
        self.lineEdit_casco_id.setValidator(validador_regex_id)
        self.lineEdit_insumo_id.setValidator(validador_regex_id)
        self.lineEdit_documento.setValidator(validador_regex_doc)

        self.dateEdit_entrega.setDate(QDate().currentDate())
        self.dateEdit_cadastro.setDate(QDate().currentDate())

        self.label_situacao.setText('')

        # Atualiza valores
        self.lineEdit_valor_total_pedido.setText('0,00')
        self.lineEdit_quantidade.editingFinished.connect(self.calcula_totais_item)
        self.lineEdit_valor_unitario.editingFinished.connect(self.calcula_totais_item)

        # Buscar registros
        self.lineEdit_documento.editingFinished.connect(self.busca_pessoa)
        self.lineEdit_casco_id.editingFinished.connect(lambda: self.busca_mercadoria(tipo='CASCO'))
        self.lineEdit_insumo_id.editingFinished.connect(lambda: self.busca_mercadoria(tipo='INSUMO'))
        self.lineEdit_mercadoria_id.editingFinished.connect(lambda: self.busca_mercadoria(tipo='MERCADORIA'))

        self.toolButton_pessoa.clicked.connect(lambda: self.busca_pessoa(force=True))
        self.toolButton_insumo.clicked.connect(lambda: self.busca_mercadoria(tipo='INSUMO', force=True))
        self.toolButton_casco.clicked.connect(lambda: self.busca_mercadoria(tipo='CASCO', force=True))
        self.toolButton_mercadoria.clicked.connect(lambda: self.busca_mercadoria(tipo='MERCADORIA', force=True))

        # Variaveis para gravar o pedido
        self.pedido = Pedido(tipo_pedido=self.tipo_pedido)
        self.pessoa = None

        ## Monta QTableWidget
        self.colunas_item = {
            "item_pedido_id": 'ID'
            , "codigo": 'Código'
            , "tipo_item": 'Tipo'
            , "descricao": 'Descrição'
            , "quantidade": "Quant."
            , "valor_unitario": "V. Unitário"
            , "valor_total": "V. Total"
        }

        self.colunas_descricao = list(self.colunas_item.values())
        self.colunas_chave = list(self.colunas_item.keys())

        self.tableWidget_items.setRowCount(len(self.pedido.itens))
        self.tableWidget_items.setColumnCount(len(self.colunas_descricao))
        self.tableWidget_items.setHorizontalHeaderLabels(self.colunas_descricao)
        self.tableWidget_items.horizontalHeader().setVisible(True)
        ### Fim monta tableWidget

        self.radioButton_mercadoria.setChecked(True)
        self.define_tipo()

        self.dialog_localizar = LocalizarDialog(db=self.db, parent=self)

        self.define_icones()

        self.adiciona_help(texto=self.help)

        self.tabWidget.setCurrentIndex(0)

        self.id_registro = kwargs.get('id_registro')
        if self.id_registro:
            self.atualizar_interface(self.id_registro)

        self.lineEdit_item_pedido_id.setVisible(False)
        self.visualizar()

        self.limpa_obrigatorios()
        self.define_permite_editar()

        self.translate_ui()

        self.show()
class CadastroPedido(CadastroPadrao, Ui_CadastroPedido):

    def __init__(self, db=None, window_list=None, parent=None, **kwargs):
        super(CadastroPedido, self).__init__(parent, **kwargs)
        ### Padrão
        self.parent_window = self
        self.setupUi(self)

        self.db = db
        self.window_list = window_list
        self.modo_edicao = False

        self.frame_menu.setDisabled(False)
        self.frame_contents.setDisabled(True)
        self.frame_buttons.setDisabled(True)

        self.pushButton_cadastrar.clicked.connect(self.cadastrar)
        self.pushButton_editar.clicked.connect(self.editar)
        self.pushButton_excluir.clicked.connect(self.excluir)
        self.pushButton_localizar.clicked.connect(self.localizar)
        self.pushButton_imprimir.clicked.connect(self.imprimir_pedido)

        self.buttonBox.button(QDialogButtonBox.Ok).clicked.connect(self.confirma)
        self.buttonBox.button(QDialogButtonBox.Cancel).clicked.connect(self.cancela)
        ### Fim padrão

        self.label_tinta.setText('')
        self.color_ink = QImage(os.path.join("Resources", "icons", "color_ink.png")).smoothScaled(45, 45)
        self.bw_ink = QImage(os.path.join("Resources", "icons", "bw_ink.png")).smoothScaled(45, 45)
        self.label_tinta.setPixmap(QPixmap.fromImage(self.bw_ink))

        self.icone_cancelar = QIcon(os.path.join('Resources', 'icons', 'cancel.png'))
        self.icone_alerta = QIcon(os.path.join('Resources', 'icons', 'warning.png'))
        self.icone_estornar = QIcon(os.path.join('Resources', 'icons', 'undo.png'))

        # Compra ou venda
        self.tipo_pedido = kwargs.get('tipo')

        self.configura_tipo()

        self.filtro_adicional = None
        self.setWindowTitle('SOAD - Registrar ' + self.tipo_pedido.capitalize())

        # buttonBox items
        self.buttonBox_item.button(QDialogButtonBox.Save).clicked.connect(self.salva_item)
        self.buttonBox_item.button(QDialogButtonBox.Reset).clicked.connect(self.limpar_item)

        self.lineEdit_valor_total_item.textChanged[str].connect(self.valida_valores)
        self.lineEdit_casco_id.textChanged[str].connect(self.valida_valores)
        self.lineEdit_insumo_id.textChanged[str].connect(self.valida_valores)
        self.lineEdit_mercadoria_id.textChanged[str].connect(self.valida_valores)
        self.lineEdit_quantidade.textChanged[str].connect(self.valida_valores)
        self.lineEdit_valor_unitario.textChanged[str].connect(self.valida_valores)

        self.tableWidget_items.itemDoubleClicked.connect(self.posicionar_item)

        self.pushButton_movimentar.clicked.connect(
            lambda: self.movimentar(self.lineEdit_id.text())
        )

        self.pushButton_remover_item.setDisabled(True)

        self.tableWidget_items.itemClicked.connect(
            lambda: self.pushButton_remover_item.setDisabled(
                len(self.tableWidget_items.selectedIndexes()) <= 0
            )
        )

        self.pushButton_remover_item.clicked.connect(self.apagar_item)

        # campos obrigatorios:
        self.campos_obrigatorios = dict([
            ('Documento', self.lineEdit_documento)
            , ('Casco', self.lineEdit_casco_id)
            , ('Mercadoria', self.lineEdit_mercadoria_id)
            , ('Insumo', self.lineEdit_insumo_id)
            , ('Quantidade', self.lineEdit_quantidade)
            , ('Valor Unitário', self.lineEdit_valor_unitario)
            , ('Valor Total Item', self.lineEdit_valor_total_item)
        ])

        # Radio Button item
        self.radioButton_remanufatura.toggled.connect(self.define_tipo)

        # Define se ativa o botão editar e excluir
        self.pushButton_editar.setDisabled(True)
        self.pushButton_excluir.setDisabled(True)
        self.lineEdit_id.textChanged[str].connect(self.define_permite_editar)

        self.pushButton_excluir.setText('Cancelar Pedido')
        self.pushButton_excluir.setIcon(self.icone_cancelar)

        self.pushButton_movimentar.setDisabled(True)

        # Validadores de tipos de dados
        validador_double = QDoubleValidator(bottom=0.000001, top=1000000.00, decimals=6)
        validador_integer = QIntValidator(bottom=1, top=1000000)
        validador_regex_doc = QRegExpValidator(QRegExp("[0-9]{1,14}"))
        validador_regex_id = QRegExpValidator(QRegExp("[0-9]{1,9}"))

        self.lineEdit_quantidade.setValidator(validador_regex_doc)
        self.lineEdit_valor_unitario.setValidator(validador_double)

        self.lineEdit_mercadoria_id.setValidator(validador_regex_id)
        self.lineEdit_casco_id.setValidator(validador_regex_id)
        self.lineEdit_insumo_id.setValidator(validador_regex_id)
        self.lineEdit_documento.setValidator(validador_regex_doc)

        self.dateEdit_entrega.setDate(QDate().currentDate())
        self.dateEdit_cadastro.setDate(QDate().currentDate())

        self.label_situacao.setText('')

        # Atualiza valores
        self.lineEdit_valor_total_pedido.setText('0,00')
        self.lineEdit_quantidade.editingFinished.connect(self.calcula_totais_item)
        self.lineEdit_valor_unitario.editingFinished.connect(self.calcula_totais_item)

        # Buscar registros
        self.lineEdit_documento.editingFinished.connect(self.busca_pessoa)
        self.lineEdit_casco_id.editingFinished.connect(lambda: self.busca_mercadoria(tipo='CASCO'))
        self.lineEdit_insumo_id.editingFinished.connect(lambda: self.busca_mercadoria(tipo='INSUMO'))
        self.lineEdit_mercadoria_id.editingFinished.connect(lambda: self.busca_mercadoria(tipo='MERCADORIA'))

        self.toolButton_pessoa.clicked.connect(lambda: self.busca_pessoa(force=True))
        self.toolButton_insumo.clicked.connect(lambda: self.busca_mercadoria(tipo='INSUMO', force=True))
        self.toolButton_casco.clicked.connect(lambda: self.busca_mercadoria(tipo='CASCO', force=True))
        self.toolButton_mercadoria.clicked.connect(lambda: self.busca_mercadoria(tipo='MERCADORIA', force=True))

        # Variaveis para gravar o pedido
        self.pedido = Pedido(tipo_pedido=self.tipo_pedido)
        self.pessoa = None

        ## Monta QTableWidget
        self.colunas_item = {
            "item_pedido_id": 'ID'
            , "codigo": 'Código'
            , "tipo_item": 'Tipo'
            , "descricao": 'Descrição'
            , "quantidade": "Quant."
            , "valor_unitario": "V. Unitário"
            , "valor_total": "V. Total"
        }

        self.colunas_descricao = list(self.colunas_item.values())
        self.colunas_chave = list(self.colunas_item.keys())

        self.tableWidget_items.setRowCount(len(self.pedido.itens))
        self.tableWidget_items.setColumnCount(len(self.colunas_descricao))
        self.tableWidget_items.setHorizontalHeaderLabels(self.colunas_descricao)
        self.tableWidget_items.horizontalHeader().setVisible(True)
        ### Fim monta tableWidget

        self.radioButton_mercadoria.setChecked(True)
        self.define_tipo()

        self.dialog_localizar = LocalizarDialog(db=self.db, parent=self)

        self.define_icones()

        self.adiciona_help(texto=self.help)

        self.tabWidget.setCurrentIndex(0)

        self.id_registro = kwargs.get('id_registro')
        if self.id_registro:
            self.atualizar_interface(self.id_registro)

        self.lineEdit_item_pedido_id.setVisible(False)
        self.visualizar()

        self.limpa_obrigatorios()
        self.define_permite_editar()

        self.translate_ui()

        self.show()

    def cadastrar(self):
        super(CadastroPedido, self).cadastrar()
        self.limpar_dados()
        self.visualizar(False)
        self.pushButton_excluir.setText('Cancelar Pedido')
        self.pushButton_excluir.setIcon(self.icone_cancelar)
        self.label_situacao.setText('')
        self.lineEdit_documento.setDisabled(False)
        self.buttonBox_item.button(QDialogButtonBox.Save).setDisabled(True)

    def editar(self):
        super(CadastroPedido, self).editar()
        self.visualizar(False)
        self.lineEdit_documento.setDisabled(True)

    def excluir(self, validar=True):

        if self.label_situacao.text() == 'CADASTRADO'\
                or self.label_situacao.text() == 'ESTORNADO':
            acao = 'cancelamento'
            prc = 'prc_cancelar_pedido'

        elif self.label_situacao.text() == 'ENCERRADO':
            acao = 'estorno'
            prc = 'prc_estornar_pedido'

        else:
            logging.debug('[CadastroPedido] Situacao invalida=' + self.label_situacao.text())
            return

        pedido_id = self.lineEdit_id.text()

        dialog = ConfirmDialog(self)
        dialog.definir_mensagem('Tem certeza que deseja realizar o ' + acao + ' desse pedido?')

        if dialog.exec():

            self.dados = {
                "metodo": prc,
                "schema": "soad",
                "params": {
                    "pedido_id": pedido_id
                }
            }

            retorno = super(CadastroPedido, self).excluir(validar=False)

            if retorno[0]:
                dialog = StatusDialog(status='OK'
                                      , mensagem=acao.capitalize() + ' realizado com sucesso.'
                                      , parent=self.parent_window)
                self.atualizar_interface(pedido_id)

            else:
                dialog = StatusDialog(status='ALERTA'
                                      , mensagem='Não foi possível realizar o ' + acao + ' do pedido.'
                                      , exception=retorno
                                      , parent=self.parent_window)

            dialog.exec()

    def valida_obrigatorios(self):
        if self.tableWidget_items.rowCount() == 0:
            dialog = StatusDialog(
                status='ALERTA'
                , mensagem='Não é possível realizar uma '
                           + self.tipo_pedido + ' sem itens.'
                , parent=self.parent_window
                , esconder_detalhes=True
            )
            return dialog.exec()
        return super(CadastroPedido, self).valida_obrigatorios()

    def confirma(self):

        if self.buttonBox_item.button(QDialogButtonBox.Save).isEnabled():
            self.salva_item()

        # Remove obrigatoriedade dos itens
        self.campos_obrigatorios = dict([
            ('Documento', self.lineEdit_documento)
        ])

        if self.valida_obrigatorios() != 'OK':
            return False

        if self.novo_cadastro:
            self.pedido.pedido_id = ''

        else:
            self.pedido.pedido_id = self.lineEdit_id.text()

        self.pedido.data_entrega = self.dateEdit_entrega.date().toString("dd.MM.yyyy").replace('.', '/')
        self.pedido.observacao = self.textEdit_observacao.toPlainText()

        pedido_dict = self.pedido.to_dict()
        pedido_dict.pop('data_cadastro')
        pedido_dict.pop('situacao')

        self.tabWidget.setCurrentIndex(1)

        self.dados = {
            "metodo": "fnc_cadastro_pedido",
            "schema": "soad",
            "params": pedido_dict
        }

        retorno = super(CadastroPedido, self).confirma()

        if retorno[0]:
            pedido_id = retorno[1]['p_retorno_json']['pedido_id']
            self.movimentar(pedido_id)

        else:
            logging.debug('[CadastroPedido] Não foi possível confirmar o cadastro.')

    def cancela(self):
        if super(CadastroPedido, self).cancela():
            if self.lineEdit_id.text() == '':
                self.limpar_dados()
            else:
                id = self.lineEdit_id.text()
                self.atualizar_interface(int(id))
            self.define_permite_editar()

    def limpar_dados(self):
        super(CadastroPedido, self).limpar_dados()
        self.pedido = Pedido(tipo_pedido=self.tipo_pedido)
        self.pedido.itens = []
        self.label_tipo_pedido.setText('')
        self.limpar_item()
        self.lineEdit_documento.clear()
        self.lineEdit_nome_pessoa.clear()
        self.label_situacao.setText('')
        self.dateEdit_entrega.setDate(QDate().currentDate())
        self.preencher_tabela()
        self.pushButton_movimentar.setDisabled(True)
        self.textEdit_observacao.clear()

    def localizar(self, parent=None):

        self.localizar_campos = {
            "id_pedido": 'ID',
            "pessoa": self.tipo_pessoa,
            "documento": 'Documento',
            "data_cadastro": 'Data cadastro',
            "situacao": 'Situação',
            "data_entrega": self.label_data.text()
        }

        self.colunas_busca = {
            "id_pedido": 'ID',
            "pessoa": self.tipo_pessoa,
            "documento": 'Documento',
            "data_cadastro": 'Data cadastro',
            "situacao": 'Situação',
            "data_entrega": self.label_data.text()
        }

        retorno = super(CadastroPedido, self).localizar(parent=self)

        if retorno is not None:
            self.atualizar_interface(retorno)

    def visualizar(self, entrar_modo_visualziacao=True):

        if entrar_modo_visualziacao:
            self.entrar_modo_visualizacao()
            self.groupBox_identificacao.setDisabled(True)
            self.groupBox_items.setDisabled(False)
            self.tabWidget.setDisabled(False)
            self.tab_campos.setDisabled(True)
            self.horizontalWidget_botoes_tabela.setVisible(False)
            self.buttonBox_item.setVisible(False)

        else:
            self.groupBox_identificacao.setDisabled(False)
            self.groupBox_items.setDisabled(False)
            self.tabWidget.setDisabled(False)
            self.tab_campos.setDisabled(False)
            self.horizontalWidget_botoes_tabela.setVisible(True)
            self.buttonBox_item.setVisible(True)

    def movimentar(self, pedido_id):
        dialog = ConfirmDialog(self)
        dialog.definir_mensagem(
            'Deseja realizar a movimentação dessa ' + self.tipo_pedido.capitalize()
            + '\n(Pedido: ' + str(pedido_id) + ')?\nO pedido não poderá mais ser editado.')

        if dialog.exec():
            dados = {
                "metodo": "prc_encerrar_pedido",
                "schema": "soad",
                "params": {"pedido_id": str(pedido_id)}
            }

            retorno = self.db.call_procedure(self.db.schema, dados)
            self.atualizar_interface(pedido_id)

            if retorno[0]:
                retorno = retorno[1][0]['p_retorno']

                if int(retorno) == int(100):
                    return True
                else:
                    return False
            else:
                dialog = StatusDialog(
                    mensagem='Não foi possível realizar a movimentação do pedido.',
                    exception=retorno,
                    status='ALERTA'
                )
                dialog.exec()
                return False
        else:
            self.atualizar_interface(pedido_id)

    def define_tipo(self):

        self.campos_obrigatorios = dict([
            ('Documento', self.lineEdit_documento)
            , ('Casco', self.lineEdit_casco_id)
            , ('Mercadoria', self.lineEdit_mercadoria_id)
            , ('Insumo', self.lineEdit_insumo_id)
            , ('Quantidade', self.lineEdit_quantidade)
            , ('Valor Unitário', self.lineEdit_valor_unitario)
            , ('Valor Total Item', self.lineEdit_valor_total_item)
        ])

        if self.radioButton_mercadoria.isChecked():
            self.stackedWidget_item.setCurrentWidget(self.page_mercadoria)
            self.campos_obrigatorios.pop('Casco')
            self.campos_obrigatorios.pop('Insumo')
            self.campos_obrigatorios['Mercadoria'] = self.lineEdit_mercadoria_id

        elif self.radioButton_remanufatura.isChecked():
            self.stackedWidget_item.setCurrentWidget(self.page_remanufatura)
            self.campos_obrigatorios.pop('Mercadoria')
            self.campos_obrigatorios['Casco'] = self.lineEdit_casco_id
            self.campos_obrigatorios['Insumo'] = self.lineEdit_insumo_id

        self.limpa_obrigatorios()
        self.marca_obrigatorios()
        self.limpar_item()

    def atualizar_interface(self, id_pedido):

        self.limpar_dados()
        self.pedido.pedido_id = id_pedido

        dados = self.db.get_registro(
            "fnc_get_pedido"
            , "pedido_id"
            , self.pedido.pedido_id
        )

        if dados[0]:
            dados = dados[1][0]['json_pedido']
            self.popular_interface(dados)
            self.tabWidget.setCurrentIndex(1)

        else:
            dialog = StatusDialog(
                status='ERRO'
                , exception=dados
                , mensagem='Erro ao buscar dados.'
                , parent=self
            )
            dialog.exec()

    def popular_interface(self, dados):
        # Preenche identificação

        pedido = dados[0]

        self.lineEdit_documento.setText(pedido['documento'])
        self.lineEdit_nome_pessoa.setText(pedido['pessoa'])

        pedido = Pedido(
            pedido_id=pedido['id_pedido']
            , pessoa_id=pedido['id_pessoa']
            , tipo_pedido=pedido['tipo_pedido']
            , data_entrega=pedido['data_entrega']
            , situacao=pedido['situacao']
            , data_cadastro=pedido['data_cadastro']
            , observacao=pedido['observacao']
        )

        self.label_situacao.setText(
            pedido.situacao if pedido.situacao is not None else ''
        )

        self.label_tipo_pedido.setText(pedido.tipo_pedido)
        self.tipo_pedido = pedido.tipo_pedido
        self.configura_tipo()

        self.textEdit_observacao.setText(pedido.observacao)

        self.dateEdit_cadastro.setDate(
            QDate.fromString(
                pedido.data_cadastro
                , 'yyyy-MM-ddTHH:mm:ss')
        )

        if pedido.situacao == 'CADASTRADO'\
                or pedido.situacao == 'ESTORNADO':
            self.pushButton_excluir.setText('Cancelar Pedido')
            self.pushButton_excluir.setIcon(self.icone_cancelar)

        elif pedido.situacao == 'ENCERRADO':
            self.pushButton_excluir.setText('Estornar Pedido')
            self.pushButton_excluir.setIcon(self.icone_estornar)

        if pedido.data_entrega is not None:

            self.dateEdit_entrega.setDate(
                QDate.fromString(
                    pedido.data_entrega
                    , 'yyyy-MM-ddTHH:mm:ss')
            )

        else:
            self.dateEdit_entrega.clear()

        # ID é o ultimo a alterar para evitar race condition com self.define_permite_editar
        self.lineEdit_id.setText(str(pedido.pedido_id))

        # Montar ItemPedido
        for item in dados[1]:
            if item['tipo'] == 'MERCADORIA':

                item_pedido = ItemPedido(
                    item_pedido_id=item['id_item_pedido']
                    , tipo=item['tipo']
                    , quantidade=item['quantidade']
                    , valor_unitario=item['valor_unitario']
                    , mercadoria_id=item['id_mercadoria']
                    , unidade_medida_id=item['id_unidade_medida']
                    , unidade_medida=item['unidade_medida']
                    , mercadoria=item['descricao']
                    , descricao=item['descricao']
                )

                item_pedido.alerta = self.verifica_disponibilidade(
                    item_pedido.tipo, item_pedido.mercadoria_id, item_pedido.quantidade)

            elif item['tipo'] == 'REMANUFATURA':

                item_pedido = ItemPedido(
                    item_pedido_id=item['id_remanufatura']
                    , tipo=item['tipo']
                    , quantidade=item['quantidade']
                    , valor_unitario=item['valor_unitario']
                    , casco_id=item['casco_id']
                    , insumo_id=item['insumo_id']
                    , nova_remanufatura=None #item['nova_remanufatura']
                    , descricao='Casco: ' + item['casco']
                                + ' Insumo: ' + item['insumo']
                )

                item_pedido.alerta = self.verifica_disponibilidade(
                    item_pedido.tipo, item_pedido.insumo_id, item_pedido.quantidade)

            else:
                logging.debug('[CadastroPedido] Não foi possível identificar o tipo do item do pedido')
                logging.debug('[CadastroPedido] Abortando...')
                return

            pedido.itens.append(item_pedido)

        # Preenche tabela
        self.pedido = pedido
        self.preencher_tabela()
        self.calcula_totais_pedido()

        self.pushButton_movimentar.setDisabled(
            self.label_situacao.text() != 'CADASTRADO'
            and self.label_situacao.text() != 'ESTORNADO'
        )

        # Posiciona o primeiro item da tabela no stack
        self.tableWidget_items.selectRow(0)
        self.posicionar_item(None)

        self.visualizar(True)

    def busca_pessoa(self, force=False):

        tabela = 'vw_pessoa_' + self.tipo_pessoa.lower()
        documento = self.lineEdit_documento.text().replace(' ', '')
        pessoa = None
        filtro_adicional = ''

        if documento != '':

            documento = documento.replace('-', '').replace('/', '')
            pessoa = self.db.busca_registro(tabela, 'documento', documento, '=')[1][0]['fnc_buscar_registro']

            if pessoa is not None:
                pessoa = pessoa[0]

        if pessoa is None or force:

            localizar_campos = {
                "id_pessoa": 'ID',
                "nome": 'Nome',
                'documento': "Documento"
            }

            colunas_busca = {
                "id_pessoa": 'ID',
                "nome": 'Nome',
                'documento': "Documento"
            }

            self.dialog_localizar.define_tabela(tabela)
            self.dialog_localizar.define_campos(localizar_campos)
            self.dialog_localizar.define_colunas(colunas_busca)
            self.dialog_localizar.filtro = filtro_adicional

            self.dialog_localizar.define_valor_padrao(localizar_campos['nome'], '') if force \
                else self.dialog_localizar.define_valor_padrao(localizar_campos['documento'], self.lineEdit_documento.text())

            pessoa_id = self.dialog_localizar.exec()

            if pessoa_id == 0:
                return False

            pessoa = self.db.busca_registro(tabela, 'id_pessoa', str(pessoa_id), '=')[1][0]['fnc_buscar_registro']

            if pessoa is not None:
                pessoa = pessoa[0]

        if pessoa:

            pessoa_pedido = Pessoa(
                nome=pessoa['nome']
                , email=pessoa['email']
                , telefone=pessoa['telefone']
                , documento=pessoa['documento']
                , inscricao_estadual=pessoa['inscricao_estadual']
                , fantasia=pessoa['fantasia']
                , id_pessoa=pessoa['id_pessoa']
            )
            self.lineEdit_documento.setText(pessoa_pedido.documento)
            self.lineEdit_nome_pessoa.setText(pessoa_pedido.nome)
            self.pedido.pessoa_id = pessoa_pedido.id_pessoa

            endereco = Endereco(
                id_pessoa=pessoa['id_pessoa']
                , municipio=pessoa['municipio']
                , estado=pessoa['sigla_uf']
                , pais=pessoa['pais']
                , logradouro=pessoa['logradouro']
                , numero=pessoa['numero']
                , bairro=pessoa['bairro']
                , cep=pessoa['cep']
                , complemento=pessoa['complemento']
                , tipo=pessoa['tipo_endereco']
            )

            pessoa_pedido.endereco.append(endereco)

            self.pessoa = pessoa_pedido

            return True

        else:
            self.lineEdit_documento.clear()
            self.lineEdit_nome_pessoa.clear()
            return False

    def busca_mercadoria(self, tipo, force=False):
        mercadoria = None
        filtro_adicional = ''

        if tipo == 'MERCADORIA':
            tabela = 'vw_mercadoria'
            campo = 'id_mercadoria'
            lineEdit_id = self.lineEdit_mercadoria_id
            lineEdit_descricao = self.lineEdit_mercadoria
            lineEdit_marca = self.lineEdit_marca_mercadoria

            if self.tipo_pedido == 'VENDA':
                filtro_adicional = 'permite_venda=true::boolean'

        elif tipo == 'CASCO':
            tabela = 'vw_casco'
            campo = 'id_casco'
            lineEdit_id = self.lineEdit_casco_id
            lineEdit_descricao = self.lineEdit_casco
            lineEdit_marca = self.lineEdit_marca_casco

        elif tipo == 'INSUMO':
            tabela = 'vw_insumo'
            campo = 'id_insumo'
            lineEdit_id = self.lineEdit_insumo_id
            lineEdit_descricao = self.lineEdit_insumo
            lineEdit_marca = self.lineEdit_marca_insumo

        else:
            logging.debug("[CadastroPedido] Tipo inválido: " + tipo)
            return False

        valor = lineEdit_id.text().replace(' ', '')

        if valor != '':

            mercadoria = self.db.busca_registro(tabela, campo, valor, '=', filtro=filtro_adicional)[1][0]['fnc_buscar_registro']

            logging.debug('[CadastroPedido] ' + str(mercadoria))
            if mercadoria is not None:
                mercadoria = mercadoria[0]
        else:
            lineEdit_descricao.clear()
            lineEdit_marca.clear()
            self.lineEdit_valor_unitario.clear()

        if mercadoria is None or force:

            localizar_campos = {
                campo: 'ID',
                "codigo": 'Código',
                "descricao": tipo.capitalize(),
                'marca': "Marca"
            }

            colunas_busca = {
                campo: 'ID',
                "codigo": 'Código',
                "descricao": tipo.capitalize(),
                'marca': "Marca"
            }

            self.dialog_localizar.define_tabela(tabela)
            self.dialog_localizar.define_campos(localizar_campos)
            self.dialog_localizar.define_colunas(colunas_busca)
            self.dialog_localizar.filtro = filtro_adicional

            self.dialog_localizar.define_valor_padrao(localizar_campos["descricao"], '') if force \
                else self.dialog_localizar.define_valor_padrao(localizar_campos[campo], lineEdit_id.text())

            mercadoria_id = self.dialog_localizar.exec()
            mercadoria = self.db.busca_registro(tabela, campo, str(mercadoria_id), '=')[1][0]['fnc_buscar_registro']

            if mercadoria_id == 0:
                return

            if mercadoria is not None:
                mercadoria = mercadoria[0]

        if mercadoria is not None:
            lineEdit_id.setText(str(mercadoria[campo]))
            lineEdit_descricao.setText(mercadoria['descricao'])
            lineEdit_marca.setText(mercadoria['marca'])

            valor = str(mercadoria['valor_venda']) if tipo != 'INSUMO' else '0,00'
            self.lineEdit_valor_unitario.setText(valor)

            if tipo == 'CASCO':
                self.lineEdit_insumo_id.setText(str(mercadoria['id_insumo']))
                self.lineEdit_insumo_id.editingFinished.emit()
                self.lineEdit_quantidade.setFocus()

                medida = str(mercadoria['quantidade_insumo']) + str(mercadoria['unidade_medida_insumo'])
                self.label_medida.setText(medida)

            if tipo == 'INSUMO':
                if bool(mercadoria['colorido']):
                    self.label_tinta.setPixmap(QPixmap.fromImage(self.color_ink))
                else:
                    self.label_tinta.setPixmap(QPixmap.fromImage(self.bw_ink))

            return True

        else:
            lineEdit_id.clear()
            lineEdit_descricao.clear()
            lineEdit_marca.clear()
            return False

    def posicionar_item(self, item):

        # buscar item em pedido.itens

        item_pedido = ItemPedido

        selecionado = self.tableWidget_items.selectedItems()[0]

        item_pedido.item_pedido_id = int(self.tableWidget_items.item(selecionado.row(), 0).text())

        for it in self.pedido.itens:
            if int(it.item_pedido_id) == int(item_pedido.item_pedido_id):
                item_pedido = it
                break

        if item_pedido.tipo == 'REMANUFATURA':

            self.radioButton_remanufatura.setChecked(True)
            self.define_tipo()
            self.lineEdit_casco_id.setText(str(item_pedido.casco_id))
            self.busca_mercadoria('CASCO')

            self.lineEdit_insumo_id.setText(str(item_pedido.insumo_id))
            self.busca_mercadoria('INSUMO')

        elif item_pedido.tipo == 'MERCADORIA':

            self.radioButton_mercadoria.setChecked(True)

            self.lineEdit_mercadoria_id.setText(str(item_pedido.mercadoria_id))
            self.busca_mercadoria('MERCADORIA')

        self.lineEdit_item_pedido_id.setText(str(item_pedido.item_pedido_id))

        if self.lineEdit_item_pedido_id.text() != '':
            self.buttonBox_item.button(QDialogButtonBox.Save).setText('Editar')
        else:
            self.buttonBox_item.button(QDialogButtonBox.Save).setText('Salvar')

        self.lineEdit_quantidade.setText(
            self.formatar_numero(item_pedido.quantidade))
        self.lineEdit_valor_unitario.setText(
            self.formatar_numero(item_pedido.valor_unitario))

        self.calcula_totais_item()

        self.tabWidget.setCurrentWidget(self.tab_campos)

        return item_pedido

    def salva_item(self):

        tipo_item = 'MERCADORIA' if self.radioButton_mercadoria.isChecked() else 'REMANUFATURA'

        if tipo_item == 'REMANUFATURA':
            descricao = 'Casco: ' + self.lineEdit_casco.text() \
                        + ' Insumo: ' + self.lineEdit_insumo.text()

            item = ItemPedido(
                tipo=tipo_item
                , quantidade=self.formatar_numero(self.lineEdit_quantidade.text())
                , valor_unitario=self.formatar_numero(self.lineEdit_valor_unitario.text())
                , casco_id=self.lineEdit_casco_id.text()
                , insumo_id=self.lineEdit_insumo_id.text()
                , nova_remanufatura=(self.checkBox_reutilizar_casco.isChecked())
                , descricao=descricao
            )

            item.alerta = self.verifica_disponibilidade(item.tipo, item.insumo_id, item.quantidade)

        else:

            descricao = self.lineEdit_mercadoria.text()

            item = ItemPedido(
                tipo=tipo_item
                , quantidade=self.formatar_numero(self.lineEdit_quantidade.text())
                , valor_unitario=self.formatar_numero(self.lineEdit_valor_unitario.text())
                , mercadoria_id=self.lineEdit_mercadoria_id.text()
                , unidade_medida_id=self.db.busca_registro(  # todo: Fazer dinâmico
                    'unidade_medida'
                    , 'abreviacao'
                    , 'UN'
                    , 'like')[1][0]['fnc_buscar_registro'][0]['id_unidade_medida']
                , mercadoria=descricao
                , descricao=descricao
            )

            item.alerta = self.verifica_disponibilidade(item.tipo, item.mercadoria_id, item.quantidade)

        item_pedido_id = self.lineEdit_item_pedido_id.text()
        novo_item = True if item_pedido_id == '' else False

        if novo_item:
            # Valida itens repetidos
            if len(self.pedido.itens) > 0:
                novo_item_id = self.lineEdit_mercadoria_id.text()
                for item_antigo in self.pedido.itens:
                    if item_antigo.tipo == 'MERCADORIA':
                        if novo_item_id == str(item_antigo.mercadoria_id):
                            print('validando repetidos')
                            dialog = StatusDialog(
                                status='ALERTA'
                                , mensagem='Não é possível inserir o mesmo item duas vezes em um pedido.'
                                , parent=self
                                , esconder_detalhes=True
                            )
                            dialog.exec()
                            return

            item.item_pedido_id = (len(self.pedido.itens) + 1) * -1
        else:
            item.item_pedido_id = int(item_pedido_id)

            for item_antigo in self.pedido.itens:
                if int(item_antigo.item_pedido_id) == int(item_pedido_id):
                    self.pedido.itens.remove(item_antigo)
                    break

        self.pedido.itens.append(item)
        self.preencher_tabela()
        self.calcula_totais_pedido()

    def verifica_disponibilidade(self, tipo, produto_id, quantidade):

        if self.tipo_pedido == 'COMPRA' \
                or self.label_situacao.text() == 'ENCERRADO'\
                or self.label_situacao.text() == 'CANCELADO':
            return ''

        dados = {
            "metodo": "fnc_verificar_disponibilidade",
            "schema": "soad",
            "params": {
                "mercadoria_id": str(produto_id)
                , "quantidade": str(quantidade)
                , "tipo": tipo
            }
        }

        retorno = self.db.call_procedure(self.db.schema, dados)

        if retorno[0]:

            disponivel = retorno[1][0]['p_retorno_json']['disponivel']

            if disponivel:
                return ''
            else:
                return 'O estoque atual não é suficiente para esta operação.'
        else:
            return ''

    def preencher_tabela(self):

        self.tableWidget_items.setRowCount(len(self.pedido.itens))

        if len(self.pedido.itens) > 0:
            row = 0
            for item_pedido in self.pedido.itens:
                col = 0
                for coluna in self.colunas_item:
                    valor = item_pedido.to_item_dict()[coluna]

                    if col in (4, 5, 6):
                        item = QTableWidgetItem(self.formatar_numero(valor))
                        item.setTextAlignment(Qt.AlignRight)

                        if col == 4 and item_pedido.alerta != '':
                            item.setIcon(self.icone_alerta)
                            item.setToolTip(item_pedido.alerta)

                    else:
                        item = QTableWidgetItem(self.formatar_numero(valor))

                    self.tableWidget_items.setItem(row, col, item)
                    col = col + 1
                row = row + 1

        self.tableWidget_items.setColumnHidden(0, True)
        self.tableWidget_items.setColumnHidden(1, True)

        self.tableWidget_items.resizeColumnsToContents()

        self.limpar_item()

    def apagar_item(self, item):
        # Remove do objeto pedido

        selecionado = self.tableWidget_items.selectedItems()

        if len(selecionado) > 0:
            selecionado = selecionado[0]

        item_pedido_id = int(self.tableWidget_items.item(selecionado.row(), 0).text())

        for it in self.pedido.itens:
            if int(it.item_pedido_id) == int(item_pedido_id):
                self.pedido.itens.remove(it)
                self.preencher_tabela()
                self.pushButton_remover_item.setDisabled(True)
                break

        self.calcula_totais_pedido()

    def limpar_item(self):

        if self.radioButton_mercadoria.isChecked():
            self.lineEdit_mercadoria_id.clear()
            self.lineEdit_mercadoria.clear()
            self.lineEdit_marca_mercadoria.clear()
        elif self.radioButton_remanufatura.isChecked():
            self.lineEdit_casco_id.clear()
            self.lineEdit_casco.clear()
            self.lineEdit_insumo_id.clear()
            self.lineEdit_insumo.clear()
            self.lineEdit_marca_casco.clear()
            self.lineEdit_marca_insumo.clear()
            self.checkBox_reutilizar_casco.setChecked(False)

        self.lineEdit_item_pedido_id.clear()
        self.lineEdit_quantidade.clear()
        self.lineEdit_valor_unitario.clear()
        self.lineEdit_valor_total_item.clear()
        self.lineEdit_valor_total_pedido.clear()

        self.label_medida.setText('0,00g')

        self.buttonBox_item.button(QDialogButtonBox.Save).setText('Salvar')

        self.calcula_totais_pedido()

    def calcula_totais_item(self):

        if self.lineEdit_valor_unitario.text() == '' or self.lineEdit_valor_unitario.text() == '0':
            valor_unitario = 0
            self.lineEdit_valor_unitario.setText('0,00')

        else:
            valor_unitario = float(self.formatar_numero(self.lineEdit_valor_unitario.text()).replace(' ', ''))
            self.lineEdit_valor_unitario.setText(self.formatar_numero(valor_unitario))

        if self.lineEdit_quantidade.text() == '' or self.lineEdit_quantidade.text() == '0':
            quantidade = 0
            self.lineEdit_quantidade.setText('0.00')

        else:
            quantidade = float(self.formatar_numero(self.lineEdit_quantidade.text()).replace(' ', ''))
            self.lineEdit_quantidade.setText(self.formatar_numero(quantidade))

        total_item = quantidade * valor_unitario
        self.lineEdit_valor_total_item.setText(self.formatar_numero(total_item))

    def calcula_totais_pedido(self):
        valor = 0
        for row in range(0, self.tableWidget_items.rowCount()):
            v = 0 if self.tableWidget_items.item(row, 6) is None else self.tableWidget_items.item(row, 6).text()
            v = self.formatar_numero(v)
            valor = valor + float(v)
        self.lineEdit_valor_total_pedido.setText(self.formatar_numero(valor))

    def define_icones(self):
        super(CadastroPedido, self).define_icones()
        self.pushButton_movimentar.setIcon(QIcon(os.path.join('Resources', 'icons', 'confirm.png')))
        self.pushButton_excluir.setIcon(self.icone_cancelar)
        self.pushButton_remover_item.setIcon(self.icone_delete)
        self.pushButton_imprimir.setIcon(QIcon(os.path.join('Resources', 'icons', 'printer.png')))
        find_icon = QIcon(os.path.join('Resources', 'icons', 'search.png'))
        self.toolButton_pessoa.setIcon(find_icon)
        self.toolButton_mercadoria.setIcon(find_icon)
        self.toolButton_insumo.setIcon(find_icon)
        self.toolButton_casco.setIcon(find_icon)

    def define_permite_editar(self):

        super(CadastroPedido, self).define_permite_editar()

        situacao = self.label_situacao.text()

        self.pushButton_editar.setDisabled(
            situacao == 'ENCERRADO' or situacao == 'CANCELADO' or self.lineEdit_id.text() == ''
        )

        self.pushButton_excluir.setDisabled(situacao == 'CANCELADO' or self.lineEdit_id.text() == '')

        self.pushButton_imprimir.setDisabled(situacao == 'CANCELADO' or self.lineEdit_id.text() == '')

    def configura_tipo(self):
        self.tipo_pedido = 'VENDA' if not self.tipo_pedido else self.tipo_pedido
        if self.tipo_pedido == 'VENDA':
            self.tipo_pessoa = 'Cliente'
            self.view_busca = 'vw_pedido_venda'
            self.formGroupBox_pessoa.setTitle(self.tipo_pessoa)
            self.horizontalFrame_tipo_item.setVisible(True)
            self.label_data.setText('Data entrega')
            self.help = \
'''Aqui podem ser realizadas vendas (remanufaturas e mercadorias).
Quando tiver terminado de cadastrar a venda é só encerrar o pedido para confirmar a venda.
Vendas encerradas devem ser estornadas para que possam ser editadas.'''

        elif self.tipo_pedido == 'COMPRA':
            self.tipo_pessoa = 'Fornecedor'
            self.view_busca = 'vw_pedido_compra'
            self.formGroupBox_pessoa.setTitle(self.tipo_pessoa)
            self.radioButton_mercadoria.setChecked(True)
            self.horizontalFrame_tipo_item.setVisible(False)
            self.label_data.setText('Data compra')
            self.help = \
'''Aqui podem ser registradas as suas compras.
Quando tiver terminado de cadastrar é só encerrar o pedido para confirmar a entrada da mercadoria.
Compras encerradas devem ser estornadas para que possam ser editadas.'''

        else:
            dialog = StatusDialog(status='ERRO', mensagem='TIPO DE PEDIDO ' + str(self.tipo_pedido) + ' INVÁLIDO',
                                  parent=self)
            dialog.exec()

    def valida_valores(self):

        ativo = (self.lineEdit_quantidade.text() == '' or self.lineEdit_quantidade.text() == '0') \
                or (self.lineEdit_valor_unitario.text() == '' or self.lineEdit_valor_unitario.text() == '0') \
                or (self.lineEdit_valor_total_item.text() == '' or self.lineEdit_valor_total_item.text() == '0.0')

        if self.radioButton_mercadoria.isChecked():
            ativo = ativo \
                    or self.lineEdit_mercadoria_id.text() == ''

        if self.radioButton_remanufatura.isChecked():
            ativo = ativo \
                    or self.lineEdit_insumo_id.text() == '' \
                    or self.lineEdit_casco_id.text() == ''

        self.buttonBox_item.button(QDialogButtonBox.Save).setDisabled(ativo)

    def imprimir_pedido(self):

        if self.lineEdit_id.text() == '':
            logging.debug("[CadastroPedido] Nenhum pedido selecionado para impressão.")
            return

        if self.pedido.situacao == 'CANCELADO':
            logging.debug("[CadastroPedido] Não é possível imprimir um pedido cancelado.")
            return

        pedido = list()
        pedido_atual = self.pedido.to_dict(generic=True)
        pedido_itens = pedido_atual['itens']
        del pedido_atual['itens']
        pedido.append(pedido_atual)

        items_aux = list()

        for item in pedido_itens:
            aux = dict()
            for coluna, desc in self.colunas_item.items():
                if coluna != 'item_pedido_id' and coluna != 'codigo':
                    if coluna == 'valor_unitario' or coluna == 'valor_total':
                        aux[desc] = "{0:.2f}".format(
                            float(item[coluna])).replace('.', ',')
                    else:
                        aux[desc] = item[coluna]
                    if aux[desc] is None or aux[desc] == 'None':
                        aux[desc] = ''
            items_aux.append(aux)
        pedido_itens = items_aux

        cnpj_emitente = "12.141.655/0001-69"
        IE_emitente = "90524475-23"
        endereco_emitente = 'Rua Dr. Paula Xavier, 1486 - sala 01 - CEP 84010 - Centro - Ponta Grossa - PR'

        html_cabecalho = os.path.join('Resources', 'html', 'RelatorioPadrao', 'cabecalho.html')
        html_rodape = os.path.join('Resources', 'html', 'RelatorioPadrao', 'rodape.html')

        try:
            with open(html_cabecalho, 'r') as f:
                html_cabecalho = f.read()

            with open(html_rodape, 'r') as f:
                html_rodape = f.read()

        except Exception as e:
            logging.debug('[] Exception ao abrir html\n> ' + str(e))
            return

        self.busca_pessoa()
        endereco = self.pessoa.endereco[0]

        html_cabecalho = html_cabecalho.format(
            razao='COMÉRCIO DE EQUIPAMENTOS E SUPRIMENTOS DE INFORMÁTICA'
            , fantasia='JOCIANE F. DA SILVA - INFORMÁTICA'
            , fone='(42) 3224-0660'
            , tipo_pedido=pedido_atual['tipo_pedido']
            , num_pedido=pedido_atual['pedido_id']
            , nome_pessoa=self.pessoa.nome
            , endereco_pessoa=endereco.logradouro + (', ' + endereco.numero if endereco.numero is not None else '')
            , bairro_pessoa=endereco.bairro if endereco.bairro is not None else ''
            , municipio_pessoa=endereco.municipio if endereco.municipio is not None else ''
            , cep_pessoa=endereco.cep if endereco.cep is not None else ''
            , uf_pessoa=endereco.estado if endereco.estado is not None else ''
            , fone_pessoa=self.pessoa.telefone if self.pessoa.telefone is not None else ''
            , situacao=self.pedido.situacao.upper()
            , endereco_emitente=endereco_emitente
            , cnpj_emitente=cnpj_emitente
            , ie_emitente=IE_emitente
            , data_cadastro=self.dateEdit_entrega.date().toString("dd.MM.yyyy").replace('.', '/')
        )

        total = "{0:.2f}".format(
                float(self.lineEdit_valor_total_pedido.text().replace(',', '.')))

        html_rodape = html_rodape.format(
            cnpj_pagador=self.pessoa.get_documento()
            , ie_pagador=self.pessoa.inscricao_estadual
            , total=total
        )

        ficha_pedido = RelatorioPadrao(
            pedido_itens
            , cabecalho=html_cabecalho
            , rodape=html_rodape
            , file=False
            , landscape=False
            , page_size='A4'
            , stylesheet=os.path.join('Resources', 'styles', 'ficha_pedido.css')
            , sort_column='Tipo'
            , override_style=True
        )

        pdf = ficha_pedido.gerar_relatorio()
        ficha_pedido.exibir_relatorio(pdf)

    def translate_ui(self):
        super(CadastroPedido, self).translate_ui()
        self.buttonBox_item.button(QDialogButtonBox.Save).setText('Salvar')
        self.buttonBox_item.button(QDialogButtonBox.Reset).setText('Limpar')
Exemple #10
0
class AjusteEstoque(CadastroPadrao, Ui_AjusteEstoque):
    def __init__(self, db=None, window_list=None, parent=None, **kwargs):
        super(AjusteEstoque, self).__init__(parent=parent, **kwargs)
        self.setupUi(self)
        self.db = db
        self.window_list = window_list
        self.setWindowFlags(Qt.Dialog)

        self.buttonBox_confirmar.button(QDialogButtonBox.Ok).clicked.connect(
            self.confirmar_ajuste)
        self.buttonBox_confirmar.button(
            QDialogButtonBox.Cancel).clicked.connect(self.cancelar)

        self.buttonBox_confirmar.button(
            QDialogButtonBox.Ok).setText("Confirmar")
        self.buttonBox_confirmar.button(
            QDialogButtonBox.Cancel).setText("Cancelar")

        self.pushButton_historico.clicked.connect(self.abrir_historico)

        validador_regex_id = QRegExpValidator(QRegExp("[0-9]{1,9}"))
        self.lineEdit_mercadoria_id.setValidator(validador_regex_id)

        self.lineEdit_mercadoria_id.editingFinished.connect(
            self.busca_mercadoria)
        self.toolButton_mercadoria.clicked.connect(
            lambda: self.busca_mercadoria(force=True))

        self.dialog_localizar = LocalizarDialog(db=self.db, parent=self)

        self.lineEdit_mercadoria_id.setStyleSheet("\nborder: 0.5px solid red")

        find_icon = QIcon(os.path.join('Resources', 'icons', 'search.png'))
        self.toolButton_mercadoria.setIcon(find_icon)
        clock_icon = QIcon(os.path.join('Resources', 'icons', 'clock.png'))
        self.pushButton_historico.setIcon(clock_icon)

        self.spinBox_quantidade.setRange(1, 999)

        help=\
'''Aqui é possível realizar lançamentos de entrada/saída, de forma manual,
para operações que ocorrem sem um pedido.

ENTRADA: Serão adicionados itens sem vínculo com pedido de entrada.
SAÍDA: Apenas itens fechados podem ser retirados do estoque.'''

        self.adiciona_help(texto=help)

        self.show()

    def confirmar_ajuste(self):

        close = False

        if self.textEdit_motivo.text() != '' \
                and self.spinBox_quantidade.text() != '0' \
                and self.lineEdit_mercadoria_id.text() != '':

            dialog = ConfirmDialog(parent=self)
            dialog.definir_mensagem(
                'Tem certeza que deseja realizar esse ajuste?')

            if not dialog.exec():
                return

            oper = self.comboBox_operacao.currentText().replace('í', 'i')

            dados = {
                "metodo": "fnc_ajuste_estoque",
                "schema": "soad",
                "params": {
                    "mercadoria_id": str(self.lineEdit_mercadoria_id.text()),
                    "tipo": oper,
                    "quantidade": self.spinBox_quantidade.text(),
                    "motivo": self.textEdit_motivo.text()
                }
            }

            retorno = self.db.call_procedure(params=dados)
            status = 'ERRO'
            mensagem = ''

            if retorno[0]:
                status = retorno[1][0]['p_retorno_json']['status']

                if status:
                    status = 'OK'
                    mensagem = '[{oper}] Operação realizada com sucesso.'\
                        .format(oper=oper.upper())
                    close = True

                else:
                    status = 'ALERTA'
                    mensagem = '[{oper}] Não foi possível realizar a operação.'\
                        .format(oper=oper.upper())

        else:

            status = 'ALERTA'
            mensagem = 'Erro não tratado.'

            if self.lineEdit_mercadoria_id.text() == '':
                mensagem = 'É necessário informar uma mercadoria.'

            elif self.spinBox_quantidade.text() == '0':
                mensagem = "A quantidade não pode ser 0 (zero)."

            elif self.textEdit_motivo.text() == '':
                mensagem = "É necessário informar um motivo."

            retorno = mensagem

        dialog = StatusDialog(status=status,
                              mensagem=mensagem,
                              exception=retorno,
                              parent=self)

        dialog.exec()

        self.limpar_campos() if close else None

    def cancelar(self):
        self.close()

    def limpar_campos(self):
        self.lineEdit_mercadoria_id.clear()
        self.lineEdit_mercadoria.clear()
        self.textEdit_motivo.clear()
        self.spinBox_quantidade.setValue(self.spinBox_quantidade.minimum())

    def busca_mercadoria(self, force=False):
        mercadoria = None
        filtro_adicional = ''

        tipo = 'MERCADORIA'
        tabela = 'vw_mercadoria'
        campo = 'id_mercadoria'
        lineEdit_id = self.lineEdit_mercadoria_id
        lineEdit_descricao = self.lineEdit_mercadoria

        valor = lineEdit_id.text().replace(' ', '')

        if valor != '':

            mercadoria = self.db.busca_registro(
                tabela, campo, valor, '=',
                filtro=filtro_adicional)[1][0]['fnc_buscar_registro']

            logging.debug('[CadastroPedido] ' + str(mercadoria))
            if mercadoria is not None:
                mercadoria = mercadoria[0]
        else:
            lineEdit_descricao.clear()

        if mercadoria is None or force:

            localizar_campos = {
                campo: 'ID',
                "codigo": 'Código',
                "descricao": tipo.capitalize(),
                'marca': "Marca"
            }

            colunas_busca = {
                campo: 'ID',
                "codigo": 'Código',
                "descricao": tipo.capitalize(),
                'marca': "Marca"
            }

            self.dialog_localizar.define_tabela(tabela)
            self.dialog_localizar.define_campos(localizar_campos)
            self.dialog_localizar.define_colunas(colunas_busca)
            self.dialog_localizar.filtro = filtro_adicional

            self.dialog_localizar.define_valor_padrao(localizar_campos["descricao"], '') if force \
                else self.dialog_localizar.define_valor_padrao(localizar_campos[campo], lineEdit_id.text())

            mercadoria_id = self.dialog_localizar.exec()
            mercadoria = self.db.busca_registro(
                tabela, campo, str(mercadoria_id),
                '=')[1][0]['fnc_buscar_registro']

            if mercadoria_id == 0:
                return

            if mercadoria is not None:
                mercadoria = mercadoria[0]

        if mercadoria is not None:
            lineEdit_id.setText(str(mercadoria[campo]))
            lineEdit_descricao.setText(mercadoria['descricao'])
            return True

        else:
            lineEdit_id.clear()
            lineEdit_descricao.clear()
            return False

    def abrir_historico(self):

        lista = ListaPadrao(db=self.db,
                            window_list=self.window_list,
                            tipo='INVENTARIO',
                            parent=self)

        self.hide()

    def closeEvent(self, event):
        self.window_list.remove(self)
        event.accept()
    def busca_registro(self, tabela, campo, lineEdit_id, campo_descricao, lineEdit_descricao, colunas_dict):

        dialog_localizar = LocalizarDialog(db=self.db, parent=self)

        registro = None
        valor = lineEdit_id.text().replace(' ', '')

        if valor != '':

            registro = self.db.busca_registro(tabela, campo, valor, '=')[1][0]['fnc_buscar_registro']

            logging.debug('[FiltroEstoqueConsolidado] ' + str(registro))
            if registro is not None:
                registro = registro[0]
        else:
            lineEdit_descricao.clear()

        if registro is None and lineEdit_id.text() != '':

            localizar_campos = colunas_dict
            colunas_busca = colunas_dict

            dialog_localizar.define_tabela(tabela)
            dialog_localizar.define_campos(localizar_campos)
            dialog_localizar.define_colunas(colunas_busca)
            dialog_localizar.define_valor_padrao(localizar_campos[campo], lineEdit_id.text())

            valor = dialog_localizar.exec()
            registro = self.db.busca_registro(tabela, campo, str(valor), '=')[1][0]['fnc_buscar_registro']

            dialog_localizar.retorno_dados.connect(self.get_dados_localizar)
            #registro = self.dados[1][0]['fnc_buscar_registro']

            if registro is not None:
                registro = registro[0]

        if registro:
            lineEdit_id.setText(str(registro[campo]))
            lineEdit_descricao.setText(registro[campo_descricao])
            return True

        else:
            lineEdit_id.clear()
            lineEdit_descricao.clear()
            return False