Skip to main content

Creating and Managing Fund Allocations

This guide walks through the complete process of creating ministraciones (fund allocations) for vendor payments and expense reimbursements in SMAF.

When to Create a Ministracion

Ministraciones for employee travel payments are created automatically by the payment module. Manual ministracion creation is primarily for:
  • Vendor/provider invoices (hotels, transportation services)
  • Direct service payments
  • Conference or event registrations
  • Equipment rentals for field work

Prerequisites

Before creating a ministracion, ensure you have:
  • Administrator or Center Chief role access
  • Approved budget allocation for the current fiscal year
  • Program/project code for budget charging
  • Vendor information (if applicable)
  • CFDI digital tax receipts (for vendor payments)

Ministracion Creation Process

1

Access Alta Ministracion Module

Navigate to the ministracion creation module from the main menu.
public void Carga_Valores()
{
    lnkUsuario.Text = Session["Crip_Nombre"].ToString() + " " + 
                     Session["Crip_ApPat"].ToString() + " " + 
                     Session["Crip_ApMat"].ToString();
    lnkHome.Text = "INICIO";
    Label1.Text = clsFuncionesGral.ConvertMayus(
        "Alta de Ministraciones :");
}
2

Select Administrative Unit and Program

Choose the budget source for this allocation.

For Administrators/Center Chiefs

if ((lsSession == Dictionary.ADMINISTRADOR) | 
    (lsSession == Dictionary.JEFE_CENTRO))
{
    Label36.Visible = false;
    dplAdscripcion.Visible = false;
    
    dplPrograma.DataSource = MngNegocioProyecto.ObtieneProyectos(
        "", "", Session["Crip_Ubicacion"].ToString());
    dplPrograma.DataTextField = Dictionary.DESCRIPCION;
    dplPrograma.DataValueField = Dictionary.CODIGO;
    dplPrograma.DataBind();
}

For Other Roles

else
{
    Label36.Visible = true;
    dplAdscripcion.Visible = true;
    
    dplAdscripcion.DataSource = 
        MngNegocioDirecciones.ObtienenDirecciones(Year);
    dplAdscripcion.DataTextField = Dictionary.DESCRIPCION;
    dplAdscripcion.DataValueField = Dictionary.CODIGO;
    dplAdscripcion.DataBind();
}
When adscription is selected, programs are filtered:
protected void dplAdscripcion_SelectedIndexChanged(
    object sender, EventArgs e)
{
    string ads = dplAdscripcion.SelectedValue.ToString();
    
    if ((ads == "1000") | (ads == "5000"))
    {
        dplPrograma.DataSource = MngNegociosProgramas.ListaProgramas(
            "'43','44','45','24','42'", Year);
    }
    else
    {
        dplPrograma.DataSource = MngNegociosProgramas.ListaProgramas(
            "'" + ads + "'", Year);
    }
    dplPrograma.DataTextField = Dictionary.DESCRIPCION;
    dplPrograma.DataValueField = Dictionary.CODIGO;
    dplPrograma.DataBind();
}
3

Select Ministracion Type

Choose the type of fund allocation being created.
dplTipoMinistracion.DataSource = 
    MngNegocioMinistracion.ListaTipoMinistracion("00");
dplTipoMinistracion.DataValueField = Dictionary.CODIGO;
dplTipoMinistracion.DataTextField = Dictionary.DESCRIPCION;
dplTipoMinistracion.DataBind();
Selecting a ministracion type activates additional form panels. You must select a type before proceeding.
protected void dplTipoMinistracion_SelectedIndexChanged(
    object sender, EventArgs e)
{
    string tipoministracion = 
        dplTipoMinistracion.SelectedValue.ToString();
    
    if (tipoministracion == "0")
    {
        ClientScript.RegisterStartupScript(this.GetType(), "Inapesca", 
            "alert('Seleccione tipo de ministracion para avanzar');", 
            true);
        return;
    }
    else
    {
        clsFuncionesGral.Activa_Paneles(pnlBusquedaProv, true);
        
        dplTipoPago.DataSource = 
            MngNegocioMinistracion.Lista_tipo_Pagos();
        dplTipoPago.DataTextField = Dictionary.DESCRIPCION;
        dplTipoPago.DataValueField = Dictionary.CODIGO;
        dplTipoPago.DataBind();
    }
}
4

Select Payment Type

