Skip to main content
The service layer encapsulates business logic and data access, providing a clean separation between controllers and data persistence.

IBiddingParticipantService

Manages bidding participants in public procurement processes. Namespace: services
Implementation: BiddingParticipantService

Dependencies

_context
ApplicationDbContext
Entity Framework database context
_mapper
IMapper
AutoMapper for DTO conversions
_uploadedFileIIS
IUploadedFileIIS
File upload service for IIS
_emailSendGrid
IEmailSendGrid
SendGrid email service for notifications

Methods

GetAll

Retrieves all bidding participants with related Master data.
Task<IEnumerable<BiddingParticipant>> GetAll()
return
Task<IEnumerable<BiddingParticipant>>
Collection of all participants with included Master relationship
Implementation:
return await _context.BiddingParticipants
    .Include(x => x.Master)
    .ToListAsync();

GetById

Retrieves a participant by ID.
id
int?
required
Participant identifier
Task<BiddingParticipant> GetById(int? id)
return
Task<BiddingParticipant>
Participant entity with Master navigation property loaded

GetByRef

Retrieves a participant by their unique reference GUID.
reference
string
required
GUID reference code (converted internally)
Task<BiddingParticipant> GetByRef(string reference)
return
Task<BiddingParticipant>
Participant matching the reference code

Create

Registers a new bidding participant with proposal file and email notifications.
model
BiddingParticipantCreateDTO
required
Participant data
Task<BiddingParticipantDTO> Create(BiddingParticipantCreateDTO model)
process
object
Example:
var participant = await _biddingParticipantService.Create(new BiddingParticipantCreateDTO
{
    NaturalPerson = true,
    Name = "Juan Pérez",
    IdentificationOrNit = "1234567890",
    Phone = "6045551234",
    Cellular = "3001234567",
    Address = "Calle 10 #20-30",
    City = "Santa Fe de Antioquia",
    Email = "[email protected]",
    Proposals = proposalPdfFile,
    MasterId = 5
});

DuplicaIdentificationOrNit

Validates that an identification/NIT is unique within a specific announcement.
identificationOrNit
string
required
ID or tax number to check
masterId
int
required
Announcement/convocatoria ID
Boolean DuplicaIdentificationOrNit(string identificationOrNit, int masterId)
return
Boolean
true if duplicate exists, false if unique

DeleteConfirmed

Removes a participant and their uploaded proposal file.
id
int
required
Participant ID to delete
Task DeleteConfirmed(int id)

IBlogService

Manages blog posts and news articles. Namespace: services
Implementation: BlogService

Dependencies

_context
ApplicationDbContext
Database context
_mapper
IMapper
AutoMapper instance
_formatStringUrl
IFormatStringUrl
URL slug generation service
_uploadedFileIIS
IUploadedFileIIS
Image upload handler

Methods

GetAll

Retrieves all blog posts ordered by creation date.
Task<IEnumerable<Master>> GetAll()
return
Task<IEnumerable<Master>>
Blog entries (Master entities where Blog = true) ordered newest first
Query:
var blogs = await _context.Masters
    .AsNoTracking()
    .Where(x => x.Blog == true)
    .OrderByDescending(x => x.DateCreate)
    .ToListAsync();

LimitHome

Retrieves the 3 most recent blog posts for homepage display.
Task<IEnumerable<Master>> LimitHome()
return
Task<IEnumerable<Master>>
Top 3 newest blog posts

GetById (int)

Retrieves a blog post by numeric ID.
id
int?
required
Blog post identifier
Task<Master> GetById(int? id)

GetById (string)

Retrieves a blog post by URL slug.
urBlog
string
required
URL-friendly blog identifier
Task<Master> GetById(string urBlog)

Create

