feat: ahora se pueden ver las propiedades dadas de baja y añadido el tema de los servicios

Signed-off-by: fede <federico.nicolas.polidoro@gmail.com>
This commit is contained in:
2024-12-06 00:01:31 -03:00
parent 5289c07d84
commit dee2031d87
12 changed files with 291 additions and 135 deletions

View File

@@ -46,6 +46,22 @@ public class PropiedadesController: ControllerBase {
return Ok(ret); return Ok(ret);
} }
[HttpGet("api/propiedades/Propietario/Bajas")]
public IActionResult ObtenerPropiedadesPorPropietarioBajas (
[FromHeader(Name = "Email")] string email,
[FromHeader(Name = "Auth")] string Auth) {
if (String.IsNullOrEmpty(Auth)) return Unauthorized();
var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 8);
if (validacion1 == false) return Unauthorized();
email = email.Trim();
if (String.IsNullOrEmpty(email)) return BadRequest(new {message ="falta campo email"});
IQueryable<PropiedadesDto> ret = RepositorioPropiedades.Singleton.ObtenerPropiedadesDeBajaPorEmail(email);
return Ok(ret);
}
[HttpPost("api/propiedad")] [HttpPost("api/propiedad")]
public IActionResult AltaPropiedad([FromBody] AltaPropiedadDto propiedad, [FromHeader(Name = "Auth")] string Auth) { public IActionResult AltaPropiedad([FromBody] AltaPropiedadDto propiedad, [FromHeader(Name = "Auth")] string Auth) {
if (String.IsNullOrEmpty(Auth)) return Unauthorized(); if (String.IsNullOrEmpty(Auth)) return Unauthorized();
@@ -86,6 +102,8 @@ public class PropiedadesController: ControllerBase {
Cliente? cli = RepositorioPropietario.Singleton.ObtenerPropietarioPorEmail(propiedad.Email); Cliente? cli = RepositorioPropietario.Singleton.ObtenerPropietarioPorEmail(propiedad.Email);
if (cli == null) return BadRequest(new { message = "El email no corresponde a un propietario"}); if (cli == null) return BadRequest(new { message = "El email no corresponde a un propietario"});
List<Servicio> servs = RepositorioServicios.Singleton.ObtenerServiciosPorDescripcion(propiedad.Servicios);
Propiedade Prop = new Propiedade{ Propiedade Prop = new Propiedade{
Id = propiedad.id, Id = propiedad.id,
Canthabitaciones = propiedad.Canthabitaciones, Canthabitaciones = propiedad.Canthabitaciones,
@@ -94,6 +112,7 @@ public class PropiedadesController: ControllerBase {
Ubicacion = propiedad.Ubicacion, Ubicacion = propiedad.Ubicacion,
Letra = propiedad.Letra ?? null, Letra = propiedad.Letra ?? null,
Piso = propiedad.Piso ?? null, Piso = propiedad.Piso ?? null,
IdServicios = servs,
}; };
bool ret = RepositorioPropiedades.Singleton.PatchPropiedad(Prop); bool ret = RepositorioPropiedades.Singleton.PatchPropiedad(Prop);
@@ -115,8 +134,8 @@ public class PropiedadesController: ControllerBase {
var ret = RepositorioPropiedades.Singleton.BajaPropiedad(id, propie); var ret = RepositorioPropiedades.Singleton.BajaPropiedad(id, propie);
return ret ? return ret ?
Ok(new {message = $"la propiedad con id {id} fue dada de baja"}): Ok(new { message = $"Se Cambio el estado de la propiedad con id {id}"}):
BadRequest(new {message="Fallo al dar de baja la propiedad"}); BadRequest(new {message="Fallo al cambiar el estado de la propiedad"});
} }
[HttpPut("api/propiedades/addServicio")] [HttpPut("api/propiedades/addServicio")]

View File

@@ -1,3 +1,3 @@
namespace Entidades.Dto; namespace Entidades.Dto;
public record PatchPropiedadDto(int id, string Ubicacion, int Canthabitaciones, int? Piso, string? Letra, string Email, int tipo); public record PatchPropiedadDto(int id, string Ubicacion, int Canthabitaciones, int? Piso, string? Letra, string Email, int tipo, List<string> Servicios);

View File

@@ -6,4 +6,5 @@ public class PropiedadesDto {
public int piso { get; set; } public int piso { get; set; }
public string letra { get; set; } = ""; public string letra { get; set; } = "";
public string Tipo { get; set; } = ""; public string Tipo { get; set; } = "";
public string? Servicios {get;set;} = "";
} }

View File

@@ -7,6 +7,7 @@
import InqPage from "./paginas/inquilino.svelte"; import InqPage from "./paginas/inquilino.svelte";
import PropPage from "./paginas/propietario.svelte"; import PropPage from "./paginas/propietario.svelte";
import MisPropiedades from "./paginas/MisPropiedades.svelte"; import MisPropiedades from "./paginas/MisPropiedades.svelte";
import MisPropiedadesDeBaja from "./paginas/MisPropiedadesDeBaja.svelte";
import FrontAdmin from "./paginas/grupos/AdminG.svelte"; import FrontAdmin from "./paginas/grupos/AdminG.svelte";
import FrontInformes from "./paginas/grupos/InformesG.svelte"; import FrontInformes from "./paginas/grupos/InformesG.svelte";
import FrontInquilino from "./paginas/grupos/InquilinoG.svelte"; import FrontInquilino from "./paginas/grupos/InquilinoG.svelte";
@@ -34,19 +35,25 @@
<ProteRoute componente={PublicarPropiedad}/> <ProteRoute componente={PublicarPropiedad}/>
</Route> </Route>
<!--Mis Propiedades-->
<Route path="/accion/2">
<ProteRoute componente={MisPropiedades}/>
</Route>
<!--Crear Cuenta Inquilino--> <!--Crear Cuenta Inquilino-->
<Route path="/accion/4"> <Route path="/accion/4">
<ProteRoute componente={InqPage}/> <ProteRoute componente={InqPage}/>
</Route> </Route>
<!--Crear Cuenta Propietario--> <!--Crear Cuenta Propietario-->
<Route path="/accion/5"> <Route path="/accion/5">
<ProteRoute componente={PropPage}/> <ProteRoute componente={PropPage}/>
</Route> </Route>
<!--Mis Propiedades--> <!--Crear Cuenta Propietario-->
<Route path="/accion/2"> <Route path="/accion/8">
<ProteRoute componente={MisPropiedades}/> <ProteRoute componente={MisPropiedadesDeBaja}/>
</Route> </Route>
<!--Paginas info Grupo--> <!--Paginas info Grupo-->

View File

@@ -39,10 +39,10 @@
} }
</script> </script>
<div class="list-group"> <div class="list-group" style="border: 1px solid black">
{#each $permisos as item} {#each $permisos as item}
<a href="/accion/{item.id}" class="list-group-item list-group-item-action"> <a href="/accion/{item.id}" class="list-group-item list-group-item-action">
{item.descripcion} {item.descripcion}
</a> </a>
{/each} {/each}
</div> </div>

View File

@@ -1,10 +1,9 @@
<script lang="ts"> <script lang="ts">
import { fade, fly, scale } from "svelte/transition"; import { fade } from "svelte/transition";
import type {PropiedadDto} from "../types"
import ModalEstatico from "./ModalEstatico.svelte"; import ModalEstatico from "./ModalEstatico.svelte";
import ModificarPropiedadForm from "./modificarPropiedadForm.svelte"; import ModificarPropiedadForm from "./modificarPropiedadForm.svelte";
let { id, ubicacion, tipo, letra, piso,canthabitaciones }: PropiedadDto = $props(); let { id, ubicacion, tipo, letra, piso,canthabitaciones, servicios } = $props();
let modal: boolean = $state(false); let modal: boolean = $state(false);
let modalpayload: string = $state(""); let modalpayload: string = $state("");
@@ -26,17 +25,10 @@
}, },
}); });
if (responce.ok){
const json = await responce.json(); const json = await responce.json();
modalpayload = json.message; modalpayload = json.message;
modal = true; modal = true;
} location.reload();
if (!responce.ok) {
const json = await responce.json();
modalpayload = json.message;
modal = true;
}
}catch (e){ }catch (e){
console.error(e); console.error(e);
} }
@@ -50,9 +42,11 @@
<td>{letra}</td> <td>{letra}</td>
<td>{piso}</td> <td>{piso}</td>
<td>{tipo}</td> <td>{tipo}</td>
<td>{servicios}</td>
<td class="text-end"> <td class="text-end">
<button class="btn btn-outline-secondary" onclick={() => setmod()}>Modificar</button> <button class="btn btn-outline-secondary" onclick={()=> setmod()}>Modificar</button>
<button class="btn btn-outline-danger" onclick={()=> BajaPropiedad()}>Baja</button> <button class="btn btn-outline-secondary" >Ver Más</button>
<button class="btn btn-outline-danger" onclick={() => BajaPropiedad()}>Baja</button>
</td> </td>
</tr> </tr>
{#if modal} {#if modal}
@@ -60,8 +54,8 @@
{/if} {/if}
{#if modificar} {#if modificar}
<tr transition:fade={{duration:100}}> <tr transition:fade={{duration:100}}>
<td colspan="7"> <td colspan="8">
<ModificarPropiedadForm {id} {ubicacion} {canthabitaciones} {letra} {piso} {tipo} /> <ModificarPropiedadForm {id} {ubicacion} {canthabitaciones} {letra} {piso} {tipo} {servicios}/>
</td> </td>
</tr> </tr>
{/if} {/if}

View File

@@ -1,130 +1,161 @@
<script lang="ts"> <script lang="ts">
import type { PropiedadDto } from "../types"; import { urlG } from "../stores/urlStore";
import {urlG} from "../stores/urlStore";
import { onMount } from "svelte"; import { onMount } from "svelte";
let {canthabitaciones, id, letra, piso, tipo, ubicacion}: PropiedadDto = $props();
onMount(()=> { let { canthabitaciones, id, letra, piso, tipo, ubicacion, servicios } = $props();
switch(tipo) { let serviciosSeleccionados: string[] = $state([]);
case"Casa": const serviciosDisponibles = ["Gas", "Internet", "Telefono", "Luz"];
tipo = "1"
break; onMount(() => {
case"Piso": switch (tipo) {
tipo = "2" case "Casa":
break; tipo = "1";
case"Departamento": break;
tipo = "3" case "Piso":
break; tipo = "2";
case"Galpon": break;
tipo = "4" case "Departamento":
break; tipo = "3";
case"LocalComercial": break;
tipo = "5" case "Galpon":
break; tipo = "4";
case"Oficina": break;
tipo = "6" case "LocalComercial":
break; tipo = "5";
} break;
case "Oficina":
tipo = "6";
break;
}
serviciosSeleccionados = servicios.split(", ");
}); });
let showAlert: boolean = $state(false); let showAlert: boolean = $state(false);
let errorMessage: string = $state(""); let errorMessage: string = $state("");
const token = sessionStorage.getItem("token"); const token = sessionStorage.getItem("token");
const email = localStorage.getItem("email"); const email = localStorage.getItem("email");
async function submitForm(e: Event) { async function submitForm(e: Event) {
e.preventDefault(); e.preventDefault();
try { try {
let response = await fetch(String($urlG + "/api/propiedad"), { let response = await fetch(String($urlG + "/api/propiedad"), {
method: 'PATCH', method: "PATCH",
headers: { headers: {
'Auth' : String(token), Auth: String(token),
'Content-Type' : 'application/json', "Content-Type": "application/json",
}, },
body: JSON.stringify({id, canthabitaciones, letra, piso, tipo, ubicacion, email}), body: JSON.stringify({
}); id,
if (response.ok){ canthabitaciones,
location.reload(); letra,
} piso,
if (!response.ok) { tipo,
const errorData = await response.json(); ubicacion,
errorMessage = errorData.message; email,
showAlert = true; servicios: serviciosSeleccionados,
} }),
} catch (e) { });
throw new Error("Fallo al enviar el formulario para crear un inquilino"); if (response.ok) {
location.reload();
} }
if (!response.ok) {
const errorData = await response.json();
errorMessage = errorData.message;
showAlert = true;
}
} catch (e) {
throw new Error("Fallo al enviar el formulario para crear un inquilino");
}
} }
</script> </script>
{#if showAlert} {#if showAlert}
<div class='alert alert-warning alert-dismissible fade show' role='alert'> <div class="alert alert-warning alert-dismissible fade show" role="alert">
<strong>{errorMessage}</strong> <strong>{errorMessage}</strong>
<button type="button" class="btn-close close" aria-label="Close" data-bs-dismiss="alert"></button> <button
type="button"
class="btn-close close"
aria-label="Close"
data-bs-dismiss="alert"
></button>
</div> </div>
{/if} {/if}
<form onsubmit={submitForm} class="card card-body"> <form onsubmit={submitForm} class="card card-body">
<div class="form-floating mb-3"> <div class="form-floating mb-3">
<input
type="text"
id="ubicacion"
class="form-control"
bind:value={ubicacion}
placeholder="Ubicación"
required
/>
<label for="ubicacion">Ubicación</label>
</div>
<div class="form-floating mb-3">
<input
type="number"
id="canthabitaciones"
class="form-control"
bind:value={canthabitaciones}
min="1"
placeholder="Cantidad de Habitaciones"
required
/>
<label for="canthabitaciones">Cantidad de Habitaciones</label>
</div>
<div class="form-floating mb-3">
<input
type="number"
id="piso"
class="form-control"
bind:value={piso}
min="0"
placeholder="Piso"
/>
<label for="piso">Piso</label>
</div>
<div class="form-floating mb-3">
<input
type="text"
id="letra"
class="form-control"
bind:value={letra}
maxlength="1"
placeholder="Letra"
/>
<label for="letra">Letra</label>
</div>
<div class="form-floating mb-3">
<select id="idtipo" class="form-select" bind:value={tipo} required>
<option value="1">Casa</option>
<option value="2">Piso</option>
<option value="3">Departamento</option>
<option value="4">Galpon</option>
<option value="5">LocalComercial</option>
<option value="6">Oficina</option>
</select>
<label for="idtipopropiedad">Tipo de propiedad</label>
</div>
<div class="mb-3">
<h6 class="form-floating form-label">Servicios</h6>
{#each serviciosDisponibles as servicio}
<div class="form-check">
<input <input
type="text" type="checkbox"
id="ubicacion" class="form-check-input"
class="form-control" bind:group={serviciosSeleccionados}
bind:value={ubicacion} value={servicio}
placeholder="Ubicación" id={`servicio-${servicio}`}
required />
/> <label class="form-check-label" for={`servicio-${servicio}`}>
<label for="ubicacion">Ubicación</label> {servicio}
</label>
</div> </div>
<div class="form-floating mb-3"> {/each}
<input </div>
type="number"
id="canthabitaciones" <button type="submit" class="btn btn-primary">Enviar</button>
class="form-control"
bind:value={canthabitaciones}
min="1"
placeholder="Cantidad de Habitaciones"
required
/>
<label for="canthabitaciones">Cantidad de Habitaciones</label>
</div>
<div class="form-floating mb-3">
<input
type="number"
id="piso"
class="form-control"
bind:value={piso}
min="0"
placeholder="Piso"
/>
<label for="piso">Piso</label>
</div>
<div class="form-floating mb-3">
<input
type="text"
id="letra"
class="form-control"
bind:value={letra}
maxlength="1"
placeholder="Letra"
/>
<label for="letra">Letra</label>
</div>
<div class="form-floating mb-3">
<select
id="idtipo"
class="form-select"
bind:value={tipo}
required
>
<option value="1">Casa</option>
<option value="2">Piso</option>
<option value="3">Departamento</option>
<option value="4">Galpon</option>
<option value="5">LocalComercial</option>
<option value="6">Oficina</option>
</select>
<label for="idtipopropiedad">Tipo de propiedad</label>
</div>
<button type="submit" class="btn btn-primary">Enviar</button>
</form> </form>

View File

@@ -48,11 +48,12 @@
<th>Letra</th> <th>Letra</th>
<th>Piso</th> <th>Piso</th>
<th>Tipo</th> <th>Tipo</th>
<th>Servicios</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{#each $propiedades as propiedad} {#each $propiedades as propiedad}
<RowPropiedad id={propiedad.id} ubicacion={propiedad.ubicacion} letra={propiedad.letra} piso={propiedad.piso} tipo={propiedad.tipo} canthabitaciones={propiedad.canthabitaciones} /> <RowPropiedad id={propiedad.id} ubicacion={propiedad.ubicacion} letra={propiedad.letra} piso={propiedad.piso} tipo={propiedad.tipo} canthabitaciones={propiedad.canthabitaciones} servicios={propiedad.servicios} />
{/each} {/each}
</tbody> </tbody>

View File

@@ -0,0 +1,64 @@
<script lang="ts">
import { onMount } from "svelte";
import NavBarAutocompletable from "../Componentes/NavBarAutocompletable.svelte" ;
import { writable } from 'svelte/store';
import RowPropiedad from "../Componentes/RowPropiedad.svelte";
import type { PropiedadDto } from "../types";
let propiedades = writable<PropiedadDto[]>([]);
let email = localStorage.getItem("email");
let token = sessionStorage.getItem("token");
let fallo: boolean = $state(false);
onMount(async ()=> {
try {
const responce = await fetch("http://localhost:5007/api/propiedades/Propietario/Bajas", {
method: "GET",
headers: {
'Auth': String(token),
'Email' : String(email),
'Content-Type' : "application/json"
},
});
if (responce.ok){
const json = await responce.json();
propiedades.set(json);
return;
}
if (!responce.ok){
fallo = true;
}
} catch (e){
console.error(e);
}
});
</script>
<NavBarAutocompletable/>
<div class="container table-responsive">
<table class="table-responsive table table-striped">
<thead>
<tr>
<th>#</th>
<th>ubicacion</th>
<th>Habitaciones</th>
<th>Letra</th>
<th>Piso</th>
<th>Tipo</th>
<th>Servicios</th>
</tr>
</thead>
<tbody>
{#each $propiedades as propiedad}
<RowPropiedad id={propiedad.id} ubicacion={propiedad.ubicacion} letra={propiedad.letra} piso={propiedad.piso} tipo={propiedad.tipo} canthabitaciones={propiedad.canthabitaciones} servicios={propiedad.servicios} />
{/each}
</tbody>
</table>
</div>
{#if fallo}
<div class="container alert alert-danger">Fallo al intentar Obtener la lista de propiedades</div>
{/if}

View File

@@ -5,6 +5,7 @@ export type PropiedadDto = {
piso: string | null, piso: string | null,
letra: string | null, letra: string | null,
canthabitaciones: number, canthabitaciones: number,
servicios: string
} }
export type Permiso = { export type Permiso = {
id: number; id: number;

View File

@@ -68,7 +68,7 @@ public bool AñadirPropiedad(Propiedade? prop) {
public bool PatchPropiedad(Propiedade prop) { public bool PatchPropiedad(Propiedade prop) {
var con = Context; var con = Context;
Propiedade? propi = con.Propiedades.FirstOrDefault(x=>x.Id == prop.Id); Propiedade? propi = con.Propiedades.Include(x=>x.IdServicios).FirstOrDefault(x=>x.Id == prop.Id);
if (propi == null) return false; if (propi == null) return false;
@@ -78,17 +78,45 @@ public bool AñadirPropiedad(Propiedade? prop) {
propi.Piso = prop.Piso; propi.Piso = prop.Piso;
propi.Letra = prop.Letra; propi.Letra = prop.Letra;
propi.IdServicios.Clear();
foreach(Servicio ser in prop.IdServicios) {
var servi = con.Servicios.FirstOrDefault(x=>x.Id == ser.Id);
if (servi == null) return false;
propi.IdServicios.Add(servi);
}
return Guardar(con); return Guardar(con);
} }
public IQueryable<PropiedadesDto> ObtenerPropiedadesPorEmail(string email) { public IQueryable<PropiedadesDto> ObtenerPropiedadesPorEmail(string email) {
FormattableString sqlq = $""" FormattableString sqlq = $"""
SELECT p.id, p.ubicacion as Ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion as Tipo From Propiedades p SELECT p.id, p.ubicacion as Ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion as Tipo, GROUP_CONCAT(IFNULL(s.descripcion, '') SEPARATOR ', ') AS Servicios
FROM Propiedades p
JOIN Clientes c ON c.dni = p.dnipropietario JOIN Clientes c ON c.dni = p.dnipropietario
JOIN TipoPropiedad tp ON tp.id = p.idtipropiedad JOIN TipoPropiedad tp ON tp.id = p.idtipropiedad
LEFT JOIN Servicio_Propiedad ps ON ps.idPropiedad = p.id
LEFT JOIN Servicios s ON s.Id = ps.idServicio
WHERE c.email = {email} AND p.idestado = 1 WHERE c.email = {email} AND p.idestado = 1
GROUP BY p.id
"""; """;
var ret = Context.Database.SqlQuery<PropiedadesDto>(sqlq); var ret = Context.Database.SqlQuery<PropiedadesDto>(sqlq);
return ret;
}
public IQueryable<PropiedadesDto> ObtenerPropiedadesDeBajaPorEmail(string email) {
FormattableString sqlq = $"""
SELECT p.id, p.ubicacion as Ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion as Tipo, GROUP_CONCAT(IFNULL(s.descripcion, '') SEPARATOR ', ') AS Servicios
FROM Propiedades p
JOIN Clientes c ON c.dni = p.dnipropietario
JOIN TipoPropiedad tp ON tp.id = p.idtipropiedad
LEFT JOIN Servicio_Propiedad ps ON ps.idPropiedad = p.id
LEFT JOIN Servicios s ON s.Id = ps.idServicio
WHERE c.email = {email} AND p.idestado = 3
GROUP BY p.id
""";
var ret = Context.Database.SqlQuery<PropiedadesDto>(sqlq);
return ret; return ret;
} }
@@ -114,7 +142,12 @@ public bool AñadirPropiedad(Propiedade? prop) {
Propiedade? prop = con.Propiedades.FirstOrDefault(x=>x.Id == id); Propiedade? prop = con.Propiedades.FirstOrDefault(x=>x.Id == id);
if (prop == null) return false; if (prop == null) return false;
if (prop.Dnipropietario != cli.Dni) return false; if (prop.Dnipropietario != cli.Dni) return false;
prop.Idestado = 3;
if(prop.Idestado == 1){
prop.Idestado = 3;
}else{
prop.Idestado = 1;
}
return Guardar(con); return Guardar(con);

View File

@@ -8,4 +8,9 @@ public class RepositorioServicios: RepositorioBase<RepositorioServicios> {
.SelectMany(x => x.IdServicios) .SelectMany(x => x.IdServicios)
.Select(x=>x.Id); .Select(x=>x.Id);
} }
public List<Servicio> ObtenerServiciosPorDescripcion(List<string> servs){
var servicios = Context.Servicios.Where(x=> servs.Contains(x.Descripcion)).ToList();
return servicios;
}
} }