Choose between employee payments and vendor payments.
protected void dplTipoPago_SelectedIndexChanged(
    object sender, EventArgs e)
{
    string TipoPago = dplTipoPago.SelectedValue.ToString();
    
    if ((TipoPago == "17") | (TipoPago == "18"))
    {
        // Employee payment - viáticos
        clsFuncionesGral.Activa_Paneles(pnlBusquedaProv, false);
        clsFuncionesGral.Activa_Paneles(pnlBuscaXRFC, false);
        clsFuncionesGral.Activa_Paneles(pnlBuscarxXML, false);
        clsFuncionesGral.Activa_Paneles(pnlProovedor, false);
        clsFuncionesGral.Activa_Paneles(pnlAgregaFac, false);
        Limpia_Campos();
    }
    else
    {
        // Vendor payment - requires provider search
        clsFuncionesGral.Activa_Paneles(pnlBusquedaProv, true);
        clsFuncionesGral.Activa_Paneles(pnlBuscaXRFC, true);
        clsFuncionesGral.Activa_Paneles(pnlBuscarxXML, false);
        clsFuncionesGral.Activa_Paneles(pnlProovedor, false);
        clsFuncionesGral.Activa_Paneles(pnlAgregaFac, false);
        Limpia_Campos();
    }
}
5

Search or Create Vendor (For Vendor Payments)

Locate existing vendor or create new vendor record.

Method 1: Search by RFC

protected void imbBuscar_Click(object sender, ImageClickEventArgs e)
{
    if ((txtRfcFind.Text == "") | (txtRfcFind.Text == null))
    {
        ClientScript.RegisterStartupScript(this.GetType(), "Inapesca", 
            "alert('Anote RFC valido');", true);
        return;
    }
    
    string lsRfcFind = txtRfcFind.Text;
    Proovedor loProovedor = 
        mngNegocioProovedor.Proveedor(txtRfcFind.Text);
    
    clsFuncionesGral.Activa_Paneles(pnlProovedor, true);
    clsFuncionesGral.Activa_Paneles(pnlAgregaFac, true);
    btnCargarPago.Enabled = true;
    
    if ((loProovedor.RFC == null) | (loProovedor.RFC == ""))
    {
        // New vendor - enable RFC field for manual entry
        loProovedor = null;
        txtRfc.Enabled = true;
        txtRfc.Text = clsFuncionesGral.ConvertMayus(txtRfcFind.Text);
        // Initialize empty fields
    }
    else
    {
        // Existing vendor - populate all fields
        txtRfc.Text = loProovedor.RFC;
        txtRfc.Enabled = false;
        txtCp.Text = loProovedor.CP;
        txtRazonSocial.Text = loProovedor.Razon_Social;
        txtEmail.Text = loProovedor.Email;
        txtCalle.Text = loProovedor.Calle;
        txtContacto.Text = loProovedor.Contacto;
        txtNumExt.Text = loProovedor.Num_Ext;
        txtTelefonoCon.Text = loProovedor.Telefono;
        // ... additional fields
        txtBanco.Text = loProovedor.Banco;
        txtCuentaBancaria.Text = loProovedor.Cuenta;
        txtClabe.Text = loProovedor.Clabe;
    }
}

Method 2: Read from CFDI (Digital Tax Receipt)

Upload PDF and XML files to automatically extract vendor information:
protected void lnkBuscarProovedor_Click(object sender, EventArgs e)
{
    bool xmlOK = false;
    bool fileOk = false;
    
    // Validate PDF file
    if (!fuplPDF.HasFile)
    {
        ClientScript.RegisterStartupScript(this.GetType(), "Inapesca", 
            "alert('Archivo pdf es nesesario.');", true);
        return;
    }
    
    // Validate XML file
    if (!fuplXML.HasFile)
    {
        ClientScript.RegisterStartupScript(this.GetType(), "Inapesca", 
            "alert('Archivo xml es nesesario');", true);
        return;
    }
    
    // Ensure file names match
    string nombrepdf = clsFuncionesGral.ConvertMinus(fuplPDF.FileName);
    nombrepdf = nombrepdf.Replace(".pdf", "");
    
    string nombreXml = clsFuncionesGral.ConvertMinus(fuplXML.FileName);
    nombreXml = nombreXml.Replace(".xml", "");
    
    if (nombrepdf != nombreXml)
    {
        ClientScript.RegisterStartupScript(this.GetType(), "Inapesca", 
            "alert('Nombres de archivos pdf y xml deben ser iguales.');", 
            true);
        return;
    }
}
Process the XML to extract vendor data:
// Save XML file
Valida_CarpetaXML();
fuplXML.PostedFile.SaveAs(
    Session["Crip_Ruta"].ToString() + "/" + fuplXML.FileName);

