@startUML

hide enum methods
hide interface attributes

package Dominio{
    class Poliza {
        -idSucursal: Integer
        -numeroPoliza: Integer
        -cobertura: TipoCobertura
        -inicioVigencia: Date
        -finVigencia: Date
        -kmsAnuales: Integer
        -estado: EstadoPoliza
        -siniestros: Integer
        +calcularSuma(): Float
        +polizaPaga(): Boolean
        +calcularPrima(): Float
        +calcularDescuentos(): Float
    }
    
    class ModificacionPoliza {
        -cobertura: TipoCobertura
        -kmsAnuales: Integer
        -siniestros: Integer
    }
    
    /'class Cobrador {
        +registrarPago(Poliza): Void
    }
    
    class ProductorSeguros {
        +altaCliente(String[]): Cliente
        +modificaCliente(String[], Cliente): Void
        +buscarCliente(String[]): Cliente
        +consultarCliente(Cliente): Void
        +bajaCliente(Cliente): Void
        +altaPoliza(String[]): Poliza
        +modificarPoliza(String[], Poliza): Void
        +bajaPoliza(Poliza): Void
    }
    
    class Gerente {
        generarPropuestasRenovacion(): Void
        generarInforme(): Void
    }
    '/
    class Cliente {
        -idCliente: Integer
        -nombre: String
        -apellido: String
        -tipoDocumento: TipoDocumento
        -numeroDocumento: Integer
        -cuil: Integer
        -sexo: Sexo
        -nacimiento: Date
        -profesion: String
        -estadoCivil: EstadoCivil
        -email: String
        -registro: Integer
        -condicionIva: CondicionIva
        -domicilio: Domicilio
        +edad(): Integer
        +enMora(): Boolean
        +alDia(): Boolean
        +clienteNormal(): Boolean
        +clienteActivo(): Boolean
        +clientePlata(): Boolean
    }

    class HijoDeclarado {
        -fechaNacimiento: Date
        -estadoCivil: EstadoCivil
        -sexo: Sexo
        +edad(): Integer
    }

    class Domicilio {
        -calle: String
        -numero: Integer
        -piso: Integer
        -departamento: String
    }

    /'abstract EstadoPoliza {
        +handle(): Void
        +generada(): Boolean
        +suspendida(): Boolean
        +vigente(): Boolean
        +finalizada(): Boolean
    }

    class PolizaGenerada {
        +generada(): Boolean //<<Override>>// 
    }
    
    class PolizaSuspendida{
        +suspendida(): Boolean //<<Override>>//
    }
    
    class PolizaVigente{
        +vigente(): Boolean //<<Override>>//
    }
    
    class PolizaFinalizada{
        +finalizada(): Boolean //<<Override>>//
    }'/
    
    class Vehiculo {
        -dominio: String
        -chasis: String
        -motor: String
        -modelo: String
        -marca: String
        -fabricacion: Integer
    }

    class MedidaSeguridad {
	  -seGuardaEnGarage: Boolean
	  -poseeAlarma: Boolean
	  -poseeRastreoVehicular: Boolean
	  -poseeTuercasAntirrobo: Boolean
    }
    
    abstract FormaPago {
        +{abstract}polizaPaga(): Boolean
    }
    
    class PagoMensual {
        +polizaPaga(): Boolean //<<Override>>//
    }
    
    class PagoSemestral {
        +polizaPaga(): Boolean //<<Override>>//
    }
    
    class Cuota {
        -importe: MonetaryAmount
		-mesCorrespondiente: Mes
		-anio: Integer
        -cuotaPaga: Boolean
        +registarPago(): Void
    }
    

	class Localidad {
		-nombre: String
		-CPA: Integer
		-factorRiegoActual: Float
	}
	
	class FactorRiesgo{
		-valor: Float
	}
	
	class VigenciaFactorRiesgo{
		-fechaInicio: Timestamp
		-fechaFin: Timestamp
	}
	Localidad "1" -  "1..n" FactorRiesgo
	(Localidad, FactorRiesgo) . VigenciaFactorRiesgo

	class Provincia {
		-nombre: String
	}
	class Pais {
		-nombre: String
	}

    class Usuario {
	    -nombreUsuario: String
	    -passwordHash: byte[512]
	    -salt: byte[16]
	    -nombre: String
	    -apellido: String
	    -email: String
    }
	
	class TipoCobertura{
		-nombre: String
		-descripcion: String
		-valor: Float
	}
	
	class Pago{
		-fechaHora: Timestamp
		-premio: MonetaryAmount
		-recargoMora: MonetaryAmount
		-bonificacionPagoAdelantado: MonetaryAmount
		+importe(): MonetaryAmount
	}
	
	class Recibo{
		-numeroRecibo: Integer
		+emitir(): ReciboDTO
	}
	

	
	
    
    enum EstadoPoliza {
        Generada
        Vigente
        Supendida
        Finalizada
    }

    enum TipoDocumento {
        DNI
        LU
        LC
        LE
    }
    
    enum TipoCliente {
        Normal
        Activo
        Plata
    }

    enum CondicionIva {
        ResponsableInscripto
        ResponsableNoInscripto
        NoResponsable
        SujetoExento
        ConsumidorFinal
        ResponsableMonotributo
        NoCategorizado
        ProveedorExterior
        ClienteExterior
        Liberado
        ResponsableInscriptoPercepcion
        PeqContribuyente
        MonotributistaSocial
        PeqContribuyenteSocial
    }


    enum EstadoCivil{
        Soltero
        Casado
        Viudo
    }

    enum Sexo {
        Masculino
        Femenino
    }
    
    Cliente "1" -up- "0..n" Poliza
    Cliente "1..n" -- "1" Domicilio
    
    /'Usuario <-- Cobrador: <<is role of>>
    Usuario <-- ProductorSeguros: <<is role of>>
    Usuario <-- Gerente: <<is role of>>
	'/
   
    Poliza "0..n" o-- "1" Localidad
    Poliza "1..n" o-- "0..n" HijoDeclarado
    Poliza "1..n" o-- "1" Vehiculo
    Poliza "1" o-- "1" FormaPago
    Poliza "1" -- "1..n" ModificacionPoliza
	Poliza "n" -right- "1" TipoCobertura
    
    ModificacionPoliza "1" -- "0..n" HijoDeclarado
    ModificacionPoliza "1" -- "1" Vehiculo
    
    Vehiculo "1..n" *-- "1" MedidaSeguridad
    
    /'Poliza .. EstadoPoliza
    EstadoPoliza <|-- PolizaVigente
    EstadoPoliza <|-- PolizaGenerada
    EstadoPoliza <|-- PolizaSuspendida
    EstadoPoliza <|-- PolizaFinalizada'/
    
    FormaPago <|-- PagoMensual
    FormaPago <|-- PagoSemestral
    
    PagoMensual "1" *-- "6" Cuota
    PagoSemestral "1" *-- "1" Cuota

    Domicilio "1..n" -- "1" Localidad
	Localidad "1..n" -- "1" Provincia
	Provincia "1..n" -- "1" Pais
	
	Pago "1" -- "1..n" Cuota
	Pago "1" -- "1" Recibo
	Poliza "1" -- "1" Pago
	Usuario "1" -- "1" Pago
}

