From a19651c02902a5a949ed44671eaf7ee584d6a333 Mon Sep 17 00:00:00 2001 From: Marius Mutu Date: Wed, 24 Jun 2026 11:19:07 +0300 Subject: [PATCH] Documentatie date facturare pentru modernizare RoRIS Specificatie minima cu datele de care depinde facturarea ROA, pentru caietul de sarcini al modernizarii RoRIS. Include: - DOCUMENTATIE_DATE_FACTURARE_RORIS.md/.docx (livrabil) - dictionar_date_facturare.csv (anexa tehnica) - PACK_ACN_IMPORT.pck (sursa analizata) - CLAUDE.md (context) Co-Authored-By: Claude Opus 4.8 (1M context) --- .gitignore | 7 + CLAUDE.md | 84 ++++ DOCUMENTATIE_DATE_FACTURARE_RORIS.docx | Bin 0 -> 25921 bytes DOCUMENTATIE_DATE_FACTURARE_RORIS.md | 160 ++++++ PACK_ACN_IMPORT.pck | 651 +++++++++++++++++++++++++ dictionar_date_facturare.csv | 95 ++++ 6 files changed, 997 insertions(+) create mode 100644 .gitignore create mode 100644 CLAUDE.md create mode 100644 DOCUMENTATIE_DATE_FACTURARE_RORIS.docx create mode 100644 DOCUMENTATIE_DATE_FACTURARE_RORIS.md create mode 100644 PACK_ACN_IMPORT.pck create mode 100644 dictionar_date_facturare.csv diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e84feee --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +# fișiere temporare generate la conversia MD -> DOCX +_md2docx.ps1 +_doc_tmp.html +_doc_new.docx + +# fișiere temporare Word +~$*.docx diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..675136f --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,84 @@ +# CLAUDE.md + +Context pentru asistarea pe acest folder. Citește înainte de a relua lucrul. + +## Ce este acest folder + +Folder de lucru pentru o **documentație de modernizare RoRIS** cerută de ACN. Autorul/clientul +este **Marius Mutu (ROMFAST SRL)** — firma care a dezvoltat ERP-ul de facturare **ROA** +(aplicația `ROAACNPRO`). ACN a depus cerere de finanțare pentru modernizarea sistemului **RoRIS** +și are nevoie de o specificație cu datele de care depinde facturarea, ca să o impună în caietul de +sarcini către firma care va face modernizarea. + +## Arhitectura sistemelor (de reținut) + +- **RoRIS** = sistemul sursă (date operaționale tranzit barje/nave, ecluzări, acostări). + Bază de date **SQL Server**. +- **ROA** (`ROAACNPRO`, dezvoltat de ROMFAST) = ERP-ul de facturare. Bază de date **Oracle**, + aplicație Visual FoxPro 9. +- ROA (Oracle) preia datele din RoRIS (SQL Server) printr-un **database link** (gateway heterogen + Oracle → SQL Server, `RORISSQL`). Importul e o copiere (`merge`) în tabele Oracle `ips_*`. + **Nu există API/REST** — clientul vrea explicit să păstreze acest model, nu să-l înlocuiască. + +## Fișierele din acest folder + +- `PACK_ACN_IMPORT.pck` — pachetul Oracle care importă din RoRIS în ROA (sursa analizei). +- `DOCUMENTATIE_DATE_FACTURARE_RORIS.md` — **livrabilul principal** (specificație minimă, în + română, ton impersonal). Structură: 1) Principiu integrare; 2) Entități + nomenclatoare (2.1); + 3) Câmpuri esențiale; 4) Impact asupra facturării (tabel de riscuri). +- `DOCUMENTATIE_DATE_FACTURARE_RORIS.docx` — versiunea Word, **generată din .md** (vezi mai jos). +- `dictionar_date_facturare.csv` — anexă tehnică, dicționar complet de câmpuri (delimitator `;`, + se deschide nativ în Excel România). + +## Sursa de adevăr (codul ROA real) + +Programul de facturare e în `D:\ROA\ROAACNPRO`. Pentru detalii de cod, relevante: +- `D:\ROA\ROAACNPRO\PACK_ACN_IMPORT.pck` (copie și aici) — ce entități se importă. +- `D:\ROA\ROAACNPRO\Programe\proceduri_acnpro.prg` — calcul/salvare facturare; rapoarte de + indicatori `vizualizare_tranzit_nave` (~linia 228) și `vizualizare_cheiaj_nave` (~383); + distribuția pe ecluze (`completeaza_regdoc_tranzit`, ~2259–2606); tarife `ips_tarife_tranzit` + (`vizualizare_tarife_tranzit`, ~4820). +- `D:\ROA\ROAACNPRO\database.txt` — sinonime/granturi RoRIS. +- `D:\ROA\ROAACNPRO\docs\fluxuri_calcul_facturare.md` și `docs\facturare.md` — fluxuri de calcul. +- `D:\ROA\ROAACNPRO\CLAUDE.md` — ghidul aplicației ROA. + +## Constatări cheie (deja încorporate în documentație) + +1. **Ecluzele se potrivesc pe DENUMIRE, nu pe `id_lock`.** Codul filtrează `lock_name LIKE + '%AGIGEA%'/'%CERNAVODA%'/'%OVIDIU%'/'%NAVODARI%'` și `chamber_name` exact `SAS1`/`SAS2` (canal + principal CDMN) sau `C1`/`C2` (canal PAMN, Năvodari). `id_lock` poate fi orice. Camera trebuie + **obligatoriu completată** (există `verificare_roris_ecluze.exe` care semnalează lipsurile). +2. **ID-urile entităților din RoRIS trebuie stabile în timp.** Sunt folosite ca FK în tarife, + contracte și vânzările deja facturate → relistarea facturilor istorice depinde de ele. +3. **Nomenclatoarele de grupare/tarifare NU există în RoRIS — sunt create în ROA** și referă prin + ID entitățile RoRIS: grupe tip navă (`ips_grup_tip_nave`), grupe marfă (`ips_goods_groups`), + UM (`ips_vas_um`), echivalențe (`ips_vas_echivalent`), dane (`ips_dane`), tarifele + (`ips_tarife_tranzit`). Tariful de tranzit se alege pe combinația **grupă tip navă + grupă/tip + marfă + rută + capacitate**, totul pe ID-uri RoRIS. Dacă RoRIS schimbă ID-urile de bază, + configurarea din ROA se desincronizează. +4. **Entități importate din RoRIS** (12): contacts, countries, goods (RISGOODS), vessels, + vessel_types (RIS_VES_TYPES), route_points, voyages, voyage_members, cargoes, voyage_locks + (VOYAGE_LOCK), berthings; `ips_routes` e generat în ROA din voyage_members + route_points. + +## Cum se regenerează DOCX din MD + +Nu există pandoc; există Word 2010 (COM). Workflow: MD → HTML curat → Word salvează ca .docx. +Scriptul convertor (`_md2docx.ps1`) se creează ad-hoc, se rulează și **se șterge după** (e temporar, +nu se păstrează în folder). Pași: +1. Scrie `_md2docx.ps1` (convertor MD→HTML cu suport pentru titluri, tabele, **bold**, `cod`, + blockquote, liste; apoi Word COM `SaveAs` format 16 = .docx). +2. Salvează întâi într-un `_doc_new.docx`, apoi `Move-Item` peste cel final (dacă fișierul final e + deschis în Word, e blocat — anunță utilizatorul să închidă Word). +3. Șterge fișierele temporare `_md2docx.ps1`, `_doc_new.docx`, `_doc_tmp.html`. + +Verificare: documentul Word este uneori deschis în IDE/Word și blochează suprascrierea. + +## Preferințe ale utilizatorului (din interacțiuni) + +- Documentație **minimă, lizibilă pentru oameni**, nu restrictivă/verbose. +- **Ton impersonal** — fără adresare cu „tu". +- Folosește terminologia din sistem (ex. `TRN`, nu „NRT"). +- Accent pe **afectarea cât mai mică a facturării** și pe **păstrarea modelului actual** (import + din vederi RoRIS, fără API/REST); dacă e nevoie de strat de compatibilitate, de menționat că + trebuie prevăzut în **buget**. +- Limba documentelor: **română**. diff --git a/DOCUMENTATIE_DATE_FACTURARE_RORIS.docx b/DOCUMENTATIE_DATE_FACTURARE_RORIS.docx new file mode 100644 index 0000000000000000000000000000000000000000..281c9e3e2727d87c71633552d950b8d18dab4023 GIT binary patch literal 25921 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 F_J0I5N8|ti literal 0 HcmV?d00001 diff --git a/DOCUMENTATIE_DATE_FACTURARE_RORIS.md b/DOCUMENTATIE_DATE_FACTURARE_RORIS.md new file mode 100644 index 0000000..b84923d --- /dev/null +++ b/DOCUMENTATIE_DATE_FACTURARE_RORIS.md @@ -0,0 +1,160 @@ +# Date necesare pentru facturare — modernizare RORIS (specificație minimă) + +**Beneficiar:** ACN — facturare tranzit/ecluzare barje și nave, cheiaj +**Sistem sursă (actual):** RORIS — bază de date **SQL Server** +**Sistem care consumă datele:** ROA (aplicația de facturare) — bază de date **Oracle** +**Scop:** stabilirea datelor minime pe care noul RORIS trebuie să le pună la dispoziția facturării. +**Autor:** ROMFAST SRL — dezvoltatorul ERP-ului ROA și al programului de facturare. +**Data:** 24.06.2026 + +--- + +## 1. Principiu de integrare (mod actual, de păstrat) + +Facturarea ROA (Oracle) preia astăzi datele din RORIS (SQL Server) **prin vederi/tabele expuse de +RORIS**, citite de Oracle printr-un **database link** (gateway heterogen Oracle → SQL Server, +`RORISSQL`). Importul este o simplă copiere (`merge`) din aceste surse în tabelele Oracle ale ROA, +**fără API sau servicii web**. Vederile/tabelele relevante poartă prefixul `ips_*` (date) și +`ips_v*` (vederi de calcul). + +**Cerința de bază a modernizării:** noul RORIS trebuie să expună în continuare, pe partea sa de +SQL Server, **aceleași vederi/tabele, cu aceleași denumiri de coloane și aceeași semnificație**, +accesibile prin database link din Oracle, astfel încât importul actual să funcționeze neschimbat +sau cu adaptări minime. + +> **De prevăzut în buget:** dacă noul RORIS este construit pe altă platformă sau cu altă structură +> de date (alte tabele/coloane, alt model), modernizarea trebuie să includă un **strat de +> compatibilitate** pe partea RORIS (vederi SQL Server / tabele intermediare / replicare) care să +> reproducă structura de mai jos și să rămână accesibil prin database link Oracle. +> **Nu se dorește rescrierea importului pe API/REST** — aceasta ar însemna refacerea integrală a +> mecanismului de facturare și costuri suplimentare nejustificate. + +--- + +## 2. Entitățile necesare facturării (12) + +| # | Sursă RORIS | Conținut | Folosită la | +|---|-------------|----------|-------------| +| 1 | `IPS_CONTACTS` | Firme (transportatori, plătitori) | Client/plătitor pe factură | +| 2 | `IPS_COUNTRIES` | Țări | Atribut navă/voiaj/marfă | +| 3 | `IPS_RISGOODS` | Mărfuri (NSTR, IMO, periculos) | Încadrare tarifară pe marfă | +| 4 | `IPS_VESSELS` | Nave/barje (tonaj, putere, LBD, tip) | Cantitate facturată tranzit/cheiaj | +| 5 | `IPS_RIS_VES_TYPES` | Tipuri de navă | Încadrare tarifară pe tip/grupă | +| 6 | `IPS_ROUTE_POINTS` | Puncte de rută (km/porturi/dane) | Rută, distanță, dană | +| 7 | `IPS_VOYAGES` | Voiaje/convoaie (avizare, declarație) | Antet tranzit; perioadă facturare | +| 8 | `IPS_VOYAGE_MEMBERS` | Membri convoi (navă + traseu + distanță) | Linia de bază a tranzitului | +| 9 | `IPS_CARGOES` | Marfă pe membru convoi (cantitate, UM) | Cantitate și încadrare marfă | +| 10 | `IPS_VOYAGE_LOCK` | Ecluzări (ecluză, cameră, durată) | Repartiția valorii pe ecluze | +| 11 | `IPS_BERTHINGS` | Acostări/staționări la dană | Baza facturării cheiajului | +| 12 | Nomenclatoare de config (în ROA) | Grupă tip navă, grupă marfă, UM, dane — pe baza ID-urilor RORIS | Selecția tarifului (vezi 2.1 și cap. 4) | + +Detaliul complet pe câmpuri (toate coloanele, tip, obligativitate) se află în anexa +**`dictionar_date_facturare.csv`**. Mai jos sunt doar câmpurile **esențiale** pentru facturare. + +### 2.1. Nomenclatoare folosite la facturare (listă completă) + +Nomenclatoarele sunt listele de clasificare/referință de care depinde facturarea (în special +selecția tarifelor — vezi cap. 4). Toate trebuie furnizate de noul sistem, cu **ID-uri stabile**. + +Coloana **„Mod de populare"** arată dacă nomenclatorul este **importat din RORIS** (copiat într-o +tabelă ROA), **creat și întreținut în ROA** (nu există în RORIS; configurarea lui — grupări, +tarife, echivalențe — se bazează pe **ID-urile din RORIS**) sau **generat în ROA** din date +importate. + +| Nomenclator | Conținut | Rol la facturare | Mod de populare | +|-------------|----------|------------------|-----------------| +| `IPS_CONTACTS` | Firme (transportatori, plătitori, armatori) | Client/plătitor pe factură | **Importat din RORIS** | +| `IPS_COUNTRIES` | Țări | Pavilion navă, țară marfă/voiaj | **Importat din RORIS** | +| `IPS_RISGOODS` | Mărfuri (cu NSTR, clasă IMO, indicator periculos) | Încadrare tarifară pe marfă | **Importat din RORIS** | +| `IPS_GOODS_GROUPS` | Grupe de marfă | Încadrare tarifară pe grupă de marfă | **Creat în ROA** (config pe baza ID-urilor RORIS — nu există în RORIS) | +| `IPS_RIS_VES_TYPES` | Tipuri de navă | Atribut navă; bază pentru grupa de tip navă | **Importat din RORIS** | +| `IPS_GRUP_TIP_NAVE` | Grupe de tip navă | Încadrare tarifară (tariful se definește pe grupă) | **Creat în ROA** (config pe baza ID-urilor RORIS — nu există în RORIS) | +| `IPS_ARAMIS_TIP_NAVE` | Tipuri de navă — clasificare ARAMIS | Clasificarea navei la cheiaj | **Creat în ROA** (config pe baza ID-urilor RORIS — nu există în RORIS) | +| `IPS_ROUTE_POINTS` | Puncte de rută (km, porturi, dane) | Definirea rutei, distanței și danei | **Importat din RORIS** | +| `IPS_ROUTES` | Rute (pereche punct plecare–sosire + distanță) | Încadrare tarifară pe rută | **Generat în ROA** din date RORIS (din `voyage_members` + `route_points`) | +| `IPS_VAS_UM` | Unități de măsură ale tarifelor (TC, TRN, LBD, CP, ZI) | Selecția unității de măsură a tarifului | **Creat în ROA** (config pe baza ID-urilor RORIS — nu există în RORIS) | +| `IPS_VAS_ECHIVALENT` | Echivalențe între unitățile de măsură | Conversii de UM la calcul | **Creat în ROA** (config pe baza ID-urilor RORIS — nu există în RORIS) | +| `IPS_DANE` | Dane | Identificarea danei la cheiaj | **Creat în ROA** (config pe baza ID-urilor RORIS — nu există în RORIS) | + +> **Observații:** +> - `IPS_CONTACTS`, `IPS_COUNTRIES`, `IPS_RISGOODS`, `IPS_RIS_VES_TYPES` și `IPS_ROUTE_POINTS` +> apar și în tabelul entităților (1-6) — sunt în același timp date de tranzacție și nomenclatoare. +> **Acestea trebuie furnizate de noul sistem**, cu ID-uri stabile. +> - Nomenclatoarele marcate **„Creat în ROA" NU există în RORIS** și **nu trebuie furnizate de +> noul sistem**. Ele sunt configurate manual în ROA (de exemplu: gruparea tipurilor de navă în +> grupe tarifare, gruparea mărfurilor, echivalențele de unități de măsură, danele) și **referă +> prin ID** entitățile din RORIS (tip navă, marfă, punct de rută). La fel, `IPS_ROUTES` este +> construit în ROA din datele importate. +> - **Consecință critică:** deoarece aceste configurări din ROA sunt legate de **ID-urile din +> RORIS**, dacă noul sistem schimbă ID-urile entităților de bază (tip navă, marfă, punct de rută, +> navă, firmă), toate grupările și tarifele configurate în ROA **se desincronizează** și trebuie +> refăcute manual. De aceea **stabilitatea ID-urilor din RORIS este esențială** (vezi cap. 4). +> - **Tarifele propriu-zise** (`IPS_TARIFE_TRANZIT` și similare) sunt tot în ROA și **referă prin +> ID** nomenclatoarele de mai sus (vezi cap. 4, pct. 5). + +--- + +## 3. Câmpuri esențiale per entitate + +> „ID" = identificator unic; toate ID-urile sunt text (uzual ≤36 caractere). Câmpurile marcate +> sunt cele fără de care facturarea nu funcționează. Restul câmpurilor — în CSV. + +**Firme (`IPS_CONTACTS`):** `id`, `name`. + +**Mărfuri (`IPS_RISGOODS`):** `id`, `name`, `dangerous` (periculos → coeficient). + +**Nave (`IPS_VESSELS`):** `id`, `name`, `gross_tonn` (capacitate), `trn` (tonaj registru net), `lbd`, +`horsepower`, `vtp_id` (tip navă). + +**Tipuri navă (`IPS_RIS_VES_TYPES`):** `id`, `name`. + +**Puncte rută (`IPS_ROUTE_POINTS`):** `id`, `name`. + +**Voiaje (`IPS_VOYAGES`):** `id`, data avizării, data declarației, `convoy_name`, `declaration`, +`ctt_id` (firmă), `origin`, `destination`. + +**Membri convoi (`IPS_VOYAGE_MEMBERS`):** `id`, `vye_id` (voiaj), `vsl_id` (navă), +`rstart_id`/`rfin_id` (plecare/sosire), `distance`, `distance_cdmn` (distanța pe canalul principal). + +**Marfă (`IPS_CARGOES`):** `id`, `vms_id` (membru), `risgds_id` (marfă), `quantity`, `unit`. + +**Ecluzări (`IPS_VOYAGE_LOCK`):** `id`, `vye_id`, `fk_voyage_member` (membru), `chamber_nr`, +`chamber_name`, `lock_name`, `date`. **(vezi cap. 4 — denumiri și camere obligatorii)** + +**Acostări (`IPS_BERTHINGS`):** `id`, `ves_id` (navă), `arrival_time`, `departure_time`, +`tip` (1=port, 2=dană așteptare, 9=altele), `rpt_id` (dană). + +--- + +## 4. Impact asupra facturării + +Tariful unei tranzitări se alege în ROA după **ID-urile din RORIS**, nu după denumiri — în funcție +de combinația **grupă de tip navă + grupă/tip de marfă + rută + capacitate**. Gruparea (tip +navă → grupă, marfă → grupă) și tarifele se configurează **în ROA**; din RORIS se folosesc doar +**ID-urile** de tip navă, marfă și punct de rută, plus atributele de calcul ale navei (capacitate, +cuplat/necuplat, distanțe pe canale). + +Următoarele modificări ale noului sistem **afectează direct facturarea**. Pentru fiecare, dacă nu +se respectă regula, va fi nevoie de un **adaptor** la nivelul importului/calculului ROA, care +trebuie prevăzut ca efort și **buget**. + +| # | Risc / modificare | Efect asupra facturării | Cerință / adaptor necesar | +|---|-------------------|-------------------------|----------------------------| +| 1 | **ID-uri schimbate** la migrare (voiaje, nave, mărfuri, puncte rută, firme) | Se rup legăturile cu tarifele/contractele și **relistarea facturilor istorice** | ID-uri păstrate identic, sau **tabel de echivalență ID_vechi↔ID_nou** pentru remapare | +| 2 | **Denumiri ecluze modificate** | Repartiția valorii pe ecluze devine 0; valoarea trece greșit pe „senal" | `lock_name` trebuie să conțină **AGIGEA / CERNAVODA / OVIDIU / NAVODARI** | +| 3 | **Coduri cameră ecluză modificate** | Aceeași problemă ca mai sus, pe cameră | `chamber_name` exact: **SAS1 / SAS2** (canal principal), **C1 / C2** (canal Năvodari) | +| 4 | **Camera ecluzei necompletată** | Ecluzarea nu se poate factura corect (caz deja problematic azi) | Completarea camerei **obligatorie** la fiecare ecluzare | +| 5 | **ID-uri de bază RORIS schimbate** (tip navă, marfă, punct de rută) | Grupările și tarifele configurate **în ROA** (pe baza acestor ID-uri) nu se mai potrivesc → tranzitul nu se facturează | ID-uri RORIS stabile, ca să rămână valide configurările din ROA (gruparea tip→grupă/marfă→grupă se întreține în ROA) | +| 6 | **Structură/denumiri coloane diferite** în vederi | Importul actual din vederi nu mai rulează | Păstrarea acelorași vederi și denumiri de coloane (cap. 1) | +| 7 | **Date fără oră** (avizare/declarație, sosire/plecare) | Perioada de facturare și durata la cheiaj sunt greșite | Livrare ca **dată + oră** completă | +| 8 | **Unități de măsură marfă/navă inconsistente** | Cantitățile facturate se denaturează | UM stabile și consecvente în timp | + +> **Notă privind responsabilitatea:** ERP-ul ROA și programul de facturare sunt dezvoltate și +> întreținute de **ROMFAST SRL**. Adaptările de pe partea de import/calcul ROA pot fi realizate de +> ROMFAST, dar **numai dacă noul sistem respectă regulile de mai sus**. Orice abatere (în special +> ID-uri instabile, denumiri de ecluze/camere schimbate, sau lipsa vederilor) transferă efort +> suplimentar și risc asupra facturării și trebuie evitată sau, după caz, prevăzută explicit în buget. + +--- + +*Anexă tehnică: `dictionar_date_facturare.csv` — lista completă a câmpurilor pe fiecare entitate.* diff --git a/PACK_ACN_IMPORT.pck b/PACK_ACN_IMPORT.pck new file mode 100644 index 0000000..a7b0947 --- /dev/null +++ b/PACK_ACN_IMPORT.pck @@ -0,0 +1,651 @@ +create or replace package PACK_ACN_IMPORT is + + -- Author : MARIUS MUTU + -- Created : 4/10/2019 4:00:22 PM + -- Purpose : IMPORT RORIS-ROA + + Procedure import_roris_job(ttLastGenerationTime date default null); + + procedure import_roris(ttLastGenerationTime date default null); + +end PACK_ACN_IMPORT; +/ +CREATE OR REPLACE PACKAGE BODY "PACK_ACN_IMPORT" is + + -- 25.09.2019 + -- import_roris: import ips_vessel_types + + -- 11.02.2020 + -- import_roris + -- Nu import nimic inainte de 01.01.2020 + -- Am schimbat in ips_voyages.generation (data declaratiei) cu notificati (data avizare) pentru ca erau incurcate + -- Am facut modificarea pentru convoaiele incepand cu 01.01.2020 sa nu afectez rapoartele pe anii precedenti + + -- 28.02.2020 + -- import_roris + -- ips_voyage_locks + chamber_nr, chamber_name + + -- 04.03.2020 + -- import_roris + -- ips_voyage_locks - tin cont ca vms_id poate fi null daca nu este completat in RORIS (nu se stie de ce nu este completat la unele tranzitari) + + -- 22.04.2020 + -- import_roris + -- nu mai sterg din ips_voyage_members. mi-a dat eroare ca mai exista referinte in ips_voyage_members_vanzari + + -- 08.05.2020 + -- import_roris + -- sterg din ips_cargoes daca id nu mai este in rorissql, in loc de vms_id + + -- 16.06.2020 + -- import_roris + -- nu sterg din ips_voyage_locks id-urile care incep cu '*NUSTERGE' + + -- 28.07.2021 + -- import_roris + -- nu sterg din ips_berthings id-urile care incep cu '*NUSTERGE' + + -- 14.12.2022 + -- import_roris + -- ips_berthings.tip (1=port, 2=dana asteptare, 9=altele) + + -- 08.04.2024 + -- import_roris + -- ips_vessels, ips_voyages, ips_cargoes + .country_id + + ------------------------------------------------- + -- Creeaza si lanseaza job IMPORTRORIS_JOB cu executia imediata + ------------------------------------------------- + Procedure import_roris_job(ttLastGenerationTime date default null) is + begin + dbms_scheduler.create_job(job_name => 'IMPORT_RORIS_JOB', + job_type => 'STORED_PROCEDURE', + job_action => 'PACK_ACN_IMPORT.IMPORT_RORIS', + number_of_arguments => 1, + start_date => systimestamp, + end_date => null, + repeat_interval => '', + enabled => false, + auto_drop => true, + comments => 'Lanseaza import din RORIS asincron.'); + + DBMS_SCHEDULER.SET_JOB_ANYDATA_VALUE(job_name => 'ACN.IMPORT_RORIS_JOB', + argument_position => 1, + argument_value => sys.anydata.convertDate(ttLastGenerationTime)); + + dbms_scheduler.enable(name => 'ACN.IMPORT_RORIS_JOB'); + + end import_roris_job; + + procedure import_roris(ttLastGenerationTime date default null) is + -- ttLastGenerationTime data de la care se preiau date din RORIS (implicit 6 luni in urma = data curenta - 180 zile) + ltLastGenerationTime date; + begin + + ltLastGenerationTime := case + when ttLastGenerationTime is null then + trunc(sysdate) - 30 + else + ttLastGenerationTime + end; + + -- Nu import nimic inainte de 01.01.2020 + -- Am schimbat in ips_voyages.generation (data declaratiei) cu notificati (data avizare) pentru ca erau incurcate + -- Am facut modificarea pentru convoaiele incepand cu 01.01.2020 sa nu afectez rapoartele pe anii precedenti + ltLastGenerationTime := greatest(ltLastGenerationTime, to_date('01012020', 'ddmmyyyy')); + + pinfo(tcmesaj => '1. Import data >= ' || + to_char(ttLastGenerationTime, + 'dd/mm/yyyy hh24:mi:ss'), + tclocatia => 'import_roris'); + + merge into ips_contacts a + using (Select trim(id) as id, + trim(substr(acronym, 1, 6)) as acronym, + trim(name) as name + From IPS_CONTACTS@RORISSQL) b + on (a.id = b.id) + when not matched then + insert (id, acronym, name) values (b.id, b.acronym, b.name); + + pinfo(tcmesaj => '2. ips_contacts ' || sql%rowcount || + ' inregistrari noi', + tclocatia => 'import_roris'); + + merge into ips_countries a + using (Select trim(id) as id, + trim(acronym) as acronym, + trim(name) as name + From IPS_COUNTRIES@RORISSQL) b + on (a.id = b.id) + when not matched then + insert (id, acronym, name) values (b.id, b.acronym, b.name); + + pinfo(tcmesaj => '3. ips_countries ' || sql%rowcount || + ' inregistrari noi', + tclocatia => 'import_roris'); + + merge into ips_goods a + using (Select trim(id) as id, + trim(name) as name, + trim(alternativ) as alternativ, + trim(dangerous) as dangerous, + trim(nstr_code) as nstr_code, + trim(nstr_name) as nstr_name, + trim(code) as code, + trim(imoclass) as imoclass, + trim(imoclass_name) as imoclass_n, + '2007' as standard + From IPS_RISGOODS@RORISSQL) b + on (a.id = b.id) + when not matched then + insert + (id, + name, + alternativ, + dangerous, + nstr_code, + nstr_name, + code, + imoclass, + imoclass_n, + standard) + values + (b.id, + b.name, + b.alternativ, + b.dangerous, + b.nstr_code, + b.nstr_name, + b.code, + b.imoclass, + b.imoclass_n, + b.standard); + + pinfo(tcmesaj => '4. ips_goods ' || sql%rowcount || + ' inregistrari noi', + tclocatia => 'import_roris'); + + merge into ips_vessels a + using (Select trim(id) as id, + vtmis_id, + trim(name) as name, + lbd, + length, + breadth, + trim(ctt_id) as ctt_id, + gross_tonn, + horsepower, + trn, + trim(risvtp_id) as vtp_id, + trim(country_id) as country_id + From IPS_VESSELS@RORISSQL) b + on (a.id = b.id) + when matched then + update + set name = b.name, + lbd = b.lbd, + length = b.length, + breadth = b.breadth, + ctt_id = b.ctt_id, + gross_tonn = b.gross_tonn, + horsepower = b.horsepower, + trn = b.trn, + vtp_id = b.vtp_id, + vtmis_id = b.vtmis_id, + country_id = b.country_id + when not matched then + insert + (id, + vtmis_id, + name, + lbd, + length, + breadth, + ctt_id, + gross_tonn, + horsepower, + trn, + vtp_id, + country_id) + values + (b.id, + b.vtmis_id, + b.name, + b.lbd, + b.length, + b.breadth, + b.ctt_id, + b.gross_tonn, + b.horsepower, + b.trn, + b.vtp_id, + b.country_id); + + pinfo(tcmesaj => '5. ips_vessels ' || sql%rowcount || + ' inregistrari noi/modificate', + tclocatia => 'import_roris'); + + merge into ips_vessel_types a + using (Select trim(id) as id, trim(name) as name + From IPS_RIS_VES_TYPES@RORISSQL) b + on (a.id = b.id) + when not matched then + insert (id, name) values (b.id, b.name); + + pinfo(tcmesaj => '6. ips_ris_ves_types ' || sql%rowcount || + ' inregistrari noi', + tclocatia => 'import_roris'); + + merge into ips_route_points a + using (Select trim(id) as id, + vtmis_id, + trim(name) as name, + TRIM(SUBSTR(name, 1, 6)) as acronym, + cnl_id + From IPS_ROUTE_POINTS@RORISSQL) b + on (a.id = b.id) + when matched then + update + set vtmis_id = b.vtmis_id, + name = b.name, + acronym = b.acronym, + cnl_id = b.cnl_id + when not matched then + insert + (id, vtmis_id, name, acronym, cnl_id) + values + (b.id, b.vtmis_id, b.name, b.acronym, b.cnl_id); + + pinfo(tcmesaj => '7. ips_route_points ' || sql%rowcount || + ' inregistrari noi/modificate', + tclocatia => 'import_roris'); + + -- voyages + merge into ips_voyages a + using (select trim(id) as id, + generation as notificati, + trim(mtr_name) as mtr_name, + trim(ctt_id) as ctt_id, + trim(vms_id) as vms_id, + trim(convoy_name) as convoy_nam, + trim(declaration) as declaratio, + notificati as generation, + trim(notificat2) as notificat2, + trim(origin) as origin, + trim(destinatio) as destinatio, + state, + trim(country_id) as country_id + from ips_voyages@RORISSQL + where notificati >= ltLastGenerationTime) b + on (a.id = b.id) + when matched then + update + set generation = b.generation, + mtr_name = b.mtr_name, + ctt_id = b.ctt_id, + vms_id = b.vms_id, + convoy_nam = b.convoy_nam, + declaratio = b.declaratio, + notificati = b.notificati, + notificat2 = b.notificat2, + origin = b.origin, + destinatio = b.destinatio, + state = b.state, + country_id = b.country_id + when not matched then + insert + (id, + generation, + mtr_name, + ctt_id, + vms_id, + convoy_nam, + declaratio, + notificati, + notificat2, + origin, + destinatio, + state, + country_id) + values + (b.id, + b.generation, + b.mtr_name, + b.ctt_id, + b.vms_id, + b.convoy_nam, + b.declaratio, + b.notificati, + b.notificat2, + b.origin, + b.destinatio, + b.state, + b.country_id); + + pinfo(tcmesaj => '8. ips_voyages ' || sql%rowcount || + ' inregistrari noi/modificate', + tclocatia => 'import_roris'); + + merge into ips_voyage_members a + using (select trim(vm.id) as id, + trim(vm.vye_id) as vye_id, + trim(vm.vsl_id) as vsl_id, + trim(vm.ctt_id) as ctt_id, + vm.dirty_tank, + trim(vm.rstart_id) as rstart_id, + trim(vm.rfin_id) as rfin_id, + vm.distance, + vm.distance_cdmn as distance_c, + vm.cnt_mnvr + From IPS_VOYAGE_MEMBERS@RORISSQL vm + JOIN IPS_VOYAGES@RORISSQL v + ON vm.vye_id = v.id + Where v.notificati >= ltLastGenerationTime) b + on (a.id = b.id) + when matched then + update + set vye_id = b.vye_id, + vsl_id = b.vsl_id, + ctt_id = b.ctt_id, + dirty_tank = b.dirty_tank, + rstart_id = b.rstart_id, + rfin_id = b.rfin_id, + distance = b.distance, + distance_c = b.distance_c, + cnt_mnvr = b.cnt_mnvr + when not matched then + insert + (id, + vye_id, + vsl_id, + ctt_id, + dirty_tank, + rstart_id, + rfin_id, + distance, + distance_c, + cnt_mnvr) + values + (b.id, + b.vye_id, + b.vsl_id, + b.ctt_id, + b.dirty_tank, + b.rstart_id, + b.rfin_id, + b.distance, + b.distance_c, + b.cnt_mnvr); + + pinfo(tcmesaj => '9. ips_voyage_members ' || sql%rowcount || + ' inregistrari noi/modificate', + tclocatia => 'import_roris'); + + -- sterg inregistrarile care nu mai sunt in RORIS +/* insert into ips_ids_temp + (idc) + (select v1.id + from (select vm.id as id + From IPS_VOYAGE_MEMBERS vm + JOIN IPS_VOYAGES v + ON vm.vye_id = v.id + Where v.generation >= ltLastGenerationTime) v1 + left join (select trim(vm.id) as id + From IPS_VOYAGE_MEMBERS@RORISSQL vm + JOIN IPS_VOYAGES@RORISSQL v + ON vm.vye_id = v.id + Where v.notificati >= ltLastGenerationTime) v2 + on v1.id = v2.id + where v2.id is null);*/ + +/* delete from ips_cargoes where vms_id in (select idc from ips_ids_temp);*/ + delete from ips_cargoes where id in (select c1.id + from ips_cargoes c1 + join ips_voyage_members vm + on c1.vms_id = vm.id + join ips_voyages v + ON vm.vye_id = v.id + left join ips_cargoes@rorissql c2 + on c1.id = trim(c2.id) + Where v.generation >= ltLastGenerationTime and c2.id is null); + + pinfo(tcmesaj => '10. ips_cargoes ' || sql%rowcount || + ' inregistrari sterse', + tclocatia => 'import_roris'); + + /* + -- nu mai sterg din ips_voyage_members. mi-a dat eroare ca mai exista referinte in ips_voyage_members_vanzari + delete from ips_voyage_members + where id in (select idc from ips_ids_temp); + pinfo(tcmesaj => '11. ips_voyage_members ' || sql%rowcount || + ' inregistrari sterse', + tclocatia => 'import_roris'); +*/ + delete from ips_ids_temp; + + merge into ips_cargoes a + using (select trim(c.id) as id, + trim(c.vms_id) as vms_id, + trim(c.risgds_id) as gds_id, + c.container, + trim(c.source) as source, + trim(c.cty_id) as cty_id, + trim(c.destination) as destinatio, + c.quantity, + trim(c.unit) as unit, + trim(c.country_id) as country_id + From IPS_CARGOES@RORISSQL c + join IPS_VOYAGE_MEMBERS@RORISSQL vm + ON c.vms_id = vm.id + JOIN IPS_VOYAGES@RORISSQL v + ON vm.vye_id = v.id + Where v.notificati >= ltLastGenerationTime) b + on (a.id = b.id) + when matched then + update + set vms_id = b.vms_id, + gds_id = b.gds_id, + container = b.container, + source = b.source, + cty_id = b.cty_id, + destinatio = b.destinatio, + quantity = b.quantity, + unit = b.unit, + country_id = b.country_id + when not matched then + insert + (id, + vms_id, + gds_id, + container, + source, + cty_id, + destinatio, + quantity, + unit, + country_id) + values + (b.id, + b.vms_id, + b.gds_id, + b.container, + b.source, + b.cty_id, + b.destinatio, + b.quantity, + b.unit, + b.country_id); + + pinfo(tcmesaj => '12. ips_cargoes ' || sql%rowcount || + ' inregistrari noi/modificate', + tclocatia => 'import_roris'); + + -- exista tranzite la care la ecluza ovidiu, impingatorul trece cu o barja prin camera 1, si cu alta barja prin camera 2 + -- astfel impingatorul apare de 2 ori, prin cate o camera + -- cheie primara este id (ecluzare), vms_id (membru convoi), chamber_nr (camera ecluza) + merge into ips_voyage_locks a + using (Select trim(vl.id) as id, + trim(vl.vye_id) as vye_id, + VL."DATE" as ddate, + trim(vl.rpt_id) as rpt_id, + vl.op_min, + vl.op_prep, + trim(vl.id_lock) as id_lock, + trim(vl.lock_name) as lock_name, + vl.chamber_nr, + vl.chamber_name, + trim(vl.fk_voyage_member) as vms_id + From IPS_VOYAGE_LOCK@RORISSQL vl + JOIN IPS_VOYAGES@RORISSQL v + ON vl.vye_id = v.id + Where v.notificati >= ltLastGenerationTime) b + on (a.id = b.id and NVL(a.vms_id, 'X') = NVL(b.vms_id, 'X') and a.chamber_nr = b.chamber_nr) + when matched then + update set a."date" = b.ddate, a.rpt_id = b.rpt_id, a.op_min = b.op_min, a.op_prep = b.op_prep + when not matched then + insert + (id, vye_id, "date", rpt_id, op_min, op_prep, id_lock, lock_name, chamber_nr, chamber_name, vms_id) + values + (b.id, + b.vye_id, + b.ddate, + b.rpt_id, + b.op_min, + b.op_prep, + b.id_lock, + b.lock_name, + b.chamber_nr, + b.chamber_name, + b.vms_id); + + pinfo(tcmesaj => '13. ips_voyage_locks ' || sql%rowcount || + ' inregistrari noi/modificate', + tclocatia => 'import_roris'); + + -- sterg inregistrarile care nu mai sunt in RORIS + delete from ips_voyage_locks + where id not like '*NUSTERGE%' and id || NVL(vms_id,'X') || chamber_nr in (select v1.id + from (select vl.id || NVL(vl.vms_id, 'X') || chamber_nr as id + from ips_voyage_locks vl + join ips_voyages v + on vl.vye_id = v.id + where v.generation >= ltLastGenerationTime) v1 + left join (select trim(vl.id) || NVL(trim(vl.fk_voyage_member), 'X') || trim(vl.chamber_nr) as id + From IPS_VOYAGE_LOCK@RORISSQL vl + JOIN IPS_VOYAGES@RORISSQL v + ON vl.vye_id = v.id + Where v.notificati >= ltLastGenerationTime) v2 + on v1.id = v2.id + where v2.id is null); + + pinfo(tcmesaj => '14. ips_voyage_locks ' || sql%rowcount || + ' inregistrari sterse', + tclocatia => 'import_roris'); + + merge into ips_berthings a + using (Select trim(id) as id, + arrival_time as arrival_ti, + trim(ves_id) as ves_id, + max(tip) as tip, + max(trim(voy_id)) as voy_id, + max(departure_time) as departure_, + max(trim(rpt_id)) as rpt_id, + max(trim(ctt_id)) as ctt_id + From IPS_BERTHINGS@RORISSQL + where arrival_time >= ltLastGenerationTime + group by id, arrival_time, ves_id) b + on (a.id = b.id and a.ves_id = b.ves_id and a.arrival_ti = b.arrival_ti) + when matched then + update + set voy_id = b.voy_id, + departure_ = b.departure_, + rpt_id = b.rpt_id, + ctt_id = b.ctt_id, + tip = b.tip + when not matched then + insert + (id, arrival_ti, voy_id, departure_, rpt_id, ctt_id, ves_id, tip) + values + (b.id, + b.arrival_ti, + b.voy_id, + b.departure_, + b.rpt_id, + b.ctt_id, + b.ves_id, + b.tip); + + pinfo(tcmesaj => '15. ips_berthings ' || sql%rowcount || + ' inregistrari noi/modificate', + tclocatia => 'import_roris'); + + -- sterg inregistrarile care nu mai sunt in RORIS + delete from ips_berthings + where id not like '*NUSTERGE%' and + id || ves_id || to_char(arrival_ti, 'yyyymmddhh24miss') in + (select v1.id || v1.ves_id || + to_char(v1.arrival_ti, 'yyyymmddhh24miss') as id + from (select id, ves_id, arrival_ti + from ips_berthings + where arrival_ti >= ltLastGenerationTime) v1 + left join (select trim(id) as id, + trim(ves_id) as ves_id, + arrival_time as arrival_ti + from ips_berthings@RORISSQL + where arrival_time >= ltLastGenerationTime) v2 + on v1.id = v2.id + and v1.ves_id = v2.ves_id + and v1.arrival_ti = v2.arrival_ti + where v2.id is null); + + pinfo(tcmesaj => '16. ips_berthings ' || sql%rowcount || + ' inregistrari sterse', + tclocatia => 'import_roris'); + + merge into ips_routes a + using (Select VM.RSTART_ID AS RPT_ID, + VM.RFIN_ID AS RPT_ID_HAS, + TRIM(SUBSTR(R1.NAME, 1, 49)) || '-' || + TRIM(SUBSTR(R2.NAME, 1, 50)) AS NAME, + R.ID, + MAX(ROUND(NVL(VM.DISTANCE, 0) / 1000, 2)) AS DISTANTA + FROM IPS_VOYAGE_MEMBERS VM + JOIN IPS_VOYAGES v + ON vm.vye_id = v.id + JOIN IPS_ROUTE_POINTS R1 + ON VM.RSTART_ID = R1.ID + JOIN IPS_ROUTE_POINTS R2 + ON VM.RFIN_ID = R2.ID + LEFT JOIN IPS_ROUTES R + ON VM.RSTART_ID = R.RPT_ID + AND VM.RFIN_ID = R.RPT_ID_HAS + Where v.generation >= ltLastGenerationTime + GROUP BY VM.RSTART_ID, + VM.RFIN_ID, + TRIM(SUBSTR(R1.NAME, 1, 49)) || '-' || + TRIM(SUBSTR(R2.NAME, 1, 50)), + R.ID) b + on (a.id = b.id) + when matched then + update set a.distanta = b.distanta + when not matched then + insert + (rpt_id, rpt_id_has, name, distanta, acronym) + values + (b.rpt_id, + b.rpt_id_has, + b.name, + b.distanta, + DBMS_RANDOM.STRING('U', 6)); + + pinfo(tcmesaj => '17. ips_routes ' || sql%rowcount || + ' inregistrari noi/modificate', + tclocatia => 'import_roris'); + COMMIT; + -- Raise_Application_Error (-20343, 'Eroare de test!'); + pinfo(tcmesaj => '18. COMMIT IMPORT FINALIZAT', tclocatia => 'import_roris'); + end import_roris; + +end PACK_ACN_IMPORT; +/ diff --git a/dictionar_date_facturare.csv b/dictionar_date_facturare.csv new file mode 100644 index 0000000..f52fbcf --- /dev/null +++ b/dictionar_date_facturare.csv @@ -0,0 +1,95 @@ +Entitate_ROA;Tabela_RORIS_sursa;Camp_ROA;Sursa_RORIS;Tip;Obligatoriu;Rol_la_facturare +ips_contacts;IPS_CONTACTS;id;id;VARCHAR(<=36);D;ID unic firma (FK pe voiaj/navat/marfa/acostare; leaga contract/client) +ips_contacts;IPS_CONTACTS;acronym;substr(acronym,1,6);VARCHAR(6);R;Acronim/cod scurt firma +ips_contacts;IPS_CONTACTS;name;name;VARCHAR;D;Denumire firma (apare pe factura) +ips_countries;IPS_COUNTRIES;id;id;VARCHAR;D;ID unic tara (FK pe navat/voiaj/marfa) +ips_countries;IPS_COUNTRIES;acronym;acronym;VARCHAR;R;Cod tara +ips_countries;IPS_COUNTRIES;name;name;VARCHAR;R;Denumire tara +ips_goods;IPS_RISGOODS;id;id;VARCHAR;D;ID unic marfa (FK pe ips_cargoes; baza tarif pe marfa) +ips_goods;IPS_RISGOODS;name;name;VARCHAR;D;Denumire marfa +ips_goods;IPS_RISGOODS;alternativ;alternativ;VARCHAR;O;Denumire alternativa +ips_goods;IPS_RISGOODS;dangerous;dangerous;CHAR/flag;D;Marfa periculoasa -> coeficient corector tranzit +ips_goods;IPS_RISGOODS;nstr_code;nstr_code;VARCHAR;R;Cod NSTR +ips_goods;IPS_RISGOODS;nstr_name;nstr_name;VARCHAR;R;Denumire NSTR +ips_goods;IPS_RISGOODS;code;code;VARCHAR;R;Cod marfa +ips_goods;IPS_RISGOODS;imoclass;imoclass;VARCHAR;R;Clasa IMO +ips_goods;IPS_RISGOODS;imoclass_n;imoclass_name;VARCHAR;O;Denumire clasa IMO +ips_goods;IPS_RISGOODS;standard;constant '2007';VARCHAR;O;Standard clasificare (fix la import) +ips_vessels;IPS_VESSELS;id;id;VARCHAR;D;ID unic navat (FK pe membru convoi/acostare) +ips_vessels;IPS_VESSELS;vtmis_id;vtmis_id;VARCHAR/NUM;O;ID navat in VTMIS +ips_vessels;IPS_VESSELS;name;name;VARCHAR;D;Numele navei (apare pe factura/recapitulatie) +ips_vessels;IPS_VESSELS;lbd;lbd;NUMBER;D;LBD - UM tarifara posibila +ips_vessels;IPS_VESSELS;length;length;NUMBER;R;Lungime navat +ips_vessels;IPS_VESSELS;breadth;breadth;NUMBER;R;Latime navat +ips_vessels;IPS_VESSELS;ctt_id;ctt_id;VARCHAR;R;Firma proprietar/operator (FK ips_contacts) +ips_vessels;IPS_VESSELS;gross_tonn;gross_tonn;NUMBER;D;Tonaj brut/capacitate - baza cantitate cheiaj/tranzit +ips_vessels;IPS_VESSELS;horsepower;horsepower;NUMBER;D;Putere (CP/HP) - UM tarifara posibila +ips_vessels;IPS_VESSELS;trn;trn;NUMBER;D;Tonaj registru net (NRT) - UM tarifara posibila +ips_vessels;IPS_VESSELS;vtp_id;risvtp_id;VARCHAR;D;Tip navat (FK ips_vessel_types) - incadrare tarifara +ips_vessels;IPS_VESSELS;country_id;country_id;VARCHAR;R;Tara navei (pavilion) +ips_vessel_types;IPS_RIS_VES_TYPES;id;id;VARCHAR;D;ID unic tip navat (FK din ips_vessels.vtp_id) +ips_vessel_types;IPS_RIS_VES_TYPES;name;name;VARCHAR;D;Denumire tip navat +ips_route_points;IPS_ROUTE_POINTS;id;id;VARCHAR;D;ID unic punct ruta (FK rute/ecluzari/acostari) +ips_route_points;IPS_ROUTE_POINTS;vtmis_id;vtmis_id;VARCHAR/NUM;O;Referinta VTMIS +ips_route_points;IPS_ROUTE_POINTS;name;name;VARCHAR;D;Denumire punct (km/port/dana) +ips_route_points;IPS_ROUTE_POINTS;acronym;substr(name,1,6);VARCHAR(6);R;Acronim punct +ips_route_points;IPS_ROUTE_POINTS;cnl_id;cnl_id;VARCHAR;R;Canalul de care apartine punctul +ips_voyages;IPS_VOYAGES;id;id;VARCHAR;D;ID unic voiaj (FK pe membri/ecluzari; cheie facturare tranzit) +ips_voyages;IPS_VOYAGES;generation;notificati (vezi 2.6);DATE;D;Data avizarii - criteriu selectie import/facturare +ips_voyages;IPS_VOYAGES;notificati;generation (vezi 2.6);DATE;D;Data declaratiei +ips_voyages;IPS_VOYAGES;notificat2;notificat2;DATE;O;A doua data de avizare +ips_voyages;IPS_VOYAGES;mtr_name;mtr_name;VARCHAR;R;Numele motorului/impingatorului +ips_voyages;IPS_VOYAGES;ctt_id;ctt_id;VARCHAR;D;Firma transportatoare/platitoare (FK ips_contacts) +ips_voyages;IPS_VOYAGES;vms_id;vms_id;VARCHAR;R;Membrul principal al convoiului +ips_voyages;IPS_VOYAGES;convoy_nam;convoy_name;VARCHAR;D;Numele convoiului (apare pe factura) +ips_voyages;IPS_VOYAGES;declaratio;declaration;VARCHAR;D;Nr declaratie tranzit +ips_voyages;IPS_VOYAGES;origin;origin;VARCHAR;R;Origine voiaj +ips_voyages;IPS_VOYAGES;destinatio;destination;VARCHAR;R;Destinatie voiaj +ips_voyages;IPS_VOYAGES;state;state;NUMBER/flag;R;Starea voiajului +ips_voyages;IPS_VOYAGES;country_id;country_id;VARCHAR;R;Tara voiajului +ips_voyage_members;IPS_VOYAGE_MEMBERS;id;id;VARCHAR;D;ID unic membru convoi (FK din cargoes/voyage_locks.vms_id) +ips_voyage_members;IPS_VOYAGE_MEMBERS;vye_id;vye_id;VARCHAR;D;Voiajul (FK ips_voyages) +ips_voyage_members;IPS_VOYAGE_MEMBERS;vsl_id;vsl_id;VARCHAR;D;Nava/barja (FK ips_vessels) +ips_voyage_members;IPS_VOYAGE_MEMBERS;ctt_id;ctt_id;VARCHAR;R;Firma pe membru (FK ips_contacts) +ips_voyage_members;IPS_VOYAGE_MEMBERS;dirty_tank;dirty_tank;flag;O;Tanc murdar (caz special) +ips_voyage_members;IPS_VOYAGE_MEMBERS;rstart_id;rstart_id;VARCHAR;D;Punct plecare (FK ips_route_points) +ips_voyage_members;IPS_VOYAGE_MEMBERS;rfin_id;rfin_id;VARCHAR;D;Punct sosire (FK ips_route_points) +ips_voyage_members;IPS_VOYAGE_MEMBERS;distance;distance;NUMBER;D;Distanta parcursa - baza coeficient distanta +ips_voyage_members;IPS_VOYAGE_MEMBERS;distance_c;distance_cdmn;NUMBER;D;Distanta pe canalul principal (CDMN) - repartitie CDMN/PAMN +ips_voyage_members;IPS_VOYAGE_MEMBERS;cnt_mnvr;cnt_mnvr;NUMBER;R;Nr manevre +ips_cargoes;IPS_CARGOES;id;id;VARCHAR;D;ID unic marfa-pe-membru +ips_cargoes;IPS_CARGOES;vms_id;vms_id;VARCHAR;D;Membrul de convoi (FK ips_voyage_members) +ips_cargoes;IPS_CARGOES;gds_id;risgds_id;VARCHAR;D;Marfa (FK ips_goods) - incadrare tarifara +ips_cargoes;IPS_CARGOES;quantity;quantity;NUMBER;D;Cantitate marfa - baza cantitate facturata +ips_cargoes;IPS_CARGOES;unit;unit;VARCHAR;D;Unitate de masura a cantitatii +ips_cargoes;IPS_CARGOES;container;container;flag/num;R;Container (da/nu) +ips_cargoes;IPS_CARGOES;source;source;VARCHAR;O;Sursa/provenienta marfa +ips_cargoes;IPS_CARGOES;cty_id;cty_id;VARCHAR;O;Legatura suplimentara +ips_cargoes;IPS_CARGOES;destinatio;destination;VARCHAR;O;Destinatia marfii +ips_cargoes;IPS_CARGOES;country_id;country_id;VARCHAR;R;Tara marfii +ips_voyage_locks;IPS_VOYAGE_LOCK;id;id;VARCHAR;D;ID ecluzare (parte din cheia compusa) +ips_voyage_locks;IPS_VOYAGE_LOCK;vye_id;vye_id;VARCHAR;D;Voiajul (FK ips_voyages) +ips_voyage_locks;IPS_VOYAGE_LOCK;vms_id;fk_voyage_member;VARCHAR;D;Membrul de convoi (parte cheie compusa; poate fi null) +ips_voyage_locks;IPS_VOYAGE_LOCK;chamber_nr;chamber_nr;NUMBER;D;Nr camera ecluza (parte din cheia compusa) +ips_voyage_locks;IPS_VOYAGE_LOCK;chamber_name;chamber_name;VARCHAR;D;COD CAMERA: SAS1/SAS2 (CDMN) sau C1/C2 (PAMN) - vezi 2.2 +ips_voyage_locks;IPS_VOYAGE_LOCK;lock_name;lock_name;VARCHAR;D;DENUMIRE ecluza - trebuie sa contina AGIGEA/CERNAVODA/OVIDIU/NAVODARI - vezi 2.2 +ips_voyage_locks;IPS_VOYAGE_LOCK;id_lock;id_lock;VARCHAR(36);R;GUID ecluza (NU se foloseste la repartitie) +ips_voyage_locks;IPS_VOYAGE_LOCK;date;date;DATE;D;Data/ora ecluzarii +ips_voyage_locks;IPS_VOYAGE_LOCK;rpt_id;rpt_id;VARCHAR;R;Punctul de ruta al ecluzei (FK ips_route_points) +ips_voyage_locks;IPS_VOYAGE_LOCK;op_min;op_min;NUMBER;O;Durata operare (min) +ips_voyage_locks;IPS_VOYAGE_LOCK;op_prep;op_prep;NUMBER;O;Durata pregatire +ips_berthings;IPS_BERTHINGS;id;id;VARCHAR;D;ID acostare (parte cheie compusa cu ves_id+arrival_ti) +ips_berthings;IPS_BERTHINGS;ves_id;ves_id;VARCHAR;D;Nava (FK ips_vessels) +ips_berthings;IPS_BERTHINGS;arrival_ti;arrival_time;DATE+ora;D;Data/ora sosirii - inceput durata stationare +ips_berthings;IPS_BERTHINGS;departure_;departure_time;DATE+ora;D;Data/ora plecarii - sfarsit durata stationare +ips_berthings;IPS_BERTHINGS;tip;tip;NUMBER;D;Tip dana: 1=port, 2=dana asteptare, 9=altele +ips_berthings;IPS_BERTHINGS;voy_id;voy_id;VARCHAR;R;Voiajul asociat +ips_berthings;IPS_BERTHINGS;rpt_id;rpt_id;VARCHAR;D;Dana/punctul de ruta (FK ips_route_points) +ips_berthings;IPS_BERTHINGS;ctt_id;ctt_id;VARCHAR;R;Firma platitoare (FK ips_contacts) +CONFIG_ROA_grupa_tip_nava;ROA (config, nu exista in RORIS);id;-;NUMBER;D;Creat in ROA; grupare a tipurilor de navat pe baza ID-urilor RORIS; tariful tranzit legat pe gtn_id - vezi 2.1/cap.4 +CONFIG_ROA_grupa_tip_nava;ROA (config, nu exista in RORIS);nume;-;VARCHAR(20);D;Denumire grupa tip navat (in ROA) +CONFIG_ROA_relatie_tip_grupa;ROA (config);vtp_id(RORIS)->grupa;maparea tip navat -> grupa;relatie;D;Maparea se intretine in ROA; depinde de ID-ul de tip navat din RORIS - vezi cap.4 +CONFIG_ROA_grupa_marfa;ROA (config, nu exista in RORIS);id;-;NUMBER;D;Creat in ROA; grupare a marfurilor; tariful tranzit legat pe gdsg_id - vezi 2.1/cap.4 +CONFIG_ROA_relatie_marfa_grupa;ROA (config);gds_id(RORIS)->grupa;maparea marfa -> grupa;relatie;D;Maparea se intretine in ROA; depinde de ID-ul de marfa din RORIS - vezi cap.4 +CONFIG_ROA_um_tarif;ROA (config, nu exista in RORIS);id;-;NUMBER;D;Creat in ROA; unitatea de masura a tarifului (vum_id in tarife) +CONFIG_ROA_aramis_tip_nava;ROA (config, nu exista in RORIS);id;-;NUMBER;R;Creat in ROA; clasificare ARAMIS tip navat (folosita la cheiaj)