JMamede.com
Soluções para os seus negócios
Soluções para os seus negócios
Email: jmamede@jmamede.com
Vamos criar a função de validação de NIPC/NIF na base de dados para posterior utilização nas nossas querys. Se a função retornar 0 (zero) é porque o contrinuinte está errado.
CREATE FUNCTION [dbo].[nipc_nif_control]
(@ncont nvarchar(25))
RETURNS bit
AS
BEGIN
DECLARE @checkdigit int,
@soma int,
@return bit
set @ncont=ltrim(rtrim(@ncont))
if left(@ncont, 1) not in ('1', '2', '5', '6', '7', '8', '9') or isnumeric(@ncont)=0
return cast(0 as bit)
set @soma= left(@ncont, 1)*9 +
substring(@ncont, 2, 1)*8+
substring(@ncont, 3, 1)*7+
substring(@ncont, 4, 1)*6+
substring(@ncont, 5, 1)*5+
substring(@ncont, 6, 1)*4+
substring(@ncont, 7, 1)*3+
substring(@ncont, 8, 1)*2
set @return=1
set @checkdigit=0
while @soma%11 <> 0
begin
set @checkdigit=@checkdigit+1
set @soma=@soma+1
end
if @checkdigit=10
set @checkdigit=0
if @checkdigit<>substring(@ncont, 9, 1)
set @return=0
RETURN @return
END
Agora vamos filtrar os clientes com NIPC/NIF que seja inválido (apenas clientes nacionais com contribuinte com 9 dígitos todos numéricos).
select ncont,* from cl where pais=1 and len(ncont)=9 and ISNUMERIC(ncont)=1 and dbo.nipc_nif_control(ncont)=0
Vamos supor que de repente tem 3000 ou 4000 que tem de gerar códigos EAN 13 ou EAN14. Para isso elaborei um pequeno script para de forma rápida gerar todos esses códigos.
-- Vamos popular o campo ST.CODIGO com os 12 dígitos para posterior cálculo do checkdigit
-- Para este preenchimento directo, vamos usar o campo identity do st para gerar o código de 12 dígitos
update st set codigo='5601234'+right('00000'+rtrim(ltrim(str(stid))), 5)
-- Agora que temos o campo ST.CODIGO com o EAN13 sem o checkdigit,
-- vamos atualizar o campo para colocar o checkdigit correto
update st set codigo= rtrim(ltrim(codigo)) +
rtrim(ltrim(right(10-right(
substring(codigo,len(codigo),1)*3
+substring(codigo,len(codigo)-1,1)*1
+substring(codigo,len(codigo)-2,1)*3
+substring(codigo,len(codigo)-3,1)*1
+substring(codigo,len(codigo)-4,1)*3
+substring(codigo,len(codigo)-5,1)*1
+substring(codigo,len(codigo)-6,1)*3
+substring(codigo,len(codigo)-7,1)*1
+substring(codigo,len(codigo)-8,1)*3
+substring(codigo,len(codigo)-9,1)*1
+substring(codigo,len(codigo)-10,1)*3
+substring(codigo,len(codigo)-11,1)*1
+substring(codigo,len(codigo)-12,1)*3
,1),1))) from st where len(codigo)=12
-- Como queremos paralelamente usar o EAN14, vamos colocar em BC (códigos de barras alternativos)
-- o EAN14, que é calculado com base no EAN13
insert into bc (bcstamp, ststamp, ref, design, codigo)
select left(newid(), 23), ststamp, ref, design, rtrim(ltrim(codigo)) +
rtrim(ltrim(right(10-right(
substring(codigo,len(codigo),1)*3
+substring(codigo,len(codigo)-1,1)*1
+substring(codigo,len(codigo)-2,1)*3
+substring(codigo,len(codigo)-3,1)*1
+substring(codigo,len(codigo)-4,1)*3
+substring(codigo,len(codigo)-5,1)*1
+substring(codigo,len(codigo)-6,1)*3
+substring(codigo,len(codigo)-7,1)*1
+substring(codigo,len(codigo)-8,1)*3
+substring(codigo,len(codigo)-9,1)*1
+substring(codigo,len(codigo)-10,1)*3
+substring(codigo,len(codigo)-11,1)*1
+substring(codigo,len(codigo)-12,1)*3
,1),1))) from st where len(codigo)=13
Já temos o ST.CODIGO om o EAN13 e na tabela BC o EAN14 correspondente, .... para todos os artigos.
Tem de ser pelo menos para uma data/hora superior à data/hora atual (pelo menos um minuto suprior à data/hora do sistema).
if sbo.adding=.t.
select bo2
if bo2.tiposaft <> '--'
if bo2.xpddata < date()
messagebox('A data de transporte é anterior à data atual!')
return .f.
endif
if bo2.xpddata = date() and bo2.xpdhora <= time()
messagebox('A hora de transporte é anterior ou igual à hora atual!'+chr(13)
+'Tem de ter no mínimo mais 1 minuto que a hora atual.')
return .f.
endif
else
return .t.
endif
endif
return .t.
Tem de ser pelo menos mais 10 minutos superior à data/hora atual.
if sft.adding=.t.
select ft
if ft.ndoc>0
if ft.cdata < date()
messagebox('A data de transporte é anterior à data atual!')
return .f.
endif
LM=right('0000'+alltrim(ft.chora), 2)
if val(LM)>59
messagebox('Hora de transporte inválido!')
return .f.
endif
LH=left(right('0000'+alltrim(ft.chora),4), 2)
if val(LH)>23
messagebox('Hora de transporte inválido!')
return .f.
endif
LHM=LH+LM
u_sqlexec([select replace(convert(char(5),dateadd(mi,10,getdate()), 114),':','') as sqltime],[sqltime])
select sqltime
LVCSQLTIME=sqltime.sqltime
if ft.cdata = date() and LHM <= LVCSQLTIME
messagebox('A hora de transporte é anterior ou igual à hora atual!'+chr(13)
+'Tem de ter no mínimo mais 10 minutos que a hora atual.')
return .f.
endif
else
return .t.
endif
endif
return .t.
Não sendo esta uma situação normal, nada nos impede que por alguma razão uma série de documentos não tenha falhas de sequencia numérica e cronológica num ou outro documento, especialmente se estamos a importar documentos de outras fontes.
Para validar essas falhas, sugiro uma tecla de utilizador associado ao ecran de faturação (bastando mudar o documento na combo box do form para ir fazendo a validação por tipo de documento), com o seguinte código:
lvndoc=y_ndoc
lvnano=getnome('Qual o ano dos documentos?',year(date()),year(date()))
u_sqlexec([select fno, fdata, cast(0 as bit) as marcada from ft where ndoc=]+str(lvndoc)
+[ and ftano=]+str(lvnano)+[ order by fno],[Listdatas])
select Listdatas
scan
if recno()=1
lvnnum=Listdatas.fno
lvdanterior=Listdatas.fdata
else
if Listdatas.fdata < lvdanterior
replace Listdatas.marcada with .t.
endif
lvdanterior = Listdatas.fdata
endif
endscan
select Listdatas
delete for Listdatas.marcada=.f.
select Listdatas
mostrameisto('Listdatas')
return .t.
Não sendo esta uma situação normal, nada nos impede que por alguma razão uma série de documentos não tenha falta um ou outro documento, especialmente se estamos a importar documentos de outras bases de dados.
Para validar essas falhas, sugiro uma tecla de utilizador associado ao ecran de faturação (bastando mudar o documento na combo box do form para ir fazendo a validação por tipo de documento), com o seguinte código:
create cursor numeros (numeros N (12,0))
lvndoc=y_ndoc
lvnano=getnome('Qual o ano dos documentos?',year(date()),year(date()))
u_sqlexec([select min(fno) as min, max(fno) as max from ft where ndoc=]+str(lvndoc)
+[ and ftano=]+str(lvnano),[NumeradoresFT])
select NumeradoresFT
lvnmin=NumeradoresFT.min
lvnmax=NumeradoresFT.max
do while lvnmin < lvnmax
wait window ('Verificar registo » '+alltrim(str(lvnmin))+' de um total de '+alltrim(str(lvnmax))) nowait
u_sqlexec([select count(*) as conta from ft where ndoc=]+str(lvndoc)+[ and fno=]+str(lvnmin)
+[ and ftano=]+str(lvnano),[Contagem])
select contagem
if contagem.conta=0
select numeros
append blank
replace numeros.numeros with lvnmin
endif
lvnmin=lvnmin+1
enddo
select numeros
mostrameisto("numeros")
fecha("numeros")
select CL if cl.pais=1 For x=1 To 8 Step 1 if x=5 if substr(cl.codpost, 5, 1)<>'-' return .f. endif else if not inlist(substr(cl.codpost, x, 1), '0', '1','2','3','4','5','6','7','8','9') return .f. endif endif Next endif return .t.É um programa
select FT if FT.pais=1 For x=1 To 8 Step 1 if x=5 if substr(ft.codpost, 5, 1)<>'-' return .f. endif else if not inlist(substr(ft.codpost, x, 1), '0', '1','2','3','4','5','6','7','8','9') return .f. endif endif Next endif return .t.É um programa
select codpost, no, nome, morada, local, pncont, * from cl where (SUBSTRING(codpost, 5, 1)<>'-' or SUBSTRING(codpost, 1, 1) not between '0' and '9' or SUBSTRING(codpost, 2, 1) not between '0' and '9' or SUBSTRING(codpost, 3, 1) not between '0' and '9' or SUBSTRING(codpost, 4, 1) not between '0' and '9' or SUBSTRING(codpost, 6, 1) not between '0' and '9' or SUBSTRING(codpost, 7, 1) not between '0' and '9' or SUBSTRING(codpost, 8, 1) not between '0' and '9') and pais=1
update cl set codpost=replace(codpost, ' ', ' ')
update cl set codpost=replace(codpost, ' - ', '-') update cl set codpost=replace(codpost, '--', '-') update cl set codpost=replace(codpost, ' -', '-')
select codpost, * from cl where SUBSTRING(codpost, 6, 1)='-' and pais=1
update cl set codpost=left(codpost, 4)+'-'+ltrim(substring(codpost, 7, 40)) where SUBSTRING(codpost, 6, 1)='-' and pais=1
select codpost, substring (codpost, 6, 1), * from cl where SUBSTRING(codpost, 5, 1)=' ' and pais=1 and left(codpost, 4) between '0000' and '9999' and substring (codpost, 6, 1)>'9'
update cl set codpost=left(codpost, 4)+'-'+'001'+substring(codpost, 5, 39) where SUBSTRING(codpost, 5, 1)=' ' and pais=1 and left(codpost, 4) between '0000' and '9999' and substring (codpost, 6, 1)>'9'
select codpost, * from cl where SUBSTRING(codpost, 5, 1)=' ' and pais=1 and left(codpost, 4) between '0000' and '9999' and substring (codpost, 6, 3) between '000' and '999'
update cl set codpost=left(codpost, 4)+'-'+substring(codpost, 6, 39) where SUBSTRING(codpost, 5, 1)=' ' and pais=1 and left(codpost, 4) between '0000' and '9999' and substring (codpost, 6, 3) between '000' and '999'
update cl set codpost='0000-000 '+rtrim(ltrim(codpost)) where (codpost='' or left(codpost, 1) not in ('0','1','2','3','4','5','6','7','8','9')) and pais=1
update cl set local=ltrim(substring(codpost,9,50)) where clstamp in ( select clstamp from cl where pais=1 and local='' and left(codpost, 4) between '0000' and '9999' and substring(codpost, 6,3) between '000' and '999')
insert into szadrs (szadrsstamp, szadrsdesc, morada, local, codpost, codpais, pais, no, estab, origem, nome) select left(newid(), 23), left(nome+' '+ltrim(rtrim(str(no))), 60), morada, local, codpost, 'PT', 'Portugal', no, estab, 'CL', nome from cl where pais=1 and estab=0 and no not in (select no from szadrs where origem='CL')
update fl set local=ltrim(substring(codpost,9,50)) where flstamp in ( select flstamp from fl where pais=1 and local='' and left(codpost, 4) between '0000' and '9999' and substring(codpost, 6,3) between '000' and '999')
insert into szadrs (szadrsstamp, szadrsdesc, morada, local, codpost, codpais, pais, no, estab, origem, nome) select left(newid(), 23), left(rtrim(ltrim(nome))+'_F_'+ltrim(rtrim(str(no))), 60), morada, local, codpost, 'PT', 'Portugal', no, estab, 'FL', nome from fl where pais=1 and estab=0 and no not in (select no from szadrs where origem='FL')
Façam download do ficheiro
Para garantirem uma série de backups, recomendo que por cada dia da semana criem um ficheiro BAT diferente, com o neme da cópia de segurança diferente.
Assim terão 1 backup por dia da semana, noo caso de ser detetado alguma anomalia na base de dados, poderão reverter até 1 semana para trás.
O código que consta do ficheiro é o seguinte:
@ECHO OFF
REM **** OSQL PARA SQL INFERIOR A SQL2005 ********
REM osql -E -S servidor\sqlexpress -d maisritmo -Q "BACKUP DATABASE [maisritmo] TO DISK = N'c:\backupphc\maisritmo_impar.bak' WITH INIT , NOUNLOAD , NAME = N'maisritmo backup', NOSKIP , STATS = 10, NOFORMAT "
REM osql -E -S servidor\sqlexpress -d maisritmo -Q "update para1 set valor=convert(char(10), getdate(), 104) where descricao='ge_dt_Bkp'"
REM **** USAR SQLCMD PARA SQL2005 OU POSTERIOR ****
sqlcmd -E -S servidor\SQLEXPRESS -d BDPHC -Q "BACKUP DATABASE [maisritmo] TO DISK = N'c:\backupphc\maisritmo_impar.bak' WITH INIT , NOUNLOAD , NAME = N'maisritmo backup', NOSKIP , STATS = 10, NOFORMAT "
sqlcmd -E -S servidor\SQLEXPRESS -d BDPHC -Q "update para1 set valor=convert(char(10), getdate(), 104) where descricao='ge_dt_Bkp'"
REM **** CASO TENHAM O 7ZIP, PODEM COMPACTAR E FAZER CÓPIA DO BACKUP PARA UNIDADE EXTERNA
REM 7z a -tzip c:\backupphc\maisritmo_impar.zip c:\backupphc\maisritmo_impar.bak
REM DEL "c:\backupphc\maisritmo_impar.bak"
REM COPY "c:\backupphc\maisritmo_impar.zip" "E:\backupphc\maisritmo_impar.zip"
Dados a alterar:
Nome do SERVIDOR: servidor\sqlexpress
Nome da Base dados: maisritmo
e respetivas diretorias de ficheiross