diff --git a/src/modules/registratura/components/deadline-add-dialog.tsx b/src/modules/registratura/components/deadline-add-dialog.tsx index 6601923..1608a96 100644 --- a/src/modules/registratura/components/deadline-add-dialog.tsx +++ b/src/modules/registratura/components/deadline-add-dialog.tsx @@ -12,36 +12,39 @@ import { Button } from "@/shared/components/ui/button"; import { Input } from "@/shared/components/ui/input"; import { Label } from "@/shared/components/ui/label"; import { Badge } from "@/shared/components/ui/badge"; +import { Info, Building2, Calendar } from "lucide-react"; import { - DEADLINE_CATALOG, CATEGORY_LABELS, + getCategoriesForDirection, + getSelectableDeadlines, } from "../services/deadline-catalog"; import { computeDueDate } from "../services/working-days"; -import type { DeadlineCategory, DeadlineTypeDef } from "../types"; +import type { + DeadlineCategory, + DeadlineTypeDef, + RegistryDirection, +} from "../types"; interface DeadlineAddDialogProps { open: boolean; onOpenChange: (open: boolean) => void; entryDate: string; - onAdd: (typeId: string, startDate: string) => void; + direction: RegistryDirection; + /** Callback: typeId, startDate, options (CJ toggle etc.) */ + onAdd: ( + typeId: string, + startDate: string, + options?: { isCJ?: boolean }, + ) => void; } type Step = "category" | "type" | "date"; -const CATEGORIES: DeadlineCategory[] = [ - "certificat", - "avize", - "completari", - "analiza", - "autorizare", - "publicitate", - "contestatie", -]; - export function DeadlineAddDialog({ open, onOpenChange, entryDate, + direction, onAdd, }: DeadlineAddDialogProps) { const [step, setStep] = useState("category"); @@ -51,10 +54,20 @@ export function DeadlineAddDialog({ null, ); const [startDate, setStartDate] = useState(entryDate); + const [isCJ, setIsCJ] = useState(false); + + // ── Prelungire helper state ── + const [cuIssueDate, setCuIssueDate] = useState(""); + const [cuDurationMonths, setCuDurationMonths] = useState(null); + + const categories = useMemo( + () => getCategoriesForDirection(direction), + [direction], + ); const typesForCategory = useMemo(() => { if (!selectedCategory) return []; - return DEADLINE_CATALOG.filter((d) => d.category === selectedCategory); + return getSelectableDeadlines(selectedCategory); }, [selectedCategory]); const dueDatePreview = useMemo(() => { @@ -74,11 +87,22 @@ export function DeadlineAddDialog({ }); }, [selectedType, startDate]); + // Compute CU expiry when user uses the prelungire helper + const computedExpiryDate = useMemo(() => { + if (!cuIssueDate || !cuDurationMonths) return null; + const issue = new Date(cuIssueDate); + issue.setMonth(issue.getMonth() + cuDurationMonths); + return issue; + }, [cuIssueDate, cuDurationMonths]); + const handleClose = () => { setStep("category"); setSelectedCategory(null); setSelectedType(null); setStartDate(entryDate); + setIsCJ(false); + setCuIssueDate(""); + setCuDurationMonths(null); onOpenChange(false); }; @@ -99,18 +123,41 @@ export function DeadlineAddDialog({ if (step === "type") { setStep("category"); setSelectedCategory(null); + setIsCJ(false); } else if (step === "date") { setStep("type"); setSelectedType(null); + setCuIssueDate(""); + setCuDurationMonths(null); } }; const handleConfirm = () => { if (!selectedType || !startDate) return; - onAdd(selectedType.id, startDate); + const isCUType = + selectedType.id === "cu-emitere-l50" || + selectedType.id === "cu-emitere-l350"; + onAdd(selectedType.id, startDate, { + isCJ: isCUType ? isCJ : undefined, + }); handleClose(); }; + // Apply prelungire helper: set start date from computed expiry + const handleApplyExpiryHelper = () => { + if (computedExpiryDate) { + const y = computedExpiryDate.getFullYear(); + const m = String(computedExpiryDate.getMonth() + 1).padStart(2, "0"); + const d = String(computedExpiryDate.getDate()).padStart(2, "0"); + setStartDate(`${y}-${m}-${d}`); + } + }; + + const isPrelungireType = selectedType?.id === "cu-prelungire-emitere"; + const isCUEmitere = + selectedType?.id === "cu-emitere-l50" || + selectedType?.id === "cu-emitere-l350"; + return ( - {step === "category" && "Adaugă termen legal — Categorie"} + {step === "category" && "Adauga termen legal — Categorie"} {step === "type" && - `Adaugă termen legal — ${selectedCategory ? CATEGORY_LABELS[selectedCategory] : ""}`} + `Adauga termen legal — ${selectedCategory ? CATEGORY_LABELS[selectedCategory] : ""}`} {step === "date" && - `Adaugă termen legal — ${selectedType?.label ?? ""}`} + `Adauga termen legal — ${selectedType?.label ?? ""}`} + {/* ── Step 1: Category selection ── */} {step === "category" && (
- {CATEGORIES.map((cat) => ( - - ))} + {categories.map((cat) => { + const count = getSelectableDeadlines(cat).length; + return ( + + ); + })} + + {/* Direction info */} +
+ +

+ {direction === "iesit" + ? "Categoriile afisate sunt pentru demersuri depuse de noi (iesiri) — termene pe care le urmarim la institutii." + : "Categoriile afisate sunt pentru acte administrative primite (intrari) — termene de contestare/raspuns."} +

+
)} + {/* ── Step 2: Type selection ── */} {step === "type" && ( -
- {typesForCategory.map((typ) => ( - + ))} +
+ + {/* Info about auto-tracked deadlines for CU */} + {selectedCategory === "certificat" && ( +
+ +
+

Termene automate (in fundal):

+

+ Verificare cerere CU (10 zile lucr.) — se creeaza automat. + Dupa expirare, institutia nu mai poate returna documentatia. +

+ {isCJ && ( +

+ Aviz primar CJ (3z + 5z) — se creeaza automat la + bifarea optiunii CJ. +

)}
-

- {typ.description} -

- {typ.legalReference && ( -

- {typ.legalReference} -

- )} - - ))} +
+ )} )} + {/* ── Step 3: Date confirmation + preview ── */} {step === "date" && selectedType && (
+ {/* Prelungire helper: compute expiry from CU issue date */} + {isPrelungireType && ( +
+
+ + + Calculator data expirare CU + +
+

+ Introdu data emiterii CU si selecteaza durata de valabilitate + pentru a calcula automat data expirarii. +

+
+
+ + setCuIssueDate(e.target.value)} + className="mt-0.5 h-8 text-xs" + /> +
+
+ {[6, 12, 24].map((months) => ( + + ))} +
+
+ {computedExpiryDate && ( +
+ + Data expirare CU:{" "} + + {computedExpiryDate.toLocaleDateString("ro-RO", { + day: "2-digit", + month: "2-digit", + year: "numeric", + })} + + + +
+ )} +
+ )} + + {/* Start date input */}
{selectedType.startDateHint && ( @@ -211,21 +385,22 @@ export function DeadlineAddDialog({ />
+ {/* Due date preview */} {dueDatePreview && (

{selectedType.isBackwardDeadline - ? "Termen limită depunere" - : "Termen limită calculat"} + ? "Termen limita depunere" + : "Termen limita calculat"}

{dueDatePreview}

{selectedType.days}{" "} {selectedType.dayType === "working" - ? "zile lucrătoare" + ? "zile lucratoare" : "zile calendaristice"} {selectedType.isBackwardDeadline - ? " ÎNAINTE" + ? " INAINTE" : " de la data start"}

{selectedType.legalReference && ( @@ -235,23 +410,38 @@ export function DeadlineAddDialog({ )}
)} + + {/* CJ info reminder */} + {isCUEmitere && isCJ && ( +
+ +

+ Solicitat la CJ — se vor crea automat sub-termenele de aviz + primar (3z solicitat + 5z emis). +

+
+ )}
)} {step !== "category" && ( )} {step === "category" && ( )} {step === "date" && ( - )} diff --git a/src/modules/registratura/components/deadline-card.tsx b/src/modules/registratura/components/deadline-card.tsx index 629d678..d63818f 100644 --- a/src/modules/registratura/components/deadline-card.tsx +++ b/src/modules/registratura/components/deadline-card.tsx @@ -1,7 +1,7 @@ "use client"; import { useState } from "react"; -import { Clock, CheckCircle2, X, History } from "lucide-react"; +import { Clock, CheckCircle2, X, History, ShieldCheck, Building2 } from "lucide-react"; import { Badge } from "@/shared/components/ui/badge"; import { Button } from "@/shared/components/ui/button"; import type { TrackedDeadline } from "../types"; @@ -42,6 +42,19 @@ export function DeadlineCard({ const [showAudit, setShowAudit] = useState(false); const auditLog = deadline.auditLog ?? []; + const isAutoTrack = def?.autoTrack === true; + const isVerificationDeadline = deadline.typeId === "cu-verificare"; + const isCJDeadline = + deadline.typeId === "cu-cj-solicitare-aviz" || + deadline.typeId === "cu-cj-aviz-primar"; + + // For verification deadlines, check if the 10-day period has passed + const verificationExpired = + isVerificationDeadline && + deadline.resolution === "pending" && + status.daysRemaining !== null && + status.daysRemaining < 0; + return (
- + {isAutoTrack ? ( + isCJDeadline ? ( + + ) : ( + + ) + ) : ( + + )}
-
+
{def?.label ?? deadline.typeId} + {isAutoTrack && ( + + auto + + )} ( {status.daysRemaining < 0 - ? `${Math.abs(status.daysRemaining)}z depășit` + ? `${Math.abs(status.daysRemaining)}z depasit` : `${status.daysRemaining}z`} ) )}
+ {/* Verification badge: institution lost right to return docs */} + {verificationExpired && ( +
+ + + Nu mai pot returna documentatia + +
+ )}
- {def?.isBackwardDeadline ? "Termen limită" : "Start"}:{" "} + {def?.isBackwardDeadline ? "Termen limita" : "Start"}:{" "} {formatDate(deadline.startDate)} - {" → "} - {def?.isBackwardDeadline ? "Depunere până la" : "Termen"}:{" "} + {" \u2192 "} + {def?.isBackwardDeadline ? "Depunere pana la" : "Termen"}:{" "} {formatDate(deadline.dueDate)} {def?.dayType === "working" && ( - (zile lucrătoare) + (zile lucratoare) )}
diff --git a/src/modules/registratura/components/registry-entry-form.tsx b/src/modules/registratura/components/registry-entry-form.tsx index a7ef5ec..62fd4be 100644 --- a/src/modules/registratura/components/registry-entry-form.tsx +++ b/src/modules/registratura/components/registry-entry-form.tsx @@ -238,10 +238,52 @@ export function RegistryEntryForm({ const handleAddDeadline = ( typeId: string, startDate: string, - chainParentId?: string, + options?: { isCJ?: boolean; chainParentId?: string }, ) => { - const tracked = createTrackedDeadline(typeId, startDate, chainParentId); - if (tracked) setTrackedDeadlines((prev) => [...prev, tracked]); + const tracked = createTrackedDeadline( + typeId, + startDate, + options?.chainParentId, + ); + if (tracked) { + const newDeadlines = [tracked]; + + // Auto-create verification deadline for CU emitere types + const isCUEmitere = + typeId === "cu-emitere-l50" || typeId === "cu-emitere-l350"; + if (isCUEmitere) { + const verification = createTrackedDeadline( + "cu-verificare", + startDate, + ); + if (verification) newDeadlines.push(verification); + } + + // Auto-create CJ sub-deadlines if CJ toggle is on + if (isCUEmitere && options?.isCJ) { + const cjRequest = createTrackedDeadline( + "cu-cj-solicitare-aviz", + startDate, + ); + if (cjRequest) { + newDeadlines.push(cjRequest); + // Chain: primar responds 5 days from when arhitect-sef requests (3 days from start) + const requestDue = new Date(startDate); + requestDue.setDate(requestDue.getDate() + 3); + const y = requestDue.getFullYear(); + const m = String(requestDue.getMonth() + 1).padStart(2, "0"); + const d = String(requestDue.getDate()).padStart(2, "0"); + const cjResponse = createTrackedDeadline( + "cu-cj-aviz-primar", + `${y}-${m}-${d}`, + cjRequest.id, + ); + if (cjResponse) newDeadlines.push(cjResponse); + } + } + + setTrackedDeadlines((prev) => [...prev, ...newDeadlines]); + } }; const handleResolveDeadline = ( @@ -1394,6 +1436,7 @@ export function RegistryEntryForm({ open={deadlineAddOpen} onOpenChange={setDeadlineAddOpen} entryDate={date} + direction={direction} onAdd={handleAddDeadline} /> diff --git a/src/modules/registratura/services/deadline-catalog.ts b/src/modules/registratura/services/deadline-catalog.ts index 42168f3..01241f3 100644 --- a/src/modules/registratura/services/deadline-catalog.ts +++ b/src/modules/registratura/services/deadline-catalog.ts @@ -1,14 +1,21 @@ -import type { DeadlineTypeDef, DeadlineCategory } from "../types"; +import type { + DeadlineTypeDef, + DeadlineCategory, + RegistryDirection, +} from "../types"; export const DEADLINE_CATALOG: DeadlineTypeDef[] = [ // ═══════════════════════════════════════════════════════════════ // CERTIFICAT DE URBANISM // ═══════════════════════════════════════════════════════════════ + + // ── Auto-tracked (system creates automatically, not user-selectable) ── + { id: "cu-verificare", label: "Verificare cerere CU", description: - "Structurile de specialitate verifica documentatia depusa. Daca este incompleta sau necorespunzatoare, se restituie in acest termen.", + "Verificare operativa a documentatiei depuse. Dupa acest termen institutia nu mai are dreptul legal sa solicite clarificari sau sa returneze documentatia.", days: 10, dayType: "working", startDateLabel: "Data depunerii cererii", @@ -16,38 +23,14 @@ export const DEADLINE_CATALOG: DeadlineTypeDef[] = [ tacitApprovalApplicable: false, category: "certificat", legalReference: "Legea 50/1991, art. 6^1 alin. (1)", - }, - { - id: "cu-emitere-l50", - label: "Emitere CU (constructii)", - description: - "Termen de emitere a Certificatului de Urbanism pentru documentatii de constructii. Se aplica avizarea tacita la depasire.", - days: 15, - dayType: "working", - startDateLabel: "Data depunerii cererii", - requiresCustomStartDate: false, - tacitApprovalApplicable: true, - category: "certificat", - legalReference: "Legea 50/1991, art. 6^1 alin. (1)", - }, - { - id: "cu-emitere-l350", - label: "Emitere CU (urbanism)", - description: - "Termen de emitere a Certificatului de Urbanism pentru documentatii de urbanism (PUG/PUZ/PUD).", - days: 30, - dayType: "calendar", - startDateLabel: "Data depunerii cererii", - requiresCustomStartDate: false, - tacitApprovalApplicable: true, - category: "certificat", - legalReference: "Legea 350/2001, art. 29 alin. (2)", + autoTrack: true, + directionFilter: ["iesit"], }, { id: "cu-suport-tehnic", label: "Suport tehnic interinstitutional", description: - "Termen in care autoritatile locale acorda suport tehnic de specialitate institutiilor din sistemul de aparare/ordine publica (SNAOPSN) — stabilirea cerintelor urbanistice.", + "Termen in care autoritatile locale acorda suport tehnic de specialitate institutiilor din SNAOPSN — stabilirea cerintelor urbanistice.", days: 10, dayType: "working", startDateLabel: "Data solicitarii", @@ -56,35 +39,91 @@ export const DEADLINE_CATALOG: DeadlineTypeDef[] = [ tacitApprovalApplicable: false, category: "certificat", legalReference: "Legea 50/1991, art. 8 alin. (2)", + autoTrack: true, + directionFilter: ["iesit"], + }, + + // ── CJ sub-deadlines (auto-created when CJ toggle is on) ── + + { + id: "cu-cj-solicitare-aviz", + label: "Arhitect-sef solicita aviz primar", + description: + "La depunerea cererii CU la Consiliul Judetean, arhitectul-sef solicita avizul structurii de specialitate a primariei in 3 zile calendaristice.", + days: 3, + dayType: "calendar", + startDateLabel: "Data depunerii cererii CU la CJ", + requiresCustomStartDate: false, + tacitApprovalApplicable: false, + chainNextTypeId: "cu-cj-aviz-primar", + chainNextActionLabel: "Adauga termen emitere aviz primar (5 zile)", + category: "certificat", + legalReference: "Legea 50/1991, art. 4 alin. (1^1)", + autoTrack: true, + directionFilter: ["iesit"], }, { - id: "cu-prelungire-depunere", - label: "Termen depunere prelungire CU", + id: "cu-cj-aviz-primar", + label: "Primar emite aviz", description: - "Cererea de prelungire trebuie depusa cu minim 15 zile calendaristice INAINTE de expirarea CU. Se calculeaza inapoi de la data expirarii.", - days: 15, + "Primarul emite avizul structurii de specialitate in 5 zile calendaristice de la solicitarea arhitectului-sef.", + days: 5, dayType: "calendar", - startDateLabel: "Data expirare CU", + startDateLabel: "Data solicitarii avizului", requiresCustomStartDate: true, - startDateHint: "Data de expirare a Certificatului de Urbanism", + startDateHint: "Data la care arhitectul-sef a solicitat avizul", tacitApprovalApplicable: false, category: "certificat", - isBackwardDeadline: true, - legalReference: "Norme metodologice Legea 50/1991", + legalReference: "Legea 50/1991, art. 4 alin. (1^1)", + autoTrack: true, + directionFilter: ["iesit"], + }, + + // ── User-selectable CU deadlines ── + + { + id: "cu-emitere-l50", + label: "Emitere CU (constructii — L50)", + description: + "Termen de emitere a Certificatului de Urbanism pentru documentatii de constructii. NU se aplica avizarea tacita.", + days: 15, + dayType: "working", + startDateLabel: "Data inregistrarii cererii", + requiresCustomStartDate: false, + tacitApprovalApplicable: false, + category: "certificat", + legalReference: "Legea 50/1991, art. 6^1 alin. (1)", + directionFilter: ["iesit"], + }, + { + id: "cu-emitere-l350", + label: "Emitere CU (urbanism — L350)", + description: + "Termen de emitere a Certificatului de Urbanism pentru documentatii de urbanism (PUG/PUZ/PUD). NU se aplica avizarea tacita.", + days: 30, + dayType: "calendar", + startDateLabel: "Data inregistrarii cererii", + requiresCustomStartDate: false, + tacitApprovalApplicable: false, + category: "certificat", + legalReference: "Legea 350/2001, art. 29 alin. (2)", + directionFilter: ["iesit"], }, { id: "cu-prelungire-emitere", label: "Emitere prelungire CU", description: - "Termen de emitere a prelungirii CU de la depunerea cererii de prelungire.", - days: 15, + "Termen de emitere a prelungirii CU de la depunerea cererii de prelungire. Termen din practica administrativa (nu e explicit in lege).", + days: 30, dayType: "calendar", startDateLabel: "Data depunerii cererii de prelungire", requiresCustomStartDate: true, - startDateHint: "Data la care s-a depus cererea de prelungire a CU", - tacitApprovalApplicable: true, + startDateHint: + "Data la care s-a depus cererea de prelungire a CU", + tacitApprovalApplicable: false, category: "certificat", - legalReference: "Legea 50/1991, art. 6^1", + legalReference: "Practica administrativa", + directionFilter: ["iesit"], }, // ═══════════════════════════════════════════════════════════════ @@ -102,6 +141,7 @@ export const DEADLINE_CATALOG: DeadlineTypeDef[] = [ tacitApprovalApplicable: true, category: "avize", legalReference: "Legea 50/1991, art. 7 alin. (1)", + directionFilter: ["iesit"], }, { id: "aviz-urbanism-30", @@ -115,12 +155,13 @@ export const DEADLINE_CATALOG: DeadlineTypeDef[] = [ tacitApprovalApplicable: true, category: "avize", legalReference: "Legea 350/2001, art. 44 alin. (4)", + directionFilter: ["iesit"], }, { id: "aviz-mediu", label: "Aviz Protectia Mediului", description: - "Actul administrativ de mediu se emite in maximum 15 zile de la data incheierii procedurilor specifice de mediu (care au propriii timpi de evaluare).", + "Actul administrativ de mediu se emite in maximum 15 zile de la data incheierii procedurilor specifice de mediu.", days: 15, dayType: "calendar", startDateLabel: "Data finalizare proceduri mediu", @@ -129,6 +170,7 @@ export const DEADLINE_CATALOG: DeadlineTypeDef[] = [ tacitApprovalApplicable: true, category: "avize", legalReference: "Legea 50/1991, art. 7 alin. (3)", + directionFilter: ["iesit"], }, { id: "aviz-cultura-comisie", @@ -143,6 +185,7 @@ export const DEADLINE_CATALOG: DeadlineTypeDef[] = [ tacitApprovalApplicable: true, category: "avize", legalReference: "Legea 50/1991, art. 7 alin. (3)", + directionFilter: ["iesit"], }, { id: "aviz-cultura-mc", @@ -153,10 +196,12 @@ export const DEADLINE_CATALOG: DeadlineTypeDef[] = [ dayType: "working", startDateLabel: "Data primirii documentatiei complete", requiresCustomStartDate: true, - startDateHint: "Data la care Min. Culturii a primit documentatia completa", + startDateHint: + "Data la care Min. Culturii a primit documentatia completa", tacitApprovalApplicable: true, category: "avize", legalReference: "Legea 50/1991, art. 7 alin. (3^1)", + directionFilter: ["iesit"], }, { id: "aviz-aeronautica", @@ -170,6 +215,7 @@ export const DEADLINE_CATALOG: DeadlineTypeDef[] = [ tacitApprovalApplicable: true, category: "avize", legalReference: "Legea 50/1991, art. 7 alin. (3)", + directionFilter: ["iesit"], }, { id: "aviz-isu", @@ -183,6 +229,7 @@ export const DEADLINE_CATALOG: DeadlineTypeDef[] = [ tacitApprovalApplicable: true, category: "avize", legalReference: "Legea 50/1991, art. 7 alin. (3)", + directionFilter: ["iesit"], }, { id: "aviz-transport-eu", @@ -196,6 +243,7 @@ export const DEADLINE_CATALOG: DeadlineTypeDef[] = [ tacitApprovalApplicable: true, category: "avize", legalReference: "Legea 50/1991, art. 7 alin. (3)", + directionFilter: ["iesit"], }, { id: "aviz-comisie-agenda", @@ -209,6 +257,7 @@ export const DEADLINE_CATALOG: DeadlineTypeDef[] = [ tacitApprovalApplicable: false, category: "avize", legalReference: "Legea 350/2001, art. 44 alin. (4)", + directionFilter: ["iesit"], }, { id: "aviz-comisie-emitere", @@ -219,10 +268,12 @@ export const DEADLINE_CATALOG: DeadlineTypeDef[] = [ dayType: "calendar", startDateLabel: "Data analizarii in comisie", requiresCustomStartDate: true, - startDateHint: "Data la care documentatia a fost analizata in comisia de specialitate", + startDateHint: + "Data la care documentatia a fost analizata in comisia de specialitate", tacitApprovalApplicable: true, category: "avize", legalReference: "Legea 350/2001, art. 44 alin. (4)", + directionFilter: ["iesit"], }, { id: "aviz-oportunitate-comisie", @@ -236,6 +287,7 @@ export const DEADLINE_CATALOG: DeadlineTypeDef[] = [ tacitApprovalApplicable: false, category: "avize", legalReference: "Legea 350/2001, art. 32 alin. (1^1)", + directionFilter: ["iesit"], }, { id: "aviz-oportunitate-emitere", @@ -248,9 +300,9 @@ export const DEADLINE_CATALOG: DeadlineTypeDef[] = [ requiresCustomStartDate: true, startDateHint: "Data sedintei comisiei tehnice in care s-a analizat", tacitApprovalApplicable: false, - chainNextTypeId: undefined, category: "avize", legalReference: "Legea 350/2001, art. 32 alin. (1^1)", + directionFilter: ["iesit"], }, { id: "aviz-reconfirmare", @@ -265,6 +317,7 @@ export const DEADLINE_CATALOG: DeadlineTypeDef[] = [ tacitApprovalApplicable: true, category: "avize", legalReference: "Legea 350/2001, art. 44 alin. (4)", + directionFilter: ["iesit"], }, { id: "aviz-primar", @@ -279,6 +332,7 @@ export const DEADLINE_CATALOG: DeadlineTypeDef[] = [ tacitApprovalApplicable: false, category: "avize", legalReference: "Legea 50/1991, art. 4 alin. (1^1)", + directionFilter: ["iesit"], }, { id: "aviz-monument-fara-ac", @@ -289,10 +343,12 @@ export const DEADLINE_CATALOG: DeadlineTypeDef[] = [ dayType: "calendar", startDateLabel: "Data notificarii", requiresCustomStartDate: true, - startDateHint: "Data la care s-a notificat serviciul deconcentrat de cultura", + startDateHint: + "Data la care s-a notificat serviciul deconcentrat de cultura", tacitApprovalApplicable: true, category: "avize", legalReference: "Legea 50/1991, art. 11 alin. (1)", + directionFilter: ["iesit"], }, // ═══════════════════════════════════════════════════════════════ @@ -310,6 +366,7 @@ export const DEADLINE_CATALOG: DeadlineTypeDef[] = [ tacitApprovalApplicable: false, category: "completari", legalReference: "Norme metodologice Legea 50/1991", + directionFilter: ["iesit"], }, { id: "completare-beneficiar-60", @@ -325,6 +382,7 @@ export const DEADLINE_CATALOG: DeadlineTypeDef[] = [ chainNextActionLabel: "Adauga termen emitere dupa completari (15 zile)", category: "completari", legalReference: "Legea 350/2001, art. 44 alin. (4)", + directionFilter: ["iesit"], }, { id: "completare-emitere-15", @@ -339,6 +397,7 @@ export const DEADLINE_CATALOG: DeadlineTypeDef[] = [ tacitApprovalApplicable: true, category: "completari", legalReference: "Legea 350/2001, art. 44 alin. (4)", + directionFilter: ["iesit"], }, { id: "completare-ac-beneficiar", @@ -353,10 +412,11 @@ export const DEADLINE_CATALOG: DeadlineTypeDef[] = [ tacitApprovalApplicable: false, category: "completari", legalReference: "Legea 50/1991, art. 7 alin. (1^1)", + directionFilter: ["iesit"], }, // ═══════════════════════════════════════════════════════════════ - // ANALIZA + // URBANISM (PUD/PUZ/PUG) — renamed from "Analiza" // ═══════════════════════════════════════════════════════════════ { id: "ctatu-analiza", @@ -368,8 +428,9 @@ export const DEADLINE_CATALOG: DeadlineTypeDef[] = [ startDateLabel: "Data depunerii", requiresCustomStartDate: false, tacitApprovalApplicable: false, - category: "analiza", + category: "urbanism", legalReference: "Legea 350/2001", + directionFilter: ["iesit"], }, { id: "consiliu-promovare", @@ -380,8 +441,9 @@ export const DEADLINE_CATALOG: DeadlineTypeDef[] = [ startDateLabel: "Data depunerii", requiresCustomStartDate: false, tacitApprovalApplicable: false, - category: "analiza", + category: "urbanism", legalReference: "Legea 350/2001", + directionFilter: ["iesit"], }, { id: "consiliu-vot", @@ -394,12 +456,13 @@ export const DEADLINE_CATALOG: DeadlineTypeDef[] = [ requiresCustomStartDate: true, startDateHint: "Data finalizarii dezbaterii publice", tacitApprovalApplicable: false, - category: "analiza", + category: "urbanism", legalReference: "Legea 350/2001", + directionFilter: ["iesit"], }, // ═══════════════════════════════════════════════════════════════ - // AUTORIZARE (AC) + // AUTORIZARE (AD/AC) // ═══════════════════════════════════════════════════════════════ { id: "ac-verificare", @@ -413,6 +476,7 @@ export const DEADLINE_CATALOG: DeadlineTypeDef[] = [ tacitApprovalApplicable: false, category: "autorizare", legalReference: "Legea 50/1991, art. 7 alin. (1)", + directionFilter: ["iesit"], }, { id: "ac-emitere", @@ -426,6 +490,7 @@ export const DEADLINE_CATALOG: DeadlineTypeDef[] = [ tacitApprovalApplicable: false, category: "autorizare", legalReference: "Legea 50/1991, art. 7 alin. (1)", + directionFilter: ["iesit"], }, { id: "ac-emitere-urgenta", @@ -439,6 +504,7 @@ export const DEADLINE_CATALOG: DeadlineTypeDef[] = [ tacitApprovalApplicable: false, category: "autorizare", legalReference: "Legea 50/1991, art. 7 alin. (1^2)", + directionFilter: ["iesit"], }, { id: "ac-emitere-agricol", @@ -452,6 +518,7 @@ export const DEADLINE_CATALOG: DeadlineTypeDef[] = [ tacitApprovalApplicable: false, category: "autorizare", legalReference: "Legea 50/1991, art. 7 alin. (1^3)", + directionFilter: ["iesit"], }, { id: "ac-prelungire", @@ -467,6 +534,7 @@ export const DEADLINE_CATALOG: DeadlineTypeDef[] = [ category: "autorizare", isBackwardDeadline: true, legalReference: "Legea 50/1991, art. 7 alin. (8)", + directionFilter: ["iesit"], }, // ═══════════════════════════════════════════════════════════════ @@ -512,12 +580,14 @@ export const DEADLINE_CATALOG: DeadlineTypeDef[] = [ dayType: "calendar", startDateLabel: "Data ultimei publicitati", requiresCustomStartDate: true, - startDateHint: "Data la care actul a fost adus la cunostinta publicului (ultima operatiune de publicitate: notare in CF, ziar, panou etc.)", + startDateHint: + "Data la care actul a fost adus la cunostinta publicului (ultima operatiune de publicitate: notare in CF, ziar, panou etc.)", tacitApprovalApplicable: false, chainNextTypeId: "contestare-ac", chainNextActionLabel: "Adauga termen contestare in instanta (60 zile)", category: "contestatie", legalReference: "Legea 554/2004, art. 7", + directionFilter: ["intrat"], }, { id: "contestare-ac", @@ -528,10 +598,12 @@ export const DEADLINE_CATALOG: DeadlineTypeDef[] = [ dayType: "calendar", startDateLabel: "Data raspuns plangere / expirare termen", requiresCustomStartDate: true, - startDateHint: "Data primirii raspunsului la plangerea prealabila (sau data la care a expirat termenul de raspuns)", + startDateHint: + "Data primirii raspunsului la plangerea prealabila (sau data la care a expirat termenul de raspuns)", tacitApprovalApplicable: false, category: "contestatie", legalReference: "Legea 50/1991, art. 12", + directionFilter: ["intrat"], }, { id: "contestare-urbanism", @@ -546,6 +618,7 @@ export const DEADLINE_CATALOG: DeadlineTypeDef[] = [ tacitApprovalApplicable: false, category: "contestatie", legalReference: "Legea 350/2001, art. 64 alin. (3)", + directionFilter: ["intrat"], }, { id: "contestare-contraventie", @@ -556,10 +629,12 @@ export const DEADLINE_CATALOG: DeadlineTypeDef[] = [ dayType: "calendar", startDateLabel: "Data comunicarii PV", requiresCustomStartDate: true, - startDateHint: "Data inmanarii sau comunicarii procesului-verbal de contraventie", + startDateHint: + "Data inmanarii sau comunicarii procesului-verbal de contraventie", tacitApprovalApplicable: false, category: "contestatie", legalReference: "OG 2/2001, art. 31 alin. (1)", + directionFilter: ["intrat"], }, ]; @@ -567,12 +642,55 @@ export const CATEGORY_LABELS: Record = { certificat: "Certificat de Urbanism", avize: "Avize", completari: "Completari", - analiza: "Analiza", - autorizare: "Autorizare (AC)", + urbanism: "Urbanism (PUD/PUZ/PUG)", + autorizare: "Autorizare (AD/AC)", publicitate: "Publicitate / Comunicare", contestatie: "Contestatie", }; +/** Which categories are shown for each direction */ +export const DIRECTION_CATEGORIES: Record< + RegistryDirection, + DeadlineCategory[] +> = { + iesit: ["certificat", "avize", "completari", "urbanism", "autorizare"], + intrat: ["contestatie"], +}; + +/** Categories always visible regardless of direction */ +export const SHARED_CATEGORIES: DeadlineCategory[] = ["publicitate"]; + +/** + * Get the ordered list of categories for a given direction. + */ +export function getCategoriesForDirection( + direction: RegistryDirection, +): DeadlineCategory[] { + return [...DIRECTION_CATEGORIES[direction], ...SHARED_CATEGORIES]; +} + +/** + * Get user-selectable deadlines for a category (excludes autoTrack deadlines). + */ +export function getSelectableDeadlines( + category: DeadlineCategory, +): DeadlineTypeDef[] { + return DEADLINE_CATALOG.filter( + (d) => d.category === category && !d.autoTrack, + ); +} + +/** + * Get auto-track deadlines that should be created automatically. + */ +export function getAutoTrackDeadlines( + category: DeadlineCategory, +): DeadlineTypeDef[] { + return DEADLINE_CATALOG.filter( + (d) => d.category === category && d.autoTrack === true, + ); +} + export function getDeadlineType(typeId: string): DeadlineTypeDef | undefined { return DEADLINE_CATALOG.find((d) => d.id === typeId); } diff --git a/src/modules/registratura/types.ts b/src/modules/registratura/types.ts index f256b2d..542762d 100644 --- a/src/modules/registratura/types.ts +++ b/src/modules/registratura/types.ts @@ -119,7 +119,7 @@ export type DeadlineCategory = | "certificat" | "avize" | "completari" - | "analiza" + | "urbanism" | "autorizare" | "publicitate" | "contestatie"; @@ -140,6 +140,10 @@ export interface DeadlineTypeDef { legalReference?: string; category: DeadlineCategory; isBackwardDeadline?: boolean; + /** If true, this deadline is auto-created by the system (not user-selectable) */ + autoTrack?: boolean; + /** Which directions this category/type applies to (undefined = both) */ + directionFilter?: RegistryDirection[]; } /** Audit log entry for deadline changes */