Creates a new blog post with cover image.
model
BlogCreateDto
required
Blog post data
Task<BlogDto> Create(BlogCreateDto model)
process
object
Example:
var blog = await _blogService.Create(new BlogCreateDto
{
    NameBlog = "Nueva Iniciativa 2026",
    Description = "<p>Contenido HTML del artículo...</p>",
    Author = "Comunicaciones ESP",
    CoverPage = imageFile
});
// Creates URL: /noticias/nueva-iniciativa-2026

Edit

Updates an existing blog post.
id
int
required
Blog post ID
model
BlogEditDto
required
Updated content
Task Edit(int id, BlogEditDto model)
behavior
string
If new cover image provided, replaces existing. Otherwise, retains current image.

DuplicaName

Checks if a blog name already exists.
_stringName
string
required
Blog name to validate
bool DuplicaName(string _stringName)

DeleteConfirmed

Deletes a blog post and its cover image.
id
int
required
Blog post ID
Task DeleteConfirmed(int id)

ICategoryService

Manages service categories. Namespace: services
Implementation: CategoryService

Methods

GetAll

Retrieves all service categories.
Task<IEnumerable<Category>> GetAll()

GetById (int)

Retrieves category by numeric ID.
Task<Category> GetById(int? id)

GetById (string)

Retrieves category by URL-friendly name.
nameCategory
string
required
URL slug of category
Task<Category> GetById(string nameCategory)

Create

Creates a new service category.
model
CategoryCreateDto
required
Category data with cover image
Task<CategoryDto> Create(CategoryCreateDto model)
process
object
Example:
var category = await _categoryService.Create(new CategoryCreateDto
{
    NameCategory = "Acueducto y Alcantarillado",
    Description = "<p>Servicios de agua potable...</p>",
    CoverPage = imageFile,
    Statud = true
});
// Creates URL: /servicios/acueducto-y-alcantarillado

Edit

Updates a category.
id
int
required
Category ID
model
CategoryEditDto
required
Updated data
Task Edit(int id, CategoryEditDto model)
note
string
Updates DateUpdate timestamp automatically

CategoryExists

Validates category existence.
bool CategoryExists(int id)

DuplicaName

Checks for duplicate category names.
bool DuplicaName(string _stringName)

IDocumentService

Manages legal documents with multiple file attachments. Namespace: services
Implementation: DocumentService

Dependencies

_uploadedFileIIS
IUploadedFileIIS
File upload service
_formatStringUrl
IFormatStringUrl
URL formatting service

Methods

GetAll

Retrieves all documents with their file attachments.
Task<IEnumerable<Document>> GetAll()
return
Task<IEnumerable<Document>>
Documents ordered by creation date (newest first) with FileDocument collection loaded
Query:
return await _context.Documents
    .Include(x => x.FileDocument)
    .OrderByDescending(x => x.CreateDate)
    .ToListAsync();

GetById (int)

Retrieves document by ID.
id
int?
required
Document identifier
Task<Document> GetById(int? id)
return
Task<Document>
Document with FileDocument collection

GetById (string)

Retrieves document by URL name.
_urlName
string
required
URL-friendly document name
Task<Document> GetById(string _urlName)

Create

Creates a document with multiple file attachments using database transaction.
model
DocumentCreateDTO
required
Document metadata and files
Task Create(DocumentCreateDTO model)
transaction
object
Example:
await _documentService.Create(new DocumentCreateDTO
{
    Name = "Plan de Desarrollo 2026",
    Description = "Documento oficial del plan...",
    MasterId = 10,
    RouteFile = new List<IFormFile> { file1, file2, file3 }
});

FilesDocuments

Retrieves all file documents.
Task<IEnumerable<FileDocument>> FilesDocuments()

DeleteConfirmed

Deletes a document and all associated files using transaction.
_id
int
required
Document ID
Task DeleteConfirmed(int _id)
process
object

DocumentExists

Validates document existence.
bool DocumentExists(int id)

DuplicaName

Checks for duplicate document names.
bool DuplicaName(string _stringName)

Common Service Utilities

IFormatStringUrl

