Compare commits
8 Commits
da0fb555d7
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| de23611b4d | |||
| 36b116c00d | |||
| 8c4a14deb1 | |||
| 8857e8fedf | |||
| ce9ec394df | |||
| 5249670062 | |||
| da19090ed9 | |||
| 349130c369 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -92,6 +92,7 @@ Teste/uisync/
|
||||
Teste/screenshots/
|
||||
Teste/_erori_test.txt
|
||||
Teste/*_log.txt
|
||||
Teste/raport_*.csv
|
||||
|
||||
# --- Cache text extern (inlocuit de fluxul in-arbore .??2) ---
|
||||
_textcache/
|
||||
@@ -102,3 +103,4 @@ _textcache/
|
||||
docs/diff_*.patch
|
||||
docs/local/
|
||||
.gstack/
|
||||
flora2roa.zip
|
||||
|
||||
12
ALTE/check_cf_litere.ps1
Normal file
12
ALTE/check_cf_litere.ps1
Normal file
@@ -0,0 +1,12 @@
|
||||
# Ce coduri fiscale NENUMERICE apar in XML-urile Fidelio (posibili parteneri straini)
|
||||
param([string]$Dir = "D:\PROIECTE\FLORA\FLORA2ROA\EXEMPLE\hotel")
|
||||
$map = @{}
|
||||
Get-ChildItem -Path $Dir -Filter 'bts_detalii_facturi_rep_*.xml' | ForEach-Object {
|
||||
$t = Get-Content $_.FullName -Raw
|
||||
foreach ($m in [regex]::Matches($t, '(?i)<CODFISCAL_CNP>([^<]*)</CODFISCAL_CNP>')) {
|
||||
$v = $m.Groups[1].Value.Trim()
|
||||
if ($v -ne '' -and $v -match '[A-Za-z]') { $map[$v] = 1 }
|
||||
}
|
||||
}
|
||||
"coduri cu litere = $($map.Count)"
|
||||
$map.Keys | Sort-Object
|
||||
50
ALTE/check_cnp.ps1
Normal file
50
ALTE/check_cnp.ps1
Normal file
@@ -0,0 +1,50 @@
|
||||
# Simulare a regulii GetCodFiscalValid pe TOATE codurile din XML-urile Fidelio.
|
||||
# Raporteaza cate coduri se pastreaza, cate se sterg si cate sunt straine (nevalidate).
|
||||
param([string]$Dir = "D:\PROIECTE\FLORA\FLORA2ROA\EXEMPLE\hotel")
|
||||
|
||||
function Test-CNP([string]$c) {
|
||||
if ($c -notmatch '^\d{13}$') { return $false }
|
||||
$w = @(2,7,9,1,4,6,3,5,8,2,7,9); $s = 0
|
||||
for ($i = 0; $i -lt 12; $i++) { $s += [int]::Parse($c[$i]) * $w[$i] }
|
||||
$r = $s % 11; if ($r -eq 10) { $r = 1 }
|
||||
return ($r -eq [int]::Parse($c[12]))
|
||||
}
|
||||
function Test-CUI([string]$c) {
|
||||
if ($c -notmatch '^\d{2,10}$') { return $false }
|
||||
$c = $c.PadLeft(10, '0'); $k = '7532175321'; $s = 0
|
||||
for ($i = 0; $i -lt 9; $i++) { $s += [int]::Parse($c[$i]) * [int]::Parse($k[$i]) }
|
||||
$r = ($s * 10) % 11; if ($r -eq 10) { $r = 0 }
|
||||
return ($r -eq [int]::Parse($c[9]))
|
||||
}
|
||||
|
||||
$map = @{}
|
||||
Get-ChildItem -Path $Dir -Filter 'bts_detalii_facturi_rep_*.xml' | ForEach-Object {
|
||||
$t = Get-Content $_.FullName -Raw
|
||||
foreach ($m in [regex]::Matches($t, '(?i)<CODFISCAL_CNP>([^<]*)</CODFISCAL_CNP>')) {
|
||||
$v = $m.Groups[1].Value.Trim().ToUpper()
|
||||
if ($v -ne '') { $map[$v] = 1 }
|
||||
}
|
||||
}
|
||||
|
||||
$pastratCNP = 0; $pastratCUI = 0; $strain = 0; $sters = 0
|
||||
$listaStersi = @()
|
||||
foreach ($cod in $map.Keys) {
|
||||
$prefix = ($cod -replace '[^A-Z]', '')
|
||||
$roPrefix = @('RO', 'CUI', 'CF', 'CIF') -contains $prefix
|
||||
$romanesc = ($prefix -eq '' -or $roPrefix)
|
||||
if (-not $romanesc) { $strain++; continue }
|
||||
$cifre = ($cod -replace '[^\d]', '')
|
||||
if ($cifre.Length -eq 13 -and -not $roPrefix) {
|
||||
if (Test-CNP $cifre) { $pastratCNP++ } else { $sters++; $listaStersi += $cod }
|
||||
} elseif ($cifre.Length -ge 2 -and $cifre.Length -le 10) {
|
||||
if (Test-CUI $cifre) { $pastratCUI++ } else { $sters++; $listaStersi += $cod }
|
||||
} else { $sters++; $listaStersi += $cod }
|
||||
}
|
||||
|
||||
"total coduri distincte : $($map.Count)"
|
||||
"CNP valide pastrate : $pastratCNP"
|
||||
"CUI valide pastrate : $pastratCUI"
|
||||
"straine (nevalidate) : $strain"
|
||||
"STERSE (invalide) : $sters"
|
||||
'--- primele 30 sterse ---'
|
||||
$listaStersi | Select-Object -First 30
|
||||
91
ALTE/check_semnale_pj.ps1
Normal file
91
ALTE/check_semnale_pj.ps1
Normal file
@@ -0,0 +1,91 @@
|
||||
# Cat de bine putem distinge persoana fizica (PF) de persoana juridica (PJ) in Fidelio,
|
||||
# FARA sa ne bazam pe validitatea codului fiscal.
|
||||
param([string]$Dir = "D:\PROIECTE\FLORA\FLORA2ROA\EXEMPLE\hotel")
|
||||
|
||||
function Test-CNP([string]$c) {
|
||||
if ($c -notmatch '^\d{13}$') { return $false }
|
||||
$w = @(2,7,9,1,4,6,3,5,8,2,7,9); $s = 0
|
||||
for ($i = 0; $i -lt 12; $i++) { $s += [int]::Parse($c[$i]) * $w[$i] }
|
||||
$r = $s % 11; if ($r -eq 10) { $r = 1 }
|
||||
return ($r -eq [int]::Parse($c[12]))
|
||||
}
|
||||
function Test-CUI([string]$c) {
|
||||
if ($c -notmatch '^\d{2,10}$') { return $false }
|
||||
$c = $c.PadLeft(10, '0'); $k = '7532175321'; $s = 0
|
||||
for ($i = 0; $i -lt 9; $i++) { $s += [int]::Parse($c[$i]) * [int]::Parse($k[$i]) }
|
||||
$r = ($s * 10) % 11; if ($r -eq 10) { $r = 0 }
|
||||
return ($r -eq [int]::Parse($c[9]))
|
||||
}
|
||||
|
||||
# indicii de denumire pentru persoana juridica
|
||||
$cuvintePJ = @('SRL','S.R.L','SA','S.A','SC','S.C','PFA','P.F.A','SNC','SCS','SRL-D','II','I.I',
|
||||
'ASOCIATIA','ASOCIATIE','FUNDATIA','SOCIETATE','COMPANY','LTD','LIMITED','GMBH','GMBH.',
|
||||
'BV','NV','INC','CORP','GROUP','HOLDING','UNIVERSITE','UNIVERSITATEA','UNIVERSITY',
|
||||
'SPITAL','PRIMARIA','MINISTERUL','AGENTIA','INSTITUTUL','SCOALA','LICEUL','COLEGIUL',
|
||||
'CLUB','ACS','A.C.S','CAR','CFR','TRANS','TOURS','TRAVEL','IMOB','CONSTRUCT','CONSULT',
|
||||
'SOLUTIONS','TECHTRONIC','WORKSHOP','STUDIO','CONCEPT','SERV','COMERCIAL','PROFESSIONAL')
|
||||
|
||||
function Get-TipDupaNume([string]$nume) {
|
||||
$cuv = $nume -split '[^A-Z0-9\.]+' | Where-Object { $_ -ne '' }
|
||||
foreach ($c in $cuv) { if ($cuvintePJ -contains $c) { return 'PJ' } }
|
||||
return ''
|
||||
}
|
||||
function Get-TipDupaReg([string]$reg) {
|
||||
if ($reg -eq '') { return '' }
|
||||
if ($reg -match '^[JFC]\s?\d{1,2}\s?/\s?\d+\s?/\s?\d{4}') { return 'PJ' } # J40/1234/2018
|
||||
if ($reg -match '^[JL]\d{6,}') { return 'PJ' } # L2019000159348
|
||||
if ($reg -match '^\d{1,2}/\d{4}$') { return 'PJ' } # 54/1997
|
||||
if ($reg -match '^[A-Z]{2}\s?\d{6}$') { return 'PF' } # serie CI: ZV 093375
|
||||
return ''
|
||||
}
|
||||
|
||||
$rows = @{}
|
||||
Get-ChildItem -Path $Dir -Filter 'bts_detalii_facturi_rep_*.xml' | ForEach-Object {
|
||||
$t = Get-Content $_.FullName -Raw
|
||||
foreach ($m in [regex]::Matches($t, '(?is)<CUMPARATOR>([^<]*)</CUMPARATOR>.*?<CODFISCAL_CNP>([^<]*)</CODFISCAL_CNP>\s*<REGCOMERT_CI_PASS>([^<]*)</REGCOMERT_CI_PASS>')) {
|
||||
$nume = $m.Groups[1].Value.Trim().ToUpper()
|
||||
$cod = $m.Groups[2].Value.Trim().ToUpper()
|
||||
$reg = $m.Groups[3].Value.Trim().ToUpper()
|
||||
if ($cod -ne '') { $rows["$nume|$cod|$reg"] = [pscustomobject]@{ Nume=$nume; Cod=$cod; Reg=$reg } }
|
||||
}
|
||||
}
|
||||
|
||||
$rez = foreach ($r in $rows.Values) {
|
||||
$d = $r.Cod -replace '[^\d]', ''
|
||||
$roPrefix = ($r.Cod -replace '[^A-Z]', '') -in @('RO','CUI','CF','CIF')
|
||||
$tipNume = Get-TipDupaNume $r.Nume
|
||||
$tipReg = Get-TipDupaReg $r.Reg
|
||||
$cnpOk = Test-CNP $d
|
||||
$cuiOk = (Test-CUI $d) -and -not $cnpOk
|
||||
|
||||
# decizie: semnale tari intai (nume/reg comert/prefix RO), apoi forma codului
|
||||
$tip = ''
|
||||
if ($roPrefix) { $tip = 'PJ' }
|
||||
elseif ($tipNume -eq 'PJ') { $tip = 'PJ' }
|
||||
elseif ($tipReg -eq 'PJ') { $tip = 'PJ' }
|
||||
elseif ($cnpOk) { $tip = 'PF' }
|
||||
elseif ($tipReg -eq 'PF') { $tip = 'PF' }
|
||||
elseif ($cuiOk) { $tip = 'PJ' }
|
||||
else { $tip = 'PF?' } # necunoscut, presupunem PF
|
||||
|
||||
[pscustomobject]@{ Nume=$r.Nume; Cod=$r.Cod; Reg=$r.Reg; Tip=$tip; CnpOk=$cnpOk; CuiOk=$cuiOk }
|
||||
}
|
||||
|
||||
"total = $($rez.Count)"
|
||||
$rez | Group-Object Tip | Sort-Object Count -Descending | Format-Table Name, Count | Out-String -Width 100
|
||||
|
||||
''
|
||||
'=== PJ cu cod care NU trece validarea de CUI (raman cu cod, ca sa atentioneze declaratia) ==='
|
||||
$pjInvalid = $rez | Where-Object { $_.Tip -eq 'PJ' -and -not $_.CuiOk }
|
||||
"numar = $($pjInvalid.Count)"
|
||||
$pjInvalid | Select-Object -First 25 | Format-Table -AutoSize Nume, Cod, Reg | Out-String -Width 200
|
||||
|
||||
''
|
||||
'=== PF cu CNP invalid (se vor salva CU CNP GOL) ==='
|
||||
$pfInvalid = $rez | Where-Object { $_.Tip -like 'PF*' -and -not $_.CnpOk }
|
||||
"numar = $($pfInvalid.Count)"
|
||||
$pfInvalid | Select-Object -First 25 | Format-Table -AutoSize Nume, Cod, Reg | Out-String -Width 200
|
||||
|
||||
''
|
||||
'=== risc: clasificate PJ dar codul e CNP valid (nu trebuie sa existe) ==='
|
||||
($rez | Where-Object { $_.Tip -eq 'PJ' -and $_.CnpOk }) | Format-Table -AutoSize Nume, Cod, Reg | Out-String -Width 200
|
||||
49
ALTE/check_swap_tara.ps1
Normal file
49
ALTE/check_swap_tara.ps1
Normal file
@@ -0,0 +1,49 @@
|
||||
# Cazuri in care CODFISCAL_CNP e invalid dar REGCOMERT_CI_PASS contine un CNP valid (campuri inversate).
|
||||
param([string]$Dir = "D:\PROIECTE\FLORA\FLORA2ROA\EXEMPLE\hotel")
|
||||
|
||||
function Test-CNP([string]$c) {
|
||||
if ($c -notmatch '^\d{13}$') { return $false }
|
||||
$w = @(2,7,9,1,4,6,3,5,8,2,7,9); $s = 0
|
||||
for ($i = 0; $i -lt 12; $i++) { $s += [int]::Parse($c[$i]) * $w[$i] }
|
||||
$r = $s % 11; if ($r -eq 10) { $r = 1 }
|
||||
return ($r -eq [int]::Parse($c[12]))
|
||||
}
|
||||
|
||||
$rows = @{}
|
||||
Get-ChildItem -Path $Dir -Filter 'bts_detalii_facturi_rep_*.xml' | ForEach-Object {
|
||||
$t = Get-Content $_.FullName -Raw
|
||||
foreach ($m in [regex]::Matches($t, '(?is)<CUMPARATOR>([^<]*)</CUMPARATOR>.*?<CODFISCAL_CNP>([^<]*)</CODFISCAL_CNP>\s*<REGCOMERT_CI_PASS>([^<]*)</REGCOMERT_CI_PASS>')) {
|
||||
$nume = $m.Groups[1].Value.Trim().ToUpper()
|
||||
$cod = $m.Groups[2].Value.Trim().ToUpper()
|
||||
$reg = $m.Groups[3].Value.Trim().ToUpper()
|
||||
if ($cod -ne '') { $rows["$nume|$cod|$reg"] = [pscustomobject]@{ Nume=$nume; Cod=$cod; Reg=$reg } }
|
||||
}
|
||||
}
|
||||
|
||||
$swap = $rows.Values | Where-Object {
|
||||
$d = $_.Cod -replace '[^\d]', ''
|
||||
$r = $_.Reg -replace '[^\d]', ''
|
||||
-not (Test-CNP $d) -and (Test-CNP $r)
|
||||
}
|
||||
"cazuri cu campuri inversate (CNP valid in REGCOMERT) = $($swap.Count)"
|
||||
$swap | Format-Table -AutoSize Nume, Cod, Reg | Out-String -Width 200
|
||||
|
||||
# exista informatie de tara la cumparator?
|
||||
$f = Get-ChildItem -Path $Dir -Filter 'bts_detalii_facturi_rep_*.xml' | Select-Object -First 1
|
||||
$t = Get-Content $f.FullName -Raw
|
||||
$m = [regex]::Match($t, '(?is)<ROW>.*?</ROW>')
|
||||
''
|
||||
'=== campurile de tara existente in XML (primul rand) ==='
|
||||
[regex]::Matches($m.Value, '(?i)<(\w*TARA\w*)>([^<]*)</\1>') | ForEach-Object { " $($_.Groups[1].Value) = [$($_.Groups[2].Value)]" }
|
||||
|
||||
''
|
||||
'=== cate randuri au COMPANIE_TARA completat ==='
|
||||
$cuTara = 0; $total = 0
|
||||
Get-ChildItem -Path $Dir -Filter 'bts_detalii_facturi_rep_*.xml' | ForEach-Object {
|
||||
$txt = Get-Content $_.FullName -Raw
|
||||
foreach ($mm in [regex]::Matches($txt, '(?i)<COMPANIE_TARA>([^<]*)</COMPANIE_TARA>')) {
|
||||
$total++
|
||||
if ($mm.Groups[1].Value.Trim() -ne '') { $cuTara++ }
|
||||
}
|
||||
}
|
||||
"COMPANIE_TARA completat pe $cuTara din $total randuri"
|
||||
113
CLAUDE.md
Normal file
113
CLAUDE.md
Normal file
@@ -0,0 +1,113 @@
|
||||
# CLAUDE.md
|
||||
|
||||
Ghid pentru agenti (Claude Code / Jcode) care lucreaza in acest repo.
|
||||
|
||||
## Ce este
|
||||
|
||||
FLORA2ROA e o aplicatie Visual FoxPro 9 care importa facturile si vanzarile din **Fidelio**
|
||||
(hotel, XML) si **BIZ** (restaurant, XML) si genereaza note contabile in **ROA** (Oracle).
|
||||
Un singur formular, `frm_import.scx`, face tot fluxul: citeste XML-urile din interval,
|
||||
completeaza nomenclatorul de parteneri, construieste notele si le scrie in ROA.
|
||||
|
||||
Radacina: `D:\PROIECTE\FLORA\FLORA2ROA`. Nu are folder `COMUN\` (doar `comun.h` local), deci
|
||||
scripturile partajate ROA au echivalente locale in `Teste\`.
|
||||
|
||||
## Reguli de lucru: OBLIGATORIU inainte de orice modificare
|
||||
|
||||
**Citeste `D:\ROA\ROACONT\COMUN\docs\reguli_lucru.md`.** Nu e context optional, e contractul de
|
||||
livrare. Ce se incalca cel mai usor daca nu-l citesti:
|
||||
|
||||
- **Nu se comite fara aprobare.** Livrezi diff ca FISIER (`docs\diff_runda<N>_<subiect>.patch`),
|
||||
iar write-back-ul in binar si commit-ul se fac dupa ce utilizatorul aproba. Patch-urile de
|
||||
review nu se comit niciodata (sunt in `.gitignore`).
|
||||
- **Comentarii minime, fara jurnal.** O linie, descriind comportamentul CURENT. Interzis inline:
|
||||
istoricul modificarii ("inlocuieste...", "nu mai depinde de..."), nume de agent, referinte la
|
||||
runde/decizii. Istoricul sta doar in antetul fisierului, cumulativ, semnat de om.
|
||||
- **Modificari minime**: doar ce s-a cerut, fara refactorizari din oficiu.
|
||||
- Punctul 7 din acel fisier e un index de conventii per zona atinsa (encoding cp1252, UX
|
||||
formulare, `GO` pe `Recno()`, `goExecutor` + `ALTER TABLE`, testare UI, export Oracle).
|
||||
|
||||
## Documentatia proprie a proiectului
|
||||
|
||||
- `docs\depanare_testare_flora2roa.md` - harnessul de testare headless, ce contine `Teste\`,
|
||||
comenzile uzuale si capcanele confirmate aici. **De citit inainte de a rula sau scrie teste.**
|
||||
- `docs\flux_git_flora2roa.md` - fluxul git + SVN, ce urmareste fiecare, `roa_sync.bat`.
|
||||
|
||||
## Versionare
|
||||
|
||||
**SVN** e sursa de adevar, inclusiv pentru binarele VFP. **git** urmareste versiunile TEXT
|
||||
(`.sc2`, `.pj2`) generate de FoxBin2Prg in arbore, plus `.prg`, `Teste\`, `docs\`. Binarele sunt
|
||||
git-ignored, ca diff-urile sa fie lizibile. La inceput de sesiune: `roa_sync.bat`.
|
||||
|
||||
`svn commit` (care atinge binarele) se face **doar cu acordul explicit al utilizatorului**.
|
||||
|
||||
## Editarea formularului
|
||||
|
||||
`frm_import.scx` se editeaza pe text, byte-safe in Windows-1252:
|
||||
|
||||
```powershell
|
||||
powershell -ExecutionPolicy Bypass -File Teste\text_din_bin.ps1 # binar -> frm_import.sc2
|
||||
# editezi frm_import.sc2 cu [IO.File]::ReadAllText/WriteAllText + GetEncoding(1252)
|
||||
powershell -ExecutionPolicy Bypass -File Teste\bin_din_text.ps1 -TextFile frm_import.sc2
|
||||
powershell -ExecutionPolicy Bypass -File Teste\recompileaza_binare.ps1
|
||||
```
|
||||
|
||||
Ultimul pas nu e optional: write-back-ul reface `.scx/.sct` fara cod obiect, deci formularul
|
||||
ruleaza fara `#INCLUDE "comun.h"` si constantele (`CT_SUCCES`) crapa in RUNTIME, desi
|
||||
verificarea de sintaxa trece.
|
||||
|
||||
## Testare
|
||||
|
||||
Nu exista IDE in flux. Totul headless, din PowerShell:
|
||||
|
||||
```powershell
|
||||
powershell -ExecutionPolicy Bypass -File Teste\ruleaza_teste.ps1 # suita + sinteza
|
||||
powershell -ExecutionPolicy Bypass -File Teste\verifica_sintaxa.ps1 # dupa orice editare .prg
|
||||
```
|
||||
|
||||
Un `.fxp` vechi ascunde modificarile din `.prg`: daca un test da acelasi rezultat dupa o
|
||||
corectie evidenta, sterge `.fxp`-ul si reia.
|
||||
|
||||
## Cod
|
||||
|
||||
- Punct de intrare `main.prg`; `myutils.prg` = biblioteca de functii utilitare; `capp/app/myapp.prg`
|
||||
= obiectele globale (`goApp`, `goConn`, `goExecutor`, `goLog`).
|
||||
- Constantele din `comun.h` (`CT_SUCCES = 1`, `CT_INSUCCES`) sunt conventia de retur.
|
||||
- Cod si mesaje in **romana, fara diacritice** (fisierele sunt cp1252).
|
||||
- Functiile utilitare partajate se copiaza din `D:\ROA\ROACONT\COMUN\programe\oproceduri_comune.prg`,
|
||||
nu se rescriu.
|
||||
|
||||
## Reguli de domeniu (contabil) de stiut
|
||||
|
||||
- In ROA, `RO12345678` (platitor de TVA) si `12345678` sunt **doi parteneri diferiti**: prefixul
|
||||
`RO` se pastreaza exact cum vine din import si nu se adauga niciodata automat.
|
||||
- La D394/D406 o **persoana fizica** poate fi raportata fara CNP, deci un CNP invalid se goleste.
|
||||
O **persoana juridica** trebuie sa aiba cod fiscal: codul ei nu se sterge niciodata, ca eroarea
|
||||
sa fie semnalata la validarea declaratiei si corectata la sursa, in Fidelio.
|
||||
- Algoritmul romanesc de validare (CNP/CUI) nu se aplica partenerilor straini; codurile lor pot fi
|
||||
si numai din cifre, de orice lungime.
|
||||
|
||||
## Changelog
|
||||
|
||||
`changelog_flora2roa.txt`, blocuri de comentariu HTML, cel mai nou primul:
|
||||
|
||||
```
|
||||
<!--
|
||||
DD/MM/YYYY
|
||||
FLORA2ROA - X.Y.Z
|
||||
|
||||
:modificare:
|
||||
Ce vede utilizatorul.
|
||||
-->
|
||||
```
|
||||
|
||||
Taguri: `:nou:`, `:modificare:`, `:eroare:`. Text **pentru utilizator**, scurt, netehnic, o fraza
|
||||
per idee. Erorile introduse si reparate in aceeasi versiune nelivrata nu se trec: `:eroare:` e
|
||||
doar pentru ce a fost in productie. La bump de versiune se actualizeaza si `flora2roa.txt`
|
||||
(fisierul pe care `update.bat` il compara cu cel de pe server).
|
||||
|
||||
## Stil de raspuns
|
||||
|
||||
Scurt si concret. Ce e gata (fisier:linie), ce urmeaza, ce trebuie decis. Fara naratiunea
|
||||
drumului pana la rezultat, fara reluari, fara justificari necerute. Detaliile lungi (dovezi,
|
||||
iesiri de test) se scriu in fisier si se trimite link.
|
||||
59
Teste/recompileaza_binare.ps1
Normal file
59
Teste/recompileaza_binare.ps1
Normal file
@@ -0,0 +1,59 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Recompileaza formularele/clasele VFP dupa un write-back din text (bin_din_text.ps1).
|
||||
|
||||
.DESCRIPTION
|
||||
FoxBin2Prg regenereaza .scx/.sct DIN TEXT, dar fara codul obiect compilat. Un formular
|
||||
regenerat si NErecompilat ruleaza fara `#INCLUDE`-uri: constantele din comun.h (CT_SUCCES,
|
||||
CT_INSUCCES...) devin "Variable not found" abia in RUNTIME, nu la verificarea de sintaxa.
|
||||
|
||||
De aceea, dupa FIECARE bin_din_text.ps1 se ruleaza si scriptul asta.
|
||||
|
||||
.EXAMPLE
|
||||
powershell -ExecutionPolicy Bypass -File Teste\bin_din_text.ps1 -TextFile frm_import.sc2
|
||||
powershell -ExecutionPolicy Bypass -File Teste\recompileaza_binare.ps1
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string[]]$Formular = @('frm_import.scx'),
|
||||
[string]$ProjectRoot
|
||||
)
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
if (-not $ProjectRoot) { $ProjectRoot = Split-Path $PSScriptRoot -Parent }
|
||||
|
||||
$vfp = 'C:\Program Files (x86)\Microsoft Visual FoxPro 9\vfp9.exe'
|
||||
if (-not (Test-Path $vfp)) { throw "Nu gasesc $vfp" }
|
||||
|
||||
$prg = Join-Path $env:TEMP ("recompile_" + [guid]::NewGuid().ToString('N') + '.prg')
|
||||
$linii = @(
|
||||
"SET DEFAULT TO `"$ProjectRoot`"",
|
||||
"SET PATH TO `"$ProjectRoot`""
|
||||
)
|
||||
foreach ($f in $Formular) {
|
||||
$cale = Join-Path $ProjectRoot $f
|
||||
if (-not (Test-Path $cale)) { throw "Nu exista $cale" }
|
||||
$linii += "COMPILE FORM `"$f`""
|
||||
}
|
||||
$linii += 'QUIT'
|
||||
[IO.File]::WriteAllLines($prg, $linii, [Text.Encoding]::GetEncoding(1252))
|
||||
|
||||
try {
|
||||
& $vfp -A -T $prg | Out-Null
|
||||
} finally {
|
||||
Remove-Item $prg -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
# verificare: .sct trebuie sa contina cod obiect, nu doar textul metodelor
|
||||
$rezultate = foreach ($f in $Formular) {
|
||||
$sct = Join-Path $ProjectRoot ([IO.Path]::ChangeExtension($f, '.sct'))
|
||||
[pscustomobject]@{
|
||||
Formular = $f
|
||||
SCT_KB = if (Test-Path $sct) { [math]::Round((Get-Item $sct).Length / 1KB) } else { 0 }
|
||||
Stare = if ((Test-Path $sct) -and (Get-Item $sct).Length -gt 0) { 'OK' } else { 'LIPSA' }
|
||||
}
|
||||
}
|
||||
$rezultate | Format-Table -AutoSize
|
||||
|
||||
if ($rezultate | Where-Object { $_.Stare -ne 'OK' }) { exit 1 }
|
||||
Write-Host 'Recompilare terminata.' -ForegroundColor Green
|
||||
@@ -34,6 +34,8 @@ $Root = Split-Path $Teste -Parent
|
||||
$suita = @(
|
||||
@{ Prg = 'test_frm_import_ui.prg'; Steps = @('afisat', 'trace', 'date') }
|
||||
@{ Prg = 'test_export_date.prg'; Steps = @('afisat', 'importat') }
|
||||
@{ Prg = 'test_cod_fiscal.prg'; Steps = @('validari') }
|
||||
@{ Prg = 'test_cod_fiscal_real.prg'; Steps = @('analiza') }
|
||||
)
|
||||
if ($Doar) { $suita = $suita | Where-Object { $_.Prg -like "*$Doar*" } }
|
||||
|
||||
|
||||
211
Teste/test_cod_fiscal.prg
Normal file
211
Teste/test_cod_fiscal.prg
Normal file
@@ -0,0 +1,211 @@
|
||||
* test_cod_fiscal.prg - teste pentru clasificarea partenerilor importati si curatarea CNP-urilor.
|
||||
*
|
||||
* Regula verificata:
|
||||
* - PERSOANA FIZICA cu CNP invalid => cod fiscal GOL (permis la D394/D406)
|
||||
* - PERSOANA FIZICA cu CNP valid => CNP pastrat, curatat de spatii/puncte
|
||||
* - PERSOANA JURIDICA => codul NU se sterge NICIODATA, chiar daca nu trece
|
||||
* validarea romaneasca (poate fi partener strain),
|
||||
* ca sa fim atentionati la validarea declaratiei
|
||||
*
|
||||
* Rulare directa:
|
||||
* vfp9.exe -A -T "D:\PROIECTE\FLORA\FLORA2ROA\Teste\test_cod_fiscal.prg"
|
||||
|
||||
SET SAFETY OFF
|
||||
SET TALK OFF
|
||||
|
||||
PUBLIC gcUILog, gcSyncDir, gnTestFail, gnMockRaspuns, gcMockUltimMesaj, gnMockUltimTip
|
||||
gnTestFail = 0
|
||||
gnMockRaspuns = 6
|
||||
gcMockUltimMesaj = ''
|
||||
gnMockUltimTip = 0
|
||||
|
||||
LOCAL lcTestDir
|
||||
lcTestDir = ADDBS(JUSTPATH(SYS(16, 0)))
|
||||
gcUILog = lcTestDir + 'test_cod_fiscal_log.txt'
|
||||
gcSyncDir = lcTestDir + 'uisync\'
|
||||
IF !DIRECTORY(gcSyncDir)
|
||||
MD (gcSyncDir)
|
||||
ENDIF
|
||||
STRTOFILE('START ' + TTOC(DATETIME()) + CHR(13) + CHR(10), gcUILog)
|
||||
|
||||
DO (lcTestDir + 'test_init_env_auto.prg') WITH .F.
|
||||
SET PROCEDURE TO (lcTestDir + 'ui_harness.prg') ADDITIVE
|
||||
SET PROCEDURE TO (lcTestDir + 'mock_amessagebox.prg') ADDITIVE
|
||||
|
||||
DO HarnessInit
|
||||
|
||||
LOCAL lnTip, lcRez
|
||||
|
||||
*==============================================================
|
||||
* 1. PERSOANE FIZICE - singurele la care se sterge codul
|
||||
*==============================================================
|
||||
lnTip = 0
|
||||
lcRez = GetCodFiscalValid('1800101410013', @lnTip, 'POPESCU ION', 'ZV 093375')
|
||||
TestAssertEqual('1800101410013', m.lcRez, 'PF: CNP valid pastrat')
|
||||
TestAssertEqual(2, m.lnTip, 'PF: CNP valid => persoana fizica')
|
||||
|
||||
TestAssertEqual('1800101410013', GetCodFiscalValid(' 1800101410013. ', @lnTip, 'POPESCU ION', ''), ;
|
||||
'PF: CNP valid curatat de spatii si punct')
|
||||
|
||||
* CNP-uri invalide reale din Fidelio: codul se goleste
|
||||
lnTip = 0
|
||||
lcRez = GetCodFiscalValid('2650407170374', @lnTip, 'TRUTA CLAUDIA MIHAELA', 'RK 800386')
|
||||
TestAssertEqual('', m.lcRez, 'PF: CNP cu cifra de control gresita se sterge')
|
||||
TestAssertEqual(2, m.lnTip, 'PF: ramane persoana fizica')
|
||||
|
||||
TestAssertEqual('', GetCodFiscalValid('171030126201', @lnTip, 'TARTA GAVRIL SILVIU', ''), ;
|
||||
'PF: CNP de 12 cifre se sterge')
|
||||
TestAssertEqual('', GetCodFiscalValid('29050709211182', @lnTip, 'HOGESCU CRISTINA', ''), ;
|
||||
'PF: CNP de 14 cifre se sterge')
|
||||
TestAssertEqual('', GetCodFiscalValid('60109121600600', @lnTip, 'IOANCA DAMARIS', ''), ;
|
||||
'PF: CNP de 14 cifre se sterge (2)')
|
||||
|
||||
* CNP valid scris cu punct la final
|
||||
TestAssertEqual('2920121295914', GetCodFiscalValid('2920121295914.', @lnTip, 'ANDREI MARIA', ''), ;
|
||||
'PF: CNP valid cu punct la final se curata')
|
||||
|
||||
* persoana fizica fara niciun semnal, cod invalid => tot persoana fizica, cod gol
|
||||
lnTip = 0
|
||||
lcRez = GetCodFiscalValid('287101935573', @lnTip, 'OPREA ANDREEA', '')
|
||||
TestAssertEqual('', m.lcRez, 'PF: fara semnale, cod invalid => gol')
|
||||
TestAssertEqual(2, m.lnTip, 'PF: fara semnale => persoana fizica')
|
||||
|
||||
*==============================================================
|
||||
* 2. PERSOANE JURIDICE - codul NU se sterge niciodata
|
||||
*==============================================================
|
||||
lnTip = 0
|
||||
lcRez = GetCodFiscalValid('RO21675175', @lnTip, 'JUST MULTISERV SRL', 'J03/245/2007')
|
||||
TestAssertEqual('RO21675175', m.lcRez, 'PJ: CUI cu prefix RO pastrat')
|
||||
TestAssertEqual(1, m.lnTip, 'PJ: prefix RO => persoana juridica')
|
||||
|
||||
TestAssertEqual('RO23565004', GetCodFiscalValid('RO 23565004', @lnTip, 'FIRMA SRL', ''), ;
|
||||
'PJ: spatiul din cod se elimina')
|
||||
|
||||
lnTip = 0
|
||||
lcRez = GetCodFiscalValid('24536740', @lnTip, 'KALVA SOLUTIONS SRL', 'J29/2677/2008')
|
||||
TestAssertEqual('24536740', m.lcRez, 'PJ: CUI fara RO pastrat')
|
||||
TestAssertEqual(1, m.lnTip, 'PJ: denumire cu SRL => persoana juridica')
|
||||
|
||||
* CUI romanesc GRESIT la o persoana juridica: NU se sterge, ca sa dea eroare la declaratie
|
||||
lnTip = 0
|
||||
lcRez = GetCodFiscalValid('24536741', @lnTip, 'KALVA SOLUTIONS SRL', 'J29/2677/2008')
|
||||
TestAssertEqual('24536741', m.lcRez, 'PJ: CUI invalid NU se sterge')
|
||||
TestAssertEqual(1, m.lnTip, 'PJ: CUI invalid ramane persoana juridica')
|
||||
|
||||
* partener strain cu cod alfanumeric
|
||||
lnTip = 0
|
||||
lcRez = GetCodFiscalValid('BE0325777171', @lnTip, 'UNIVERSITE DE LIEGE', '')
|
||||
TestAssertEqual('BE0325777171', m.lcRez, 'PJ straina: TVA belgian pastrat')
|
||||
TestAssertEqual(1, m.lnTip, 'PJ straina: cod TVA intracomunitar => persoana juridica')
|
||||
|
||||
TestAssertEqual('DICA9712015/99KS', GetCodFiscalValid('DICA9712015/99KS', @lnTip, 'FIRMA STRAINA SRL', ''), ;
|
||||
'PJ straina: cod cu slash pastrat cand denumirea are forma juridica')
|
||||
|
||||
* cod cu litere care NU e cod de TVA si fara alt semnal => pasaport de persoana fizica
|
||||
lnTip = 0
|
||||
lcRez = GetCodFiscalValid('NN9J17714', @lnTip, 'TORRES MELISSA', '')
|
||||
TestAssertEqual('', m.lcRez, 'PF straina: pasaportul nu se salveaza pe cod fiscal')
|
||||
TestAssertEqual(2, m.lnTip, 'PF straina: pasaport fara alt semnal => persoana fizica')
|
||||
|
||||
* prefixul romanesc se normalizeaza la RO
|
||||
lnTip = 0
|
||||
lcRez = GetCodFiscalValid('CUI 14770212', @lnTip, 'ASOCIATIA JUDETEANA DE HANDBAL', '')
|
||||
TestAssertEqual('14770212', m.lcRez, 'PJ: eticheta CUI se scoate, fara sa se adauge RO')
|
||||
TestAssertEqual(1, m.lnTip, 'PJ: eticheta CUI => persoana juridica')
|
||||
|
||||
* 'RO' inseamna platitor de TVA: in ROA e ALT partener decat neplatitorul cu acelasi numar,
|
||||
* deci prefixul se pastreaza exact cum vine si NU se adauga niciodata de noi
|
||||
TestAssertEqual('RO24536740', GetCodFiscalValid('RO24536740', @lnTip, 'KALVA SOLUTIONS SRL', ''), ;
|
||||
'PJ platitoare de TVA: prefixul RO se pastreaza')
|
||||
TestAssertEqual('24536740', GetCodFiscalValid('24536740', @lnTip, 'KALVA SOLUTIONS SRL', ''), ;
|
||||
'PJ neplatitoare: NU se adauga RO')
|
||||
|
||||
* partener strain cu cod NUMAI DIN CIFRE, recunoscut dupa tara
|
||||
lnTip = 0
|
||||
lcRez = GetCodFiscalValid('123456789012345', @lnTip, 'HOTEL PARTNER', '', 'BE')
|
||||
TestAssertEqual('123456789012345', m.lcRez, 'PJ straina: cod numeric cu tara straina se pastreaza')
|
||||
TestAssertEqual(1, m.lnTip, 'PJ straina: tara straina => persoana juridica')
|
||||
|
||||
* persoana juridica recunoscuta dupa numarul de registrul comertului
|
||||
lnTip = 0
|
||||
lcRez = GetCodFiscalValid('99999999', @lnTip, 'DENUMIRE FARA FORMA JURIDICA', 'J40/5790/2018')
|
||||
TestAssertEqual('99999999', m.lcRez, 'PJ: cod invalid pastrat cand exista nr. reg. comertului')
|
||||
TestAssertEqual(1, m.lnTip, 'PJ: nr. registrul comertului => persoana juridica')
|
||||
|
||||
lnTip = 0
|
||||
lcRez = GetCodFiscalValid('88888888', @lnTip, 'TICMAR EMMA CONCEPT', 'J2018000211289')
|
||||
TestAssertEqual(1, m.lnTip, 'PJ: nr. reg. comertului fara slash => persoana juridica')
|
||||
|
||||
lnTip = 0
|
||||
lcRez = GetCodFiscalValid('9924188', @lnTip, 'CAR CFR SECTIA L2 SI CT1 BRAILA', '54/1997')
|
||||
TestAssertEqual(1, m.lnTip, 'PJ: numar/an => persoana juridica')
|
||||
|
||||
* tipul venit direct din import bate toate celelalte semnale
|
||||
lnTip = 0
|
||||
lcRez = GetCodFiscalValid('1800101410013', @lnTip, 'POPESCU ION', '', '', '1')
|
||||
TestAssertEqual('1800101410013', m.lcRez, 'tip impus PJ: codul se pastreaza')
|
||||
TestAssertEqual(1, m.lnTip, 'tip impus din import => persoana juridica')
|
||||
|
||||
*==============================================================
|
||||
* 3. Recuperare din campuri inversate in Fidelio
|
||||
*==============================================================
|
||||
* operatorul a scris pasaportul pe cod fiscal si CNP-ul pe serie CI
|
||||
lnTip = 0
|
||||
lcRez = GetCodFiscalValid('XD 061964', @lnTip, 'POPITIU IOANA', '2640626364228')
|
||||
TestAssertEqual('2640626364228', m.lcRez, 'recuperare: CNP valid luat din campul de serie CI')
|
||||
TestAssertEqual(2, m.lnTip, 'recuperare: ramane persoana fizica')
|
||||
|
||||
* daca in campul de serie CI nu exista CNP valid, nu inventam nimic
|
||||
TestAssertEqual('', GetCodFiscalValid('XD 061964', @lnTip, 'POPITIU IOANA', 'ZV 093375'), ;
|
||||
'recuperare: fara CNP valid in serie CI ramane gol')
|
||||
|
||||
*==============================================================
|
||||
* 4. Cazuri limita
|
||||
*==============================================================
|
||||
lnTip = 0
|
||||
TestAssertEqual('', GetCodFiscalValid('', @lnTip, 'POPESCU ION', ''), 'cod gol ramane gol')
|
||||
TestAssertEqual(2, m.lnTip, 'cod gol + nume de persoana => persoana fizica')
|
||||
|
||||
lnTip = 0
|
||||
TestAssertEqual('', GetCodFiscalValid(' ', @lnTip, 'POPESCU ION', ''), 'spatii => gol')
|
||||
|
||||
lnTip = 0
|
||||
lcRez = GetCodFiscalValid('', @lnTip, 'ALFA CONSTRUCT SRL', '')
|
||||
TestAssertEqual('', m.lcRez, 'PJ fara cod ramane fara cod')
|
||||
TestAssertEqual(1, m.lnTip, 'PJ fara cod este tot persoana juridica')
|
||||
|
||||
*--- functiile ajutatoare ---
|
||||
TestAssert(EstePersoanaJuridica('KALVA SOLUTIONS SRL'), 'EstePersoanaJuridica: SRL')
|
||||
TestAssert(EstePersoanaJuridica('ASOCIATIA SPORTIVA X'), 'EstePersoanaJuridica: ASOCIATIA')
|
||||
TestAssert(EstePersoanaJuridica('UNIVERSITE DE LIEGE'), 'EstePersoanaJuridica: UNIVERSITE')
|
||||
TestAssert(!EstePersoanaJuridica('SAVU MARIA'), 'EstePersoanaJuridica: SAVU nu e SA')
|
||||
TestAssert(!EstePersoanaJuridica('MIHAII ION'), 'EstePersoanaJuridica: MIHAII nu e II')
|
||||
TestAssert(!EstePersoanaJuridica('POPESCU ION'), 'EstePersoanaJuridica: nume simplu')
|
||||
|
||||
TestAssert(EsteNrRegComert('J40/5790/2018'), 'EsteNrRegComert: J40/5790/2018')
|
||||
TestAssert(EsteNrRegComert('J2018000211289'), 'EsteNrRegComert: J2018000211289')
|
||||
TestAssert(EsteNrRegComert('54/1997'), 'EsteNrRegComert: 54/1997')
|
||||
TestAssert(!EsteNrRegComert('ZV 093375'), 'EsteNrRegComert: serie CI nu e reg. comert')
|
||||
TestAssert(!EsteNrRegComert(''), 'EsteNrRegComert: gol')
|
||||
|
||||
TestAssert(EsteSerieCI('ZV 093375'), 'EsteSerieCI: cu spatiu')
|
||||
TestAssert(EsteSerieCI('IF834409'), 'EsteSerieCI: fara spatiu')
|
||||
TestAssert(!EsteSerieCI('J40/5790/2018'), 'EsteSerieCI: nr. reg. comert nu e serie CI')
|
||||
TestAssert(!EsteSerieCI('2990118070015'), 'EsteSerieCI: CNP nu e serie CI')
|
||||
|
||||
TestAssert(EsteCodTVAStrain('BE0325777171'), 'EsteCodTVAStrain: BE')
|
||||
TestAssert(EsteCodTVAStrain('DE811234567'), 'EsteCodTVAStrain: DE')
|
||||
TestAssert(!EsteCodTVAStrain('NN9J17714'), 'EsteCodTVAStrain: pasaport nu e cod TVA')
|
||||
TestAssert(!EsteCodTVAStrain('XD061964'), 'EsteCodTVAStrain: serie pasaport nu e cod TVA')
|
||||
|
||||
TestAssertEqual('RO23565004', GetCodFiscalCurat('RO 23565004'), 'GetCodFiscalCurat: spatii, RO pastrat')
|
||||
TestAssertEqual('14770212', GetCodFiscalCurat('CUI 14770212'), 'GetCodFiscalCurat: eticheta CUI se scoate')
|
||||
TestAssertEqual('14770212', GetCodFiscalCurat('CF 14770212'), 'GetCodFiscalCurat: eticheta CF se scoate')
|
||||
TestAssertEqual('2920121295914', GetCodFiscalCurat('2920121295914.'), 'GetCodFiscalCurat: punct')
|
||||
|
||||
DO HarnessStep WITH 0, 'validari cod fiscal'
|
||||
|
||||
HarnessLog('REZULTAT: ' + TestRezultat())
|
||||
DO HarnessDone WITH TestRezultat()
|
||||
|
||||
QUIT
|
||||
133
Teste/test_cod_fiscal_real.prg
Normal file
133
Teste/test_cod_fiscal_real.prg
Normal file
@@ -0,0 +1,133 @@
|
||||
* test_cod_fiscal_real.prg - ruleaza GetCodFiscalValid pe TOATE codurile din XML-urile Fidelio
|
||||
* si scrie un raport, ca sa vedem efectul real inainte de import.
|
||||
*
|
||||
* Verifica invariantii care conteaza pentru declaratii:
|
||||
* - nicio persoana JURIDICA nu ramane fara cod din cauza noastra (codul nu se sterge)
|
||||
* - se sterge cod DOAR la persoane fizice si DOAR cand CNP-ul chiar este invalid
|
||||
* - niciun CNP valid nu se pierde
|
||||
*
|
||||
* Rulare: vfp9.exe -A -T "D:\PROIECTE\FLORA\FLORA2ROA\Teste\test_cod_fiscal_real.prg"
|
||||
|
||||
SET SAFETY OFF
|
||||
SET TALK OFF
|
||||
|
||||
PUBLIC gcUILog, gcSyncDir, gnTestFail, gnMockRaspuns, gcMockUltimMesaj, gnMockUltimTip
|
||||
gnTestFail = 0
|
||||
gnMockRaspuns = 6
|
||||
gcMockUltimMesaj = ''
|
||||
gnMockUltimTip = 0
|
||||
|
||||
LOCAL lcTestDir
|
||||
lcTestDir = ADDBS(JUSTPATH(SYS(16, 0)))
|
||||
gcUILog = lcTestDir + 'test_cod_fiscal_real_log.txt'
|
||||
gcSyncDir = lcTestDir + 'uisync\'
|
||||
IF !DIRECTORY(gcSyncDir)
|
||||
MD (gcSyncDir)
|
||||
ENDIF
|
||||
STRTOFILE('START ' + TTOC(DATETIME()) + CHR(13) + CHR(10), gcUILog)
|
||||
|
||||
DO (lcTestDir + 'test_init_env_auto.prg') WITH .F.
|
||||
SET PROCEDURE TO (lcTestDir + 'ui_harness.prg') ADDITIVE
|
||||
SET PROCEDURE TO (lcTestDir + 'mock_amessagebox.prg') ADDITIVE
|
||||
|
||||
DO HarnessInit
|
||||
|
||||
LOCAL lcCale, lcFisier, lnFisiere, lcRaport
|
||||
lcCale = ADDBS(ALLTRIM(goApp.oSettings.cale_import_fidelio))
|
||||
HarnessLog('Citesc XML-urile din: ' + m.lcCale)
|
||||
|
||||
CREATE CURSOR cTot (denumire C(200), cod C(50), reg_com C(50))
|
||||
|
||||
lnFisiere = 0
|
||||
lnSarite = 0
|
||||
lcFisier = SYS(2000, m.lcCale + 'bts_detalii_facturi_rep_*.xml')
|
||||
DO WHILE !EMPTY(m.lcFisier)
|
||||
lnRanduri = 0
|
||||
* fisierele goale sau fara coloanele asteptate se sar controlat
|
||||
TRY
|
||||
lnRanduri = XMLTOCURSOR(m.lcCale + m.lcFisier, 'cUnul', 512)
|
||||
CATCH
|
||||
lnRanduri = 0
|
||||
ENDTRY
|
||||
|
||||
IF m.lnRanduri > 0 AND USED('cUnul') AND ;
|
||||
TYPE('cUnul.codfiscal_cnp') = 'C' AND TYPE('cUnul.cumparator') = 'C'
|
||||
SELECT DISTINCT CAST(ALLTRIM(cumparator) AS C(200)) AS denumire, ;
|
||||
CAST(ALLTRIM(codfiscal_cnp) AS C(50)) AS cod, ;
|
||||
CAST(ALLTRIM(regcomert_ci_pass) AS C(50)) AS reg_com ;
|
||||
FROM cUnul WHERE !EMPTY(NVL(codfiscal_cnp, '')) INTO CURSOR cTemp
|
||||
SELECT cTot
|
||||
APPEND FROM DBF('cTemp')
|
||||
USE IN (SELECT('cTemp'))
|
||||
lnFisiere = m.lnFisiere + 1
|
||||
ELSE
|
||||
lnSarite = m.lnSarite + 1
|
||||
ENDIF
|
||||
|
||||
USE IN (SELECT('cUnul'))
|
||||
lcFisier = SYS(2000, m.lcCale + 'bts_detalii_facturi_rep_*.xml', 1)
|
||||
ENDDO
|
||||
|
||||
HarnessLog('Fisiere citite: ' + TRANSFORM(m.lnFisiere) + ', sarite (goale/fara coloane): ' + TRANSFORM(m.lnSarite))
|
||||
TestAssert(m.lnFisiere > 0, 'exista fisiere XML de analizat')
|
||||
|
||||
SELECT DISTINCT denumire, cod, reg_com FROM cTot INTO CURSOR cUnic
|
||||
HarnessLog('Combinatii distincte nume+cod+regcom: ' + TRANSFORM(RECCOUNT('cUnic')))
|
||||
|
||||
LOCAL lnPF, lnPJ, lnSters, lnPJNevalidat, lnCnpPierdut, lnPJFaraCod
|
||||
LOCAL lnTip, lcRez, lcCifre, lcCod
|
||||
STORE 0 TO lnPF, lnPJ, lnSters, lnPJNevalidat, lnCnpPierdut, lnPJFaraCod
|
||||
lcRaport = 'denumire;cod_import;reg_com;tip;cod_salvat' + CHR(13) + CHR(10)
|
||||
|
||||
SELECT cUnic
|
||||
SCAN
|
||||
lcCod = ALLTRIM(cUnic.cod)
|
||||
lnTip = 0
|
||||
lcRez = GetCodFiscalValid(m.lcCod, @lnTip, cUnic.denumire, cUnic.reg_com)
|
||||
|
||||
IF m.lnTip = 1
|
||||
lnPJ = m.lnPJ + 1
|
||||
* invariant 1: la persoana juridica NU stergem niciodata codul
|
||||
IF EMPTY(m.lcRez) AND !EMPTY(m.lcCod)
|
||||
lnPJFaraCod = m.lnPJFaraCod + 1
|
||||
HarnessLog('EROARE invariant: PJ ramasa fara cod: ' + ALLTRIM(cUnic.denumire) + ' [' + m.lcCod + ']')
|
||||
ENDIF
|
||||
IF !VerifCF(m.lcRez)
|
||||
lnPJNevalidat = m.lnPJNevalidat + 1
|
||||
ENDIF
|
||||
ELSE
|
||||
lnPF = m.lnPF + 1
|
||||
IF EMPTY(m.lcRez)
|
||||
lnSters = m.lnSters + 1
|
||||
* invariant 2: nu stergem CNP-uri VALIDE
|
||||
lcCifre = CHRTRAN(m.lcCod, CHRTRAN(m.lcCod, '0123456789', ''), '')
|
||||
IF LEN(m.lcCifre) = 13 AND cValidCNP(m.lcCifre)
|
||||
lnCnpPierdut = m.lnCnpPierdut + 1
|
||||
HarnessLog('EROARE invariant: CNP valid pierdut: ' + ALLTRIM(cUnic.denumire) + ' [' + m.lcCod + ']')
|
||||
ENDIF
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
lcRaport = m.lcRaport + ALLTRIM(cUnic.denumire) + ';' + m.lcCod + ';' + ALLTRIM(cUnic.reg_com) + ';' + ;
|
||||
IIF(m.lnTip = 1, 'PJ', 'PF') + ';' + m.lcRez + CHR(13) + CHR(10)
|
||||
ENDSCAN
|
||||
|
||||
STRTOFILE(m.lcRaport, m.lcTestDir + 'raport_cod_fiscal_real.csv', .F.)
|
||||
|
||||
HarnessLog('persoane fizice : ' + TRANSFORM(m.lnPF))
|
||||
HarnessLog('persoane juridice : ' + TRANSFORM(m.lnPJ))
|
||||
HarnessLog('PF cu CNP sters : ' + TRANSFORM(m.lnSters))
|
||||
HarnessLog('PJ cu cod nevalidat RO : ' + TRANSFORM(m.lnPJNevalidat) + ' (raman cu cod, atentioneaza declaratia)')
|
||||
|
||||
TestAssertEqual(0, m.lnPJFaraCod, 'nicio persoana juridica nu ramane fara cod')
|
||||
TestAssertEqual(0, m.lnCnpPierdut, 'niciun CNP valid nu se pierde')
|
||||
TestAssert(m.lnPF + m.lnPJ > 1000, 's-au analizat toti partenerii din exemple')
|
||||
TestAssert(m.lnSters > 0, 'exista CNP-uri invalide care se curata')
|
||||
TestAssert(m.lnPJ > 0, 'exista si persoane juridice detectate')
|
||||
|
||||
DO HarnessStep WITH 0, 'analiza pe date reale'
|
||||
|
||||
HarnessLog('REZULTAT: ' + TestRezultat())
|
||||
DO HarnessDone WITH TestRezultat()
|
||||
|
||||
QUIT
|
||||
87
Teste/test_parteneri_roa.prg
Normal file
87
Teste/test_parteneri_roa.prg
Normal file
@@ -0,0 +1,87 @@
|
||||
* test_parteneri_roa.prg - cautarea partenerului la import, pe datele reale din ROA.
|
||||
*
|
||||
* Reguli verificate:
|
||||
* - cautarea se face pe codul cu care partenerul se salveaza (GetCodFiscalValid), nu pe cel brut
|
||||
* - cand mai multi parteneri au acelasi cod fiscal, se ia cel mai vechi (id_part minim)
|
||||
*
|
||||
* Testul e READ ONLY (doar SELECT) si NU face parte din suita implicita: cere Oracle.
|
||||
* vfp9.exe -A -T "D:\PROIECTE\FLORA\FLORA2ROA\Teste\test_parteneri_roa.prg"
|
||||
|
||||
#INCLUDE "comun.h"
|
||||
|
||||
SET SAFETY OFF
|
||||
SET TALK OFF
|
||||
|
||||
PUBLIC gcUILog, gcSyncDir, gnTestFail, gnMockRaspuns, gcMockUltimMesaj, gnMockUltimTip
|
||||
gnTestFail = 0
|
||||
gnMockRaspuns = 6
|
||||
gcMockUltimMesaj = ''
|
||||
gnMockUltimTip = 0
|
||||
|
||||
LOCAL lcTestDir, lcSqlPart, lnSucces, lnTip, lcCodSalvat, lnIdVechi, lnIdGasit
|
||||
lcTestDir = ADDBS(JUSTPATH(SYS(16, 0)))
|
||||
gcUILog = lcTestDir + 'test_parteneri_roa_log.txt'
|
||||
gcSyncDir = lcTestDir + 'uisync\'
|
||||
IF !DIRECTORY(gcSyncDir)
|
||||
MD (gcSyncDir)
|
||||
ENDIF
|
||||
STRTOFILE('START ' + TTOC(DATETIME()) + CHR(13) + CHR(10), gcUILog)
|
||||
|
||||
SQLSETPROP(0, 'DispLogin', 3)
|
||||
DO (lcTestDir + 'test_init_env_auto.prg') WITH .T.
|
||||
SET PROCEDURE TO (lcTestDir + 'ui_harness.prg') ADDITIVE
|
||||
SET PROCEDURE TO (lcTestDir + 'mock_amessagebox.prg') ADDITIVE
|
||||
DO HarnessInit
|
||||
|
||||
IF TYPE('gnHandle') <> 'N' OR gnHandle <= 0
|
||||
HarnessLog('Fara conexiune la ROA (' + ALLTRIM(goApp.oSettings.host) + '), testul iese controlat.')
|
||||
DO HarnessDone WITH 'SKIP'
|
||||
QUIT
|
||||
ENDIF
|
||||
|
||||
DO FORM (gcAppPath + 'frm_import') NAME goImportFrm NOSHOW
|
||||
goImportFrm.WindowType = 0
|
||||
|
||||
* un CNP care in ROA e pe mai multi parteneri: se ia cel mai vechi
|
||||
LOCAL lcCnpDublat
|
||||
lcCnpDublat = '1951113297313'
|
||||
lnSucces = goExecutor.oExecute(GetHash("cSql=>select min(id_part) as id_part, count(*) as nr from nom_parteneri " + ;
|
||||
"where replace(upper(cod_fiscal), ' ', '') = '" + m.lcCnpDublat + "' and sters = 0??cCursor=>cAsteptat"))
|
||||
TestAssertEqual(CT_SUCCES, m.lnSucces, 'interogare de control executata')
|
||||
lnIdVechi = NVL(cAsteptat.id_part, 0)
|
||||
HarnessLog('CNP ' + m.lcCnpDublat + ': ' + TRANSFORM(cAsteptat.nr) + ' parteneri, cel mai vechi ' + TRANSFORM(m.lnIdVechi))
|
||||
TestAssert(m.lnIdVechi > 0, 'CNP-ul de test exista in ROA')
|
||||
|
||||
* cursorul de cautare, ca in CompleteazaParteneriROA
|
||||
CREATE CURSOR cParteneri (id_part N(10), cod_fiscal C(30) null, denumire C(100) null)
|
||||
lcSqlPart = [select id_part, cod_fiscal, denumire from nom_parteneri where sters = 0 and inactiv = 0]
|
||||
lnSucces = goExecutor.oExecute(GetHash("cSql=>" + m.lcSqlPart + '??cCursor=>cParteneriTemp'))
|
||||
TestAssertEqual(CT_SUCCES, m.lnSucces, 'parteneri ROA cititi')
|
||||
SELECT cParteneri
|
||||
APPEND FROM DBF('cParteneriTemp')
|
||||
INDEX on denumire TAG denumire
|
||||
INDEX on PADR(STRTRAN(cod_fiscal, ' ', ''),30, ' ') TAG cod_fiscal
|
||||
USE IN (SELECT('cParteneriTemp'))
|
||||
|
||||
* randul din Fidelio cu campurile inversate: CNP in 'serie CI / pasaport'
|
||||
lnTip = 0
|
||||
lcCodSalvat = GetCodFiscalValid('PX920016', @lnTip, 'STRATON ADRIAN FLORIN', m.lcCnpDublat, '')
|
||||
TestAssertEqual(m.lcCnpDublat, m.lcCodSalvat, 'CNP-ul din serie CI este codul care se salveaza')
|
||||
|
||||
lnIdGasit = goImportFrm.GetIdPartener(PADR('PX920016', 30, ' '), PADR('STRATON ADRIAN FLORIN', 100, ' '))
|
||||
TestAssertEqual(0, m.lnIdGasit, 'codul brut din import nu gaseste partenerul')
|
||||
|
||||
lnIdGasit = goImportFrm.GetIdPartener(PADR(m.lcCodSalvat, 30, ' '), PADR('STRATON ADRIAN FLORIN', 100, ' '))
|
||||
TestAssertEqual(m.lnIdVechi, m.lnIdGasit, 'codul salvat gaseste partenerul cel mai vechi')
|
||||
|
||||
lnIdGasit = goImportFrm.GetIdPartenerROA(m.lcCodSalvat)
|
||||
TestAssertEqual(m.lnIdVechi, m.lnIdGasit, 'cautarea in ROA da tot partenerul cel mai vechi')
|
||||
|
||||
TestAssertEqual(0, goImportFrm.GetIdPartenerROA(''), 'cod fiscal gol: nu se cauta in ROA')
|
||||
|
||||
goImportFrm.Release()
|
||||
goConn.Disconnect()
|
||||
|
||||
HarnessLog('REZULTAT: ' + TestRezultat())
|
||||
DO HarnessDone WITH TestRezultat()
|
||||
QUIT
|
||||
@@ -1,3 +1,24 @@
|
||||
<!--
|
||||
18/08/2026
|
||||
FLORA2ROA - 2.0.7
|
||||
|
||||
:eroare:
|
||||
Importul nu se mai opreste cand partenerul exista deja in ROA cu acelasi cod fiscal sau CNP:
|
||||
este folosit partenerul cel mai vechi cu acel cod.
|
||||
Partenerii al caror CNP a fost scris in campul de serie CI sunt acum regasiti corect, fara sa mai fie adaugati inca o data.
|
||||
-->
|
||||
|
||||
<!--
|
||||
02/08/2026
|
||||
FLORA2ROA - 2.0.6
|
||||
|
||||
:modificare:
|
||||
Import parteneri. Persoanele fizice cu CNP invalid se salveaza fara CNP, ca sa nu dea eroare la D394/D406.
|
||||
Codul persoanelor juridice nu se mai sterge, ca sa fie semnalat la validarea declaratiei si corectat in Fidelio.
|
||||
Daca CNP-ul a fost scris din greseala in campul de serie CI, este preluat de acolo.
|
||||
In jurnalul de import se scriu CNP-urile curatate si codurile de firma care nu trec validarea.
|
||||
-->
|
||||
|
||||
<!--
|
||||
02/07/2026
|
||||
FLORA2ROA - 2.0.5
|
||||
|
||||
@@ -31,9 +31,17 @@ Specific FLORA2ROA:
|
||||
`settings.ini`, `Trace` scrie in `edtInfo`.
|
||||
- `test_export_date.prg` - functional: `ExportDate()` citeste XML-urile din interval si
|
||||
populeaza cursoarele (fara Oracle).
|
||||
- `test_cod_fiscal.prg` - unitar: clasificarea partenerilor (persoana fizica / juridica) si
|
||||
curatarea CNP-urilor invalide (`GetCodFiscalValid` si functiile ajutatoare din `myutils.prg`).
|
||||
- `test_cod_fiscal_real.prg` - ruleaza aceeasi logica pe TOATE codurile din `EXEMPLE\hotel`
|
||||
si verifica invariantii: nicio persoana juridica nu ramane fara cod, niciun CNP valid nu se
|
||||
pierde. Scrie `Teste\raport_cod_fiscal_real.csv` cu decizia luata pentru fiecare partener.
|
||||
- `test_conectare_roa.prg` - verifica drumul CU conectare la Oracle: fie se conecteaza si
|
||||
executa o interogare de proba, fie raporteaza esecul si iese controlat. NU e in suita
|
||||
implicita (depinde de reteaua/serverul Oracle).
|
||||
- `test_parteneri_roa.prg` - cautarea partenerului la import, pe datele reale din ROA:
|
||||
cautarea se face pe codul cu care partenerul se salveaza, iar cand mai multi parteneri au
|
||||
acelasi cod fiscal se ia cel mai vechi. Doar SELECT-uri, NU e in suita implicita (cere Oracle).
|
||||
|
||||
## Comenzi uzuale
|
||||
|
||||
@@ -66,8 +74,14 @@ powershell -ExecutionPolicy Bypass -File Teste\text_din_bin.ps1 # binar
|
||||
# [IO.File]::WriteAllText($p, $t, [Text.Encoding]::GetEncoding(1252))
|
||||
powershell -ExecutionPolicy Bypass -File Teste\bin_din_text.ps1 -TextFile _textcache\frm_import.sc2 -DryRun
|
||||
powershell -ExecutionPolicy Bypass -File Teste\bin_din_text.ps1 -TextFile _textcache\frm_import.sc2
|
||||
powershell -ExecutionPolicy Bypass -File Teste\recompileaza_binare.ps1 # OBLIGATORIU dupa write-back
|
||||
```
|
||||
|
||||
> **Write-back-ul NU compileaza.** FoxBin2Prg reface `.scx`/`.sct` din text, dar fara codul
|
||||
> obiect, deci formularul ruleaza fara `#INCLUDE "comun.h"`: constantele (`CT_SUCCES`,
|
||||
> `CT_INSUCCES`) devin *"Variable not found"* abia in RUNTIME. Verificarea de sintaxa trece,
|
||||
> testul pica. `Teste\recompileaza_binare.ps1` face `COMPILE FORM` si repara asta.
|
||||
|
||||
Write-back-ul face fidelity check (bin -> text, comparat pe octeti) inainte de a atinge
|
||||
binarul si refuza daca `frm_import.scx` e blocat de IDE sau de `flora2roa.exe`.
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
2.0.3
|
||||
2.0.7
|
||||
168
frm_import.sc2
168
frm_import.sc2
@@ -47,6 +47,8 @@ DEFINE CLASS form1 AS form
|
||||
*m: disconnectmentor
|
||||
*m: disconnectroa
|
||||
*m: exportdate
|
||||
*m: getidpartener
|
||||
*m: getidpartenerroa
|
||||
*m: scrienote
|
||||
*m: sql_temp_insert
|
||||
*m: sterge_import
|
||||
@@ -73,6 +75,8 @@ DEFINE CLASS form1 AS form
|
||||
<memberdata name="nhandlementor" display="nHandleMentor"/>
|
||||
<memberdata name="disconnectmentor" display="DisconnectMentor"/>
|
||||
<memberdata name="completeazaparteneriroa" display="CompleteazaParteneriROA"/>
|
||||
<memberdata name="getidpartener" display="GetIdPartener"/>
|
||||
<memberdata name="getidpartenerroa" display="GetIdPartenerROA"/>
|
||||
</VFPData>
|
||||
*</PropValue>
|
||||
|
||||
@@ -272,13 +276,13 @@ DEFINE CLASS form1 AS form
|
||||
* Completez id_part
|
||||
Local lcBanca, lcCod_fiscal, lcCont_Banca, lcCorespDel, lcDenumire, lcIdString, lcId_categ_ent
|
||||
Local lcId_loc_inreg, lcId_util, lcMesaj, lcMotiv_inactiv, lcNume, lcPrefix, lcPrenume, lcReg_comert
|
||||
Local lcSql, lcSqlInsert, lcSufix, lcTip_persoana, lcinactiv, lnSucces
|
||||
Local lcSql, lcSqlInsert, lcSufix, lcTip_persoana, lcinactiv, lnSucces, lnTip_persoana, lcCodTara
|
||||
Local lcAdresa, lcAdreseParteneri, lcApart, lcBloc, lcCaleImport, lcCod, lcCodpostal, lcDA_apare
|
||||
Local lcDenumire_adresa, lcEmail, lcEtaj, lcFax, lcFile, lcIdPart, lcId_Judet, lcId_loc, lcId_tara
|
||||
Local lcItem1, lcItem2, lcItem3, lcItem4, lcJudet, lcJudetBucuresti, lcLocalitate, lcNumar
|
||||
Local lcPrincipala, lcScara, lcSqlJudete, lcSqlLocalitati, lcSqlPart, lcStrada, lcTelefon1
|
||||
Local lcTelefon2, lcWeb, lnIdJudet, lnIdJudetBucuresti, lnIdLocalitateBucuresti, lnIdTaraRO, lnPos
|
||||
Local lnRecc
|
||||
Local lnRecc, lcCodBrut
|
||||
*:Global pcDenumire, pnIdAdresa, pnNrAdrese
|
||||
|
||||
*:Global pcCodFiscal, pnIdPart
|
||||
@@ -353,12 +357,8 @@ DEFINE CLASS form1 AS form
|
||||
lnRecc = RECCOUNT()
|
||||
Scan
|
||||
pnIdPart = 0
|
||||
pcCodFiscal = PADR(STRTRAN(cod_fiscal, ' ', ''),30, ' ')
|
||||
pcDenumire = PADR(Alltrim(Upper(denumire)), 100, ' ')
|
||||
lcAdresa = Strtran(Alltrim(Upper(Nvl(adresa, ''))), Chr(13), ' ')
|
||||
IF LEN(ALLTRIM(m.pcCodFiscal)) <= 3
|
||||
pcCodFiscal = PADL(ALLTRIM(cod), 10, '0')
|
||||
ENDIF
|
||||
|
||||
lcCod = cod
|
||||
IF MOD(RECNO(), 250) = 0
|
||||
@@ -375,23 +375,6 @@ DEFINE CLASS form1 AS form
|
||||
|
||||
|
||||
|
||||
SELECT cParteneri
|
||||
DO CASE
|
||||
CASE !Empty(m.pcCodFiscal)
|
||||
IF SEEK(m.pcCodFiscal, 'cParteneri', 'cod_fiscal')
|
||||
pnIdPart = cParteneri.id_part
|
||||
ENDIF
|
||||
OTHERWISE
|
||||
IF SEEK(m.pcDenumire, 'cParteneri', 'denumire')
|
||||
pnIdPart = cParteneri.id_part
|
||||
ENDIF
|
||||
ENDCASE
|
||||
If !Empty(Nvl(m.pnIdPart, 0))
|
||||
Replace id_part With m.pnIdPart In cClientiFurnizori
|
||||
*!* lcMesaj = 'Client existent ' + Alltrim(cParteneri.denumire) + ' CUI: ' + Alltrim(cParteneri.cod_fiscal) + ' ID: ' + Alltrim(Transform(cParteneri.id_part))
|
||||
*!* Thisform.trace(m.lcMesaj)
|
||||
Else
|
||||
* Adaugare clienti
|
||||
Select cClientiFurnizori
|
||||
lcDenumire = Nvl(Strtran(Alltrim(Upper(denumire)), ['], ['']), "")
|
||||
lcNume = Nvl(Strtran(Alltrim(Upper(denumire)), ['], ['']), "")
|
||||
@@ -399,31 +382,28 @@ DEFINE CLASS form1 AS form
|
||||
lcCod_fiscal = Upper(Alltrim(cod_fiscal))
|
||||
lcReg_comert = Nvl(Alltrim(Upper(reg_com)), "")
|
||||
***************************
|
||||
lcCod=Alltrim(Upper(Nvl(m.lcCod_fiscal,"")))
|
||||
lcTip_persoana="2" && 1 = juridica, 2 = fizica
|
||||
* Prefer persoanele fizice pentru ca sunt mai multe fata de persoanele juridice
|
||||
* Sunt multe persoane fizice cu CNP-uri gresite
|
||||
If !Empty(m.lcCod)
|
||||
If Left(lcCod,2)="RO"
|
||||
lcCod=Substr(m.lcCod,3)
|
||||
lcTip_persoana="1"
|
||||
ENDIF
|
||||
IF ISALPHA(m.lcCod)
|
||||
lcTip_persoana="1"
|
||||
ENDIF
|
||||
lcCodBrut = Alltrim(Upper(Nvl(m.lcCod_fiscal,"")))
|
||||
lcTip_persoana = "2" && 1 = juridica, 2 = fizica
|
||||
* GetCodFiscalValid decide tipul de persoana din denumire, nr. registrul comertului si
|
||||
* forma codului, apoi curata DOAR CNP-urile invalide ale persoanelor fizice.
|
||||
* Codul unei persoane juridice nu se sterge niciodata: daca e gresit, vrem sa fim
|
||||
* atentionati la validarea declaratiei si sa il corectam in Fidelio, nu sa il ascundem.
|
||||
If !Empty(m.lcCodBrut)
|
||||
lnTip_persoana = 0
|
||||
lcCodTara = Alltrim(Upper(Nvl(cod_tara, "")))
|
||||
lcCod_fiscal = GetCodFiscalValid(m.lcCodBrut, @lnTip_persoana, m.lcDenumire, m.lcReg_comert, m.lcCodTara)
|
||||
lcTip_persoana = Iif(m.lnTip_persoana = 1, "1", "2")
|
||||
|
||||
If Len(m.lcCod)=13 And Isdigit(m.lcCod)
|
||||
If !cValidCNP(m.lcCod)
|
||||
* daca CNP invalid, sterg CNP, sa nu dea eroare la D406
|
||||
lcCod_fiscal = ''
|
||||
Endif
|
||||
ELSE
|
||||
* PJ din ROMANIA au coduri fiscale intre 2-10 cifre
|
||||
* Exista si PJ din alte tari care pot avea coduri fiscale cu alt numar de cifre, dar sunt exceptii
|
||||
If Len(m.lcCod)>=2 And Len(m.lcCod)<=10 And Isdigit(m.lcCod)
|
||||
lcTip_persoana="1"
|
||||
Endif
|
||||
Endif
|
||||
Do Case
|
||||
Case m.lcTip_persoana = "2" And Empty(m.lcCod_fiscal)
|
||||
* persoana fizica cu CNP invalid: se salveaza fara CNP (permis la D394/D406)
|
||||
Thisform.trace('CNP invalid, partenerul se salveaza fara CNP: [' + m.lcCodBrut + '] ' + Alltrim(m.lcDenumire))
|
||||
Case m.lcTip_persoana = "1" And !VerifCF(m.lcCod_fiscal)
|
||||
* persoana juridica cu cod fiscal care nu trece validarea romaneasca: poate fi
|
||||
* partener strain (cod valid la el in tara) sau o eroare de operare. Codul ramane,
|
||||
* dar il semnalam in log ca sa poata fi verificat.
|
||||
Thisform.trace('ATENTIE: persoana juridica cu cod fiscal nevalidat: [' + m.lcCod_fiscal + '] ' + Alltrim(m.lcDenumire))
|
||||
Endcase
|
||||
ENDIF
|
||||
IF m.lcTip_Persoana = "2"
|
||||
lnPos = At(' ', m.lcNume)
|
||||
@@ -434,6 +414,24 @@ DEFINE CLASS form1 AS form
|
||||
ENDIF
|
||||
***************************
|
||||
|
||||
* Cautarea se face pe codul cu care partenerul se salveaza in ROA, nu pe cel din import:
|
||||
* GetCodFiscalValid poate lua CNP-ul din campul de serie CI / pasaport.
|
||||
pcCodFiscal = PADR(STRTRAN(m.lcCod_fiscal, ' ', ''), 30, ' ')
|
||||
IF LEN(ALLTRIM(m.pcCodFiscal)) <= 3
|
||||
pcCodFiscal = PADR(STRTRAN(m.lcCodBrut, ' ', ''), 30, ' ')
|
||||
ENDIF
|
||||
IF LEN(ALLTRIM(m.pcCodFiscal)) <= 3
|
||||
pcCodFiscal = PADL(ALLTRIM(cod), 10, '0')
|
||||
ENDIF
|
||||
|
||||
pnIdPart = Thisform.GetIdPartener(m.pcCodFiscal, m.pcDenumire)
|
||||
If !Empty(Nvl(m.pnIdPart, 0))
|
||||
Replace id_part With m.pnIdPart In cClientiFurnizori
|
||||
*!* lcMesaj = 'Client existent ' + Alltrim(cParteneri.denumire) + ' CUI: ' + Alltrim(cParteneri.cod_fiscal) + ' ID: ' + Alltrim(Transform(cParteneri.id_part))
|
||||
*!* Thisform.trace(m.lcMesaj)
|
||||
Else
|
||||
* Adaugare clienti
|
||||
|
||||
lcId_loc_inreg = 'NULL'
|
||||
lcId_categ_ent = 'NULL'
|
||||
lcPrefix = ""
|
||||
@@ -454,15 +452,25 @@ DEFINE CLASS form1 AS form
|
||||
lnSucces = goExecutor.oExecute(GetHash("cSql=>" + m.lcSqlInsert))
|
||||
If !Empty(Nvl(m.pnIdPart, 0))
|
||||
Replace id_part With m.pnIdPart In cClientiFurnizori
|
||||
Thisform.trace('Client nou ' + Alltrim(cClientiFurnizori.denumire) + ' CUI: ' + Alltrim(cClientiFurnizori.cod_fiscal) + ' ID: ' + Alltrim(Transform(cClientiFurnizori.id_part)))
|
||||
INSERT INTO cParteneri (id_part, denumire, cod_fiscal) VALUES (m.pnIdPart, cClientiFurnizori.denumire, cClientiFurnizori.cod_fiscal)
|
||||
Thisform.trace('Client nou ' + Alltrim(m.lcDenumire) + ' CUI: ' + Alltrim(m.lcCod_fiscal) + ' ID: ' + Alltrim(Transform(m.pnIdPart)))
|
||||
INSERT INTO cParteneri (id_part, denumire, cod_fiscal) VALUES (m.pnIdPart, m.pcDenumire, m.pcCodFiscal)
|
||||
Else
|
||||
lcMesaj = 'Eroare la adaugarea in clienti ROA ' + Alltrim(cParteneri.denumire) + ' CUI: ' + Alltrim(cParteneri.cod_fiscal) + Chr(13) + Chr(10) + goExecutor.oPrelucrareEroare()
|
||||
|
||||
* Codul fiscal exista deja in ROA, uneori pe mai multi parteneri: se preia cel mai vechi si
|
||||
* importul continua. Doar daca nici asa nu se gaseste partenerul, importul se opreste.
|
||||
lcMesaj = goExecutor.oPrelucrareEroare()
|
||||
pnIdPart = Thisform.GetIdPartenerROA(m.lcCod_fiscal)
|
||||
If !Empty(Nvl(m.pnIdPart, 0))
|
||||
Replace id_part With m.pnIdPart In cClientiFurnizori
|
||||
INSERT INTO cParteneri (id_part, denumire, cod_fiscal) VALUES (m.pnIdPart, m.pcDenumire, m.pcCodFiscal)
|
||||
Thisform.trace('Partener existent in ROA ' + Alltrim(m.lcDenumire) + ' CUI: ' + Alltrim(m.lcCod_fiscal) + ;
|
||||
' ID: ' + Alltrim(Transform(m.pnIdPart)) + ' (' + Alltrim(m.lcMesaj) + ')')
|
||||
Else
|
||||
lcMesaj = 'Eroare la adaugarea in clienti ROA ' + Alltrim(m.lcDenumire) + ' CUI: ' + ;
|
||||
Alltrim(m.lcCod_fiscal) + Chr(13) + Chr(10) + m.lcMesaj
|
||||
Thisform.trace(m.lcMesaj)
|
||||
aMessagebox(m.lcMesaj)
|
||||
SET STEP ON
|
||||
Exit
|
||||
Endif
|
||||
Endif && !Empty(Nvl(m.pnIdPart,0))
|
||||
Endif && !Empty(Nvl(m.pnIdPart,0))
|
||||
|
||||
@@ -1748,6 +1756,62 @@ DEFINE CLASS form1 AS form
|
||||
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE getidpartener
|
||||
* Cauta partenerul in cursorul cParteneri, intai dupa cod fiscal, apoi dupa denumire.
|
||||
* Cand mai multi parteneri au acelasi cod fiscal, il intoarce pe cel mai vechi (id_part minim).
|
||||
Lparameters tcCodFiscal, tcDenumire
|
||||
Local lcCheie, lnArie, lnIdPart
|
||||
|
||||
lnIdPart = 0
|
||||
lnArie = Select()
|
||||
If !Empty(m.tcCodFiscal)
|
||||
lcCheie = Padr(Strtran(Upper(Alltrim(m.tcCodFiscal)), ' ', ''), 30, ' ')
|
||||
Select cParteneri
|
||||
Set Order To Tag cod_fiscal
|
||||
If Seek(m.lcCheie, 'cParteneri', 'cod_fiscal')
|
||||
Scan Rest While Padr(Strtran(cod_fiscal, ' ', ''), 30, ' ') == m.lcCheie
|
||||
If m.lnIdPart = 0 Or cParteneri.id_part < m.lnIdPart
|
||||
lnIdPart = cParteneri.id_part
|
||||
Endif
|
||||
Endscan
|
||||
Endif
|
||||
Endif
|
||||
If Empty(m.tcCodFiscal) And !Empty(m.tcDenumire)
|
||||
Select cParteneri
|
||||
Set Order To Tag denumire
|
||||
If Seek(Padr(Alltrim(Upper(m.tcDenumire)), 100, ' '), 'cParteneri', 'denumire')
|
||||
lnIdPart = cParteneri.id_part
|
||||
Endif
|
||||
Endif
|
||||
Select (m.lnArie)
|
||||
|
||||
Return m.lnIdPart
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE getidpartenerroa
|
||||
* Intoarce cel mai vechi partener nesters din ROA cu acest cod fiscal (id_part minim), 0 daca nu exista.
|
||||
Lparameters tcCodFiscal
|
||||
Local lcCod, lcSql, lnArie, lnIdPart, lnSucces
|
||||
|
||||
lnIdPart = 0
|
||||
lcCod = Strtran(Upper(Alltrim(Nvl(m.tcCodFiscal, ''))), ' ', '')
|
||||
If Empty(m.lcCod)
|
||||
Return 0
|
||||
Endif
|
||||
|
||||
lnArie = Select()
|
||||
lcSql = [select min(id_part) as id_part from nom_parteneri where replace(upper(cod_fiscal), ' ', '') = '] + ;
|
||||
m.lcCod + [' and sters = 0]
|
||||
lnSucces = goExecutor.oExecute(GetHash("cSql=>" + m.lcSql + '??cCursor=>cPartExistent'))
|
||||
If m.lnSucces >= 0 And Used('cPartExistent')
|
||||
lnIdPart = Nvl(cPartExistent.id_part, 0)
|
||||
Use In (Select('cPartExistent'))
|
||||
Endif
|
||||
Select (m.lnArie)
|
||||
|
||||
Return m.lnIdPart
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE Init
|
||||
Local ldData1, ldData2, ldLastDay, lnHeight, lnWidth
|
||||
|
||||
|
||||
265
myutils.prg
265
myutils.prg
@@ -1664,6 +1664,25 @@ FUNCTION GetDataCNP
|
||||
RETURN CTOD(SUBSTR(plcnp, 6, 2) + "." + SUBSTR(plcnp, 4, 2) + "." + mlan)
|
||||
ENDFUNC
|
||||
*
|
||||
*
|
||||
* Copiata din D:\ROA\ROACONT\COMUN\programe\oproceduri_comune.prg (GetNrFromString),
|
||||
* ca sa nu duplic logica: taie de la inceputul sirului literele si separatorii,
|
||||
* pana la prima cifra. Ex. 'RO 15613488' -> '15613488', 'CUI 14770212' -> '14770212'.
|
||||
FUNCTION GetNrFromString
|
||||
LPARAMETERS plstr
|
||||
LOCAL mlenstr
|
||||
mlenstr = LEN(ALLTRIM(plstr))
|
||||
|
||||
DO WHILE ISALPHA(plstr) .OR. LEFT(plstr, 1) == " ";
|
||||
.OR. LEFT(plstr, 1) == "&" .OR. LEFT(plstr, 1) == "/";
|
||||
.OR. LEFT(plstr, 1) == "-" .OR. LEFT(plstr, 1) == "_";
|
||||
.OR. LEFT(plstr, 1) == "." .OR. LEFT(plstr, 1) == ":"
|
||||
plstr = RTRIM(SUBSTR(plstr, 2, mlenstr))
|
||||
ENDDO
|
||||
|
||||
RETURN plstr
|
||||
ENDFUNC
|
||||
*
|
||||
FUNCTION VerifCF
|
||||
LPARAMETERS plcfisc
|
||||
LOCAL mlsuma, mlrest
|
||||
@@ -1705,3 +1724,249 @@ FUNCTION GetCodFiscalFRO
|
||||
RETURN m.lcCodFiscalFRO
|
||||
ENDFUNC
|
||||
*
|
||||
* Clasifica partenerul importat (Fidelio hotel, BIZ restaurant) in persoana fizica / juridica
|
||||
* si curata DOAR CNP-urile invalide.
|
||||
*
|
||||
* De ce asa:
|
||||
* - la declaratii (D394/D406) o PERSOANA FIZICA poate fi raportata FARA CNP, deci un CNP
|
||||
* invalid se poate goli fara sa pierdem nimic si fara sa dea eroare de validare;
|
||||
* - o PERSOANA JURIDICA trebuie sa aiba cod fiscal, deci codul ei NU se sterge niciodata:
|
||||
* daca e gresit, ramane asa ca sa fie semnalat la validarea declaratiei si sa fie corectat
|
||||
* la sursa (in Fidelio), nu ascuns aici.
|
||||
*
|
||||
* De ce NU ne putem baza pe validarea romaneasca ca sa decidem tipul:
|
||||
* codurile straine pot fi si numai cifre (fara prefix de tara), deci un cod numeric care nu
|
||||
* trece algoritmul romanesc NU inseamna automat "gresit". Tipul se decide din alte semnale,
|
||||
* in ordinea increderii:
|
||||
* 1. tcTipCunoscut - tip venit din import, daca sistemul sursa il stie (cel mai sigur)
|
||||
* 2. prefix de tara pe cod (RO/BE/DE...) sau litere in cod => persoana juridica
|
||||
* 3. denumire cu forma juridica (SRL, SA, PFA, ASOCIATIA...) => persoana juridica
|
||||
* 4. numar de registrul comertului in tcRegCom (J40/1234/2018, L2019...) => juridica
|
||||
* serie+numar de CI (2 litere + 6 cifre) => fizica
|
||||
* 5. CNP valid pe 13 cifre => fizica; CUI romanesc valid => juridica
|
||||
* 6. altfel => fizica (majoritatea covarsitoare a clientilor de hotel)
|
||||
*
|
||||
* Parametri:
|
||||
* tcCod - codul brut din import (CODFISCAL_CNP)
|
||||
* tnTipPersoana - IESIRE prin referinta: 1 = juridica, 2 = fizica
|
||||
* tcDenumire - optional, denumirea partenerului (pentru forma juridica)
|
||||
* tcRegCom - optional, REGCOMERT_CI_PASS (nr. registrul comertului sau serie CI)
|
||||
* tcCodTara - optional, codul/denumirea tarii daca importul o stie
|
||||
* tcTipCunoscut - optional, tipul deja stiut din import: '1'/'PJ' sau '2'/'PF'
|
||||
*
|
||||
* Intoarce: codul de pastrat in ROA. Sir GOL doar cand este persoana fizica cu CNP invalid.
|
||||
FUNCTION GetCodFiscalValid
|
||||
LPARAMETERS tcCod, tnTipPersoana, tcDenumire, tcRegCom, tcCodTara, tcTipCunoscut
|
||||
|
||||
LOCAL lcCod, lcBrut, lcCifre, lcCifreReg, lcPrefix, lcPrefixBrut, lcTara, lcTip
|
||||
LOCAL llLitere, llPrefixFiscal, lnParam
|
||||
lnParam = PCOUNT()
|
||||
|
||||
lcCod = GetCodFiscalCurat(m.tcCod)
|
||||
lcCifre = CHRTRAN(m.lcCod, CHRTRAN(m.lcCod, '0123456789', ''), '')
|
||||
lcPrefix = ALLTRIM(CHRTRAN(m.lcCod, CHRTRAN(m.lcCod, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', ''), ''))
|
||||
llLitere = !EMPTY(m.lcPrefix)
|
||||
|
||||
* Eticheta din codul BRUT ('CUI 14770212') e semnal de persoana juridica, chiar daca
|
||||
* GetCodFiscalCurat o scoate din codul salvat. 'RO' se pastreaza in cod pentru ca inseamna
|
||||
* platitor de TVA, iar in ROA acela e alt partener decat neplatitorul cu acelasi numar.
|
||||
lcBrut = ALLTRIM(UPPER(TRANSFORM(NVL(m.tcCod, ''))))
|
||||
lcPrefixBrut = ALLTRIM(CHRTRAN(m.lcBrut, CHRTRAN(m.lcBrut, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', ''), ''))
|
||||
llPrefixFiscal = INLIST(m.lcPrefixBrut, 'RO', 'CUI', 'CF', 'CIF')
|
||||
|
||||
lcTara = IIF(m.lnParam > 4 AND VARTYPE(m.tcCodTara) = 'C', ALLTRIM(UPPER(m.tcCodTara)), '')
|
||||
lcTip = IIF(m.lnParam > 5 AND VARTYPE(m.tcTipCunoscut) = 'C', ALLTRIM(UPPER(m.tcTipCunoscut)), '')
|
||||
|
||||
DO CASE
|
||||
CASE INLIST(m.lcTip, '1', 'PJ', 'J')
|
||||
tnTipPersoana = 1
|
||||
CASE INLIST(m.lcTip, '2', 'PF', 'F')
|
||||
tnTipPersoana = 2
|
||||
CASE m.llPrefixFiscal
|
||||
* eticheta romaneasca de cod fiscal (RO/CUI/CF/CIF) => persoana juridica
|
||||
tnTipPersoana = 1
|
||||
CASE !EMPTY(m.lcTara) AND !INLIST(m.lcTara, 'RO', 'ROU', 'ROMANIA')
|
||||
* tara straina declarata: nu putem valida romaneste, tratam ca juridica
|
||||
tnTipPersoana = 1
|
||||
CASE EstePersoanaJuridica(m.tcDenumire)
|
||||
tnTipPersoana = 1
|
||||
CASE EsteNrRegComert(m.tcRegCom)
|
||||
tnTipPersoana = 1
|
||||
CASE LEN(m.lcCifre) = 13 AND cValidCNP(m.lcCifre)
|
||||
tnTipPersoana = 2
|
||||
CASE EsteSerieCI(m.tcRegCom)
|
||||
tnTipPersoana = 2
|
||||
CASE m.llLitere
|
||||
* cod cu litere fara alt semnal: TVA intracomunitar (BE0325777171) daca incepe cu
|
||||
* un cod de tara UE, altfel e cel mai probabil pasaport de persoana fizica
|
||||
tnTipPersoana = IIF(EsteCodTVAStrain(m.lcCod), 1, 2)
|
||||
CASE BETWEEN(LEN(m.lcCifre), 2, 10) AND VerifCF(m.lcCifre)
|
||||
tnTipPersoana = 1
|
||||
OTHERWISE
|
||||
* clientii de hotel sunt in marea lor majoritate persoane fizice
|
||||
tnTipPersoana = 2
|
||||
ENDCASE
|
||||
|
||||
IF m.tnTipPersoana = 1
|
||||
* persoana juridica: codul NU se sterge niciodata, chiar daca nu trece validarea.
|
||||
* Vrem sa fim atentionati la declaratie, nu sa ascundem problema.
|
||||
RETURN m.lcCod
|
||||
ENDIF
|
||||
|
||||
* persoana fizica: pastram CNP-ul doar daca este valid, altfel gol (permis la declaratii).
|
||||
* Pasapoartele si seriile de CI nu sunt CNP-uri, deci nu se salveaza pe cod fiscal.
|
||||
IF LEN(m.lcCifre) = 13 AND cValidCNP(m.lcCifre)
|
||||
RETURN m.lcCifre
|
||||
ENDIF
|
||||
|
||||
* recuperare: in Fidelio se intampla ca operatorul sa inverseze campurile si sa scrie CNP-ul
|
||||
* in 'serie CI / pasaport'. Daca acolo gasim un CNP valid, il folosim pe acela.
|
||||
lcCifreReg = GetCodFiscalCurat(m.tcRegCom)
|
||||
lcCifreReg = CHRTRAN(m.lcCifreReg, CHRTRAN(m.lcCifreReg, '0123456789', ''), '')
|
||||
IF LEN(m.lcCifreReg) = 13 AND cValidCNP(m.lcCifreReg)
|
||||
RETURN m.lcCifreReg
|
||||
ENDIF
|
||||
|
||||
RETURN ''
|
||||
ENDFUNC
|
||||
*
|
||||
* .T. daca sirul arata a cod de TVA intracomunitar: 2 litere = cod de tara UE, urmate de cifre.
|
||||
* Ex: 'BE0325777171', 'DE811234567', 'HU12345678'. NU include 'RO' (tratat separat).
|
||||
FUNCTION EsteCodTVAStrain
|
||||
LPARAMETERS tcCod
|
||||
|
||||
LOCAL lcCod, lcTari, lcTara, lcRest
|
||||
lcCod = ALLTRIM(UPPER(TRANSFORM(NVL(m.tcCod, ''))))
|
||||
lcCod = CHRTRAN(m.lcCod, ' .-', '')
|
||||
IF LEN(m.lcCod) < 6
|
||||
RETURN .F.
|
||||
ENDIF
|
||||
|
||||
* coduri de tara UE + cateva uzuale in turism
|
||||
lcTari = ' AT BE BG CY CZ DE DK EE EL ES FI FR GR HR HU IE IT LT LU LV MT NL PL PT SE SI SK ' + ;
|
||||
' GB CH NO MD UA RS TR US '
|
||||
|
||||
lcTara = LEFT(m.lcCod, 2)
|
||||
IF !(' ' + m.lcTara + ' ' $ m.lcTari)
|
||||
RETURN .F.
|
||||
ENDIF
|
||||
|
||||
* dupa codul de tara trebuie sa urmeze numai cifre
|
||||
lcRest = SUBSTR(m.lcCod, 3)
|
||||
RETURN LEN(CHRTRAN(m.lcRest, CHRTRAN(m.lcRest, '0123456789', ''), '')) = LEN(m.lcRest)
|
||||
ENDFUNC
|
||||
*
|
||||
* Curata un cod fiscal / CNP de spatii, puncte si separatori redundanti, pastrand literele
|
||||
* semnificative.
|
||||
* 'RO 23565004' -> 'RO23565004'
|
||||
* 'CUI 14770212' -> '14770212'
|
||||
* '2920121295914.' -> '2920121295914'
|
||||
*
|
||||
* ATENTIE: prefixul 'RO' NU se adauga niciodata de la noi. In ROA, 'RO12345678' (platitor de
|
||||
* TVA) si '12345678' (neplatitor) sunt DOI parteneri diferiti, deci prefixul se pastreaza
|
||||
* exact cum a venit din import. Etichetele 'CUI'/'CF'/'CIF' sunt doar text descriptiv, nu
|
||||
* atribut fiscal, deci se sterg fara sa fie inlocuite cu 'RO'.
|
||||
FUNCTION GetCodFiscalCurat
|
||||
LPARAMETERS tcCod
|
||||
|
||||
LOCAL lcCod, lcCifre, lcPrefix
|
||||
lcCod = ALLTRIM(UPPER(TRANSFORM(NVL(m.tcCod, ''))))
|
||||
lcCod = CHRTRAN(m.lcCod, CHR(9) + CHR(13) + CHR(10), ' ')
|
||||
* scot spatiile si punctele; liniuta si slash-ul pot face parte din coduri straine
|
||||
lcCod = ALLTRIM(CHRTRAN(m.lcCod, ' .', ''))
|
||||
|
||||
* 'CUI 14770212' -> '14770212': eticheta nu spune nimic despre calitatea de platitor de TVA
|
||||
lcPrefix = ALLTRIM(CHRTRAN(m.lcCod, CHRTRAN(m.lcCod, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', ''), ''))
|
||||
IF INLIST(m.lcPrefix, 'CUI', 'CF', 'CIF')
|
||||
lcCifre = CHRTRAN(m.lcCod, CHRTRAN(m.lcCod, '0123456789', ''), '')
|
||||
IF !EMPTY(m.lcCifre)
|
||||
lcCod = m.lcCifre
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
RETURN m.lcCod
|
||||
ENDFUNC
|
||||
*
|
||||
* .T. daca denumirea contine o forma juridica (SRL, SA, PFA, ASOCIATIA, LTD, GMBH...).
|
||||
* Compara pe cuvinte intregi, ca sa nu ia 'SA' din 'SAVU' sau 'II' din 'MIHAII'.
|
||||
FUNCTION EstePersoanaJuridica
|
||||
LPARAMETERS tcDenumire
|
||||
|
||||
LOCAL lcDen, lcForme, lcCuv, lnI, lnCuvinte
|
||||
lcDen = ALLTRIM(UPPER(TRANSFORM(NVL(m.tcDenumire, ''))))
|
||||
IF EMPTY(m.lcDen)
|
||||
RETURN .F.
|
||||
ENDIF
|
||||
|
||||
* separatorii devin spatii, ca sa pot compara cuvant cu cuvant
|
||||
lcDen = CHRTRAN(m.lcDen, '.,-/()"' + CHR(9), ' ')
|
||||
|
||||
lcForme = ' SRL SA SC SNC SCS SCA PFA II IF SRLD RA RL ' + ;
|
||||
' ASOCIATIA ASOCIATIE FUNDATIA FUNDATIE SOCIETATEA COOPERATIVA CABINET ' + ;
|
||||
' PRIMARIA MINISTERUL AGENTIA INSTITUTUL SPITALUL SCOALA LICEUL COLEGIUL ' + ;
|
||||
' UNIVERSITATEA UNIVERSITE UNIVERSITY UNIVERSITAT INSPECTORATUL DIRECTIA ' + ;
|
||||
' LTD LIMITED GMBH AG BV NV INC LLC PLC CORP CORPORATION COMPANY HOLDING KFT SPZOO OOD '
|
||||
|
||||
lnCuvinte = GETWORDCOUNT(m.lcDen, ' ')
|
||||
FOR lnI = 1 TO m.lnCuvinte
|
||||
lcCuv = ALLTRIM(GETWORDNUM(m.lcDen, m.lnI, ' '))
|
||||
IF !EMPTY(m.lcCuv) AND (' ' + m.lcCuv + ' ') $ m.lcForme
|
||||
RETURN .T.
|
||||
ENDIF
|
||||
ENDFOR
|
||||
|
||||
RETURN .F.
|
||||
ENDFUNC
|
||||
*
|
||||
* .T. daca sirul arata a numar de inregistrare la Registrul Comertului.
|
||||
* Forme acceptate: 'J40/1234/2018', 'F13/45/2005', 'C23/9/2019', 'L2019000159348', '54/1997'
|
||||
FUNCTION EsteNrRegComert
|
||||
LPARAMETERS tcRegCom
|
||||
|
||||
LOCAL lcReg, lcRest
|
||||
lcReg = ALLTRIM(UPPER(TRANSFORM(NVL(m.tcRegCom, ''))))
|
||||
lcReg = CHRTRAN(m.lcReg, ' ', '')
|
||||
IF EMPTY(m.lcReg)
|
||||
RETURN .F.
|
||||
ENDIF
|
||||
|
||||
* J40/1234/2018 - litera + cifre + doua slash-uri
|
||||
IF INLIST(LEFT(m.lcReg, 1), 'J', 'F', 'C') AND OCCURS('/', m.lcReg) = 2 AND ;
|
||||
ISDIGIT(SUBSTR(m.lcReg, 2, 1))
|
||||
RETURN .T.
|
||||
ENDIF
|
||||
|
||||
* L2019000159348 / J2018000211289 - litera urmata de minim 10 cifre
|
||||
IF INLIST(LEFT(m.lcReg, 1), 'J', 'L') AND LEN(m.lcReg) >= 11
|
||||
lcRest = SUBSTR(m.lcReg, 2)
|
||||
IF ISDIGIT(m.lcRest) AND LEN(CHRTRAN(m.lcRest, CHRTRAN(m.lcRest, '0123456789', ''), '')) = LEN(m.lcRest)
|
||||
RETURN .T.
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
* 54/1997 - numar/an, tipic institutiilor publice
|
||||
IF OCCURS('/', m.lcReg) = 1 AND LEN(m.lcReg) <= 8 AND ;
|
||||
ISDIGIT(m.lcReg) AND LEN(GETWORDNUM(m.lcReg, 2, '/')) = 4
|
||||
RETURN .T.
|
||||
ENDIF
|
||||
|
||||
RETURN .F.
|
||||
ENDFUNC
|
||||
*
|
||||
* .T. daca sirul arata a serie + numar de carte de identitate: 2 litere urmate de 6 cifre.
|
||||
* Ex: 'ZV 093375', 'IF834409', 'RK 340434'
|
||||
FUNCTION EsteSerieCI
|
||||
LPARAMETERS tcRegCom
|
||||
|
||||
LOCAL lcReg
|
||||
lcReg = ALLTRIM(UPPER(TRANSFORM(NVL(m.tcRegCom, ''))))
|
||||
lcReg = CHRTRAN(m.lcReg, ' -.', '')
|
||||
IF LEN(m.lcReg) <> 8
|
||||
RETURN .F.
|
||||
ENDIF
|
||||
|
||||
RETURN ISALPHA(LEFT(m.lcReg, 1)) AND ISALPHA(SUBSTR(m.lcReg, 2, 1)) AND ;
|
||||
ISDIGIT(SUBSTR(m.lcReg, 3, 1)) AND ;
|
||||
LEN(CHRTRAN(SUBSTR(m.lcReg, 3), CHRTRAN(SUBSTR(m.lcReg, 3), '0123456789', ''), '')) = 6
|
||||
ENDFUNC
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user