// Parse XML
List<Entidad> llEntidad = new List<Entidad>();
Entidades.Xml oXml = new Entidades.Xml();

clsFuncionesGral.Lee_XMl(
    Session["Crip_Ruta"].ToString() + "/" + fuplXML.FileName, 
    llEntidad, 
    oXml
);

// Validate CFDI hasn't been used
string existe = 
    MngNegocioComprobacion.Exist_UUUID(oXml.TIMBRE_FISCAL);
string existe1 = 
    MngNegocioComprobacion.Exist_UUUID_Ministracion(
        oXml.TIMBRE_FISCAL);

if (((existe == "") | (existe == null)) && 
    ((existe1 == "") | (existe1 == null)))
{
    // Populate vendor fields from XML
    txtRfc.Text = clsFuncionesGral.ConvertMayus(oXml.RFC_EMISOR);
    txtRazonSocial.Text = 
        clsFuncionesGral.ConvertMayus(oXml.NOMBRE_EMISOR);
    txtCalle.Text = oXml.CALLE_EMISOR;
    txtNumExt.Text = oXml.NO_EXTERIOR_EMMISOR;
    txtNumInt.Text = oXml.NO_INTERIOR_EMISOR;
    txtColonia.Text = oXml.COLONIA_EMISOR;
    txtMunicipio.Text = oXml.MUNICIPIO_EMISOR;
    txtCuidad.Text = oXml.LOCALIDAD_EMISOR;
    txtEstado.Text = oXml.ESTADO_EMISOR;
    txtPais.Text = oXml.PAIS_EMISOR;
    txtCp.Text = oXml.CP_EMISOR;
    txtRegimenFiscal.Text = oXml.REGIMENFISCAL_EMISOR;
}
else
{
    ClientScript.RegisterStartupScript(this.GetType(), "Inapesca", 
        "alert('Este CFDI ya fue utilizadfo en otra ministracion');", 
        true);
    return;
}
The CFDI must be issued to INAPESCA (Instituto Nacional de Pesca). The system validates the receptor RFC.
if (oXml.RFC_RECEPTOR != Dictionary.RFC_INP)
{
    Limpia_Campos();
    ClientScript.RegisterStartupScript(this.GetType(), "Inapesca", 
        "alert('El CFDI que intenta cargar no fue expedidad " +
        "para el Instituto Nacional de Pesca');", true);
    return;
}
6

Complete or Update Vendor Information

Fill in or verify all required vendor fields.

Required Vendor Fields

txtRfc
string
required
RFC (Tax ID): Federal taxpayer registry code
txtRazonSocial
string
required
Business Name: Legal registered name
txtCalle
string
required
Street Address
txtNumExt
string
Exterior Number
txtNumInt
string
Interior Number (optional)
txtColonia
string
required
Neighborhood/Colony
txtMunicipio
string
required
Municipality/Delegation
txtCuidad
string
City
txtEstado
string
required
State
txtCp
string
required
Postal Code

Banking Information

txtBanco
string
required
Bank Name
txtCuentaBancaria
string
required
Account Number
txtClabe
string
required
CLABE Interbank Code: 18-digit standardized bank account code

Contact Information

txtEmail
string
Email Address
txtContacto
string
Contact Person Name
txtTelefonoCon
string
Contact Phone
txtTelefonoEmpresa
string
Company Phone 1
txtTelefonoEmpresa2
string
Company Phone 2

Tax Information

txtRegimenFiscal
string
Tax Regime: Fiscal classification of the business
txtServicio
string
Services Provided: Description of vendor services
7

Update Vendor Record

