OpcionVenta-y-Ventas #50
25
Aspnet/Builder/DtoBuilder/OpcionVentaDtoBuilder.cs
Normal file
25
Aspnet/Builder/DtoBuilder/OpcionVentaDtoBuilder.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using Entidades.Dto;
|
||||
|
||||
namespace AlquilaFacil.Builder;
|
||||
public class OpcionVentaDtoBuilder: Builder<OpcionVentaDto>{
|
||||
public OpcionVentaDtoBuilder SetId(long id) {
|
||||
data.Id = id;
|
||||
return this;
|
||||
}
|
||||
public OpcionVentaDtoBuilder SetMonto(decimal monto) {
|
||||
data.Monto = monto;
|
||||
return this;
|
||||
}
|
||||
public OpcionVentaDtoBuilder SetDivisa(string divisa) {
|
||||
data.Divisa = divisa;
|
||||
return this;
|
||||
}
|
||||
public OpcionVentaDtoBuilder SetEnOrden(bool v) {
|
||||
data.EnOrden = v;
|
||||
return this;
|
||||
}
|
||||
public OpcionVentaDtoBuilder SetFueEjercido(int idestado) {
|
||||
data.FueEjercido = idestado==1?false:true;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
41
Aspnet/Builder/DtoBuilder/VentasDtoBuilder.cs
Normal file
41
Aspnet/Builder/DtoBuilder/VentasDtoBuilder.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using Entidades.Dto;
|
||||
|
||||
namespace AlquilaFacil.Builder;
|
||||
public class VentasDtoBuilder: Builder<VentasDto> {
|
||||
public VentasDtoBuilder SetId(long id) {
|
||||
data.Id = id;
|
||||
return this;
|
||||
}
|
||||
public VentasDtoBuilder SetMonto(decimal monto) {
|
||||
data.Monto = monto;
|
||||
return this;
|
||||
}
|
||||
public VentasDtoBuilder SetDivisa(string divisa) {
|
||||
data.Divisa = divisa;
|
||||
return this;
|
||||
}
|
||||
public VentasDtoBuilder SetUbicacion(string ubicacion) {
|
||||
data.Ubicacion = ubicacion;
|
||||
return this;
|
||||
}
|
||||
public VentasDtoBuilder SetNombreVendedor(string nombre) {
|
||||
data.NombreVendedor = nombre;
|
||||
return this;
|
||||
}
|
||||
public VentasDtoBuilder SetIdVendedor(long idVendedor) {
|
||||
data.IdVendedor = idVendedor;
|
||||
return this;
|
||||
}
|
||||
public VentasDtoBuilder SetNombreComprador(string nombre) {
|
||||
data.NombreComprador = nombre;
|
||||
return this;
|
||||
}
|
||||
public VentasDtoBuilder SetIdComprador(long Id) {
|
||||
data.IdComprador = Id;
|
||||
return this;
|
||||
}
|
||||
public VentasDtoBuilder SetEstado(string estado) {
|
||||
data.Estado = estado;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -47,4 +47,9 @@ public class PrecontratoBuilder : Builder<Contrato> {
|
||||
data.MesesDurationContrato = mesesDuracionContrato;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PrecontratoBuilder SetOpcionVenta(bool tieneOpcionVenta){
|
||||
data.Tieneopcionventa = tieneOpcionVenta == false?0Lu:1Lu;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -336,6 +336,7 @@ public class ContratoController: ControllerBase {
|
||||
.SetPropiedad(p.Id)
|
||||
.SetFecha(DateTime.Parse(dto.fechaprimernotificacion))
|
||||
.SetMesesDuracion(dto.MesesDuracionContrato)
|
||||
.SetOpcionVenta(dto.TieneOpcionVenta)
|
||||
.Build();
|
||||
|
||||
|
||||
@@ -349,7 +350,18 @@ public class ContratoController: ControllerBase {
|
||||
.SetMensaje($"El propietario {propi.Nombre} {propi.Apellido} te requiere que carges informacion de {dto.CantidadGarantes} Garantes")
|
||||
.Build();
|
||||
|
||||
var ret = RepositorioContratos.Singleton.CargaPrecontrato(precontrato, notificacion);
|
||||
bool ret;
|
||||
if (dto.TieneOpcionVenta==false){
|
||||
ret = RepositorioContratos.Singleton.CargaPrecontrato(precontrato, notificacion);
|
||||
} else {
|
||||
Venta v = new Venta{
|
||||
Idestado = 1,
|
||||
Iddivisa = dto.iddivisa,
|
||||
Monto = dto.MontoOpcion,
|
||||
};
|
||||
ret = RepositorioContratos.Singleton.CargaPrecontratoOpcionVenta(precontrato, notificacion, v);
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
ret = RepositorioNotificaciones.Singleton.MarcarComoLeido(cli.Dni, DateTime.Parse(dto.fechaprimernotificacion));
|
||||
}
|
||||
@@ -816,6 +828,7 @@ public class ContratoController: ControllerBase {
|
||||
if (dto.MesesHastaAumento <= 0) ret += "No puede tener 0 o menos meses hasta el aumento\n";
|
||||
if (dto.MesesDuracionContrato <= 0) ret += "No puede tener 0 o menos meses de duracion\n";
|
||||
if (dto.MesesDuracionContrato < dto.MesesHastaAumento) ret += "el tiempo hasta aumento no puede ser mayor de \n";
|
||||
if (dto.TieneOpcionVenta == true && dto.MontoOpcion <=0) ret +="No puede tener un monto de venta negativo o 0";
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
321
Aspnet/Controllers/VentaController.cs
Normal file
321
Aspnet/Controllers/VentaController.cs
Normal file
@@ -0,0 +1,321 @@
|
||||
using System.Configuration;
|
||||
using System.Formats.Asn1;
|
||||
using System.Text.Json;
|
||||
using AlquilaFacil.Builder;
|
||||
using AlquilaFacil.Config;
|
||||
using Entidades;
|
||||
using Entidades.Dto;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Minio;
|
||||
using Minio.DataModel.Args;
|
||||
using Modelo;
|
||||
|
||||
namespace AlquilaFacil.Controllers;
|
||||
[ApiController]
|
||||
public class VentaController:ControllerBase {
|
||||
|
||||
[HttpPost("/api/ventas/ejercerOpcionVenta")]
|
||||
public IActionResult EjercerOpcionVenta([FromHeader(Name="Auth")]string Auth, [FromQuery]long idcontrato=0) {
|
||||
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Inquilino");
|
||||
if (validacion1 == false) {
|
||||
return Unauthorized();
|
||||
}
|
||||
if (idcontrato <= 0) return BadRequest(new { message = "No pueden hacer cotratos con id 0 o menor"});
|
||||
|
||||
Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
|
||||
if (cli == null) return Unauthorized();
|
||||
|
||||
Contrato? cont = RepositorioVentas.Singleton.ObtenerVentaPorContrato(idcontrato);
|
||||
if (cont == null || cont.IdventaNavigation == null) return BadRequest(new { message = "no hay un contrato por esa id"});
|
||||
if (cont.Tieneopcionventa == 0) return BadRequest(new { message = "No tiene opcion de venta"});
|
||||
if (puedeEjercer(cont) == false) return BadRequest(new { message = "No cumple con los requisitos para ejercer la opcion de compra"});
|
||||
|
||||
Venta venta = cont.IdventaNavigation;
|
||||
venta.IdVendedor = cont.Dnipropietario;
|
||||
venta.IdComprador = cont.Dniinquilino;
|
||||
venta.Idpropiedad = cont.Idpropiedad;
|
||||
venta.Fechainicio = DateTime.Now;
|
||||
|
||||
bool ret = RepositorioVentas.Singleton.PatchVenta(venta);
|
||||
|
||||
return ret?
|
||||
Ok(new { message = "Se ejercio la opcion de venta"}):
|
||||
BadRequest(new { message = "No se pude ejercer la opcion de venta"});
|
||||
}
|
||||
|
||||
[HttpPost("/api/ventas/subirReciboPago")]
|
||||
public async Task<IActionResult> SubirRecibo([FromHeader(Name="Auth")]string Auth, [FromForm]IFormFile file, long idventa ) {
|
||||
if (String.IsNullOrWhiteSpace(Auth)) return Unauthorized();
|
||||
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario");
|
||||
if (validacion1 == false){
|
||||
validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Inquilino");
|
||||
if (validacion1 == false) {
|
||||
return Unauthorized();
|
||||
}
|
||||
}
|
||||
|
||||
if (idventa <=0) return BadRequest(new { message = "Las id 0 o menor no son validas" });
|
||||
|
||||
Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
|
||||
if (cli == null) return Unauthorized();
|
||||
|
||||
Venta? venta = RepositorioVentas.Singleton.ObtenerVentaPorId(idventa);
|
||||
if (venta == null) return BadRequest(new { message = "no hay una venta por esa id"});
|
||||
|
||||
if (cli.Dni !=venta.IdComprador && cli.Dni != venta.IdVendedor) return Unauthorized();
|
||||
|
||||
if (file == null) return BadRequest(new { message = "Debe subir un archivo." });
|
||||
if (file.ContentType != "application/pdf") return BadRequest(new { message = "El archivo debe ser un documento PDF." });
|
||||
if (!Path.GetExtension(file.FileName).Equals(".pdf", StringComparison.OrdinalIgnoreCase)) return BadRequest(new { message = "El archivo debe tener la extensión .pdf." });
|
||||
|
||||
string nuevoNombreArchivo = $"id:{venta.Id}-comprador:{venta.IdComprador}-vendedor:{venta.IdVendedor}-idprop:{venta.Idpropiedad}.pdf";
|
||||
bool ret = await subirContrato(file, nuevoNombreArchivo);
|
||||
if(ret == false) return BadRequest(new {message = "No se pudo subir el archivo"});
|
||||
|
||||
ret = RepositorioVentas.Singleton.SetUrlRecibo(venta.Id, nuevoNombreArchivo);
|
||||
if (ret == false) return BadRequest(new { message = "no se pudo guardar el nombre del archivo subido"});
|
||||
|
||||
return Ok(new { message = "Se Subio el Recibo"});
|
||||
|
||||
}
|
||||
private readonly IMinioClient mc;
|
||||
public VentaController(IMinioClient minioClient) {
|
||||
mc = minioClient;
|
||||
if (mc == null){
|
||||
MinioConfigcus? mcon = JsonSerializer.Deserialize<MinioConfigcus>(System.IO.File.ReadAllText("./settings.json"))?? null;
|
||||
if (mcon == null) throw new Exception();
|
||||
|
||||
mc = new MinioClient().WithCredentials(mcon.usr, mcon.scrt)
|
||||
.WithEndpoint("192.168.1.11:9000")
|
||||
.WithSSL(false)
|
||||
.Build();
|
||||
}
|
||||
}
|
||||
private async Task<bool> subirContrato(IFormFile f, string flname) {
|
||||
try {
|
||||
var buck = new BucketExistsArgs().WithBucket("alquilafacil");
|
||||
bool encontrado = await mc.BucketExistsAsync(buck).ConfigureAwait(false);
|
||||
|
||||
if(!encontrado){
|
||||
var mb = new MakeBucketArgs().WithBucket("alquilafacil");
|
||||
await mc.MakeBucketAsync(mb).ConfigureAwait(false);
|
||||
}
|
||||
using (var stream = new MemoryStream()){
|
||||
await f.CopyToAsync(stream);
|
||||
stream.Position=0;
|
||||
PutObjectArgs putbj = new PutObjectArgs()
|
||||
.WithBucket("alquilafacil")
|
||||
.WithObject(flname)
|
||||
.WithStreamData(stream)
|
||||
.WithContentType("application/pdf")
|
||||
.WithObjectSize(stream.Length);
|
||||
await mc.PutObjectAsync(putbj);
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e ) {
|
||||
Console.Error.WriteLine(e.Message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet("/api/ventas/verRecibo")]
|
||||
public IActionResult verRecibo([FromHeader(Name="Auth")]string Auth, long idventa=0){
|
||||
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario");
|
||||
if (validacion1 == false){
|
||||
validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Inquilino");
|
||||
if (validacion1 == false) {
|
||||
return Unauthorized();
|
||||
}
|
||||
}
|
||||
if (idventa <= 0) return BadRequest(new { message = "No existen ventas validas para la id 0"});
|
||||
|
||||
Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
|
||||
if (cli == null) return Unauthorized();
|
||||
|
||||
Venta? venta = RepositorioVentas.Singleton.ObtenerVentaPorId(idventa);
|
||||
if (venta == null) return BadRequest(new { message = "no hay una venta con esa id"});
|
||||
if (cli.Dni != venta.IdComprador && cli.Dni != venta.IdVendedor) return Unauthorized();
|
||||
|
||||
try{
|
||||
var memstream = new MemoryStream();
|
||||
|
||||
var goa = new GetObjectArgs()
|
||||
.WithBucket("alquilafacil")
|
||||
.WithObject(venta.UrlRecibo)
|
||||
.WithCallbackStream(stream => {
|
||||
memstream.Position=0;
|
||||
stream.CopyTo(memstream);
|
||||
});
|
||||
|
||||
mc.GetObjectAsync(goa).Wait();
|
||||
memstream.Position = 0;
|
||||
|
||||
if (memstream.Length == 0) return BadRequest(new { message = "El archivo está vacío" });
|
||||
|
||||
return File(memstream, "application/pdf", venta.UrlRecibo);
|
||||
|
||||
} catch (Exception e){
|
||||
Console.Error.WriteLine(e);
|
||||
return BadRequest(new { message = "Fallo al intentar obtener el archivo del almacenamiento o este no existe"});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[HttpPost("/api/ventas/propietarioverifica")]
|
||||
public IActionResult PropietarioVerifica([FromHeader(Name="Auth")]string Auth, long idventa=0) {
|
||||
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario");
|
||||
if (validacion1 == false){
|
||||
validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Inquilino");
|
||||
if (validacion1 == false) {
|
||||
return Unauthorized();
|
||||
}
|
||||
}
|
||||
if (idventa <= 0) return BadRequest(new { message = "No existen ventas validas para la id 0"});
|
||||
|
||||
Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
|
||||
if (cli == null) return Unauthorized();
|
||||
|
||||
var ventas = RepositorioVentas.Singleton.ObtenerVentaPorId(idventa);
|
||||
if (ventas == null) return BadRequest(new { message ="No hay una venta con ese id"});
|
||||
if (ventas.IdVendedor != cli.Dni) return Unauthorized();
|
||||
|
||||
bool ret = RepositorioVentas.Singleton.EfectuarVenta(idventa);
|
||||
return ret ? Ok(new { message = "Se traspaso la propiedad"}): BadRequest(new { message = ""});
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("/api/venta")]
|
||||
public IActionResult ObtenerVenta([FromHeader(Name="Auth")]string Auth, long idventa=0) {
|
||||
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario");
|
||||
if (validacion1 == false){
|
||||
validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Inquilino");
|
||||
if (validacion1 == false) {
|
||||
return Unauthorized();
|
||||
}
|
||||
}
|
||||
if (idventa <= 0) return BadRequest(new { message = "No existen ventas validas para la id 0"});
|
||||
|
||||
Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
|
||||
if (cli == null) return Unauthorized();
|
||||
|
||||
var ventas = RepositorioVentas.Singleton.ObtenerVentaPorId(idventa);
|
||||
if (ventas == null) return BadRequest(new { message ="No hay una venta con ese id"});
|
||||
if (ventas.IdVendedor !=cli.Dni && ventas.IdComprador != cli.Dni) return Unauthorized();
|
||||
|
||||
var v = new VentasDtoBuilder()
|
||||
.SetId(ventas.Id)
|
||||
.SetMonto(ventas.Monto)
|
||||
.SetDivisa(ventas.IddivisaNavigation.Signo)
|
||||
.SetUbicacion(ventas.IdpropiedadNavigation.Ubicacion)
|
||||
.SetNombreVendedor($"{ventas.IdVendedorNavigation.Nombre} {ventas.IdVendedorNavigation.Apellido}")
|
||||
.SetIdVendedor(ventas.IdVendedor??0)
|
||||
.SetNombreComprador($"{ventas.IdCompradorNavigation.Nombre} {ventas.IdCompradorNavigation.Apellido}")
|
||||
.SetIdComprador(ventas.IdComprador??0)
|
||||
.SetEstado(ventas.IdestadoNavigation.Descripcion??"")
|
||||
.Build();
|
||||
|
||||
return Ok(new { data = v, iscomprador = (ventas.IdComprador==cli.Dni)?true:false,
|
||||
necesitaRecibo = ventas.UrlRecibo==null?true:false});
|
||||
}
|
||||
|
||||
[HttpGet("/api/ventas")]
|
||||
public IActionResult ObtenerVentas([FromHeader(Name="Auth")]string Auth) {
|
||||
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario");
|
||||
if (validacion1 == false){
|
||||
validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Inquilino");
|
||||
if (validacion1 == false) {
|
||||
return Unauthorized();
|
||||
}
|
||||
}
|
||||
|
||||
Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
|
||||
if (cli == null) return Unauthorized();
|
||||
|
||||
var ventas = RepositorioVentas.Singleton.ObtenerVentasPorDni(cli.Dni);
|
||||
if (ventas == null) return BadRequest(new { message ="no estas involucrado en ninguna venta o compra"});
|
||||
|
||||
List<VentasDto> lista = new();
|
||||
foreach (var i in ventas) {
|
||||
var v = new VentasDtoBuilder()
|
||||
.SetId(i.Id)
|
||||
.SetMonto(i.Monto)
|
||||
.SetDivisa(i.IddivisaNavigation.Signo)
|
||||
.SetUbicacion(i.IdpropiedadNavigation.Ubicacion)
|
||||
.SetNombreVendedor($"{i.IdVendedorNavigation.Nombre} {i.IdVendedorNavigation.Apellido}")
|
||||
.SetIdVendedor(i.IdVendedor??0)
|
||||
.SetNombreComprador($"{i.IdCompradorNavigation.Nombre} {i.IdCompradorNavigation.Apellido}")
|
||||
.SetIdComprador(i.IdComprador??0)
|
||||
.SetEstado(i.IdestadoNavigation.Descripcion??"")
|
||||
.Build();
|
||||
lista.Add(v);
|
||||
}
|
||||
return Ok(lista);
|
||||
}
|
||||
|
||||
[HttpGet("/api/opcionventa")]
|
||||
public IActionResult ObtenerDto([FromHeader(Name="Auth")]string Auth, long idcontrato=0) {
|
||||
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario");
|
||||
if (validacion1 == false){
|
||||
validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Inquilino");
|
||||
if (validacion1 == false) {
|
||||
return Unauthorized();
|
||||
}
|
||||
}
|
||||
if (idcontrato == 0) return BadRequest(new { message = "No existen contatos validos para la id 0"});
|
||||
|
||||
Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
|
||||
if (cli == null) return Unauthorized();
|
||||
|
||||
Contrato? cont = RepositorioVentas.Singleton.ObtenerVentaPorContrato(idcontrato);
|
||||
if (cont == null) return BadRequest(new { message = "No hay un contrato por esa id"});
|
||||
|
||||
var dto = new OpcionVentaDtoBuilder()
|
||||
.SetId(cont.Idventa??0)
|
||||
.SetMonto(cont.IdventaNavigation.Monto)
|
||||
.SetDivisa(cont.IdventaNavigation.IddivisaNavigation.Signo)
|
||||
.SetEnOrden(puedeEjercer(cont))
|
||||
.SetFueEjercido(cont.IdventaNavigation.Idestado??0)
|
||||
.Build();
|
||||
|
||||
return Ok(dto);
|
||||
}
|
||||
|
||||
private bool puedeEjercer(Contrato c) {
|
||||
bool ret = c.Idcanons.All(x => x.Pagado == 1);
|
||||
|
||||
if (ret) {
|
||||
var canonConFechaMasTardia = c.Idcanons.OrderByDescending(x => x.Fecha).FirstOrDefault();
|
||||
|
||||
if (canonConFechaMasTardia != null && canonConFechaMasTardia.Fecha.Year >= DateTime.Now.Year
|
||||
&& canonConFechaMasTardia.Fecha.Month >= DateTime.Now.Month) {
|
||||
ret = true;
|
||||
}else{
|
||||
ret = false;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
[HttpGet("/api/contrato/tieneopcionventa")]
|
||||
public IActionResult TieneOpcionVenta([FromHeader(Name="Auth")]string Auth, long idcontrato=0) {
|
||||
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario");
|
||||
if (validacion1 == false){
|
||||
validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Inquilino");
|
||||
if (validacion1 == false) {
|
||||
return Unauthorized();
|
||||
}
|
||||
}
|
||||
|
||||
if (idcontrato == 0) return BadRequest(new { message = "No existen contatos validos para la id 0"});
|
||||
|
||||
Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
|
||||
if (cli == null) return Unauthorized();
|
||||
|
||||
Contrato? cont = RepositorioContratos.Singleton.ObtenerContratoPorId(idcontrato);
|
||||
if (cont == null) return BadRequest(new { message = "No hay un contrato por esa id"});
|
||||
if (cont.Dniinquilino !=cli.Dni && cont.Dnipropietario != cli.Dni) return Unauthorized();
|
||||
|
||||
return Ok( new { message = cont.Tieneopcionventa});
|
||||
}
|
||||
}
|
||||
@@ -670,6 +670,9 @@ public partial class AlquilaFacilContext : DbContext
|
||||
entity.Property(e => e.Monto)
|
||||
.HasPrecision(12)
|
||||
.HasColumnName("monto");
|
||||
entity.Property(e => e.UrlRecibo)
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("urlRecibo");
|
||||
|
||||
entity.HasOne(d => d.IdCompradorNavigation).WithMany(p => p.VentaIdCompradorNavigations)
|
||||
.HasForeignKey(d => d.IdComprador)
|
||||
|
||||
8
Entidades/Dto/OpcionVentaDto.cs
Normal file
8
Entidades/Dto/OpcionVentaDto.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace Entidades.Dto;
|
||||
public class OpcionVentaDto{
|
||||
public long Id { get; set;}
|
||||
public decimal Monto { get; set;}
|
||||
public string Divisa { get; set;} ="";
|
||||
public bool EnOrden { get; set;}
|
||||
public bool FueEjercido { get; set; }
|
||||
}
|
||||
@@ -8,4 +8,6 @@ public class PrecontratoDto {
|
||||
public bool TieneOpcionVenta { get; set; }
|
||||
public string fechaprimernotificacion { get; set; } = "";
|
||||
public int MesesDuracionContrato { get; set; }
|
||||
public Decimal MontoOpcion {get; set; }
|
||||
public int iddivisa { get; set; }
|
||||
}
|
||||
12
Entidades/Dto/VentasDto.cs
Normal file
12
Entidades/Dto/VentasDto.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace Entidades.Dto;
|
||||
public class VentasDto {
|
||||
public long Id { get; set; }
|
||||
public decimal Monto { get; set; }
|
||||
public string Divisa { get; set; }="";
|
||||
public string Ubicacion { get; set; }="";
|
||||
public string NombreVendedor { get; set; }="";
|
||||
public long IdVendedor { get; set; }
|
||||
public string NombreComprador { get; set; }="";
|
||||
public long IdComprador { get; set; }
|
||||
public string Estado { get; set; }="";
|
||||
}
|
||||
@@ -17,12 +17,14 @@ public partial class Venta
|
||||
|
||||
public int? Idpropiedad { get; set; }
|
||||
|
||||
public DateTime Fechainicio { get; set; }
|
||||
public DateTime? Fechainicio { get; set; }
|
||||
|
||||
public DateTime? Fechafinal { get; set; }
|
||||
|
||||
public int Iddivisa { get; set; }
|
||||
|
||||
public string? UrlRecibo { get; set; }
|
||||
|
||||
public virtual ICollection<Contrato> Contratos { get; set; } = new List<Contrato>();
|
||||
|
||||
public virtual Cliente? IdCompradorNavigation { get; set; }
|
||||
|
||||
@@ -21,7 +21,9 @@
|
||||
import ControlAlquileresPropietario from "./paginas/ControlAlquileresPropietario.svelte";
|
||||
import ContratosPropietario from "./paginas/ContratosPropietario.svelte";
|
||||
import ContratoInquilino from "./paginas/ContratoInquilino.svelte";
|
||||
import Informes from "./paginas/Informes.svelte";
|
||||
import Informes from "./paginas/Informes.svelte";
|
||||
import CompraYVentas from "./paginas/CompraYVenta.svelte";
|
||||
import Ventas from "./paginas/Ventas.svelte";
|
||||
</script>
|
||||
|
||||
<Router>
|
||||
@@ -95,6 +97,16 @@
|
||||
<ProteRoute componente={ControlAlquileresPropietario}/>
|
||||
</Route>
|
||||
|
||||
<!-- Compra y Ventas -->
|
||||
<Route path="/accion/13">
|
||||
<ProteRoute componente={CompraYVentas}/>
|
||||
</Route>
|
||||
|
||||
<!-- Pagina Ventas -->
|
||||
<Route path="/Ventas">
|
||||
<ProteRoute componente={Ventas}/>
|
||||
</Route>
|
||||
|
||||
<!--Paginas info Grupo-->
|
||||
<Route path="/grupo/Inquilino">
|
||||
<ProteRoute componente={FrontInquilino}/>
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
<script lang="ts">
|
||||
let { onClose, onSubmit } : {
|
||||
onClose: () => void,
|
||||
onSubmit: (data: { opcionVenta: boolean; cantGarantes: number; mesesHastaAumento: number, mesesDuracionContrato:number }) => void
|
||||
onSubmit: (data: { opcionVenta: boolean; cantGarantes: number; mesesHastaAumento: number, mesesDuracionContrato:number, montoOpcion:number, iddivisa:number }) => void
|
||||
} = $props();
|
||||
|
||||
let opcionVenta: boolean = $state(false);
|
||||
let cantGarantes: number = $state(0);
|
||||
let mesesHastaAumento: number = $state(0);
|
||||
let mesesDuracionContrato:number =$state(0);
|
||||
let montoOpcion:number=$state(0);
|
||||
let iddivisa:number=$state(0);
|
||||
|
||||
function handleSubmit(e:Event) {
|
||||
e.preventDefault();
|
||||
onSubmit({ opcionVenta, cantGarantes, mesesHastaAumento, mesesDuracionContrato });
|
||||
onSubmit({ opcionVenta, cantGarantes, mesesHastaAumento, mesesDuracionContrato, montoOpcion, iddivisa });
|
||||
onClose();
|
||||
}
|
||||
</script>
|
||||
@@ -25,11 +28,23 @@
|
||||
<form onsubmit={handleSubmit}>
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="form-check-input" bind:checked={opcionVenta} id="opcionVenta" />
|
||||
<label class="form-check-label" for="opcionVenta">Seleccionar Opcion de Venta</label>
|
||||
</div>
|
||||
{#if opcionVenta}
|
||||
<div class="form-group">
|
||||
<label for="montoOpcion">Definir monto</label>
|
||||
<input type="number" class="form-control" bind:value={montoOpcion} id="montoOpcion">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="iddivisa">Seleccionar Divisa</label>
|
||||
<select class="form-select" bind:value={iddivisa} id="iddivisa">
|
||||
<option value="0">AR$</option>
|
||||
<option value="1">US$</option>
|
||||
</select>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="cantGarantes">Cantidad de Garantes</label>
|
||||
|
||||
75
Front/src/paginas/CompraYVenta.svelte
Normal file
75
Front/src/paginas/CompraYVenta.svelte
Normal file
@@ -0,0 +1,75 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from "svelte";
|
||||
import NavBarAutocompletable from "../Componentes/NavBarAutocompletable.svelte";
|
||||
import type { VentasDto } from "../types";
|
||||
import ModalEstatico from "../Componentes/ModalEstatico.svelte";
|
||||
import { urlG } from "../stores/urlStore";
|
||||
import Ventas from "./Ventas.svelte";
|
||||
import { navigate } from "svelte-routing";
|
||||
|
||||
let token:string = sessionStorage.getItem("token")||"";
|
||||
let modaldata:string = $state("");
|
||||
|
||||
let ventas:VentasDto[] = $state([]);
|
||||
|
||||
onMount(()=>{
|
||||
obtenerVentas();
|
||||
});
|
||||
|
||||
async function obtenerVentas() {
|
||||
try{
|
||||
const r = await fetch($urlG+"/api/ventas", {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Auth": token
|
||||
}
|
||||
});
|
||||
let data = await r.json();
|
||||
if (!r.ok){
|
||||
modaldata = data;
|
||||
return;
|
||||
}
|
||||
ventas = data;
|
||||
}catch{
|
||||
modaldata = "Fallo al hacer la request";
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<NavBarAutocompletable/>
|
||||
|
||||
{#if modaldata}
|
||||
<ModalEstatico payload={modaldata} close={()=> !!(modaldata = "")} />
|
||||
{/if}
|
||||
|
||||
<div class="container-fluid mt-3">
|
||||
<div class="row">
|
||||
{#each ventas as venta (venta.id)}
|
||||
<div class="col-md-6 mb-4">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5>{venta.nombreVendedor} → {venta.nombreComprador}</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="card-text">
|
||||
<strong>Monto:</strong> {venta.monto} {venta.divisa}<br>
|
||||
<strong>Ubicación:</strong> {venta.ubicacion}<br>
|
||||
<strong>Estado:</strong> {venta.estado}
|
||||
</p>
|
||||
</div>
|
||||
<div class="card-footer d-flex justify-content-center">
|
||||
<button class="btn btn-secondary" onclick={()=>navigate("/Ventas?idventa="+venta.id)}>Ver</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.card {
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
</style>
|
||||
@@ -3,9 +3,10 @@
|
||||
import { onMount } from "svelte";
|
||||
import ModalEstatico from "../Componentes/ModalEstatico.svelte";
|
||||
import {urlG} from "../stores/urlStore";
|
||||
import type { AltaDefectoDto, CanonDto, ContratoDto, ContratoPropiedadDto, DefectoDto, GaranteDto2 } from "../types";
|
||||
import type { AltaDefectoDto, CanonDto, ContratoDto, ContratoPropiedadDto, DefectoDto, GaranteDto2, OpcionVentaDto } from "../types";
|
||||
import ModalPedirDoc from "../Componentes/ModalPedirDoc.svelte";
|
||||
import FormAltaDefecto from "../Componentes/FormAltaDefecto.svelte";
|
||||
import { navigate } from "svelte-routing";
|
||||
|
||||
let token:string = sessionStorage.getItem("token")||"";
|
||||
|
||||
@@ -29,14 +30,62 @@
|
||||
});
|
||||
let defectos:DefectoDto[] = $state([]);
|
||||
|
||||
let TieneOpcionVenta:boolean =$state(false);
|
||||
let dtoVenta:OpcionVentaDto =$state({divisa:"", id:0, monto:0, enOrden:false, fueEjercido:false});
|
||||
|
||||
let modaldata:string = $state("");
|
||||
let contratoid:string = $state("");
|
||||
|
||||
onMount(()=>{
|
||||
getparams();
|
||||
obtenerDatosACargar();
|
||||
opcionVenta();
|
||||
});
|
||||
|
||||
async function opcionVenta() {
|
||||
try {
|
||||
const r = await fetch($urlG+"/api/contrato/tieneopcionventa?idcontrato="+contratoid, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Auth": String(token),
|
||||
}
|
||||
});
|
||||
if (r.ok){
|
||||
let data = await r.json();
|
||||
TieneOpcionVenta = data.message;
|
||||
if (TieneOpcionVenta){
|
||||
ObtenerOpcionVentaDto();
|
||||
}
|
||||
return;
|
||||
}
|
||||
let data = await r.json();
|
||||
modaldata = data.message;
|
||||
return;
|
||||
}catch {
|
||||
modaldata = "Fallo hacer la request";
|
||||
}
|
||||
}
|
||||
|
||||
async function ObtenerOpcionVentaDto() {
|
||||
try{
|
||||
const r = await fetch($urlG+"/api/opcionventa?idcontrato="+contratoid, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Auth": String(token),
|
||||
}
|
||||
});
|
||||
if (r.ok) {
|
||||
let data = await r.json();
|
||||
dtoVenta = data;
|
||||
return
|
||||
}
|
||||
let data = await r.json();
|
||||
modaldata = data.message;
|
||||
}catch{
|
||||
modaldata = "Fallo hacer la request";
|
||||
}
|
||||
}
|
||||
|
||||
async function obtenerDatosACargar() {
|
||||
try {
|
||||
const respPropiedad = fetch($urlG+"/api/contrato/inquilino?id="+contratoid, {
|
||||
@@ -223,6 +272,25 @@
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async function ejercerOpcionVenta() {
|
||||
try {
|
||||
const r = await fetch($urlG+"/api/ventas/ejercerOpcionVenta?idcontrato="+contratoid, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Auth": token,
|
||||
}
|
||||
});
|
||||
let data = await r.json();
|
||||
modaldata =data.message;
|
||||
if(r.ok){
|
||||
opcionVenta();
|
||||
return;
|
||||
}
|
||||
} catch {
|
||||
modaldata = "Fallo al intentar hacer la request";
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<NavBarAutocompletable/>
|
||||
@@ -374,8 +442,10 @@
|
||||
class="accordion-collapse collapse"
|
||||
aria-labelledby="ht"
|
||||
data-bs-parent="#accordionExample"
|
||||
>
|
||||
>
|
||||
|
||||
<div class="accordion-body">
|
||||
{#if prop.estado != "Terminado"}
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
Notificar Defecto en Propiedad
|
||||
@@ -384,10 +454,11 @@
|
||||
<FormAltaDefecto onConfirm={cargarDefecto} idcontrato={prop.id} />
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
{/if}
|
||||
<table class="table table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -419,6 +490,55 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{#if TieneOpcionVenta}
|
||||
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header" id="hq">
|
||||
<button
|
||||
class="accordion-button collapsed"
|
||||
type="button"
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target="#cq"
|
||||
aria-expanded="false"
|
||||
aria-controls="cq"
|
||||
>
|
||||
Opcion Venta
|
||||
</button>
|
||||
</h2>
|
||||
<div
|
||||
id="cq"
|
||||
class="accordion-collapse collapse"
|
||||
aria-labelledby="hq"
|
||||
data-bs-parent="#accordionExample"
|
||||
>
|
||||
<div class="accordion-body">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
Datos Opcion Venta
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<b>Monto</b>: {dtoVenta.divisa} {dtoVenta.monto}.
|
||||
|
||||
<p class="mt-2 text-muted">
|
||||
Para poder ejercer la opcion de venta necesitas estar en el mismo mes que el ultimo pago y haber pagado todos los canones
|
||||
</p>
|
||||
<div class="d-flex justify-content-between">
|
||||
<button class="btn btn-primary" disabled={dtoVenta.enOrden==false || dtoVenta.fueEjercido == true} onclick={()=>ejercerOpcionVenta()}>
|
||||
Ejercer
|
||||
</button>
|
||||
{#if dtoVenta.fueEjercido}
|
||||
<button class="btn btn-secondary" onclick={()=>navigate("/Ventas?idventa="+dtoVenta.id)}>
|
||||
Ir a la pagina de la Venta
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer text-center">IdOpcionVenta: {dtoVenta.id}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,10 +3,11 @@
|
||||
import NavBarAutocompletable from "../Componentes/NavBarAutocompletable.svelte";
|
||||
import ModalEstatico from "../Componentes/ModalEstatico.svelte";
|
||||
import {urlG} from "../stores/urlStore";
|
||||
import type { CanonDto, ContratoDto, ContratoPropiedadDto, DefectoDto, GaranteDto2 } from "../types";
|
||||
import type { CanonDto, ContratoDto, ContratoPropiedadDto, DefectoDto, GaranteDto2, OpcionVentaDto } from "../types";
|
||||
import ModalConfirm from "../Componentes/ModalConfirm.svelte";
|
||||
import ModalPedirDoc from "../Componentes/ModalPedirDoc.svelte";
|
||||
import ModalNotificacion from "../Componentes/ModalNotificacion.svelte";
|
||||
import { navigate } from "svelte-routing";
|
||||
|
||||
|
||||
let token:string = sessionStorage.getItem("token")||"";
|
||||
@@ -35,6 +36,8 @@
|
||||
mesesDuracion:0,
|
||||
});
|
||||
let defectos:DefectoDto[] = $state([]);
|
||||
let TieneOpcionVenta:boolean =$state(false);
|
||||
let dtoVenta:OpcionVentaDto =$state({divisa:"", id:0, monto:0, enOrden:false, fueEjercido:false});
|
||||
|
||||
let modaldata:string = $state("");
|
||||
let contratoid:string = $state("");
|
||||
@@ -43,8 +46,54 @@
|
||||
getparams();
|
||||
await obtenerDatosACargar();
|
||||
max = canons.at(-1).mesNum||0;
|
||||
opcionVenta();
|
||||
|
||||
});
|
||||
|
||||
async function opcionVenta() {
|
||||
try {
|
||||
const r = await fetch($urlG+"/api/contrato/tieneopcionventa?idcontrato="+contratoid, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Auth": String(token),
|
||||
}
|
||||
});
|
||||
if (r.ok){
|
||||
let data = await r.json();
|
||||
TieneOpcionVenta = data.message;
|
||||
if (TieneOpcionVenta){
|
||||
ObtenerOpcionVentaDto();
|
||||
}
|
||||
return;
|
||||
}
|
||||
let data = await r.json();
|
||||
modaldata = data.message;
|
||||
return;
|
||||
}catch {
|
||||
modaldata = "Fallo hacer la request";
|
||||
}
|
||||
}
|
||||
|
||||
async function ObtenerOpcionVentaDto() {
|
||||
try{
|
||||
const r = await fetch($urlG+"/api/opcionventa?idcontrato="+contratoid, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Auth": String(token),
|
||||
}
|
||||
});
|
||||
if (r.ok) {
|
||||
let data = await r.json();
|
||||
dtoVenta = data;
|
||||
return
|
||||
}
|
||||
let data = await r.json();
|
||||
modaldata = data.message;
|
||||
}catch{
|
||||
modaldata = "Fallo hacer la request";
|
||||
}
|
||||
}
|
||||
|
||||
async function obtenerDatosACargar() {
|
||||
try {
|
||||
const respPropiedad = fetch($urlG+"/api/contrato/propietario?id="+contratoid, {
|
||||
@@ -511,6 +560,50 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{#if TieneOpcionVenta}
|
||||
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header" id="hq">
|
||||
<button
|
||||
class="accordion-button collapsed"
|
||||
type="button"
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target="#cq"
|
||||
aria-expanded="false"
|
||||
aria-controls="cq"
|
||||
>
|
||||
Opcion Venta
|
||||
</button>
|
||||
</h2>
|
||||
<div
|
||||
id="cq"
|
||||
class="accordion-collapse collapse"
|
||||
aria-labelledby="hq"
|
||||
data-bs-parent="#accordionExample"
|
||||
>
|
||||
<div class="accordion-body">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
Datos Opcion Venta
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<b>Monto</b>: {dtoVenta.divisa} {dtoVenta.monto}.
|
||||
|
||||
<p class="mt-2 text-muted">
|
||||
Para que el inquilino pueda ejercer la opcion de venta necesitas estar en el mismo mes que el ultimo pago y haber pagado todos los canones
|
||||
</p>
|
||||
<div class="d-flex">
|
||||
<button class="btn btn-primary" disabled={!dtoVenta.fueEjercido} onclick={()=>navigate("/Ventas?idventa="+dtoVenta.id)}>
|
||||
Ir a la pagina de la Venta
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer text-center">IdOpcionVenta: {dtoVenta.id}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -161,7 +161,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
async function handleEnviarmensaje2(data: {opcionVenta:boolean, cantGarantes:number, mesesHastaAumento:number, mesesDuracionContrato:number}) {
|
||||
async function handleEnviarmensaje2(data: {opcionVenta:boolean, cantGarantes:number,
|
||||
mesesHastaAumento:number, mesesDuracionContrato:number, montoOpcion:number, iddivisa:number}) {
|
||||
if (data.opcionVenta == null || data.cantGarantes <=0 || data.mesesHastaAumento<=0 || data.mesesDuracionContrato <=0) {
|
||||
modaldata = "Estan mal cargados los datos del form";
|
||||
return;
|
||||
@@ -177,7 +178,9 @@
|
||||
fechaprimernotificacion: fecha,
|
||||
emailInquilino: Selmens.remitente,
|
||||
emailPropietario: Selmens.receptor,
|
||||
mesesDuracionContrato: data.mesesDuracionContrato
|
||||
mesesDuracionContrato: data.mesesDuracionContrato,
|
||||
montoOpcion: data.montoOpcion,
|
||||
iddivisa: data.iddivisa
|
||||
};
|
||||
|
||||
let responce = await fetch($urlG+"/api/contratos/precontrato", {
|
||||
@@ -431,7 +434,7 @@
|
||||
<ModalEstatico payload={Selmens.mensaje} close={()=> !!(Selmens.accion = "") }/>
|
||||
{/if}
|
||||
|
||||
<div class="container">
|
||||
<div class="container-fluid">
|
||||
<br>
|
||||
<BarraHorizontalConTexto text="Notificaciones"/>
|
||||
<br>
|
||||
|
||||
263
Front/src/paginas/Ventas.svelte
Normal file
263
Front/src/paginas/Ventas.svelte
Normal file
@@ -0,0 +1,263 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from "svelte";
|
||||
import NavBarAutocompletable from "../Componentes/NavBarAutocompletable.svelte";
|
||||
import type { VentasDto } from "../types";
|
||||
import ModalEstatico from "../Componentes/ModalEstatico.svelte";
|
||||
import { urlG } from "../stores/urlStore";
|
||||
|
||||
let modaldata:string = $state("");
|
||||
let token:string = sessionStorage.getItem("token")||"";
|
||||
let file: File| null =$state(null);
|
||||
|
||||
let venta: VentasDto|any = $state({divisa:""});
|
||||
let ventaid:string = $state("");
|
||||
let escomprador:boolean = $state(true);
|
||||
let necesitaRecibo:boolean = $state(false);
|
||||
let checkAceptaRecibo:boolean = $state(false);
|
||||
|
||||
onMount(()=>{
|
||||
setQueryparam();
|
||||
obtenerVenta();
|
||||
});
|
||||
|
||||
async function obtenerVenta() {
|
||||
try{
|
||||
const r = await fetch($urlG+"/api/venta?idventa="+ventaid, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Auth": token
|
||||
}
|
||||
});
|
||||
let d = await r.json();
|
||||
if (r.ok) {
|
||||
venta = d.data;
|
||||
escomprador = d.iscomprador;
|
||||
necesitaRecibo = d.necesitaRecibo;
|
||||
return;
|
||||
}
|
||||
modaldata = d.message;
|
||||
} catch {
|
||||
modaldata = "Fallo al hacer la request";
|
||||
}
|
||||
}
|
||||
|
||||
function setQueryparam() {
|
||||
const qs = window.location.search;
|
||||
const par = new URLSearchParams(qs);
|
||||
ventaid = par.get("idventa")||"";
|
||||
}
|
||||
|
||||
function handleComprobateFile(e:Event){
|
||||
const input = e.target as HTMLInputElement;
|
||||
if (input.files && input.files.length > 0 ) {
|
||||
file = input.files[0];
|
||||
}
|
||||
}
|
||||
|
||||
async function handleSubirComprobante(e:Event) {
|
||||
e.preventDefault();
|
||||
if(file == null) {
|
||||
modaldata = "No se seleciono un pdf";
|
||||
return;
|
||||
}
|
||||
let formdata = new FormData();
|
||||
formdata.append("file", file);
|
||||
try {
|
||||
const r = await fetch($urlG+"/api/ventas/subirReciboPago?idventa="+ventaid, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Auth": token
|
||||
},
|
||||
body: formdata,
|
||||
});
|
||||
let data = await r.json();
|
||||
if (r.ok) {
|
||||
obtenerVenta();
|
||||
}
|
||||
modaldata = data.message;
|
||||
} catch {
|
||||
modaldata = "Fallo al hacer la request";
|
||||
}
|
||||
}
|
||||
|
||||
async function verComprobante() {
|
||||
try {
|
||||
const responce = await fetch($urlG+"/api/ventas/verRecibo?idventa="+ventaid, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Auth": String(token),
|
||||
}
|
||||
});
|
||||
if (!responce.ok) {
|
||||
modaldata="Error al obtener el archivo";
|
||||
return;
|
||||
}
|
||||
|
||||
let blob = await responce.blob();
|
||||
const blobUrl = URL.createObjectURL(blob);
|
||||
window.open(blobUrl, '_blank');
|
||||
setTimeout(() => URL.revokeObjectURL(blobUrl), 100000);
|
||||
} catch {
|
||||
modaldata = "Fallo al intentar conectarse al servidor";
|
||||
}
|
||||
}
|
||||
|
||||
async function aceptarRecibo() {
|
||||
try {
|
||||
const r = await fetch($urlG+"/api/ventas/propietarioverifica?idventa="+ventaid, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Auth": token
|
||||
},
|
||||
});
|
||||
let data = await r.json();
|
||||
if (r.ok) {
|
||||
obtenerVenta();
|
||||
}
|
||||
modaldata = data.message;
|
||||
} catch {
|
||||
modaldata = "Fallo al hacer la request";
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<NavBarAutocompletable/>
|
||||
|
||||
{#if modaldata}
|
||||
<ModalEstatico payload={modaldata} close={()=>!!(modaldata ="")} />
|
||||
{/if}
|
||||
|
||||
<div class="container-fluid mt-4 d-flex">
|
||||
<div class="col-md-4 me-4">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
Datos Venta
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<b>Monto: </b> {venta.divisa} {venta.monto}<br>
|
||||
<b>Ubicación: </b> {venta.ubicacion}<br>
|
||||
<b>Vendedor: </b> {venta.nombreVendedor} <br>
|
||||
<b>Comprador: </b> {venta.nombreComprador} <br>
|
||||
<b>Estado: </b> {venta.estado} <br>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
VentaID: {venta.id}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="accordion" id="accordion">
|
||||
{#if escomprador}
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header" id="h1">
|
||||
<button class="btn accordion-button"
|
||||
type="button"
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target="#c1"
|
||||
aria-expanded="true"
|
||||
aria-controls="c1">
|
||||
Subir Comprobante de Pago
|
||||
</button>
|
||||
</h2>
|
||||
<div class="accordion-collapse collapse show"
|
||||
data-bs-parent="#accordion" id="c1"
|
||||
>
|
||||
<div class="accordion-body">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
Suba su Comprobante de pago
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form>
|
||||
<label for="comprobante" class="form-label">El comprobante debe estar en formato pdf</label>
|
||||
<input disabled={!necesitaRecibo} class="form-control" type="file" name="comprobante" id="comprobante"
|
||||
onchange={handleComprobateFile}>
|
||||
<div class="d-flex justify-content-between">
|
||||
<button disabled={!necesitaRecibo} class="btn btn-primary mt-2" type="submit" onclick={(e)=>handleSubirComprobante(e)}>Subir</button>
|
||||
</div>
|
||||
</form>
|
||||
<button disabled={necesitaRecibo} class="btn btn-primary mt-2" type="submit" onclick={verComprobante}>Ver</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header" id="h2">
|
||||
<button class="btn accordion-button"
|
||||
type="button"
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target="#c2"
|
||||
aria-expanded="true"
|
||||
aria-controls="c2">
|
||||
Ver Comprobante de Pago
|
||||
</button>
|
||||
</h2>
|
||||
<div class="accordion-collapse collapse show"
|
||||
data-bs-parent="#accordion" id="c2"
|
||||
>
|
||||
<div class="accordion-body">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
Vea el comprobante de pago
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{#if necesitaRecibo}
|
||||
<p>El boton estará habilitado cuando el comprador suba el recibo</p>
|
||||
{/if}
|
||||
<button disabled={necesitaRecibo} class="btn btn-primary mt-1" type="submit" onclick={verComprobante}>Ver</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{#if !necesitaRecibo}
|
||||
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header" id="h3">
|
||||
<button class="btn accordion-button"
|
||||
type="button"
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target="#c3"
|
||||
aria-expanded="true"
|
||||
aria-controls="c3">
|
||||
Aceptar comprobante de pago
|
||||
</button>
|
||||
</h2>
|
||||
<div class="accordion-collapse collapse"
|
||||
data-bs-parent="#accordion" id="c3"
|
||||
>
|
||||
<div class="accordion-body">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<button disabled={necesitaRecibo} class="btn btn-primary mt-1" type="submit" onclick={verComprobante}>
|
||||
Ver comprobante
|
||||
</button>
|
||||
<hr>
|
||||
<input disabled={checkAceptaRecibo} type="checkbox" class="form-check-input" name="check" id="check" bind:checked={checkAceptaRecibo}>
|
||||
<label for="check">Acepto el comprobante</label>
|
||||
{#if checkAceptaRecibo}
|
||||
<hr>
|
||||
<div class="row align-items-center">
|
||||
<div class="col-3">
|
||||
<button class="btn btn-primary" onclick={aceptarRecibo}>
|
||||
Aceptar
|
||||
</button>
|
||||
</div>
|
||||
<div class="col">
|
||||
<p class="text-muted mb-0">Al darle al botón se va a iniciar el proceso de traspaso de la propiedad</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
20
Front/src/types.d.ts
vendored
20
Front/src/types.d.ts
vendored
@@ -144,4 +144,24 @@ export type ChartData = {
|
||||
label: string,
|
||||
data:string[],
|
||||
}]
|
||||
}
|
||||
|
||||
export type OpcionVentaDto = {
|
||||
id:number,
|
||||
monto:number,
|
||||
divisa:string,
|
||||
enOrden:boolean,
|
||||
fueEjercido:boolean
|
||||
}
|
||||
|
||||
export type VentasDto = {
|
||||
id:number,
|
||||
monto:numver,
|
||||
divisa:string,
|
||||
ubicacion:string,
|
||||
nombreVendedor:string,
|
||||
idVendedor:number,
|
||||
nombreComprador:string,
|
||||
idComprador:number,
|
||||
estado:string,
|
||||
}
|
||||
@@ -14,7 +14,7 @@ public class RepositorioContratos: RepositorioBase<RepositorioContratos> {
|
||||
}
|
||||
}
|
||||
|
||||
public bool CargaPrecontrato(Contrato? c = null, Notificacione? n = null) {
|
||||
public bool CargaPrecontrato( Contrato? c = null, Notificacione? n = null) {
|
||||
if (c == null || c.Habilitado == 1) return false;
|
||||
if (n == null) return false;
|
||||
var con = Context;
|
||||
@@ -201,4 +201,39 @@ public class RepositorioContratos: RepositorioBase<RepositorioContratos> {
|
||||
var con = Context;
|
||||
return con.Contratos.Where(x=>x.Fechainicio.Year == year).Any();
|
||||
}
|
||||
|
||||
public bool SetOpcionVenta(Venta v, long idcontrato) {
|
||||
var con = Context;
|
||||
var cont = con.Contratos.Include(x=>x.IdventaNavigation).FirstOrDefault(x=>x.Id == idcontrato);
|
||||
if (cont != null) return false;
|
||||
|
||||
v.Id = (con.Ventas.Any()?con.Ventas.Count():0)+1;
|
||||
|
||||
cont.IdventaNavigation = v;
|
||||
con.Ventas.Add(v);
|
||||
return Guardar(con);
|
||||
}
|
||||
|
||||
public bool CargaPrecontratoOpcionVenta(Contrato c, Notificacione n, Venta v) {
|
||||
if (c == null || c.Habilitado == 1) return false;
|
||||
if (n == null) return false;
|
||||
var con = Context;
|
||||
|
||||
var prop = con.Propiedades.FirstOrDefault(x=>x.Id==c.Idpropiedad);
|
||||
if (prop == null) return false;
|
||||
prop.Idestado = 2;
|
||||
|
||||
c.Iddivisa = prop.Iddivisa;
|
||||
c.Id = (con.Contratos.Any() ? con.Contratos.Max(x => x.Id) : 0) + 1;
|
||||
c.Monto = prop.Monto;
|
||||
|
||||
v.Id = (con.Ventas.Any()?con.Ventas.Count():0)+1;
|
||||
c.Idventa = v.Id;
|
||||
|
||||
con.Ventas.Add(v);
|
||||
con.Contratos.Add(c);
|
||||
con.Notificaciones.Add(n);
|
||||
|
||||
return Guardar(con);
|
||||
}
|
||||
}
|
||||
|
||||
74
Modelo/RepositorioVentas.cs
Normal file
74
Modelo/RepositorioVentas.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
using Entidades;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Modelo;
|
||||
public class RepositorioVentas: RepositorioBase<RepositorioVentas> {
|
||||
public bool EfectuarVenta(long idventa) {
|
||||
var con = Context;
|
||||
var vent = con.Ventas.Include(x=>x.IdpropiedadNavigation).FirstOrDefault(x => x.Id == idventa);
|
||||
if (vent == null||vent.Idestado != 2) return false;
|
||||
|
||||
vent.IdpropiedadNavigation.Dnipropietario = vent.IdComprador;
|
||||
|
||||
vent.IdpropiedadNavigation.Idestado=3;
|
||||
vent.Idestado=3;
|
||||
|
||||
return Guardar(con);
|
||||
}
|
||||
|
||||
public Contrato? ObtenerVentaPorContrato(long idcontrato) {
|
||||
var con = Context;
|
||||
var c = con.Contratos.Include(x=>x.Idcanons).Include(x=>x.IdventaNavigation).ThenInclude(x=>x.IddivisaNavigation)
|
||||
.FirstOrDefault(x=>x.Id == idcontrato);
|
||||
if (c == null || c.IdventaNavigation == null) return null;
|
||||
return c;
|
||||
}
|
||||
|
||||
public Venta? ObtenerVentaPorId(long idventa) {
|
||||
var con = Context;
|
||||
var vent = con.Ventas
|
||||
.Include(x=>x.IddivisaNavigation)
|
||||
.Include(x=>x.IdestadoNavigation)
|
||||
.Include(x=>x.IdVendedorNavigation)
|
||||
.Include(x=>x.IdCompradorNavigation)
|
||||
.Include(x=>x.IdpropiedadNavigation)
|
||||
.Where(x=>x.Idestado != 1)
|
||||
.FirstOrDefault(x=>x.Id == idventa);
|
||||
if (vent == null) return null;
|
||||
return vent;
|
||||
}
|
||||
|
||||
public IQueryable<Venta>? ObtenerVentasPorDni(long dni) {
|
||||
var con = Context;
|
||||
var venta = con.Ventas
|
||||
.Include(x=>x.IddivisaNavigation)
|
||||
.Include(x=>x.IdestadoNavigation)
|
||||
.Include(x=>x.IdVendedorNavigation)
|
||||
.Include(x=>x.IdCompradorNavigation)
|
||||
.Include(x=>x.IdpropiedadNavigation)
|
||||
.Where(x=>(x.IdComprador == dni || x.IdVendedor == dni) && x.Idestado!=1 )
|
||||
.Distinct();
|
||||
return venta;
|
||||
}
|
||||
|
||||
public bool PatchVenta(Venta venta) {
|
||||
var con = Context;
|
||||
var a = con.Ventas.FirstOrDefault(x=>x.Id == venta.Id);
|
||||
|
||||
a.IdVendedor = venta.IdVendedor;
|
||||
a.IdComprador = venta.IdComprador;
|
||||
a.Idpropiedad = venta.Idpropiedad;
|
||||
a.Fechainicio = venta.Fechainicio;
|
||||
a.Idestado=2;
|
||||
|
||||
return Guardar(con);
|
||||
}
|
||||
|
||||
public bool SetUrlRecibo(long id, string nuevoNombreArchivo) {
|
||||
var con = Context;
|
||||
var venta = con.Ventas.FirstOrDefault(x=>x.Id == id);
|
||||
if (venta==null) return false;
|
||||
venta.UrlRecibo = nuevoNombreArchivo;
|
||||
return Guardar(con);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user