-
Posts
6,413 -
Joined
Everything posted by nunopicado
-
Utilizar Webservices da AT
nunopicado replied to cjulio's topic in Software de Contabilidade, Finanças e Admin. Pública
😂😂 -
Utilizar Webservices da AT
nunopicado replied to cjulio's topic in Software de Contabilidade, Finanças e Admin. Pública
Mas o ficheiro em questão é a Chave Publica AT? No portal o ficheiro da chave publica ainda é o mesmo que está desde o ano passado, pelo que, ou se esqueceram de atualizar o link no portal, ou isto não tem nada a ver com a chave publica. Mal por mal, preferia que não tivesse nada a ver, porque se for mesmo a chave publica, vamos ter fandango esta semana. Mas se for, onde raio pára o ficheiro novo? -
O Pascal dispõe de 4 comandos para controlo de fluxo não ortodoxo, Break, Continue, Exit e Halt. O Break sai de um ciclo, o Continue passa para a próxima iteração de um ciclo, o Exit sai da função atual e o Halt sai do programa. Mas a sua disponibilidade depende de qual compilador estás a usar. De qualquer forma, não recomendo que uses nenhum deles na fase atual em que te encontras, a julgar pelo código que mostraste. Qualquer delas é um pesadelo para debug, e é preciso ter alguma prática para não seres enganado pela sua presença, em caso de ocorrer algum erro que estejas à procura da causa. Este tipo de programa (menu + seleção de opções) é um exercício muito usado no início exatamente porque te força a detetar os problemas que uma programação básica te trás neste cenário. Todos os problemas que te possam ocorrer para este tipo de programa resolves facilmente com recurso a ciclos e funções: Os ciclos para controlar o fluxo do programa de uma forma mais ortodoxa, e as funções para que possas criar um código 'menos pastoso', em que possas reutilizar código comum sem recurso ao copy/paste (regra de outro da boa programação: pensa 20 vezes antes de fazeres copy/paste de um código. Se estás a fazer copy/paste, há uma boa chance de estares a fazer algo mal). Pensa no menu como se fosse um mordomo, a perguntar-te o que queres. Ele diz-te as opções e pergunta o que queres. Tu respondes. Mediante a tua resposta, ele vai perguntar oura coisa qualquer, num ciclo que só termina quando a tua opção escolhida for 'sair'. Assim, se todas as perguntas forem feitas dentro de um loop (o REPEAT...UNTIL é muito bom para isto) e a cada resposta ele chama a função adequada, eventualmente até usando um outro loop para obrigar a que a resposta seja uma das possíveis, o menu funcionará corretamente.
-
O que respondeu o @iznougudpt está corretíssimo. É esse o problema deste código específico. No entanto quero ir um pouco mais a fundo no caso, pois parece-me que há aí um problema de raciocínio que deve ser corrigido. O que estás a fazer, e que causou o problema descrito, é a usar a mesma variável que serve para ler a opção, para acumular o preço. E pior, estás a somar o preço à opção, o que claro, vai dar um preço errado. Obviamente estás a começar, e este tipo de problema todos por lá passámos. Mas é mesmo por isso que é importante corrigir já, antes que se instituam maus hábitos. Os computadores atuais têm muitos recursos. A sério, mesmo muitos. No contexto de um programa deste tipo, os recursos de um computador atual são virtualmente infinitos. E antigamente, quando os computadores eram infinitamente mais limitados, já aí a regra era não reaproveitar variáveis. Isto é importante, pelo que vou repetir: Nunca deves reaproveitar uma variável. Quando crias uma variável, ela deve ter um, e um só objetivo. Se é para a opção do menu, é para a opção do menu. Se é para o preço, é para o preço. Não interessa para que é, mas a partir do momento que é para uma coisa, é só para essa coisa. Cria quantas variáveis a tua imaginação ditar, o computador aguenta. Neste caso concreto, se a variável sobremesa_1 fosse usada apenas para ler a opção, nunca terias problemas, independentemente de usar um else ou não. Cria uma nova variável para o preço a pagar, inicializa-a a 0, e dentro do IF, somas o preço do arroz doce (ou do que for) a essa variável, e não à Sobremesa_1. Tens o problema resolvido. --------------------- Bónus: Corrigindo a situação das variáveis, o teu código vai funcionar, mas não é um código optimizado. Como eu dizia, os computadores têm recursos quasi-infinitos, mas o nosso código deve sempre procurar ser o mais optimizado possível. Em vez de IFs, substitui por um CASE ... OF. Ficaria algo como isto: ... case Sobremesa_1 of 1: Begin Total := Total + Arroz_Doce; WriteLn; WriteLn('Iremos trazer agora o seu arroz doce então.'); End; 2: Begin Total := Total + Leite_Creme; WriteLn; WriteLn('Iremos trazer agora o seu leite creme então.'); End; 3: Begin Total := Total + Bolo_Bolacha; WriteLn; WriteLn('Iremos trazer agora o seu bolo de bolacha então.'); End; 4: Begin Total := Total + Doce_Casa; WriteLn; WriteLn('Iremos trazer agora o doce da casa então.'); End; 5: Begin Total := Total + Cafe; WriteLn; WriteLn('Iremos trazer agora o seu café então.'); End; 6: Begin Total := Total + Gelado; WriteLn; WriteLn('Iremos trazer agora o seu gelado então.'); End; else begin WriteLn; WriteLn('Opção inválida.'); end; end; Neste código, além de esteticamente mais apelativo e organizado, o compilador não precisa percorrer todas as opções, avaliando a cada uma se a opção é correta ou não. Entra no case, vai à opção cerca, e faz o que tem a fazer. E ainda ficas com a possibilidade de alertar o utilizador caso a opção escolhida não seja nenhuma das propostas, algo que de contrário precisarias de IFs encadeados para fazer, o que deixaria o código ainda mais frágil.
-
Isso acontece porque quando estás a ler uma variável do tipo char, a consola não diz ao comando quando terminou o input. Quando lês um integer, ao dares enter depois de indicares o valor ele saber que o enter, que é um caracter #13, não pode ser um integer, e portanto, sabe que terminou a inserção. No char não é assim, porque #13 é também ele um char. Felizmente é fácil resolveres isso. Deixa de usar o read, passa a usar o readln. Assim ele saberá quando ler o #13 que é uma mudança de linha, que é o fim de valor que o readln está à espera. o read é um comando mais indicado para leitura de outras fontes, que não a consola (teclado). Em alternativa, caso o compilador que estás a usar suporte este comando, podes substituir o read por um readkey. O readkey permite ler um único caracter, o que significa que ele irá retornar o resultado ao sistema assim que uma (qualquer) tecla for pressionada. É mais adequado para usar num menu como o que tens aí, pois significa que o utilizador não precisa indicar a letra e depois pressionar no enter. Assim que marca a letra, a opção é lida e aceite. Ficaria algo tipo: ... WriteLn; WriteLn('(G) Pastéis de Bacalhau- 3.50$'); WriteLn; WriteLn; Write('Vai desejar alguma entrada? (Y/y,N/n) '); Entrada := ReadKey; Nem todos os compiladores de pascal suportam isto (apenas os bons), por isso convém testar se ele reconhece o comando.
-
AT - questões legais
nunopicado replied to marcolopes's topic in Software de Contabilidade, Finanças e Admin. Pública
Os pedidos à cozinha não têm de ser comunicados, e se formos ver bem as coisas, nem sequer faturados. A fatura é devida apenas quando o pedido é entregue a um cliente. 🤔 -
AT - questões legais
nunopicado replied to marcolopes's topic in Software de Contabilidade, Finanças e Admin. Pública
Creio que não será bem assim. Há um motivo para o contabilista dizer que é ilegal, penso eu. Esse talão é basicamente uma "consulta de mesa". As consultas de mesa devem ser faturadas e mencionadas na fatura. Ora, se fizeres consultas de mesa e depois não as faturares, estás a cometer uma ilegalidade. Claro, com ou sem consultas de mesa, é obrigatório faturar, pelo que tudo isto acaba por ser pouco relevante: Perdido por 100, perdido por 1000. -
Access Violation inesperado aquando do uso de Interfaces
nunopicado replied to thoga31's topic in Delphi/Lazarus
Já percebi. Estás a usar um interface, mas não estás a colocar nele todos os métodos que vais usar. Mas sendo assim, o interface está incorreto. É a mesma coisa que teres uma ficha LAN com PoE e alterares para transportar 220V no mesmo cabo. Vais acabar por fritar alguma coisa. Uma mesma classe pode implementar vários interfaces, se quiseres, mas tens de ver depois como chamas cada um para teres acesso às funções corretas.- 14 replies
-
- delphi
- object pascal
-
(and 1 more)
Tagged with:
-
Access Violation inesperado aquando do uso de Interfaces
nunopicado replied to thoga31's topic in Delphi/Lazarus
Isso. Não tinha reparado (já te disse que estou a dormir hoje). Para que foi o typecast? Se _FG e _BG já são IIAnsiCode, é uso direto. Nem que não fosse, really. Usares o nome da classe em vez do interface põe por terra todo o uso de interfaces, e com isso, obriga-te a libertar a memória dessa chamada, pois deixa de ser ref counted nessa instancia.- 14 replies
-
- delphi
- object pascal
-
(and 1 more)
Tagged with:
-
Access Violation inesperado aquando do uso de Interfaces
nunopicado replied to thoga31's topic in Delphi/Lazarus
Hmmm. Isto geralmente acontece quando alguma variável está definida como TAnsiCode em vez de IAnsiCode. Alguma assim?- 14 replies
-
- delphi
- object pascal
-
(and 1 more)
Tagged with:
-
Access Violation inesperado aquando do uso de Interfaces
nunopicado replied to thoga31's topic in Delphi/Lazarus
Para o teu problema concreto, tenta criar uma lista, e libertar a lista numa secção finalization. Crias também um enumerator, em vez daquelas variáveis RESET, BOLD, etc., cujos valores serão os do index do objeto na lista. Depois, o array dinâmico não será do objeto, mas sim do enumerator. Ao chamar, usas o valor do enumerator para aceder à lista e usar o objeto. Creio que isso resolve, mas só tentando.- 14 replies
-
- delphi
- object pascal
-
(and 1 more)
Tagged with:
-
Access Violation inesperado aquando do uso de Interfaces
nunopicado replied to thoga31's topic in Delphi/Lazarus
Faz uma experiência. Em todas as classes que implementem um interface, cria algo como isto: TAnsiCode = class(TInterfacedObject, IAnsiCode) private vCode : byte; vString : string; function WithCode(const code : byte) : IAnsiCode; public constructor Create(const code : byte); class function New(const code : byte): IAnsiCode; function AsString : string; function AsByte : byte; end; // implementation class function TAnsiCode.New(const code : byte): IAnsiCode; begin Result := Create(code); end; E depois, ao construíres o objeto, em vez do create usas o new. Isto obriga a criar uma variável que força o interface quando usado de forma implícita. Não creio, sinceramente, que seja esta a solução neste caso concreto, mas não custa tentar, além de que te resolve uma série de outros problemas ao usar interfaces.- 14 replies
-
- 1
-
- delphi
- object pascal
-
(and 1 more)
Tagged with:
-
Access Violation inesperado aquando do uso de Interfaces
nunopicado replied to thoga31's topic in Delphi/Lazarus
Qual a declaração de RESET, BOLD, FAINT, etc? Faz um teste: Colocar este código logo a seguir ao main BEGIN: {$IFDEF DEBUG} ReportMemoryLeaksOnShutdown := True; {$ENDIF} Ao sair do programa, se houver leaks, ele vai-te avisar.- 14 replies
-
- delphi
- object pascal
-
(and 1 more)
Tagged with:
-
Access Violation inesperado aquando do uso de Interfaces
nunopicado replied to thoga31's topic in Delphi/Lazarus
hmmm Todos, todos? Mesmo os que não usaste na primeira?- 14 replies
-
- delphi
- object pascal
-
(and 1 more)
Tagged with:
-
Access Violation inesperado aquando do uso de Interfaces
nunopicado replied to thoga31's topic in Delphi/Lazarus
Bem, deixa lá ver se consigo juntar os únicos 2 neurónios que não tiraram férias para conseguir construir uma resposta mais ou menos inteligível. 😁 Uma AV é basicamente o compilador a dizer-te que algo ou não foi construído ou já foi libertado. Algo não existe. Até aí, já tinhas notado. O que me parece que está a acontecer aí é que o uso de interfaces (recomendo sempre) funciona por reference count. Ou seja, quando atribuis uma implementação de um interface a uma variável, o ref count faz +1. Quando libertas, faz -1. Quando o ref count for 0, automaticamente o objeto é libertado e bye bye Maria Ivone. Quando crias o objeto na initialization, estás a fazer +1. Quando o passas para dentro de Ansify e depois para Codify, tu imaginas que o compilador faça +1 por cada uma das funções. Mas, e atenção que estou a falar de cor, isso não acontece. Ao usares um array dinâmicos, estás implicitamente a passar a referência da posição de memória onde está o 'code'. Ou seja, o ref count continua, penso eu de que, em 1. Quando termina a função e o array dinâmico é libertado, o endereço de memória que ele tem para libertar é o do objeto original. Ou seja, ao libertar o array, estás na prática a libertar os objetos nele contidos. Arrays dinâmicos são dinossauros de outra época. Volta e meia dão jeito, atenção. Mas num mundo de interfaces, arrays dinâmicos são... não ideais. É preciso cuidado ao fazer esta mistura. Agora, não sei é se tens, em FPC, alguma alternativa a isto. Podes tentar pesquisar por Collections, um termo genérico para este tipo de recurso. Sei que há uma TList, mas não sei ao certo como se comporta neste caso concreto. Testa a TList para ver se serve o propósito, e tem em atenção pode favor que hoje estou todo frito, pelo que posso ter dado alguma calinada na resposta. 😂- 14 replies
-
- 1
-
- delphi
- object pascal
-
(and 1 more)
Tagged with:
-
Utilizar Webservices da AT
nunopicado replied to cjulio's topic in Software de Contabilidade, Finanças e Admin. Pública
Não sei se vais conseguir. A DLL usa interfaces, tanto quanto sei VB6 não suporta isso. -
O inspetor da AT, quando certifiquei o programa, sugeriu-me a solução para esse problema: Trabalha os cálculos sempre com pelo menos 4 a 6 casa decimais. Reduzes a duas casas decimais somente depois de todas as contas feitas, ao apresentar o valor. Nunca mais tive problema.
-
Utilizar Webservices da AT
nunopicado replied to cjulio's topic in Software de Contabilidade, Finanças e Admin. Pública
O processo passa, em linhas muito gerais, por criar o XML na estrutura indicada pela AT. Alguns dos campos do cabeçalho têm de ser assinados com a chave pública. Depois é enviado o XML para a AT, usando o certificado como base de autenticação. Por fim recebes a resposta. Ou seja, indo por partes, o XML: Tens a certeza que está de acordo com a estrutura XSD disponibilizada? Como é que estás a criar o XSD, string a string ou com base no XSD? -
AT - questões legais
nunopicado replied to marcolopes's topic in Software de Contabilidade, Finanças e Admin. Pública
Sim, mas nesse caso é preferível o teu método: Um 'recibo provisório' para descansar o cliente, e depois o recibo oficial faz já com a certeza que está pago. Ou então, lá está, anular o recibo caso o cliente não pague. -
AT - questões legais
nunopicado replied to marcolopes's topic in Software de Contabilidade, Finanças e Admin. Pública
Como disse o @karlynhuz, se o recibo foi emitido pressupõe-se o pagamento da fatura. Se acaso tal não se verificar, significa que o recibo foi, tecnicamente, mal emitido, ou seja, deve ser anulado, e com isso, marcadas como não cobradas as faturas a que se refere o recibo. No fim volta a comunicar o recibo, agora com o PaymentStatus = "A". É essa a estrutura disponibilizada pela AT, que prevê a comunicação de alteração de estado num recibo. Um documento de "não pagamento" como falaste em cima, do ponto de vista da AT, é uma mera folha de couve. Não tem qualquer valor legal. Nada te impede de criar um documento assim, se achares que deves para teu controlo interno, mas isso não te isenta de cumprir os pressupostos da AT, que no caso, passa pela anulação do recibo. -
AT - questões legais
nunopicado replied to marcolopes's topic in Software de Contabilidade, Finanças e Admin. Pública
O PaymentStatus = "A" é para recibos anulados. No teu caso, estás a emitir outro documento, não a anular o recibo, pelo que não deve ser usada essa forma. No fundo estarias a comunicar um dado errado à AT. -
AT - questões legais
nunopicado replied to marcolopes's topic in Software de Contabilidade, Finanças e Admin. Pública
Ou - e isto é uma ideia completamente fora da caixa - que tal quem tem dados num software exportar o SAFT antes de terminar o contrato se não estiver a pensar em renovar? -
Utilizar Webservices da AT
nunopicado replied to cjulio's topic in Software de Contabilidade, Finanças e Admin. Pública
Está resolvida a questão. Estava a comunicar para o servidor de testes, mas a DB é um backup da DB de produção, pelo que o código de validação da série que estava a gerar era da série comunicada em produção, que é diferente do código da mesma série comunicada em testes. -
Utilizar Webservices da AT
nunopicado replied to cjulio's topic in Software de Contabilidade, Finanças e Admin. Pública
Isso é um sim ou um não? 🤣 -
Utilizar Webservices da AT
nunopicado replied to cjulio's topic in Software de Contabilidade, Finanças e Admin. Pública
Mas registaste a série no endpoint de testes?