Converts text to URL-friendly slugs. Example transformations:
  • “Acueducto y Alcantarillado” → “acueducto-y-alcantarillado”
  • “PQRSD 2026” → “pqrsd-2026”
  • “Noticias: Nueva Obra” → “noticias-nueva-obra”

IUploadedFileIIS

Handles file operations on IIS server. Storage locations:
  • blog/ - Blog cover images
  • categories/ - Category images
  • filesBiddingParticipant/ - Proposal PDFs
  • filesDocuments/ - Legal document files

IEmailSendGrid

Sends emails via SendGrid API.
Task Execute(string subject, string htmlBody, string recipientEmail)
Used for:
  • Bidding participant confirmations
  • PQRSD submission receipts
  • Admin notifications

Service Layer Patterns

Dependency Injection

All services are registered in Startup.cs and injected via constructor:
services.AddScoped<IBiddingParticipantService, BiddingParticipantService>();
services.AddScoped<IBlogService, BlogService>();
services.AddScoped<ICategoryService, CategoryService>();
services.AddScoped<IDocumentService, DocumentService>();

AutoMapper Usage

DTOs are mapped to entities and vice versa:
var dto = _mapper.Map<BiddingParticipantDTO>(entity);
var entity = _mapper.Map<BiddingParticipant>(createDto);

Error Handling

Services with complex operations use transactions:
using var transaction = _context.Database.BeginTransaction();
try
{
    // Operations
    transaction.Commit();
}
catch (Exception ex)
{
    transaction.Rollback();
}

Async/Await

All database operations are asynchronous for better performance.

INacionLicitanteService

Manages public bidding announcements (Licitaciones) with document attachments. Namespace: services
Implementation: NacionLicitanteService

Dependencies

_context
ApplicationDbContext
Entity Framework database context
_mapper
IMapper
AutoMapper for DTO conversions
_formatStringUrl
IFormatStringUrl
URL slug generation service
_uploadedFileIIS
IUploadedFileIIS
File upload service for IIS

Methods

GetAll

Retrieves all bidding announcements.
Task<IEnumerable<Master>> GetAll()
return
Task<IEnumerable<Master>>
Collection where NacionLicitante == true
Query:
return await _context.Masters
    .AsNoTracking()
    .Where(x => x.NacionLicitante == true)
    .ToListAsync();

GetById (int)

Retrieves announcement by ID with file documents.
id
int?
required
Announcement identifier
Task<Master> GetById(int? id)
return
Task<Master>
Master entity with FileDocument collection included

GetById (string)

Retrieves announcement by URL slug.
nacionLicitante
string
required
URL-friendly identifier
Task<Master> GetById(string nacionLicitante)

Details

Retrieves announcement details as DTO.
Task<NacionLicitanteDto> Details(int? id)

Create

Creates new bidding announcement with cover image and optional file attachments using transaction.
model
NacionLicitanteCreateDto
required
Announcement data
Task Create(NacionLicitanteCreateDto model)
process
object
Example:
await _nacionLicitante.Create(new NacionLicitanteCreateDto
{
    NameMaster = "Licitación Pública 001-2026",
    Description = "<p>Detalles de la convocatoria...</p>",
    CoverPage = imageFile,
    NacionLicitantegStartDate = new DateTime(2026, 3, 1),
    NacionLicitanteEndDate = new DateTime(2026, 3, 31),
    NacionLicitantegFile = new List<IFormFile> { pdfFile1, pdfFile2 }
});

FilesDocuments

Retrieves all file documents in system.
Task<IEnumerable<FileDocument>> FilesDocuments()
return
Task<IEnumerable<FileDocument>>
All FileDocument records

DelatedDocuments

Retrieves documents associated with specific announcement.
id
int
required
Master/announcement ID
Task<IEnumerable<Document>> DelatedDocuments(int id)
return
Task<IEnumerable<Document>>
Documents where MasterId == id

DeleteConfirmed