package "Acceso a Datos"{
    interface "DAO<T>" {
        +guardar(<T>): Void
        +modifcar(<T>, String[]): Void
        +eliminar(<T>): Void
        +getAll(): ArrayList<T>
    }
    
    class DaoCliente{
        -clientes: ArrayList<Cliente>
        +guardar(Cliente): Void //<<Override>>//
        +modificar(Cliente, String[]): Void //<<Override>>//
        +eliminar(Cliente): Void //<<Override>>//
        +getAll(): ArrayList<Cliente> //<<Override>>//
    }
    
    class DaoPoliza{
        -polizas: ArrayList<Poliza>
        +guardar(Poliza): Void //<<Override>>//
        +modificar(Poliza, String[]): Void //<<Override>>//
        +eliminar(Poliza): Void //<<Override>>//
        +getAll(): ArrayList<Poliza> //<<Override>>//
    }
    
    class DaoUsuario{
        -usuarios: ArrayList<Usuario>
        +guardar(Usuario): Void //<<Override>>//
        +modificar(Usuario, String[]): Void //<<Override>>//
        +eliminar(Usuario): Void //<<Override>>//
        +getAll(): ArrayList<Usuario> //<<Override>>//
    }
    
    class ReciboDTO {
		-nroCliente: Integer
		-nombreCliente: String
		-apellidoCliente: String
		-domicilioRiesgo: String
		-marca: String
		-modelo: String
		-anioFabricacion: Integer
		-patente: String
		-nroPoliza: Integer
		-inicioVigencia: Date
		-finVigencia: Date
		-tipoCobertura: String
		-sumaAsegurada: MonetaryAmount
		-fechaPago: Date
		-premio: MonetaryAmount
		-recargosMora: MonetaryAmount
		-bonificacionPagoAdelantado: MonetaryAmount
	}
	
    "DAO<T>" <|.. DaoPoliza: <<implements>>
    "DAO<T>" <|.. DaoCliente: <<implements>>
    "DAO<T>" <|.. DaoUsuario: <<implements>>
}

