bueno parece que termine lo de ventas bruh

This commit is contained in:
2025-01-27 03:37:03 -03:00
parent 1fd0c12793
commit d0a24ce0b7
6 changed files with 428 additions and 10 deletions

View File

@@ -1,7 +1,13 @@
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;
@@ -36,18 +42,148 @@ public class VentaController:ControllerBase {
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 IActionResult SubirRecibo([FromForm]IFormFile file, long idventa ) {
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(long idventa) {
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");
@@ -78,11 +214,12 @@ public class VentaController:ControllerBase {
.SetEstado(ventas.IdestadoNavigation.Descripcion??"")
.Build();
return Ok(new { data = v, iscomprador = (ventas.IdComprador==cli.Dni)?true:false});
return Ok(new { data = v, iscomprador = (ventas.IdComprador==cli.Dni)?true:false,
necesitaRecibo = ventas.UrlRecibo==null?true:false});
}
[HttpGet("/api/ventas")]
public IActionResult ObtenerVenta([FromHeader(Name="Auth")]string Auth) {
public IActionResult ObtenerVentas([FromHeader(Name="Auth")]string Auth) {
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario");
if (validacion1 == false){
validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Inquilino");

View File

@@ -53,7 +53,9 @@
if (r.ok){
let data = await r.json();
TieneOpcionVenta = data.message;
ObtenerOpcionVentaDto();
if (TieneOpcionVenta){
ObtenerOpcionVentaDto();
}
return;
}
let data = await r.json();

View File

@@ -61,7 +61,9 @@
if (r.ok){
let data = await r.json();
TieneOpcionVenta = data.message;
ObtenerOpcionVentaDto();
if (TieneOpcionVenta){
ObtenerOpcionVentaDto();
}
return;
}
let data = await r.json();

View File

@@ -434,7 +434,7 @@
<ModalEstatico payload={Selmens.mensaje} close={()=> !!(Selmens.accion = "") }/>
{/if}
<div class="container">
<div class="container-fluid">
<br>
<BarraHorizontalConTexto text="Notificaciones"/>
<br>

View File

@@ -1,7 +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/>
<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>

View File

@@ -3,6 +3,19 @@ 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)
@@ -50,4 +63,12 @@ public class RepositorioVentas: RepositorioBase<RepositorioVentas> {
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);
}
}