Removes announcement with complete cascade deletion using transaction.
id
int
required
Announcement ID to delete
Task DeleteConfirmed(int id)
cascade-deletion
object

NacionLicitantegExists

Validates announcement existence.
bool NacionLicitantegExists(int id)

DuplicaName

Checks for duplicate announcement names.
_stringName
string
required
Name to validate
bool DuplicaName(string _stringName)

IBrigadeService

Manages community brigade events. Namespace: services
Implementation: BrigadeService

Dependencies

_context
ApplicationDbContext
Database context
_mapper
IMapper
AutoMapper instance
_formatStringUrl
IFormatStringUrl
URL slug generator
_uploadedFileIIS
IUploadedFileIIS
File upload handler

Methods

GetAll

Retrieves all brigade events ordered by creation date.
Task<IEnumerable<Master>> GetAll()
return
Task<IEnumerable<Master>>
Brigade entries (Master where Brigade == true) ordered newest first
Query:
return await _context.Masters
    .AsNoTracking()
    .Where(x => x.Brigade == true)
    .OrderByDescending(x => x.DateCreate)
    .ToListAsync();

GetById (int)

Retrieves brigade by numeric ID.
id
int?
required
Brigade identifier
Task<Master> GetById(int? id)

GetById (string)

Retrieves brigade by URL slug.
urBrigade
string
required
URL-friendly identifier
Task<Master> GetById(string urBrigade)

Details

Retrieves brigade details as DTO.
Task<BrigadeDto> Details(int? id)

Create

Creates new brigade event with cover image.
model
BrigadeCreateDto
required
Brigade data including event date
Task<BrigadeDto> Create(BrigadeCreateDto model)
process
object
Example:
var brigade = await _brigadeService.Create(new BrigadeCreateDto
{
    NameMaster = "Jornada de Salud Barrio Centro",
    Description = "<p>Atención médica gratuita...</p>",
    Author = "Secretaría de Salud",
    DateBrigade = new DateTime(2026, 4, 15),
    CoverPage = imageFile
});
// Creates URL: /brigadas/jornada-de-salud-barrio-centro

DeleteConfirmed

Removes brigade and cover image.
id
int
required
Brigade ID
Task DeleteConfirmed(int id)
process
string
Deletes cover page from brigade folder, then removes Master record

BrigadeExists

Validates brigade existence.
bool BrigadeExists(int id)

DuplicaName

Checks for duplicate brigade names.
bool DuplicaName(string _stringName)

IEmployeeService

Manages employee records and staff directory. Namespace: services
Implementation: EmployeeService

Dependencies

_context
ApplicationDbContext
Database context
_mapper
IMapper
AutoMapper instance
_uploadedFileIIS
IUploadedFileIIS
File upload service

Methods

GetAll

Retrieves all employees ordered by creation date.
Task<IEnumerable<Employee>> GetAll()
return
Task<IEnumerable<Employee>>
All employee records ordered newest first
Query:
return await _context.Employees
    .AsNoTracking()
    .OrderByDescending(x => x.DateCreate)
    .ToListAsync();

GetById

Retrieves employee by ID.
id
int?
required
Employee identifier
Task<Employee> GetById(int? id)

Details

Retrieves employee details as DTO.
Task<EmployeeDto> Details(int? id)

Create

Creates new employee record with photo.
model
EmployeeCreateDto
required
Employee data
Task<EmployeeDto> Create(EmployeeCreateDto model)
process
object
Example:
var employee = await _employeeService.Create(new EmployeeCreateDto
{
    Name = "María García López",
    Occupation = "Gerente General",
    CoverPage = photoFile
});

DeleteConfirmed

Removes employee and photo.
id
int
required
Employee ID
Task DeleteConfirmed(int id)
process
string
Deletes photo from employees folder, then removes Employee record

IProductService

Manages service products offered by the organization. Namespace: services
Implementation: ProductService

Dependencies

