normalizeSubjectCode($codiceUnivoco, $condominoId); $codice = $this->buildCodice('AR', $stabileId, 'C', $subjectCode); $descrizione = 'Crediti vs ' . ($nominativo ? trim($nominativo) : ('condomino #' . $condominoId)); return app(ChiusuraGestioneService::class)->resolveOrCreateConto($codice, $descrizione, 'Attività'); } public function resolveContoDebitoFornitore(int $stabileId, int $fornitoreId, ?string $ragioneSociale = null, ?string $codiceUnivoco = null): PianoConti { $subjectCode = $this->normalizeSubjectCode($codiceUnivoco, $fornitoreId); $codice = $this->buildCodice('AP', $stabileId, 'F', $subjectCode); $descrizione = 'Debiti vs ' . ($ragioneSociale ? trim($ragioneSociale) : ('fornitore #' . $fornitoreId)); return app(ChiusuraGestioneService::class)->resolveOrCreateConto($codice, $descrizione, 'Passività'); } private function buildCodice(string $prefix, int $stabileId, string $subjectPrefix, string $subjectCode): string { // Stable-scoped, globally unique and readable codes. // Examples: // - AR-S0007-CABC123 (crediti vs condomino con codice univoco ABC123 in stabile 7) // - AP-S0007-FXYZ987 (debiti vs fornitore con codice univoco XYZ987 in stabile 7) return sprintf('%s-S%04d-%s%s', $prefix, $stabileId, $subjectPrefix, $subjectCode); } private function normalizeSubjectCode(?string $codiceUnivoco, int $fallbackId): string { $clean = is_string($codiceUnivoco) ? strtoupper(trim($codiceUnivoco)) : ''; $clean = preg_replace('/[^A-Z0-9]/', '', $clean ?? '') ?? ''; if ($clean === '') { return sprintf('%06d', $fallbackId); } return $clean; } }