Add TaxSecction on QuoteCreate
All checks were successful
CI/CD Pipeline / Build and Deploy with Docker Compose (push) Successful in 5m31s
All checks were successful
CI/CD Pipeline / Build and Deploy with Docker Compose (push) Successful in 5m31s
This commit is contained in:
parent
f1bc764bbf
commit
b1ab76aa5a
14
Core/Interfaces/ITaxTypeDom.cs
Normal file
14
Core/Interfaces/ITaxTypeDom.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using Domain.Entities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Core.Interfaces
|
||||
{
|
||||
public interface ITaxTypeDom
|
||||
{
|
||||
Task<IEnumerable<ETaxType>> GetAllActiveAsync();
|
||||
}
|
||||
}
|
||||
32
Core/Services/TaxTypeService.cs
Normal file
32
Core/Services/TaxTypeService.cs
Normal file
@ -0,0 +1,32 @@
|
||||
using Core.Interfaces;
|
||||
using Domain.Entities;
|
||||
using Models.Interfaces;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Core.Services
|
||||
{
|
||||
public class TaxTypeService: ITaxTypeDom
|
||||
{
|
||||
#region Declaraciones y Constructor
|
||||
private readonly IPhOhArcataxTypeRepository _repository;
|
||||
public TaxTypeService(IPhOhArcataxTypeRepository repository)
|
||||
{
|
||||
_repository = repository ?? throw new ArgumentNullException(nameof(repository));
|
||||
}
|
||||
#endregion
|
||||
#region Metodos de clases
|
||||
public async Task<IEnumerable<ETaxType>> GetAllActiveAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _repository.GetAllActiveAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var method = MethodBase.GetCurrentMethod()?.Name ?? "UnknownMethod";
|
||||
throw new Exception($"{method} Message: {ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
40
Domain/Entities/ETaxType.cs
Normal file
40
Domain/Entities/ETaxType.cs
Normal file
@ -0,0 +1,40 @@
|
||||
namespace Domain.Entities
|
||||
{
|
||||
public class ETaxType
|
||||
{
|
||||
/// <summary>
|
||||
/// Identificador único del impuesto.
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Código oficial del impuesto según ARCA.
|
||||
/// </summary>
|
||||
public int TaxCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Descripción del impuesto.
|
||||
/// </summary>
|
||||
public string Description { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Porcentaje de la alícuota aplicable al impuesto, expresado como un valor decimal. Una alícuota del 21%, se debe almacenar el valor 21.00
|
||||
/// </summary>
|
||||
public decimal Taxrate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indica si el impuesto está activo (1) o inactivo (0).
|
||||
/// </summary>
|
||||
public bool IsActive { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Fecha de creación del registro.
|
||||
/// </summary>
|
||||
public DateTime CreatedAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Fecha de última modificación del registro.
|
||||
/// </summary>
|
||||
public DateTime? ModifiedAt { get; set; }
|
||||
}
|
||||
}
|
||||
@ -7,7 +7,7 @@
|
||||
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
|
||||
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\maski\.nuget\packages\;C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages</NuGetPackageFolders>
|
||||
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
|
||||
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.13.2</NuGetToolVersion>
|
||||
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.13.1</NuGetToolVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<SourceRoot Include="C:\Users\maski\.nuget\packages\" />
|
||||
|
||||
14
Models/Interfaces/IPhOhArcataxTypeRepository.cs
Normal file
14
Models/Interfaces/IPhOhArcataxTypeRepository.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using Domain.Entities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Models.Interfaces
|
||||
{
|
||||
public interface IPhOhArcataxTypeRepository
|
||||
{
|
||||
Task<IEnumerable<ETaxType>> GetAllActiveAsync();
|
||||
}
|
||||
}
|
||||
@ -23,6 +23,11 @@ public partial class PhOhArcataxType
|
||||
/// </summary>
|
||||
public string Description { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Porcentaje de la alícuota aplicable al impuesto, expresado como un valor decimal. Una alícuota del 21%, se debe almacenar el valor 21.00
|
||||
/// </summary>
|
||||
public decimal Taxrate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indica si el impuesto está activo (1) o inactivo (0).
|
||||
/// </summary>
|
||||
|
||||
@ -141,6 +141,10 @@ public partial class PhronCareOperationsHubContext : DbContext
|
||||
entity.Property(e => e.TaxCode)
|
||||
.HasComment("Código oficial del impuesto según AFIP.")
|
||||
.HasColumnName("tax_code");
|
||||
entity.Property(e => e.Taxrate)
|
||||
.HasComment("Porcentaje de la alícuota aplicable al impuesto, expresado como un valor decimal. Una alícuota del 21%, se debe almacenar el valor 21.00")
|
||||
.HasColumnType("decimal(18, 0)")
|
||||
.HasColumnName("taxrate");
|
||||
});
|
||||
|
||||
modelBuilder.Entity<PhOhTaxCondition>(entity =>
|
||||
|
||||
33
Models/Repositories/PhOhArcataxTypeRepository.cs
Normal file
33
Models/Repositories/PhOhArcataxTypeRepository.cs
Normal file
@ -0,0 +1,33 @@
|
||||
using Domain.Entities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Models.Helpers;
|
||||
using Models.Interfaces;
|
||||
using Models.Models;
|
||||
|
||||
namespace Models.Repositories
|
||||
{
|
||||
public class PhOhArcataxTypeRepository (PhronCareOperationsHubContext context) : IPhOhArcataxTypeRepository
|
||||
{
|
||||
#region Declaraciones y Constructor
|
||||
private readonly PhronCareOperationsHubContext _context = context;
|
||||
#endregion
|
||||
#region Metodos de clase
|
||||
public async Task<IEnumerable<ETaxType>> GetAllActiveAsync()
|
||||
{
|
||||
var taxTypes= await _context.PhOhArcataxTypes
|
||||
.Where(t => t.IsActive)
|
||||
.Select(t => new PhOhArcataxType
|
||||
{
|
||||
Id = t.Id,
|
||||
TaxCode = t.TaxCode,
|
||||
Description = t.Description,
|
||||
Taxrate=t.Taxrate,
|
||||
IsActive=t.IsActive
|
||||
})
|
||||
.ToListAsync();
|
||||
|
||||
return taxTypes.Select(EntityMapper.MapEntity<PhOhArcataxType, ETaxType>);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -7,7 +7,7 @@
|
||||
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
|
||||
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\maski\.nuget\packages\;C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages</NuGetPackageFolders>
|
||||
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
|
||||
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.13.2</NuGetToolVersion>
|
||||
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.13.1</NuGetToolVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<SourceRoot Include="C:\Users\maski\.nuget\packages\" />
|
||||
|
||||
@ -152,26 +152,6 @@ namespace phronCare.API.Controllers.Sales
|
||||
|
||||
#endregion
|
||||
|
||||
#region Exportación
|
||||
|
||||
[HttpPost("exportfiltered")]
|
||||
public async Task<IActionResult> ExportFiltered([FromBody] QuoteSearchParams searchParams)
|
||||
{
|
||||
try
|
||||
{
|
||||
var file = await _quoteService.ExportFilteredQuotesToExcelAsync(searchParams);
|
||||
return File(file,
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||
"Presupuestos.xlsx");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Impuestos (QuoteTaxes)
|
||||
|
||||
[HttpGet("{quoteId:int}/taxes")]
|
||||
@ -241,5 +221,96 @@ namespace phronCare.API.Controllers.Sales
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Ajustes Comerciales (QuoteAdjustments)
|
||||
|
||||
[HttpGet("{quoteId:int}/adjustments")]
|
||||
public async Task<IActionResult> GetAdjustments(int quoteId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var adjustments = await _quoteService.GetAdjustmentsByQuoteIdAsync(quoteId);
|
||||
return Ok(adjustments);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var methodName = MethodBase.GetCurrentMethod()?.Name ?? "UnknownMethod";
|
||||
return StatusCode(500, $"{methodName} Message: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("{quoteId:int}/adjustments")]
|
||||
public async Task<IActionResult> AddAdjustment(int quoteId, [FromBody] EQuoteAdjustment adjustment)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (adjustment == null || quoteId != adjustment.QuoteheaderId)
|
||||
return BadRequest("Datos inválidos para el ajuste.");
|
||||
|
||||
var result = await _quoteService.AddAdjustmentAsync(adjustment);
|
||||
return Ok(result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var methodName = MethodBase.GetCurrentMethod()?.Name ?? "UnknownMethod";
|
||||
return StatusCode(500, $"{methodName} Message: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPut("adjustments")]
|
||||
public async Task<IActionResult> UpdateAdjustment([FromBody] EQuoteAdjustment adjustment)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (adjustment == null || adjustment.Id <= 0)
|
||||
return BadRequest("Datos inválidos para actualizar el ajuste.");
|
||||
|
||||
await _quoteService.UpdateAdjustmentAsync(adjustment);
|
||||
return Ok("Ajuste actualizado correctamente.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var methodName = MethodBase.GetCurrentMethod()?.Name ?? "UnknownMethod";
|
||||
return StatusCode(500, $"{methodName} Message: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpDelete("adjustments/{adjustmentId:int}")]
|
||||
public async Task<IActionResult> DeleteAdjustment(int adjustmentId)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _quoteService.DeleteAdjustmentAsync(adjustmentId);
|
||||
return Ok("Ajuste eliminado correctamente.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var methodName = MethodBase.GetCurrentMethod()?.Name ?? "UnknownMethod";
|
||||
return StatusCode(500, $"{methodName} Message: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Exportación
|
||||
|
||||
[HttpPost("exportfiltered")]
|
||||
public async Task<IActionResult> ExportFiltered([FromBody] QuoteSearchParams searchParams)
|
||||
{
|
||||
try
|
||||
{
|
||||
var file = await _quoteService.ExportFilteredQuotesToExcelAsync(searchParams);
|
||||
return File(file,
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||
"Presupuestos.xlsx");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
29
phronCare.API/Controllers/Sales/TaxTypeController.cs
Normal file
29
phronCare.API/Controllers/Sales/TaxTypeController.cs
Normal file
@ -0,0 +1,29 @@
|
||||
using Core.Interfaces;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace phronCare.API.Controllers.Sales
|
||||
{
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
public class TaxTypeController : ControllerBase
|
||||
{
|
||||
private readonly ITaxTypeDom _taxTypeDom;
|
||||
public TaxTypeController(ITaxTypeDom taxTypeDom)
|
||||
{
|
||||
_taxTypeDom = taxTypeDom ?? throw new ArgumentNullException(nameof(taxTypeDom));
|
||||
}
|
||||
[HttpGet("GetAll")]
|
||||
public async Task<IActionResult> GetAll()
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = await _taxTypeDom.GetAllActiveAsync();
|
||||
return Ok(result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -239,7 +239,8 @@ static void RepositorysAndServices(WebApplicationBuilder builder)
|
||||
|
||||
builder.Services.AddScoped<IAdjustmentReasonDom, AdjustmentReasonService>();
|
||||
builder.Services.AddScoped<IPhSAdjustmentReasonRepository, PhSAdjustmentReasonRepository>();
|
||||
|
||||
builder.Services.AddScoped<ITaxTypeDom, TaxTypeService>();
|
||||
builder.Services.AddScoped<IPhOhArcataxTypeRepository, PhOhArcataxTypeRepository>();
|
||||
builder.Services.AddScoped<IQuoteDom, QuoteService>();
|
||||
|
||||
builder.Services.AddScoped<IPhSQuoteHeaderRepository, PhSQuoteHeaderRepository>();
|
||||
|
||||
@ -1556,6 +1556,43 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ContainingType": "phronCare.API.Controllers.Sales.QuoteController",
|
||||
"Method": "GetAdjustments",
|
||||
"RelativePath": "api/Quote/{quoteId}/adjustments",
|
||||
"HttpMethod": "GET",
|
||||
"IsController": true,
|
||||
"Order": 0,
|
||||
"Parameters": [
|
||||
{
|
||||
"Name": "quoteId",
|
||||
"Type": "System.Int32",
|
||||
"IsRequired": true
|
||||
}
|
||||
],
|
||||
"ReturnTypes": []
|
||||
},
|
||||
{
|
||||
"ContainingType": "phronCare.API.Controllers.Sales.QuoteController",
|
||||
"Method": "AddAdjustment",
|
||||
"RelativePath": "api/Quote/{quoteId}/adjustments",
|
||||
"HttpMethod": "POST",
|
||||
"IsController": true,
|
||||
"Order": 0,
|
||||
"Parameters": [
|
||||
{
|
||||
"Name": "quoteId",
|
||||
"Type": "System.Int32",
|
||||
"IsRequired": true
|
||||
},
|
||||
{
|
||||
"Name": "adjustment",
|
||||
"Type": "Domain.Entities.EQuoteAdjustment",
|
||||
"IsRequired": true
|
||||
}
|
||||
],
|
||||
"ReturnTypes": []
|
||||
},
|
||||
{
|
||||
"ContainingType": "phronCare.API.Controllers.Sales.QuoteController",
|
||||
"Method": "GetTaxes",
|
||||
@ -1593,6 +1630,38 @@
|
||||
],
|
||||
"ReturnTypes": []
|
||||
},
|
||||
{
|
||||
"ContainingType": "phronCare.API.Controllers.Sales.QuoteController",
|
||||
"Method": "UpdateAdjustment",
|
||||
"RelativePath": "api/Quote/adjustments",
|
||||
"HttpMethod": "PUT",
|
||||
"IsController": true,
|
||||
"Order": 0,
|
||||
"Parameters": [
|
||||
{
|
||||
"Name": "adjustment",
|
||||
"Type": "Domain.Entities.EQuoteAdjustment",
|
||||
"IsRequired": true
|
||||
}
|
||||
],
|
||||
"ReturnTypes": []
|
||||
},
|
||||
{
|
||||
"ContainingType": "phronCare.API.Controllers.Sales.QuoteController",
|
||||
"Method": "DeleteAdjustment",
|
||||
"RelativePath": "api/Quote/adjustments/{adjustmentId}",
|
||||
"HttpMethod": "DELETE",
|
||||
"IsController": true,
|
||||
"Order": 0,
|
||||
"Parameters": [
|
||||
{
|
||||
"Name": "adjustmentId",
|
||||
"Type": "System.Int32",
|
||||
"IsRequired": true
|
||||
}
|
||||
],
|
||||
"ReturnTypes": []
|
||||
},
|
||||
{
|
||||
"ContainingType": "phronCare.API.Controllers.Sales.QuoteController",
|
||||
"Method": "GetAll",
|
||||
@ -1802,6 +1871,16 @@
|
||||
],
|
||||
"ReturnTypes": []
|
||||
},
|
||||
{
|
||||
"ContainingType": "phronCare.API.Controllers.Sales.TaxTypeController",
|
||||
"Method": "GetAll",
|
||||
"RelativePath": "api/TaxType/GetAll",
|
||||
"HttpMethod": "GET",
|
||||
"IsController": true,
|
||||
"Order": 0,
|
||||
"Parameters": [],
|
||||
"ReturnTypes": []
|
||||
},
|
||||
{
|
||||
"ContainingType": "phronCare.API.Controllers.TestController",
|
||||
"Method": "GetAdministradores",
|
||||
|
||||
@ -0,0 +1,123 @@
|
||||
@using Blazored.Modal
|
||||
@using Blazored.Modal.Services
|
||||
@using Blazored.Typeahead
|
||||
@using Domain.Entities
|
||||
@inject Services.Lookups.ISalesLookupService SalesLookupService
|
||||
|
||||
<EditForm Model="_model" OnValidSubmit="HandleValidSubmit">
|
||||
<DataAnnotationsValidator />
|
||||
<ValidationSummary />
|
||||
<div class="card" style="zoom:90%;">
|
||||
<div class="card-header">
|
||||
<h5 class="card-title mb-0">Agregar Impuesto</h5>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Tipo de Impuesto *</label>
|
||||
<BlazoredTypeahead TItem="ETaxType" TValue="ETaxType"
|
||||
SearchMethod="SearchTaxTypes"
|
||||
Value="_selectedTaxType"
|
||||
ValueChanged="OnTaxTypeSelected"
|
||||
ValueExpression="@(() => _selectedTaxType)"
|
||||
TextProperty="Description"
|
||||
Placeholder="Buscar tipo de impuesto...">
|
||||
<ResultTemplate Context="item">
|
||||
@item.Description (@item.Taxrate.ToString("0.#")%)
|
||||
</ResultTemplate>
|
||||
<SelectedTemplate Context="item">
|
||||
@item.Description
|
||||
</SelectedTemplate>
|
||||
</BlazoredTypeahead>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Base Imponible *</label>
|
||||
<InputNumber class="form-control"
|
||||
Value="_model.TaxableAmount"
|
||||
ValueChanged="(decimal val) => OnValueChanged(val, (m, v) => m.TaxableAmount = v)"
|
||||
ValueExpression="@(() => _model.TaxableAmount)" />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Alícuota (%) *</label>
|
||||
<InputNumber class="form-control"
|
||||
Value="_model.Taxrate"
|
||||
ValueChanged="(decimal val) => OnValueChanged(val, (m, v) => m.Taxrate = v)"
|
||||
ValueExpression="@(() => _model.Taxrate)" />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Importe del impuesto</label>
|
||||
<InputNumber class="form-control" @bind-Value="_model.Taxamount" readonly />
|
||||
</div>
|
||||
|
||||
<div class="form-check form-switch">
|
||||
<InputCheckbox class="form-check-input" @bind-Value="_model.IsIncludedInPrice" />
|
||||
<label class="form-check-label ms-2">¿Incluido en precio?</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-footer text-end">
|
||||
<button type="submit" class="btn btn-success">Agregar</button>
|
||||
<button type="button" class="btn btn-secondary ms-2" @onclick="Cancelar">Cancelar</button>
|
||||
</div>
|
||||
</div>
|
||||
</EditForm>
|
||||
|
||||
@code {
|
||||
[CascadingParameter] public BlazoredModalInstance ModalInstance { get; set; } = default!;
|
||||
[Parameter] public decimal NetAmount { get; set; }
|
||||
private ETaxType? _selectedTaxType;
|
||||
private EQuoteTax _model = new();
|
||||
private List<ETaxType> _taxTypes = new();
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
_taxTypes = (await SalesLookupService.GetTaxTypesAsync()).ToList();
|
||||
_model.TaxableAmount = NetAmount;
|
||||
Recalculate();
|
||||
}
|
||||
|
||||
private Task<IEnumerable<ETaxType>> SearchTaxTypes(string searchTerm)
|
||||
{
|
||||
var result = string.IsNullOrWhiteSpace(searchTerm)
|
||||
? _taxTypes
|
||||
: _taxTypes.Where(t => t.Description.Contains(searchTerm, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
return Task.FromResult(result);
|
||||
}
|
||||
|
||||
|
||||
private Task OnTaxTypeSelected(ETaxType selected)
|
||||
{
|
||||
_model.Taxname = selected.Description;
|
||||
_model.Taxcode = selected.TaxCode.ToString();
|
||||
_model.Taxrate = selected.Taxrate;
|
||||
Recalculate();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private void OnValueChanged(decimal value, Action<EQuoteTax, decimal> setter)
|
||||
{
|
||||
setter(_model, value);
|
||||
Recalculate();
|
||||
}
|
||||
|
||||
private void Recalculate()
|
||||
{
|
||||
_model.Taxamount = Math.Round(_model.TaxableAmount * (_model.Taxrate / 100), 2);
|
||||
}
|
||||
|
||||
private async Task HandleValidSubmit()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(_model.Taxname))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
await ModalInstance.CloseAsync(ModalResult.Ok(_model));
|
||||
}
|
||||
|
||||
private async Task Cancelar()
|
||||
{
|
||||
await ModalInstance.CancelAsync();
|
||||
}
|
||||
}
|
||||
@ -205,8 +205,12 @@
|
||||
<!-- Totales + Ajustes -->
|
||||
<div class="row justify-content-end mt-3">
|
||||
<div class="col-md-4">
|
||||
<label class="form-label d-block">Ajustes comerciales</label>
|
||||
|
||||
<label class="form-label d-flex justify-content-between align-items-center">
|
||||
Ajustes comerciales
|
||||
<button class="btn btn-sm btn-outline-success mt-2" @onclick="OpenAdjustmentModal">
|
||||
<i class="fas fa-plus me-1"></i> Agregar
|
||||
</button>
|
||||
</label>
|
||||
@if (_quoteModel.PhSQuoteAdjustments.Any())
|
||||
{
|
||||
<div class="mb-2">
|
||||
@ -226,12 +230,52 @@
|
||||
<p class="text-muted">Sin ajustes.</p>
|
||||
}
|
||||
|
||||
<button class="btn btn-sm btn-outline-success mt-2" @onclick="OpenAdjustmentModal">
|
||||
<i class="fas fa-plus me-1"></i> Agregar ajuste
|
||||
</button>
|
||||
|
||||
</div>
|
||||
<!-- Impuestos -->
|
||||
<div class="col-md-4">
|
||||
</div>
|
||||
<label class="form-label d-flex justify-content-between align-items-center">
|
||||
Impuestos
|
||||
<button class="btn btn-sm btn-outline-success mt-2" @onclick="AddNewTax">
|
||||
<i class="fas fa-percentage me-1"></i> Agregar
|
||||
</button>
|
||||
</label>
|
||||
|
||||
@if (_quoteModel.PhSQuoteTaxes.Any())
|
||||
{
|
||||
<div class="table-responsive">
|
||||
<table class="table table-sm table-bordered mb-0">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>Nombre</th>
|
||||
<th class="text-end">%</th>
|
||||
<th class="text-end">Importe</th>
|
||||
<th style="width: 30px;"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var tax in _quoteModel.PhSQuoteTaxes)
|
||||
{
|
||||
<tr>
|
||||
<td>@tax.Taxname</td>
|
||||
<td class="text-end">@tax.Taxrate.ToString("0.##")%</td>
|
||||
<td class="text-end">$@tax.Taxamount.ToString("N2")</td>
|
||||
<td class="text-center">
|
||||
<button class="btn btn-sm btn-danger" @onclick="() => RemoveTax(tax)">
|
||||
<i class="fas fa-trash-alt"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<p class="text-muted"><em>No hay impuestos aplicados</em></p>
|
||||
}
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item d-flex justify-content-between">
|
||||
@ -369,5 +413,30 @@
|
||||
{
|
||||
_quoteModel.PhSQuoteAdjustments.Remove(adj);
|
||||
}
|
||||
private async Task AddNewTax()
|
||||
{
|
||||
var parameters = new ModalParameters();
|
||||
parameters.Add(nameof(QuoteTaxQuickAddModal.NetAmount), _netAmount);
|
||||
|
||||
|
||||
var options = new ModalOptions
|
||||
{
|
||||
HideHeader = true,
|
||||
Size = ModalSize.Small
|
||||
};
|
||||
|
||||
var modal = Modal.Show<QuoteTaxQuickAddModal>("", parameters, options);
|
||||
var result = await modal.Result;
|
||||
|
||||
if (!result.Cancelled && result.Data is EQuoteTax newTax)
|
||||
{
|
||||
_quoteModel.PhSQuoteTaxes.Add(newTax);
|
||||
RecalculateTotals();
|
||||
}
|
||||
}
|
||||
private void RemoveTax(EQuoteTax tax)
|
||||
{
|
||||
_quoteModel.PhSQuoteTaxes.Remove(tax);
|
||||
RecalculateTotals();
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,5 +12,6 @@ namespace phronCare.UIBlazor.Services.Lookups
|
||||
Task<IEnumerable<ELookUpItem>> SearchBussinessUnitsAsync(string filtro);
|
||||
Task<IEnumerable<EProductLookupItem>> SearchProductsAsync(string filtro);
|
||||
Task<IEnumerable<EAdjustmentReason>> GetAdjustmentReasonsAsync();
|
||||
Task<IEnumerable<ETaxType>> GetTaxTypesAsync();
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,5 +49,12 @@ namespace phronCare.UIBlazor.Services.Lookups
|
||||
var items = await _http.GetFromJsonAsync<EProductLookupItem[]>(url);
|
||||
return items ?? Array.Empty<EProductLookupItem>();
|
||||
}
|
||||
public async Task<IEnumerable<ETaxType>> GetTaxTypesAsync()
|
||||
{
|
||||
var items = await _http.GetFromJsonAsync<ETaxType[]>("api/taxtype/getall");
|
||||
return items ?? Array.Empty<ETaxType>();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user