Save the vendor information to the database.
protected void lnkUpdateProovedor_Click(object sender, EventArgs e)
{
    Proovedor loProovedor = new Proovedor();
    
    loProovedor.RFC = txtRfc.Text;
    loProovedor.Razon_Social = txtRazonSocial.Text;
    loProovedor.Calle = txtCalle.Text;
    loProovedor.Num_Ext = txtNumExt.Text;
    loProovedor.Num_int = txtNumInt.Text;
    loProovedor.Colonia = txtColonia.Text;
    loProovedor.Municipio = txtMunicipio.Text;
    loProovedor.Ciudad = txtCuidad.Text;
    loProovedor.Estado = txtEstado.Text;
    loProovedor.Pais = txtPais.Text;
    loProovedor.CP = txtCp.Text;
    loProovedor.Email = txtEmail.Text;
    loProovedor.Contacto = txtContacto.Text;
    loProovedor.Telefono = txtTelefonoCon.Text;
    loProovedor.Telefono1 = txtTelefonoEmpresa.Text;
    loProovedor.Telefono2 = txtTelefonoEmpresa2.Text;
    loProovedor.Regimen_Fiscal = txtRegimenFiscal.Text;
    loProovedor.Servicio = txtServicio.Text;
    loProovedor.Cuenta = txtCuentaBancaria.Text;
    loProovedor.Banco = txtBanco.Text;
    loProovedor.Clabe = txtClabe.Text;
    
    bool update = mngNegocioProovedor.Update_Proveedor(loProovedor);
    
    if (update)
    {
        ClientScript.RegisterStartupScript(this.GetType(), "Inapesca", 
            "alert('Datos Actualizado correctamente');", true);
    }
    else
    {
        ClientScript.RegisterStartupScript(this.GetType(), "Inapesca", 
            "alert('Ocurrio un error al actualizar');", true);
    }
}
The system performs an upsert - if the RFC exists, it updates the record; otherwise, it creates a new vendor.
8

Upload Invoice Documents (For Vendor Payments)

After vendor information is complete, upload the invoice files.

Required Documents

  1. PDF Invoice: Visual representation of the CFDI
  2. XML CFDI: Digital tax receipt with fiscal data
  3. Supporting Documents (optional): Additional proof like tickets, contracts
Label29.Text = clsFuncionesGral.ConvertMayus("archivo pdf");
Label30.Text = clsFuncionesGral.ConvertMayus("archivo xml");
Label31.Text = clsFuncionesGral.ConvertMayus(
    "Documentacion comprobatoria adicional en formato PDF " +
    "que avalan factura ") + " (Opcional)";
The files are uploaded through FileUpload controls:
  • FileUpload1: PDF invoice
  • FileUpload2: XML CFDI
  • FileUpload3: Supporting documents (optional)
9

Submit Ministracion for Approval

Click “Cargar Pago a ministracion” to submit the allocation request.
btnCargarPago.Text = 
    clsFuncionesGral.ConvertMayus("Cargar Pago a ministracion");
btnCargarPago.Enabled = true; // Enabled after vendor validated
The system will:
  1. Validate all required fields
  2. Verify CFDI hasn’t been used
  3. Create ministracion record
  4. Link to appropriate budget codes
  5. Route for financial approval

Allocation Amount Calculation

For vendor payments, amounts are extracted from the CFDI XML:
Entidades.Xml oXml = new Entidades.Xml();
clsFuncionesGral.Lee_XMl(
    Session["Crip_Ruta"].ToString() + "/" + fuplXML.FileName, 
    llEntidad, 
    oXml
);

// CFDI contains:
// - oXml.SUBTOTAL: Base amount
// - oXml.IVA: Value Added Tax
// - oXml.TOTAL: Total payable amount
// - oXml.TIMBRE_FISCAL: UUID for validation

Budget Validation

Before ministracion approval, the system validates:
Ensures sufficient unallocated funds exist in the selected program/project.Checks against:
  • Approved annual budget
  • Previous ministraciones
  • Committed but unpaid amounts
  • Fiscal year constraints
Verifies the requesting user has authority for the allocation amount.Approval requirements:
  • Under threshold: Center chief approval
  • Over threshold: Financial director approval
  • Special programs: Additional oversight required
Confirms the allocation is within the current fiscal year and accounting period.
MngNegocioMinistracion.Obtiene_ClvPeriodo(lsHoy, Year)
For vendor payments, ensures the CFDI hasn’t been previously processed.
string existe = MngNegocioComprobacion.Exist_UUUID(oXml.TIMBRE_FISCAL);
string existe1 = MngNegocioComprobacion.Exist_UUUID_Ministracion(
    oXml.TIMBRE_FISCAL);

if (((existe == "") | (existe == null)) && 
    ((existe1 == "") | (existe1 == null)))
{
    // CFDI is valid and unused
}