package Logica{
    class GestorCliente <<(S, #FF7700) Singleton>> {
        -{static} singleton: GestorCliente
        -GestorCliente()
        +{static} getInstance(): GestorCliente
        +buscar(String[]): Cliente 
        +modificar(Cliente, String[]): Void
        +alta(String[]): Cliente
        +calcularIdCliente(Cliente): Void
    }
    
    class GestorPoliza <<(S, #FF7700) Singleton>> {
        -{static} singleton: GestorPoliza
        -GestorPoliza()
        +{static} getInstance(): GestorPoliza
        +alta(String[]): Poliza
        +buscar(String[]): Poliza
        +modificar(Poliza, String[]): Void
        +registrarPago(Poliza): Void
    }

    class GestorUsuario <<(S, #FF7700) Singleton>> {
        -{static} singleton: GestorUsuario
        -GestorUsuario()
        +{static} getInstance(): GestorUsuario
        +alta(String[]): Usuario
        +buscar(String[]): Usuario
        +modifcar(Usuario, String[]): Void
        +eliminar(Usuario): Void
    }
    
    class GestorSubSistemaDeSiniestros <<(S, #FF7700) Singleton>> {
        -{static} singleton: GestorSubSistemaDeSiniestros
        -GestorSubSistemaDeSiniestros()
        +{static} getInstance(): GestorSubSistemaDeSiniestros 
    }

	class GestorSistemaFinanciero <<(S, #FF7700) Singleton>> {
        -{static} singleton: GestorSistemaFinanciero
        -GestorSistemaFinanciero()
        +{static} getInstance(): GestorSistemaFinanciero
    }
	class GestorGeografico <<(S, #FF7700) Singleton>>{
		-{static} singleton: GestorGeografico
		-GestorGeografico()
		+{static} getInstance(): GestorGeografico
	}
	class GestorPagos <<(S, #FF7700) Singleton>>{
		-{static} singleton: GestorPagos
		-GestorPagos()
		+{static} getInstance(): GestorPagos
	}
	class GestorDocumentos <<(S, #FF7700) Singleton>>{
		-{static} singleton: GestorDocumentos
		-GestorDocumentos()
		+{static} getInstance(): GestorDocumentos
	}

    GestorPoliza .. GestorCliente
}


DaoCliente -- GestorCliente
DaoPoliza -- GestorPoliza
DaoUsuario -- GestorUsuario
'Poliza -- ValorAutomovil'

'Relaciones entre clases y gestores'

Cliente "n" -- "1" GestorCliente
Localidad "n" -- "1" GestorGeografico
Provincia "n" -- "1" GestorGeografico
Pais "n" -- "1" GestorGeografico

'Relaciones entredistintos gestores'

GestorPagos "1" -- "1" GestorDocumentos
GestorPoliza "1" -- "1" GestorPagos
GestorPagos "1" -- "1" GestorSubSistemaDeSiniestros
Gestor

@endUML