_context
ApplicationDbContext
Database context
_mapper
IMapper
AutoMapper instance
_formatStringUrl
IFormatStringUrl
URL slug generator

Methods

GetAll

Retrieves all products ordered by creation date.
Task<IEnumerable<Product>> GetAll()
return
Task<IEnumerable<Product>>
All products ordered newest first

GetById

Retrieves product by numeric ID.
Task<Product> GetById(int? id)

Details (int)

Retrieves product details by ID.
Task<ProductDto> Details(int? id)

Details (string)

Retrieves product details by URL slug.
urlProduct
string
required
URL-friendly product identifier
Task<ProductDto> Details(string urlProduct)

Create

Creates new product/service.
model
ProductCreateDto
required
Product data
Task<ProductDto> Create(ProductCreateDto model)
process
object
Example:
var product = await _productService.Create(new ProductCreateDto
{
    Name = "Instalación de Medidores",
    Icono = "icon-meter",  // Becomes "icon-meter.svg"
    Description = "<p>Servicio de instalación...</p>"
});
// Creates URL: /servicios/instalacion-de-medidores

DeleteConfirmed

Removes product record.
Task DeleteConfirmed(int id)

ProductExists

Validates product existence.
bool ProductExists(int id)

DuplicaName

Checks for duplicate product names.
bool DuplicaName(string _stringName)

IPQRSDService

Manages PQRSD submissions (Petitions, Complaints, Claims, Suggestions, Congratulations) with email notifications. Namespace: services
Implementation: PQRSDService

Dependencies

_context
ApplicationDbContext
Database context
_mapper
IMapper
AutoMapper instance
_formatStringUrl
IFormatStringUrl
URL formatter
_uploadedFileIIS
IUploadedFileIIS
File upload service
_emailSendGrid
IEmailSendGrid
SendGrid email service
_hostingEnvironment
IHostingEnvironment
Access to web root for email templates

Methods

GetAll

Retrieves all PQRSD submissions.
IEnumerable<PQRSD> GetAll()
return
IEnumerable<PQRSD>
All PQRSD records

GetById

Retrieves PQRSD by unique identifier.
id
Guid?
required
PQRSD identifier
PQRSD GetById(Guid? id)

Details

Retrieves PQRSD details as DTO.
PQRSDDto Details(Guid? id)

Create

Creates new PQRSD submission and sends email notifications.
model
PQRSDCreateDto
required
PQRSD data
Task<PQRSDDto> Create(PQRSDCreateDto model)
process
object
Example:
var pqrsd = await _pqrsdService.Create(new PQRSDCreateDto
{
    NamePerson = "Carlos Ramírez",
    Email = "[email protected]",
    PQRSDName = "Solicitud de instalación de servicio",
    Description = "Requiero instalación...",
    NameSotypeOfRequest = "Petición"
});
// Returns PQRSDID (Guid) for tracking

Review

Administrative response to PQRSD submission.
id
Guid
required
PQRSD identifier
model
ReviewCreateDto
required
Admin response data
Boolean Review(Guid id, ReviewCreateDto model)
updates
object

DeleteConfirmed

Removes PQRSD submission.
id
Guid
required
PQRSD identifier
Task DeleteConfirmed(Guid id)

Service Utilities Detail

File Storage Folders

nacionLicitante
folder
Bidding announcement cover images
brigade
folder
Brigade event cover images
employees
folder
Employee photos
filesDocuments
folder
PDF attachments for announcements and documents
PQRSD
folder
PQRSD file attachments (currently unused)

Email Templates

Email templates are stored in /emailTemplete/ directory:

Transaction Management

Services that handle complex multi-step operations use database transactions:
using var transaction = _context.Database.BeginTransaction();
try
{
    // Multiple database operations
    // File uploads
    transaction.Commit();
}
catch (Exception ex)
{
    transaction.Rollback();
}
Used in:
  • NacionLicitanteService.Create
  • NacionLicitanteService.DeleteConfirmed

Build docs developers (and LLMs) love