Approval Process Workflow

After ministracion creation:
1

Submitted

Ministracion created with status “pending”
2

Financial Review

Financial department validates:
  • Budget availability
  • Correct program/project coding
  • CFDI authenticity (for vendors)
  • Vendor banking information
3

Authorization

Deputy Financial Director authorizes the allocation
MngNegocioDependencia.Obtiene_DIrector_Financieros(
    Dictionary.PUESTO_FINANCIERO, 
    Dictionary.SUBDIRECTOR_ADJUNTO
)
4

Final Approval (if required)

For amounts exceeding threshold, Financial Director provides final approval
5

Payment Processing

Once approved, ministracion is available for payment processing

Managing Existing Ministraciones

Viewing Ministracion Status

Ministraciones can be queried by:
  • Fiscal year
  • Program/project
  • Vendor RFC
  • Status (pending, partial, complete)
  • Date range

Modifying Ministraciones

Ministraciones cannot be modified after approval. If changes are needed:
  1. Cancel the existing ministracion (requires justification)
  2. Create a new ministracion with correct information

Payment Tracking

For ministraciones associated with multiple payments:
List<Entidad> ListaMinistracion = 
    MngNegocioMinistracion.Obtiene_Ministracion(Year, archivo);

// Returns all ministraciones for a commission/vendor
// Each showing:
// - Folio (ministracion number)
// - Total requested
// - Total paid
// - Balance remaining
// - Status

Common Issues and Solutions

IssueCauseSolution
”Este CFDI ya fue utilizado”CFDI UUID already exists in systemVerify you have the correct invoice; contact vendor for clarification
”El CFDI no fue expedido para INAPESCA”CFDI issued to different recipientRequest vendor issue correct CFDI with INAPESCA as receptor
”Nombres de archivos deben ser iguales”PDF and XML file names don’t matchRename files to have identical names (excluding extension)
“Tipo de Archivo no valido”Wrong file format uploadedEnsure PDF has .pdf extension and XML has .xml extension
”Seleccione tipo de ministracion”No ministracion type selectedChoose appropriate type from dropdown before proceeding

Helper Functions

Clearing Form Fields

public void Limpia_Campos()
{
    txtRfcFind.Text = Dictionary.CADENA_NULA;
    txtRfc.Text = Dictionary.CADENA_NULA;
    txtRazonSocial.Text = Dictionary.CADENA_NULA;
    txtCalle.Text = Dictionary.CADENA_NULA;
    txtNumExt.Text = Dictionary.CADENA_NULA;
    txtNumInt.Text = Dictionary.CADENA_NULA;
    txtColonia.Text = Dictionary.CADENA_NULA;
    txtMunicipio.Text = Dictionary.CADENA_NULA;
    txtCuidad.Text = Dictionary.CADENA_NULA;
    txtEstado.Text = Dictionary.CADENA_NULA;
    txtPais.Text = Dictionary.CADENA_NULA;
    txtCp.Text = Dictionary.CADENA_NULA;
    txtEmail.Text = Dictionary.CADENA_NULA;
    txtContacto.Text = Dictionary.CADENA_NULA;
    txtTelefonoCon.Text = Dictionary.CADENA_NULA;
    txtTelefonoEmpresa.Text = Dictionary.CADENA_NULA;
    txtTelefonoEmpresa2.Text = Dictionary.CADENA_NULA;
    txtRegimenFiscal.Text = Dictionary.CADENA_NULA;
    txtServicio.Text = Dictionary.CADENA_NULA;
    txtCuentaBancaria.Text = Dictionary.CADENA_NULA;
    txtClabe.Text = Dictionary.CADENA_NULA;
    txtBanco.Text = Dictionary.CADENA_NULA;
    
    FileUpload1.Dispose();
    FileUpload2.Dispose();
    FileUpload3.Dispose();
}

Validating XML Storage Directory

public void Valida_CarpetaXML()
{
    string raiz = HttpContext.Current.Server.MapPath("..");
    if (!Directory.Exists(raiz + "\\" + " XML")) 
        Directory.CreateDirectory(raiz + "\\" + " XML");
    Session["Crip_Ruta"] = raiz + "\\" + " XML";
}

Next Steps

Process Payments

Use approved ministraciones to process payments

Budget Reports

Generate budget consumption and allocation reports

Build docs developers (and LLMs) love