Compare commits
2 Commits
bb4934a031
...
c4f958e688
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c4f958e688 | ||
|
|
547ec5d45a |
811
AGENTS.md
811
AGENTS.md
@@ -45,7 +45,7 @@ Database
|
||||
## Language rules
|
||||
|
||||
- All new code must be **C#**.
|
||||
- All new project-owned identifiers must use Spanish domain terminology, including C# members and local variables, JavaScript functions and variables, CSS hooks, HTML `data-*` attributes, and `ViewState` keys. Keep framework, library, protocol, and established external API names unchanged.
|
||||
- All new project-owned identifiers and file names must use Spanish domain terminology. This includes file names, namespaces, classes, interfaces, methods, properties, fields, parameters and local variables in C#; JavaScript functions and variables; CSS hooks; HTML `data-*` attributes; and `ViewState` keys. Keep framework, library, protocol, generated-code, and established external API names unchanged.
|
||||
- Do not introduce English aliases for Spanish database or business concepts. For example, use `CveUnidadMedida`, `unidadMedida`, or `data-cve-unidad-medida`, not `MeasurementUnit`, `measurementUnit`, or `data-measurement-unit-id`.
|
||||
- Do not add VB.NET files.
|
||||
- Do not add `.vb` files to the active project.
|
||||
@@ -74,745 +74,33 @@ All generated or modified source code must be formatted for human maintenance.
|
||||
- Preserve existing user-authored rules, terminology, capitalization, examples, and formatting outside the requested change.
|
||||
- When adding a rule, first verify whether an equivalent or conflicting rule already exists and update only the relevant section.
|
||||
|
||||
## Command rules
|
||||
|
||||
When giving commands for this project:
|
||||
|
||||
- Prefer **PowerShell**, **Developer PowerShell**, or **Visual Studio Package Manager Console** commands.
|
||||
- Commands must be written in **one line**.
|
||||
- Do not use PowerShell line continuation with backticks.
|
||||
- Do not suggest `dotnet new webforms` because WebForms is not supported by the .NET CLI as an ASP.NET Core project.
|
||||
- If a WebForms project must be created from command line, use Visual Studio/MSBuild-compatible project files or create the project through Visual Studio using **ASP.NET Web Application (.NET Framework)**.
|
||||
- Target framework must be `.NET Framework 4.8` or `.NET Framework 4.8.1`.
|
||||
|
||||
Recommended project creation path:
|
||||
|
||||
```powershell
|
||||
mkdir "C:\Proyectos\Agua de hermosillo\Plataforma de Desarrolladores"
|
||||
```
|
||||
|
||||
```powershell
|
||||
cd "C:\Proyectos\Agua de hermosillo\Plataforma de Desarrolladores"
|
||||
```
|
||||
|
||||
Then create/open the WebForms project in Visual Studio 2022 as:
|
||||
|
||||
```text
|
||||
ASP.NET Web Application (.NET Framework) → Web Forms → C# → .NET Framework 4.8/4.8.1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Project folder rules
|
||||
|
||||
Use this base structure:
|
||||
|
||||
```text
|
||||
SIG.Web/
|
||||
App_Code/
|
||||
Infrastructure/
|
||||
Sql/
|
||||
Repositories/
|
||||
Security/
|
||||
Utilities/
|
||||
Contracts/
|
||||
Models/
|
||||
Services/
|
||||
Styles/
|
||||
Scripts/
|
||||
Metronic/
|
||||
Site.master
|
||||
Site.master.cs
|
||||
Login.aspx
|
||||
Login.aspx.cs
|
||||
Inicio.aspx
|
||||
Inicio.aspx.cs
|
||||
BundleConfig.cs
|
||||
Global.asax
|
||||
Global.asax.cs
|
||||
Web.config
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- The active application uses the ASP.NET Web Site runtime-compilation model.
|
||||
- Shared C# source belongs in the exact special folder `App_Code`.
|
||||
- Pages, master pages, controls, handlers, and `Global.asax` use `CodeFile` or source compiled from `App_Code`; do not introduce new `CodeBehind` dependencies on `SIG.Web.dll`.
|
||||
- Keep third-party and external assemblies in `bin`, but do not build or deploy a project assembly named `SIG.Web.dll`.
|
||||
- Do not place database access directly inside `.aspx.cs`, `.ascx.cs`, or `Site.master.cs`.
|
||||
- Database-related helpers go under `App_Code/Sql` or a clearly named SQL/data folder.
|
||||
- Business access goes through `Contracts` and `Services`.
|
||||
- The active Web Site does not use explicit project compilation entries; C# files under `App_Code` compile automatically at runtime.
|
||||
|
||||
---
|
||||
|
||||
## Asset folder rules
|
||||
|
||||
The following folders are legacy visual dependencies and must be copied as complete folders:
|
||||
|
||||
```text
|
||||
Styles/
|
||||
Scripts/
|
||||
Metronic/
|
||||
```
|
||||
|
||||
Do not replace Metronic with Bootstrap-only layout.
|
||||
Do not upgrade Metronic unless the user explicitly asks.
|
||||
Do not remove old scripts just because they look unused; only remove references from bundles when they are not used by the master/login flow.
|
||||
|
||||
---
|
||||
|
||||
## Bundle rules
|
||||
|
||||
The project must implement only the bundle methods needed by the current `Site.master` and login page.
|
||||
|
||||
Do not bring every old bundle method from the legacy project.
|
||||
Do not add unused bundle groups just because they existed before.
|
||||
Do not add duplicate bundle keys.
|
||||
Do not add empty bundle methods.
|
||||
|
||||
Allowed current bundle keys are the ones actually rendered by master/login, especially:
|
||||
|
||||
```text
|
||||
~/bundles/modernizr
|
||||
~/bundles/scripts
|
||||
~/bundles/highcharts
|
||||
~/Metronic/assets/global/scripts/JSV1
|
||||
~/Metronic/assets/global/css/cssV1
|
||||
```
|
||||
|
||||
WebForms/AjaxControlToolkit support bundles are allowed only when referenced by `ScriptManager` or required by WebForms controls:
|
||||
|
||||
```text
|
||||
~/bundles/jquery
|
||||
~/bundles/WebFormsJs
|
||||
~/bundles/MsAjaxJs
|
||||
~/Content/AjaxControlToolkit/Styles/Bundle
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- If `Site.master` or `Login.aspx` does not render a bundle, do not add it.
|
||||
- If a bundle exists only for old pages not migrated yet, leave it out until the page needs it.
|
||||
- Prefer preserving original asset paths from `Styles`, `Scripts`, and `Metronic`.
|
||||
- Use `CssRewriteUrlTransform` for CSS bundles that reference fonts, images, or relative URLs.
|
||||
- Do not register CSS/JS from server controls when the style/script is global; use `BundleConfig` and the master page.
|
||||
|
||||
---
|
||||
|
||||
## WebForms page rules
|
||||
|
||||
All normal `.aspx` pages must use `Site.master`, except the login page.
|
||||
|
||||
Normal pages:
|
||||
|
||||
- Must include `MasterPageFile="~/Site.master"`.
|
||||
- Must not include `<html>`, `<head>`, `<body>`, or `<form>`.
|
||||
- Must use `<asp:Content>` controls.
|
||||
- Should inherit from `ClsPaginaBase` or the current C# page base class.
|
||||
- Must not connect directly to SQL classes.
|
||||
- Must call contracts/services for data, authentication, permissions, catalogs, menus, and user context.
|
||||
|
||||
Public registration exception:
|
||||
|
||||
- `Pages/Security/RegistroCliente.aspx`, `RegistroPendiente.aspx` and `VerificarCorreo.aspx` may be standalone public pages with their own `form runat="server"`.
|
||||
- `RegistroCliente.aspx` keeps its two-step draft in encrypted ViewState and persists only after all client/company validations pass.
|
||||
- All persistence continues through contracts/services/repositories and stored procedures.
|
||||
|
||||
Login page:
|
||||
|
||||
- Is the only page allowed to have its own full HTML structure.
|
||||
- May inherit from `System.Web.UI.Page` or its own login base class.
|
||||
- Must not inherit from `ClsPaginaBase` if that base class requires an authenticated session.
|
||||
- Must use `IAuthContract` or the current auth contract.
|
||||
- Must create a dummy session until real authentication is implemented.
|
||||
- Must not hardcode real database login logic in `Login.aspx.cs`.
|
||||
|
||||
Important naming rule:
|
||||
|
||||
- Do not create both `Login.aspx` and `LogIn.aspx`.
|
||||
- If the starter already uses `LogIn.aspx`, keep that name and keep `Web.config` consistent.
|
||||
- If creating from scratch, prefer `Login.aspx`, but update `Web.config`, redirects, and links consistently.
|
||||
|
||||
---
|
||||
|
||||
## Master page rules
|
||||
|
||||
`Site.master` owns the main HTML structure.
|
||||
|
||||
Rules:
|
||||
|
||||
- `Site.master` owns the only main `<form runat="server">`.
|
||||
- `Site.master` must keep the Metronic layout structure.
|
||||
- Keep the sidebar/header/page-content structure similar to the original Metronic project.
|
||||
- Do not restore the hidden search box from the old header.
|
||||
- Keep the actions button if it exists in the selected master layout.
|
||||
- Do not hardcode real user/menu database logic inside `Site.master.cs`.
|
||||
- User data must come from a contract/service.
|
||||
- Menu data must come from a contract/service.
|
||||
- Breadcrumb/title/layout data must come from a contract/service when dynamic.
|
||||
- Do not use `<title id="Titulo" runat="server">`.
|
||||
- Prefer `<title><%: Page.Title %></title>`.
|
||||
- If a generated starter currently uses a title literal, replace it with `Page.Title` unless there is a specific reason to keep the literal.
|
||||
|
||||
Current preferred contracts:
|
||||
|
||||
```text
|
||||
IAuthContract
|
||||
IUserSessionContract
|
||||
IMenuContract
|
||||
IMasterPageContract
|
||||
```
|
||||
|
||||
If old names such as `IUserContextProvider` or `IMenuProvider` exist, migrate them to the current contract naming or create adapters. Do not keep two competing naming systems.
|
||||
|
||||
---
|
||||
|
||||
## ContentPlaceHolder rules
|
||||
|
||||
`Site.master` must use short placeholder IDs.
|
||||
|
||||
Preferred final placeholder IDs:
|
||||
|
||||
```text
|
||||
H = page-specific head/CSS content
|
||||
C = main page content
|
||||
J = page-specific JavaScript
|
||||
```
|
||||
|
||||
Example in `Site.master`:
|
||||
|
||||
```aspx
|
||||
<asp:ContentPlaceHolder ID="H" runat="server" />
|
||||
<asp:ContentPlaceHolder ID="C" runat="server" />
|
||||
<asp:ContentPlaceHolder ID="J" runat="server" />
|
||||
```
|
||||
|
||||
Example in a normal page:
|
||||
|
||||
```aspx
|
||||
<asp:Content ID="ContentHead" ContentPlaceHolderID="H" runat="server">
|
||||
</asp:Content>
|
||||
|
||||
<asp:Content ID="ContentMain" ContentPlaceHolderID="C" runat="server">
|
||||
</asp:Content>
|
||||
|
||||
<asp:Content ID="ContentScripts" ContentPlaceHolderID="J" runat="server">
|
||||
</asp:Content>
|
||||
```
|
||||
|
||||
If the generated starter currently has `HeadContent`, `MainContent`, or `ScriptsContent`, rename them to `H`, `C`, and `J` before adding more pages.
|
||||
|
||||
Do not mix placeholder naming systems in the same project.
|
||||
|
||||
---
|
||||
|
||||
## WebForms tab and page-state rules
|
||||
|
||||
- Register AjaxControlToolkit once in `Web.config` under `system.web/pages/controls` with the exact prefix `ajax`; do not add `<%@ Register ... %>` directives for it in individual pages.
|
||||
- AjaxControlToolkit controls must use the `ajax:` prefix, for example `ajax:TabContainer` and `ajax:TabPanel`; do not use `ajaxToolkit:` or another page-specific prefix.
|
||||
- Tabs in WebForms pages must use `ajax:TabContainer` and `ajax:TabPanel`; do not build page tabs with Bootstrap `nav-tabs`, custom hidden panels, or JavaScript-only tab switching.
|
||||
- Use the `ScriptManager` owned by `Site.master` and the existing AjaxControlToolkit resources. Do not add another `ScriptManager` or duplicate Toolkit scripts/styles.
|
||||
- Server-side page state such as current entity keys, selected child keys, editing mode, flags, and the active tab must be stored in typed `ViewState` properties when it must survive postback.
|
||||
- Do not add `asp:HiddenField` merely to preserve server-side state across postbacks. A hidden field is allowed only when client-side JavaScript must read or change the value.
|
||||
- Hidden-field values are client-controlled and must never be trusted for authorization or sensitive decisions; validate them again on the server when their use is unavoidable.
|
||||
- Keep ViewState values small and serializable. Do not store database connections, commands, readers, services, repositories, or unnecessarily large result sets in ViewState.
|
||||
- ViewState property and key names must identify the entity and purpose, for example `CveFraccionamientoActual` and `CveFraccionamientoEtapaActual`.
|
||||
- When a postback needs to recover related values from an already loaded catalog, store the typed serializable object list in a typed `ViewState` property and locate the selected object by its key.
|
||||
- Do not copy server-owned catalog or model values into HTML `data-*` attributes, CSS classes, hidden fields, or other client-controlled markup merely to recover them during a postback. Read them from the typed object list stored in `ViewState`.
|
||||
|
||||
---
|
||||
## Login and session rules
|
||||
|
||||
Authentication must go through a contract.
|
||||
|
||||
Required flow:
|
||||
|
||||
```text
|
||||
Login.aspx.cs
|
||||
↓
|
||||
IAuthContract
|
||||
↓
|
||||
DummyAuthContract now, real AuthService later
|
||||
↓
|
||||
IUserSessionContract
|
||||
↓
|
||||
Session user
|
||||
```
|
||||
|
||||
Initial login may be dummy.
|
||||
|
||||
Dummy session user should be safe and clearly fake, for example:
|
||||
|
||||
```text
|
||||
UserId: 15
|
||||
CompanyId: 1
|
||||
RoleId: 1
|
||||
RoleName: Administrador
|
||||
CompanyName: Empresa Demo
|
||||
DisplayName: Usuario Demo
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- Dummy login may accept any non-empty username and password during starter setup.
|
||||
- Mark dummy authentication clearly in code comments.
|
||||
- Do not mix real SQL authentication with dummy authentication in the same class.
|
||||
- When real login is implemented, create a new service such as `SqlAuthContract` or `AuthService`.
|
||||
- Do not store passwords in session.
|
||||
- Do not log raw passwords.
|
||||
- Use Forms Authentication if staying with classic WebForms auth.
|
||||
|
||||
---
|
||||
|
||||
## Contract rules
|
||||
|
||||
Contracts belong in `/Contracts`.
|
||||
|
||||
Current minimum contracts:
|
||||
|
||||
```text
|
||||
Contracts/IAuthContract.cs
|
||||
Contracts/IUserSessionContract.cs
|
||||
Contracts/IMenuContract.cs
|
||||
Contracts/IMasterPageContract.cs
|
||||
```
|
||||
|
||||
Suggested future contracts:
|
||||
|
||||
```text
|
||||
Contracts/IPermissionContract.cs
|
||||
Contracts/INotificationContract.cs
|
||||
Contracts/ICatalogSearchContract.cs
|
||||
Contracts/IAuditContract.cs
|
||||
Contracts/ICurrentCompanyContract.cs
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- Pages call contracts, not SQL classes.
|
||||
- Master page calls contracts, not SQL classes.
|
||||
- Login calls contracts, not SQL classes.
|
||||
- Contracts must return models, DTOs, or result objects, not raw `DataTable` unless migrating legacy code.
|
||||
- If legacy `DataTable` is required, isolate it behind a contract and document why.
|
||||
|
||||
---
|
||||
|
||||
## Repository ownership rules
|
||||
|
||||
Repository ownership is determined by the data domain and stored-procedure prefix, not by the page or feature that currently consumes the data.
|
||||
|
||||
- Procedures named `PA_Gral_*` belong behind contracts and repositories under `Contracts/General` and `Repositories/General`.
|
||||
- General catalogs such as states, countries, municipalities, neighborhoods, and postal codes must not be placed in a security, registration, sales, or page-specific repository.
|
||||
- A feature service such as public registration may orchestrate both its feature repository and `IGeneralCatalogRepository`, but it must not move general catalog access into the feature repository.
|
||||
- Apply the same ownership rule to future procedure families: `PA_Sis_*` belongs to security/system infrastructure, `PA_Tra_*` to procedures, `PA_Vta_*` to sales, and so on.
|
||||
|
||||
## Database executor ownership rules
|
||||
|
||||
- `IDbExecutor`, `DbExecutor`, `StoredProcedureCommand`, `IDbCommand`, and direct stored-procedure execution may only be used inside classes under `Repositories` or repository database infrastructure.
|
||||
- Services must not reference or receive `IDbExecutor`, create database commands, execute readers, or call stored procedures directly.
|
||||
- A service that needs persisted data must depend on a repository contract. The concrete repository receives `IDbExecutor` and owns parameter configuration and result mapping.
|
||||
- Keep the `DbExecutor` implementation under `Repositories/Database`; do not place it under `Services` or expose it publicly through `AppServices`.
|
||||
|
||||
---
|
||||
## Service rules
|
||||
|
||||
Services belong in `/Services`.
|
||||
|
||||
Current starter services may include:
|
||||
|
||||
```text
|
||||
Services/ContractRegistry.cs
|
||||
Services/DummyAuthContract.cs
|
||||
Services/UserSessionContract.cs
|
||||
Services/DummyMenuContract.cs
|
||||
Services/MasterPageContract.cs
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- `ContractRegistry` may be used as a simple manual dependency resolver for WebForms.
|
||||
- Do not introduce a complex dependency injection framework unless required.
|
||||
- Services may depend on SQL helpers/repositories.
|
||||
- `.aspx.cs` files should be thin and delegate work to services.
|
||||
- Keep dummy services separate from SQL-backed services.
|
||||
- Services own application transactions when one business operation performs one or more repository mutations.
|
||||
- Use `TransactionLogic` inside a `using` block around the repository calls and invoke `Commit()` only after every required repository result succeeds.
|
||||
- Pages and repositories must not create, commit, roll back, or dispose application transactions.
|
||||
- Repositories participate through the ambient `TransactionScope`; connection strings used for transactional work must not set `Enlist=false`.
|
||||
- Select `TransactionScopeOption`, isolation level, and timeout in the service according to the business operation. Use `RequiresNew` or `Suppress` only when that behavior is intentional and documented by the call site.
|
||||
- Do not include slow external operations such as SMTP or HTTP calls inside a database transaction.
|
||||
|
||||
---
|
||||
|
||||
## Model rules
|
||||
|
||||
Models belong in `/Models`.
|
||||
|
||||
Current starter models may include:
|
||||
|
||||
```text
|
||||
Models/AppUser.cs
|
||||
Models/LoginResult.cs
|
||||
Models/MenuItemModel.cs
|
||||
Models/MasterLayoutModel.cs
|
||||
Models/BreadcrumbItem.cs
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- Use models to move data between contracts and WebForms pages.
|
||||
- Do not pass anonymous objects across layers.
|
||||
- Do not expose SQL connection classes or `SqlDataReader` from services to pages.
|
||||
- Keep models simple and serializable when possible.
|
||||
|
||||
---
|
||||
|
||||
## Database and SQL structure rules
|
||||
|
||||
All database connection structure must be centralized under `App_Code/Sql` or an equivalent SQL/data folder.
|
||||
|
||||
Current starter SQL structure:
|
||||
|
||||
```text
|
||||
App_Code/Sql/ConnectionNames.cs
|
||||
App_Code/Sql/IConnectionStringProvider.cs
|
||||
App_Code/Sql/WebConfigConnectionStringProvider.cs
|
||||
App_Code/Sql/SqlConnectionFactory.cs
|
||||
App_Code/Sql/SqlQueryExecutor.cs
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- Define connection names in one place.
|
||||
- Read connection strings from `Web.config`.
|
||||
- Do not hardcode connection strings in pages, master, controls, or services.
|
||||
- Do not create `SqlConnection` directly in `.aspx.cs`.
|
||||
- Do not create `SqlCommand` directly in `.aspx.cs`.
|
||||
- Use repositories or SQL executor classes behind contracts.
|
||||
- All application database reads and writes must use stored procedures; inline SQL in C# is prohibited.
|
||||
- Access to modules and catalogs is controlled by the menu and page-access layer. Reusable catalog stored procedures must not query `Sis_Usuarios`, restrict execution by `CveRol`, or return access-denied messages for module authorization.
|
||||
- Keep `@CveUsuarioEjecuta` in catalog procedures for the required signature and auditing when applicable, not to authorize access to the module.
|
||||
- Mandatory: read and follow `AGENTS_STORED_PROCEDURES.md` for naming, output parameters, TRY/CATCH, logging, transactions, and physical deletion.
|
||||
- Mandatory: read and follow `AGENTS_DATA_READER_MAPPING.md` for object, list, `DataTable`, and `JArray` result mapping.
|
||||
- Mandatory: read and follow `AGENTS_DATABASE_ERROR_LOGGING.md` for safe parameter logging and reproducible stored-procedure calls.
|
||||
- Mandatory: read and follow `AGENTS_PAGE_STRUCTURE.md` for the `Pages/Modulo/` location of all new WebForms pages.
|
||||
- Mandatory: read and follow `AGENTS_WEBFORMS_PARTIAL_POSTBACKS.md` for the single master form, ScriptManager ownership, UpdatePanel usage, and partial-postback rules.
|
||||
- Mandatory: read and follow `AGENTS_JAVASCRIPT_INITIALIZATION.md` for per-element initialization flags, global event guards, and idempotent control setup after partial postbacks.
|
||||
- Mandatory: read and follow `AGENTS_CATALOG_STRUCTURE.md` for catalog titles, breadcrumbs, actions, filters, indicators, grids, quick-create modals, and detail pages.
|
||||
- Mandatory: read and follow `AGENTS_DOCUMENT_STORAGE.md` for document folders, client access validation, protected file retrieval, and GIS file naming.
|
||||
- Keep stored procedure names centralized.
|
||||
- Repositories must use `CommandType.StoredProcedure` and parameterized inputs/outputs.
|
||||
- Never concatenate raw user input into SQL.
|
||||
- The database default collation and general text columns must use `Modern_Spanish_CS_AS`.
|
||||
- Columns named `Codigo`, beginning with `Codigo`, or containing a real user login identifier such as `NombreUsuario`, `UsuarioPortal`, or `Acum_PortalUsuario` must use `Modern_Spanish_CI_AS`.
|
||||
- `AgenteUsuario` is browser/device metadata, not a login identifier, and must use the general `Modern_Spanish_CS_AS` collation.
|
||||
- Do not use `Modern_Spanish_CS_AI`.
|
||||
|
||||
Recommended Web.config connection string pattern:
|
||||
|
||||
```xml
|
||||
<connectionStrings>
|
||||
<add name="DefaultConnection" connectionString="..." providerName="System.Data.SqlClient" />
|
||||
<add name="SecurityConnection" connectionString="..." providerName="System.Data.SqlClient" />
|
||||
<add name="ReportingConnection" connectionString="..." providerName="System.Data.SqlClient" />
|
||||
</connectionStrings>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Base page rules
|
||||
|
||||
Normal pages should inherit from a C# base page.
|
||||
|
||||
Preferred base class:
|
||||
|
||||
```text
|
||||
App_Code/Infrastructure/ClsPaginaBase.cs
|
||||
```
|
||||
|
||||
If the starter currently has `WebFormsPageBase.cs`, either:
|
||||
|
||||
- rename it to `ClsPaginaBase.cs`, or
|
||||
- keep `WebFormsPageBase` and update this AGENTS.md/project rules consistently.
|
||||
|
||||
Do not keep both base classes doing the same job.
|
||||
|
||||
Base page responsibilities:
|
||||
|
||||
- Validate authenticated session.
|
||||
- Expose current user from `IUserSessionContract`.
|
||||
- Provide helper methods for messages, redirects, and permissions.
|
||||
- Avoid database access.
|
||||
- Avoid page-specific business logic.
|
||||
|
||||
---
|
||||
|
||||
## Global.asax rules
|
||||
|
||||
`Global.asax` / `Global.asax.cs` should:
|
||||
|
||||
- Register bundles through `BundleConfig.RegisterBundles(BundleTable.Bundles)`.
|
||||
- Configure basic application startup.
|
||||
- Avoid business logic.
|
||||
- Avoid direct database startup queries unless absolutely required.
|
||||
|
||||
If OWIN is not used, prevent startup errors by adding this to `Web.config`:
|
||||
|
||||
```xml
|
||||
<add key="owin:AutomaticAppStartup" value="false" />
|
||||
```
|
||||
|
||||
Do not add OWIN packages unless the project actually needs OWIN.
|
||||
|
||||
---
|
||||
|
||||
## Web.config rules
|
||||
|
||||
`Web.config` must stay compatible with ASP.NET WebForms on .NET Framework 4.8/4.8.1.
|
||||
|
||||
Rules:
|
||||
|
||||
- Use Forms Authentication unless a different auth system is explicitly requested.
|
||||
- Allow anonymous access only to the login page and required static assets.
|
||||
- Do not add ASP.NET Core middleware settings.
|
||||
- Do not add unsupported `.NET Core` config sections.
|
||||
- Do not add CodeDom provider entries unless the matching NuGet package is installed.
|
||||
- If this error appears: `No se pudo ubicar el tipo de proveedor CodeDom Microsoft.CodeDom.Providers.DotNetCompilerPlatform...`, either install the exact package version or remove/fix the `system.codedom` section.
|
||||
- Keep MIME mappings for fonts such as `.woff` and `.woff2` when Metronic requires them.
|
||||
|
||||
---
|
||||
|
||||
## OWIN rule
|
||||
|
||||
If the application shows this error:
|
||||
|
||||
```text
|
||||
No assembly found containing an OwinStartupAttribute
|
||||
```
|
||||
|
||||
And the project does not use OWIN, add this in `appSettings`:
|
||||
|
||||
```xml
|
||||
<add key="owin:AutomaticAppStartup" value="false" />
|
||||
```
|
||||
|
||||
Do not create an empty OWIN startup class just to silence the error unless OWIN is actually required.
|
||||
|
||||
---
|
||||
|
||||
## Site.master rendering rules
|
||||
|
||||
The master page should render bundles and scripts in this general order:
|
||||
|
||||
Inside `<head>`:
|
||||
|
||||
```aspx
|
||||
<%: Scripts.Render("~/bundles/modernizr") %>
|
||||
<%: Styles.Render("~/Content/AjaxControlToolkit/Styles/Bundle") %>
|
||||
<%: Styles.Render("~/Metronic/assets/global/css/cssV1") %>
|
||||
<asp:ContentPlaceHolder ID="H" runat="server" />
|
||||
```
|
||||
|
||||
Inside `<form>` near the top:
|
||||
|
||||
```aspx
|
||||
<asp:ScriptManager ID="TSM" runat="server" />
|
||||
<%: Scripts.Render("~/bundles/scripts") %>
|
||||
```
|
||||
|
||||
Before closing `</form>`:
|
||||
|
||||
```aspx
|
||||
<%: Scripts.Render("~/Metronic/assets/global/scripts/JSV1") %>
|
||||
<%: Scripts.Render("~/bundles/highcharts") %>
|
||||
<asp:ContentPlaceHolder ID="J" runat="server" />
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- Do not render the same script twice.
|
||||
- Do not render JQuery twice.
|
||||
- Keep `ScriptManager` if AjaxControlToolkit, UpdatePanel, or WebForms AJAX is used.
|
||||
- Keep `TSM_AsyncPostBackError` only if implemented in code-behind.
|
||||
- Remove or implement any event handler referenced by markup.
|
||||
|
||||
---
|
||||
|
||||
## Header/menu rules
|
||||
|
||||
The master header must preserve the selected Metronic layout.
|
||||
|
||||
Rules:
|
||||
|
||||
- Keep user dropdown.
|
||||
- Keep logout option.
|
||||
- Keep actions button when present.
|
||||
- Do not restore the hidden/old search box from legacy header.
|
||||
- Sidebar menu must be built from `IMenuContract`.
|
||||
- Do not build the menu from SQL inside `Site.master.cs`.
|
||||
- Menu items should use `MenuItemModel` or an equivalent model.
|
||||
- Encode text output when generating HTML menu strings.
|
||||
- Module visibility and page access are separate concerns: `Sis_Modulos.Visible` controls whether an item is shown in the menu, but it must not deny direct page access.
|
||||
- `PA_Sis_PaginaAccessCheck` must validate role assignment, `PuedeVer`, active state, and URL. It must not require `Sis_Modulos.Visible = 1`.
|
||||
|
||||
---
|
||||
|
||||
## Page title and breadcrumb rules
|
||||
|
||||
Page title and breadcrumb should be handled consistently.
|
||||
|
||||
Rules:
|
||||
|
||||
- Use `Page.Title` for the browser title.
|
||||
- Use a master/layout model for visible page title and breadcrumb.
|
||||
- Do not hardcode global breadcrumb logic in every page.
|
||||
- Normal pages may set page title in `Page_Load` or via properties.
|
||||
|
||||
Preferred model:
|
||||
|
||||
```text
|
||||
MasterLayoutModel
|
||||
PageTitle
|
||||
Breadcrumbs
|
||||
CurrentUser
|
||||
MenuItems
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Security rules
|
||||
|
||||
- Do not store passwords in code, comments, Web.config examples, or session.
|
||||
- Do not expose real connection strings in committed files.
|
||||
- Use dummy values in examples.
|
||||
- Use parameterized SQL.
|
||||
- Validate uploaded files by extension, MIME type, and size when uploads are later added.
|
||||
- Avoid writing raw exception details to the user in production.
|
||||
- Keep `customErrors mode="Off"` only for local development.
|
||||
|
||||
---
|
||||
|
||||
## Error handling rules
|
||||
|
||||
Controlled outcomes and technical failures must use different logs.
|
||||
|
||||
- `@ErrorTipo = 1`, SQL exceptions, timeouts, contract failures, and unexpected exceptions go to the main technical log.
|
||||
- `@ErrorTipo = 2` is a controlled warning. It must not be written to the main technical log.
|
||||
- Controlled warnings go to daily compact files under `~/log/controlled`.
|
||||
- Controlled log files retain only the current day and the previous two days. The retention is configured with `ControlledLogRetentionDays = 3`.
|
||||
- Explicit controlled throws must use `ControlledApplicationException`; do not classify arbitrary `Exception` or `InvalidOperationException` instances as controlled.
|
||||
- Controlled logs record date, source, procedure, URL, and friendly message, but omit full stack traces and replay SQL to remain compact.
|
||||
- A controlled exception must still return a friendly result to the page and must never be presented as an unexpected application failure.
|
||||
|
||||
- Handle null session user cleanly and redirect to login.
|
||||
- Handle failed login with a friendly message.
|
||||
- Handle async postback errors through `ScriptManager.AsyncPostBackError` only if the handler exists.
|
||||
- Avoid infinite loading states in JavaScript controls.
|
||||
- For AJAX/server search controls, use client and server timeouts.
|
||||
- Recommended default search timeout: about 20 to 30 seconds unless the user asks otherwise.
|
||||
## Action availability and feedback rules
|
||||
|
||||
- Do not disable a button or primary action only because a business prerequisite is missing, such as an unassigned client or an empty related catalog.
|
||||
- Keep the action available by default; when the user clicks it, validate the prerequisite and show a clear message explaining why the operation cannot continue and what must be done next.
|
||||
- Never leave a disabled action without an immediately visible explanation.
|
||||
- Before adding `Enabled="false"`, the HTML `disabled` attribute, or an equivalent disabled CSS/JavaScript state to a catalog or page action, ask the user whether disabling is acceptable or whether a message, modal, link, or other alternative should be used.
|
||||
- A transient disabled state used only while a request is being processed to prevent duplicate submissions is allowed, but the action must be restored when processing finishes.
|
||||
|
||||
---
|
||||
|
||||
## Grid display rules
|
||||
|
||||
- Every new or modified `asp:GridView` must declare `GridLines="None"`.
|
||||
- Its `CssClass` must include the exact utility class `Widthall` so the grid uses the full available width.
|
||||
- Do not add `table-bordered` to a GridView. Existing visual classes such as `table`, `table-striped`, and `table-hover` may be retained when appropriate.
|
||||
- Keep GridView declarations and their columns expanded and indented according to the source code readability rules.
|
||||
- Detail-page navigation from a GridView or list must use `asp:HyperLink` or another real link with `NavigateUrl`; do not use `LinkButton`, `RowCommand`, or a postback only to open a detail page.
|
||||
- URL-building variables and helpers must describe the row entity, for example `cveFraccionamiento`, `fraccionamientoDetalleUrl`, or `GetFraccionamientoDetalleUrl`. Avoid generic names such as `id`, `itemUrl`, or `detailUrl` when the entity is known.
|
||||
|
||||
---
|
||||
## JavaScript and CSS rules
|
||||
|
||||
- Global scripts/styles must be registered in `BundleConfig` and rendered by master.
|
||||
- Page-specific scripts go in placeholder `J`.
|
||||
- Page-specific CSS/head content goes in placeholder `H`.
|
||||
- Do not inline large JavaScript blocks in `.aspx` unless page-specific and small.
|
||||
- Do not remove existing custom legacy files unless the user asks.
|
||||
- Fix null `addEventListener` errors by checking that the element exists before attaching events.
|
||||
- Avoid blocking Ctrl+V unless a specific feature requires it.
|
||||
|
||||
---
|
||||
|
||||
## User control rules
|
||||
|
||||
If server controls are migrated:
|
||||
|
||||
- Prefer C# classes under `App_Code/SigControls` when creating reusable server controls.
|
||||
- Do not mix WebForms `.ascx` user controls with App_Code server-control classes unless there is a clear reason.
|
||||
- Do not register global CSS/JS from the control when master bundles already include them.
|
||||
- Controls should expose properties/events and avoid direct SQL access.
|
||||
- Controls should call contracts/services when they need data.
|
||||
|
||||
---
|
||||
|
||||
## PDF viewer migration rules
|
||||
|
||||
If the PDF viewer is added to this project later:
|
||||
|
||||
- Implement it in C#.
|
||||
- Prefer `App_Code/SigControls` for server controls.
|
||||
- Do not add VB files.
|
||||
- Do not use `/* */` comments in VB reference files; VB references must remain `.vb.txt` only.
|
||||
- Keep global PDF viewer CSS/JS references in bundles.
|
||||
- Do not register duplicate resources from the control and master at the same time.
|
||||
- Session or temp-folder PDF storage must be explicit and centralized.
|
||||
|
||||
---
|
||||
|
||||
## Home page rules
|
||||
|
||||
Use only one active home page convention.
|
||||
|
||||
For local development, the canonical home URL is:
|
||||
|
||||
```text
|
||||
http://localhost:52706/Inicio.aspx
|
||||
```
|
||||
|
||||
The application root must be equivalent and redirect explicitly to that page:
|
||||
|
||||
```text
|
||||
http://localhost:52706/ -> http://localhost:52706/Inicio.aspx
|
||||
```
|
||||
|
||||
Keep the root redirect and the `Inicio.aspx` default document consistent. Do not introduce another startup page.
|
||||
|
||||
Allowed options:
|
||||
|
||||
```text
|
||||
Default.aspx
|
||||
Inicio.aspx
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- Do not keep both as competing entry pages.
|
||||
- If using `Inicio.aspx`, redirect `Default.aspx` to `Inicio.aspx` or update Forms Authentication default URL.
|
||||
- If using `Default.aspx`, keep Web.config and menu links pointing to `Default.aspx`.
|
||||
- The home page must use `Site.master`.
|
||||
|
||||
---
|
||||
|
||||
## File delivery rules for this project
|
||||
|
||||
When generating a single downloadable file:
|
||||
|
||||
- If the file is `.js` or `.css` and it is not inside a ZIP, append `.txt` to the filename.
|
||||
- Example: `custom.js.txt`, `styles.css.txt`.
|
||||
- If the file is inside a ZIP, keep the real extension `.js` or `.css`.
|
||||
- For project-level delivery, prefer ZIP files.
|
||||
|
||||
---
|
||||
## Mandatory authorization and change-control rules
|
||||
|
||||
- The agent is permanently prohibited from executing `git commit`, `git commit --amend`, creating commits through another command, or asking another agent to create a commit in this repository.
|
||||
- Before modifying code, files, configuration, stored procedures, database schema, or database data, the agent must tell the user exactly which files and objects it proposes to change and what each change will do.
|
||||
- The agent must wait for the user's explicit confirmation before making any modification.
|
||||
- Until explicit confirmation is received, the agent may perform read-only inspection and diagnosis only.
|
||||
- Authorization to inspect, diagnose, or review does not authorize implementation.
|
||||
- Authorization is limited to the files and objects explicitly disclosed. If the proposed scope changes, the agent must explain the additional changes and obtain new explicit confirmation.
|
||||
- Authorization to edit a SQL script does not authorize installing or executing it against a database. Database execution requires separate explicit confirmation.
|
||||
- A corrective action, rollback, or attempted restoration is still a modification and also requires explicit confirmation before execution.
|
||||
- The agent must never infer authorization from urgency, prior approval for a different change, or the fact that the agent caused the problem.
|
||||
|
||||
## Mandatory complementary instruction files
|
||||
|
||||
The following files are part of these instructions. Read each file whose scope applies before taking action:
|
||||
|
||||
- `AGENTS_ARQUITECTURA.md`: project structure, contracts, services, repositories, models, database access, and transactions.
|
||||
- `AGENTS_WEBFORMS_ESTRUCTURA.md`: WebForms pages, master page, login, bundles, assets, configuration, controls, and application shell.
|
||||
- `AGENTS_MANTENIMIENTO_PROYECTO.md`: commands, security, errors, feedback, grids, delivery, checklist, and project evolution.
|
||||
- `AGENTS_STORED_PROCEDURES.md`: stored-procedure rules.
|
||||
- `AGENTS_DATA_READER_MAPPING.md`: database-result mapping.
|
||||
- `AGENTS_DATABASE_ERROR_LOGGING.md`: database error diagnostics.
|
||||
- `AGENTS_PAGE_STRUCTURE.md`: page locations and structure.
|
||||
- `AGENTS_WEBFORMS_PARTIAL_POSTBACKS.md`: forms, ScriptManager, UpdatePanel, and partial postbacks.
|
||||
- `AGENTS_JAVASCRIPT_INITIALIZATION.md`: idempotent JavaScript initialization.
|
||||
- `AGENTS_CATALOG_STRUCTURE.md`: catalog layout and behavior.
|
||||
- `AGENTS_DOCUMENT_STORAGE.md`: protected document storage and retrieval.
|
||||
|
||||
## What not to add yet
|
||||
|
||||
@@ -837,46 +125,3 @@ Do not add the following until the user explicitly asks:
|
||||
The starter must stay small and focused: commands, master page, login, contracts, dummy user session, bundle structure, copied assets, and centralized SQL foundation.
|
||||
|
||||
---
|
||||
|
||||
## Current implementation checklist
|
||||
|
||||
When modifying or regenerating the project, verify:
|
||||
|
||||
- [ ] Project targets .NET Framework 4.8 or 4.8.1.
|
||||
- [ ] All new code is C#.
|
||||
- [ ] No active `.vb` files were added.
|
||||
- [ ] `Styles`, `Scripts`, and `Metronic` were copied as-is.
|
||||
- [ ] `BundleConfig.cs` contains only bundles rendered by master/login or required by WebForms AJAX.
|
||||
- [ ] `Site.master` owns the only main form.
|
||||
- [ ] Normal pages use `Site.master`.
|
||||
- [ ] Normal pages do not contain full HTML structure.
|
||||
- [ ] Login is the only standalone full HTML page.
|
||||
- [ ] User/session data comes from `IUserSessionContract`.
|
||||
- [ ] Login uses `IAuthContract`.
|
||||
- [ ] Menu comes from `IMenuContract`.
|
||||
- [ ] Master layout data comes from `IMasterPageContract`.
|
||||
- [ ] SQL connection helpers are centralized under `App_Code/Sql`.
|
||||
- [ ] Pages do not directly instantiate SQL connections.
|
||||
- [ ] Placeholder IDs are `H`, `C`, and `J`.
|
||||
- [ ] No hidden old search box was restored.
|
||||
- [ ] Actions button is preserved when present in the selected layout.
|
||||
- [ ] `Web.config` login URL matches the actual login page filename.
|
||||
- [ ] No duplicate `Login.aspx` / `LogIn.aspx` pages exist.
|
||||
- [ ] No OWIN startup error exists, or OWIN automatic startup is disabled.
|
||||
- [ ] No missing CodeDom provider error exists.
|
||||
|
||||
---
|
||||
|
||||
## Preferred next evolution
|
||||
|
||||
After the starter works, the safest growth path is:
|
||||
|
||||
1. Replace dummy login with SQL-backed `IAuthContract`.
|
||||
2. Replace dummy menu with SQL-backed `IMenuContract`.
|
||||
3. Add permission contract.
|
||||
4. Add base page authorization checks.
|
||||
5. Add reusable controls one by one.
|
||||
6. Add catalog search and UI helpers.
|
||||
7. Add PDF viewer only after the base shell is stable.
|
||||
|
||||
Keep every new feature behind contracts so the WebForms UI remains thin and easier to migrate later if needed.
|
||||
|
||||
232
AGENTS_ARQUITECTURA.md
Normal file
232
AGENTS_ARQUITECTURA.md
Normal file
@@ -0,0 +1,232 @@
|
||||
# AGENTS_ARQUITECTURA.md
|
||||
|
||||
These rules complement `AGENTS.md` and are mandatory whenever the task changes project structure, C# architecture, database access, repositories, services, contracts, models, or application transactions.
|
||||
|
||||
## Project folder rules
|
||||
|
||||
Use this base structure:
|
||||
|
||||
```text
|
||||
SIG.Web/
|
||||
App_Code/
|
||||
Infrastructure/
|
||||
Sql/
|
||||
Repositories/
|
||||
Security/
|
||||
Utilities/
|
||||
Contracts/
|
||||
Models/
|
||||
Services/
|
||||
Styles/
|
||||
Scripts/
|
||||
Metronic/
|
||||
Site.master
|
||||
Site.master.cs
|
||||
Login.aspx
|
||||
Login.aspx.cs
|
||||
Inicio.aspx
|
||||
Inicio.aspx.cs
|
||||
BundleConfig.cs
|
||||
Global.asax
|
||||
Global.asax.cs
|
||||
Web.config
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- The active application uses the ASP.NET Web Site runtime-compilation model.
|
||||
- Shared C# source belongs in the exact special folder `App_Code`.
|
||||
- Pages, master pages, controls, handlers, and `Global.asax` use `CodeFile` or source compiled from `App_Code`; do not introduce new `CodeBehind` dependencies on `SIG.Web.dll`.
|
||||
- Keep third-party and external assemblies in `bin`, but do not build or deploy a project assembly named `SIG.Web.dll`.
|
||||
- Do not place database access directly inside `.aspx.cs`, `.ascx.cs`, or `Site.master.cs`.
|
||||
- Database-related helpers go under `App_Code/Sql` or a clearly named SQL/data folder.
|
||||
- Business access goes through `Contracts` and `Services`.
|
||||
- The active Web Site does not use explicit project compilation entries; C# files under `App_Code` compile automatically at runtime.
|
||||
|
||||
---
|
||||
|
||||
## Contract rules
|
||||
|
||||
Contracts belong in `/Contracts`.
|
||||
|
||||
Current minimum contracts:
|
||||
|
||||
```text
|
||||
Contracts/IAuthContract.cs
|
||||
Contracts/IUserSessionContract.cs
|
||||
Contracts/IMenuContract.cs
|
||||
Contracts/IMasterPageContract.cs
|
||||
```
|
||||
|
||||
Suggested future contracts:
|
||||
|
||||
```text
|
||||
Contracts/IPermissionContract.cs
|
||||
Contracts/INotificationContract.cs
|
||||
Contracts/ICatalogSearchContract.cs
|
||||
Contracts/IAuditContract.cs
|
||||
Contracts/ICurrentCompanyContract.cs
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- Pages call contracts, not SQL classes.
|
||||
- Master page calls contracts, not SQL classes.
|
||||
- Login calls contracts, not SQL classes.
|
||||
- Contracts must return models, DTOs, or result objects, not raw `DataTable` unless migrating legacy code.
|
||||
- If legacy `DataTable` is required, isolate it behind a contract and document why.
|
||||
|
||||
---
|
||||
|
||||
## Repository ownership rules
|
||||
|
||||
Repository ownership is determined by the data domain and stored-procedure prefix, not by the page or feature that currently consumes the data.
|
||||
|
||||
- Procedures named `PA_Gral_*` belong behind contracts and repositories under `Contracts/General` and `Repositories/General`.
|
||||
- General catalogs such as states, countries, municipalities, neighborhoods, and postal codes must not be placed in a security, registration, sales, or page-specific repository.
|
||||
- A feature service such as public registration may orchestrate both its feature repository and `IGeneralCatalogRepository`, but it must not move general catalog access into the feature repository.
|
||||
- Apply the same ownership rule to future procedure families: `PA_Sis_*` belongs to security/system infrastructure, `PA_Tra_*` to procedures, `PA_Vta_*` to sales, and so on.
|
||||
|
||||
## Database executor ownership rules
|
||||
|
||||
- `IDbExecutor`, `DbExecutor`, `StoredProcedureCommand`, `IDbCommand`, and direct stored-procedure execution may only be used inside classes under `Repositories` or repository database infrastructure.
|
||||
- Services must not reference or receive `IDbExecutor`, create database commands, execute readers, or call stored procedures directly.
|
||||
- A service that needs persisted data must depend on a repository contract. The concrete repository receives `IDbExecutor` and owns parameter configuration and result mapping.
|
||||
- Keep the `DbExecutor` implementation under `Repositories/Database`; do not place it under `Services` or expose it publicly through `AppServices`.
|
||||
|
||||
---
|
||||
|
||||
## Service rules
|
||||
|
||||
Services belong in `/Services`.
|
||||
|
||||
Current starter services may include:
|
||||
|
||||
```text
|
||||
Services/ContractRegistry.cs
|
||||
Services/DummyAuthContract.cs
|
||||
Services/UserSessionContract.cs
|
||||
Services/DummyMenuContract.cs
|
||||
Services/MasterPageContract.cs
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- `ContractRegistry` may be used as a simple manual dependency resolver for WebForms.
|
||||
- Do not introduce a complex dependency injection framework unless required.
|
||||
- Services may depend on SQL helpers/repositories.
|
||||
- `.aspx.cs` files should be thin and delegate work to services.
|
||||
- Keep dummy services separate from SQL-backed services.
|
||||
- Services own application transactions when one business operation performs one or more repository mutations.
|
||||
- Use `TransactionLogic` inside a `using` block around the repository calls and invoke `Commit()` only after every required repository result succeeds.
|
||||
- Pages and repositories must not create, commit, roll back, or dispose application transactions.
|
||||
- Repositories participate through the ambient `TransactionScope`; connection strings used for transactional work must not set `Enlist=false`.
|
||||
- Select `TransactionScopeOption`, isolation level, and timeout in the service according to the business operation. Use `RequiresNew` or `Suppress` only when that behavior is intentional and documented by the call site.
|
||||
- Do not include slow external operations such as SMTP or HTTP calls inside a database transaction.
|
||||
|
||||
---
|
||||
|
||||
## Model rules
|
||||
|
||||
Models belong in `/Models`.
|
||||
|
||||
Current starter models may include:
|
||||
|
||||
```text
|
||||
Models/AppUser.cs
|
||||
Models/LoginResult.cs
|
||||
Models/MenuItemModel.cs
|
||||
Models/MasterLayoutModel.cs
|
||||
Models/BreadcrumbItem.cs
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- Use models to move data between contracts and WebForms pages.
|
||||
- Do not pass anonymous objects across layers.
|
||||
- Do not expose SQL connection classes or `SqlDataReader` from services to pages.
|
||||
- Keep models simple and serializable when possible.
|
||||
|
||||
---
|
||||
|
||||
## Database and SQL structure rules
|
||||
|
||||
All database connection structure must be centralized under `App_Code/Sql` or an equivalent SQL/data folder.
|
||||
|
||||
Current starter SQL structure:
|
||||
|
||||
```text
|
||||
App_Code/Sql/ConnectionNames.cs
|
||||
App_Code/Sql/IConnectionStringProvider.cs
|
||||
App_Code/Sql/WebConfigConnectionStringProvider.cs
|
||||
App_Code/Sql/SqlConnectionFactory.cs
|
||||
App_Code/Sql/SqlQueryExecutor.cs
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- Define connection names in one place.
|
||||
- Read connection strings from `Web.config`.
|
||||
- Do not hardcode connection strings in pages, master, controls, or services.
|
||||
- Do not create `SqlConnection` directly in `.aspx.cs`.
|
||||
- Do not create `SqlCommand` directly in `.aspx.cs`.
|
||||
- Use repositories or SQL executor classes behind contracts.
|
||||
- All application database reads and writes must use stored procedures; inline SQL in C# is prohibited.
|
||||
- Access to modules and catalogs is controlled by the menu and page-access layer. Reusable catalog stored procedures must not query `Sis_Usuarios`, restrict execution by `CveRol`, or return access-denied messages for module authorization.
|
||||
- Keep `@CveUsuarioEjecuta` in catalog procedures for the required signature and auditing when applicable, not to authorize access to the module.
|
||||
- Do not invent or add authorization, role, user-client association, ownership, or business-prerequisite validations to any stored procedure unless the user explicitly requests that exact validation. The user prefers to add those validations manually.
|
||||
- Mandatory: read and follow `AGENTS_STORED_PROCEDURES.md` for naming, output parameters, TRY/CATCH, logging, transactions, and physical deletion.
|
||||
- Mandatory: read and follow `AGENTS_DATA_READER_MAPPING.md` for object, list, `DataTable`, and `JArray` result mapping.
|
||||
- Mandatory: read and follow `AGENTS_DATABASE_ERROR_LOGGING.md` for safe parameter logging and reproducible stored-procedure calls.
|
||||
- Mandatory: read and follow `AGENTS_PAGE_STRUCTURE.md` for the `Pages/Modulo/` location of all new WebForms pages.
|
||||
- Mandatory: read and follow `AGENTS_WEBFORMS_PARTIAL_POSTBACKS.md` for the single master form, ScriptManager ownership, UpdatePanel usage, and partial-postback rules.
|
||||
- Mandatory: read and follow `AGENTS_JAVASCRIPT_INITIALIZATION.md` for per-element initialization flags, global event guards, and idempotent control setup after partial postbacks.
|
||||
- Mandatory: read and follow `AGENTS_CATALOG_STRUCTURE.md` for catalog titles, breadcrumbs, actions, filters, indicators, grids, quick-create modals, and detail pages.
|
||||
- Mandatory: read and follow `AGENTS_DOCUMENT_STORAGE.md` for document folders, client access validation, protected file retrieval, and GIS file naming.
|
||||
- Keep stored procedure names centralized.
|
||||
- Repositories must use `CommandType.StoredProcedure` and parameterized inputs/outputs.
|
||||
- Never concatenate raw user input into SQL.
|
||||
- The database default collation and general text columns must use `Modern_Spanish_CS_AS`.
|
||||
- Columns named `Codigo`, beginning with `Codigo`, or containing a real user login identifier such as `NombreUsuario`, `UsuarioPortal`, or `Acum_PortalUsuario` must use `Modern_Spanish_CI_AS`.
|
||||
- `AgenteUsuario` is browser/device metadata, not a login identifier, and must use the general `Modern_Spanish_CS_AS` collation.
|
||||
- Do not use `Modern_Spanish_CS_AI`.
|
||||
|
||||
Recommended Web.config connection string pattern:
|
||||
|
||||
```xml
|
||||
<connectionStrings>
|
||||
<add name="DefaultConnection" connectionString="..." providerName="System.Data.SqlClient" />
|
||||
<add name="SecurityConnection" connectionString="..." providerName="System.Data.SqlClient" />
|
||||
<add name="ReportingConnection" connectionString="..." providerName="System.Data.SqlClient" />
|
||||
</connectionStrings>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Base page rules
|
||||
|
||||
Normal pages should inherit from a C# base page.
|
||||
|
||||
Preferred base class:
|
||||
|
||||
```text
|
||||
App_Code/Infrastructure/ClsPaginaBase.cs
|
||||
```
|
||||
|
||||
If the starter currently has `WebFormsPageBase.cs`, either:
|
||||
|
||||
- rename it to `ClsPaginaBase.cs`, or
|
||||
- keep `WebFormsPageBase` and update this AGENTS.md/project rules consistently.
|
||||
|
||||
Do not keep both base classes doing the same job.
|
||||
|
||||
Base page responsibilities:
|
||||
|
||||
- Validate authenticated session.
|
||||
- Expose current user from `IUserSessionContract`.
|
||||
- Provide helper methods for messages, redirects, and permissions.
|
||||
- Avoid database access.
|
||||
- Avoid page-specific business logic.
|
||||
|
||||
---
|
||||
|
||||
153
AGENTS_MANTENIMIENTO_PROYECTO.md
Normal file
153
AGENTS_MANTENIMIENTO_PROYECTO.md
Normal file
@@ -0,0 +1,153 @@
|
||||
# AGENTS_MANTENIMIENTO_PROYECTO.md
|
||||
|
||||
These rules complement `AGENTS.md` and are mandatory whenever the task involves commands, security, error handling, user feedback, grids, PDF migration, file delivery, verification, or project evolution.
|
||||
|
||||
## Command rules
|
||||
|
||||
When giving commands for this project:
|
||||
|
||||
- Prefer **PowerShell**, **Developer PowerShell**, or **Visual Studio Package Manager Console** commands.
|
||||
- Commands must be written in **one line**.
|
||||
- Do not use PowerShell line continuation with backticks.
|
||||
- Do not suggest `dotnet new webforms` because WebForms is not supported by the .NET CLI as an ASP.NET Core project.
|
||||
- If a WebForms project must be created from command line, use Visual Studio/MSBuild-compatible project files or create the project through Visual Studio using **ASP.NET Web Application (.NET Framework)**.
|
||||
- Target framework must be `.NET Framework 4.8` or `.NET Framework 4.8.1`.
|
||||
|
||||
Recommended project creation path:
|
||||
|
||||
```powershell
|
||||
mkdir "C:\Proyectos\Agua de hermosillo\Plataforma de Desarrolladores"
|
||||
```
|
||||
|
||||
```powershell
|
||||
cd "C:\Proyectos\Agua de hermosillo\Plataforma de Desarrolladores"
|
||||
```
|
||||
|
||||
Then create/open the WebForms project in Visual Studio 2022 as:
|
||||
|
||||
```text
|
||||
ASP.NET Web Application (.NET Framework) → Web Forms → C# → .NET Framework 4.8/4.8.1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Security rules
|
||||
|
||||
- Do not store passwords in code, comments, Web.config examples, or session.
|
||||
- Do not expose real connection strings in committed files.
|
||||
- Use dummy values in examples.
|
||||
- Use parameterized SQL.
|
||||
- Validate uploaded files by extension, MIME type, and size when uploads are later added.
|
||||
- Avoid writing raw exception details to the user in production.
|
||||
- Keep `customErrors mode="Off"` only for local development.
|
||||
|
||||
---
|
||||
|
||||
## Error handling rules
|
||||
|
||||
Controlled outcomes and technical failures must use different logs.
|
||||
|
||||
- `@ErrorTipo = 1`, SQL exceptions, timeouts, contract failures, and unexpected exceptions go to the main technical log.
|
||||
- `@ErrorTipo = 2` is a controlled warning. It must not be written to the main technical log.
|
||||
- Controlled warnings go to daily compact files under `~/log/controlled`.
|
||||
- Controlled log files retain only the current day and the previous two days. The retention is configured with `ControlledLogRetentionDays = 3`.
|
||||
- Explicit controlled throws must use `ControlledApplicationException`; do not classify arbitrary `Exception` or `InvalidOperationException` instances as controlled.
|
||||
- Controlled logs record date, source, procedure, URL, and friendly message, but omit full stack traces and replay SQL to remain compact.
|
||||
- A controlled exception must still return a friendly result to the page and must never be presented as an unexpected application failure.
|
||||
|
||||
- Handle null session user cleanly and redirect to login.
|
||||
- Handle failed login with a friendly message.
|
||||
- Handle async postback errors through `ScriptManager.AsyncPostBackError` only if the handler exists.
|
||||
- Avoid infinite loading states in JavaScript controls.
|
||||
- For AJAX/server search controls, use client and server timeouts.
|
||||
- Recommended default search timeout: about 20 to 30 seconds unless the user asks otherwise.
|
||||
|
||||
## Action availability and feedback rules
|
||||
|
||||
- Do not disable a button or primary action only because a business prerequisite is missing, such as an unassigned client or an empty related catalog.
|
||||
- Keep the action available by default; when the user clicks it, validate the prerequisite and show a clear message explaining why the operation cannot continue and what must be done next.
|
||||
- Never leave a disabled action without an immediately visible explanation.
|
||||
- Before adding `Enabled="false"`, the HTML `disabled` attribute, or an equivalent disabled CSS/JavaScript state to a catalog or page action, ask the user whether disabling is acceptable or whether a message, modal, link, or other alternative should be used.
|
||||
- A transient disabled state used only while a request is being processed to prevent duplicate submissions is allowed, but the action must be restored when processing finishes.
|
||||
|
||||
---
|
||||
|
||||
## Grid display rules
|
||||
|
||||
- Every new or modified `asp:GridView` must declare `GridLines="None"`.
|
||||
- Its `CssClass` must include the exact utility class `Widthall` so the grid uses the full available width.
|
||||
- Do not add `table-bordered` to a GridView. Existing visual classes such as `table`, `table-striped`, and `table-hover` may be retained when appropriate.
|
||||
- Keep GridView declarations and their columns expanded and indented according to the source code readability rules.
|
||||
- Detail-page navigation from a GridView or list must use `asp:HyperLink` or another real link with `NavigateUrl`; do not use `LinkButton`, `RowCommand`, or a postback only to open a detail page.
|
||||
- URL-building variables and helpers must describe the row entity, for example `cveFraccionamiento`, `fraccionamientoDetalleUrl`, or `GetFraccionamientoDetalleUrl`. Avoid generic names such as `id`, `itemUrl`, or `detailUrl` when the entity is known.
|
||||
|
||||
---
|
||||
|
||||
## PDF viewer migration rules
|
||||
|
||||
If the PDF viewer is added to this project later:
|
||||
|
||||
- Implement it in C#.
|
||||
- Prefer `App_Code/SigControls` for server controls.
|
||||
- Do not add VB files.
|
||||
- Do not use `/* */` comments in VB reference files; VB references must remain `.vb.txt` only.
|
||||
- Keep global PDF viewer CSS/JS references in bundles.
|
||||
- Do not register duplicate resources from the control and master at the same time.
|
||||
- Session or temp-folder PDF storage must be explicit and centralized.
|
||||
|
||||
---
|
||||
|
||||
## File delivery rules for this project
|
||||
|
||||
When generating a single downloadable file:
|
||||
|
||||
- If the file is `.js` or `.css` and it is not inside a ZIP, append `.txt` to the filename.
|
||||
- Example: `custom.js.txt`, `styles.css.txt`.
|
||||
- If the file is inside a ZIP, keep the real extension `.js` or `.css`.
|
||||
- For project-level delivery, prefer ZIP files.
|
||||
|
||||
---
|
||||
|
||||
## Current implementation checklist
|
||||
|
||||
When modifying or regenerating the project, verify:
|
||||
|
||||
- [ ] Project targets .NET Framework 4.8 or 4.8.1.
|
||||
- [ ] All new code is C#.
|
||||
- [ ] No active `.vb` files were added.
|
||||
- [ ] `Styles`, `Scripts`, and `Metronic` were copied as-is.
|
||||
- [ ] `BundleConfig.cs` contains only bundles rendered by master/login or required by WebForms AJAX.
|
||||
- [ ] `Site.master` owns the only main form.
|
||||
- [ ] Normal pages use `Site.master`.
|
||||
- [ ] Normal pages do not contain full HTML structure.
|
||||
- [ ] Login is the only standalone full HTML page.
|
||||
- [ ] User/session data comes from `IUserSessionContract`.
|
||||
- [ ] Login uses `IAuthContract`.
|
||||
- [ ] Menu comes from `IMenuContract`.
|
||||
- [ ] Master layout data comes from `IMasterPageContract`.
|
||||
- [ ] SQL connection helpers are centralized under `App_Code/Sql`.
|
||||
- [ ] Pages do not directly instantiate SQL connections.
|
||||
- [ ] Placeholder IDs are `H`, `C`, and `J`.
|
||||
- [ ] No hidden old search box was restored.
|
||||
- [ ] Actions button is preserved when present in the selected layout.
|
||||
- [ ] `Web.config` login URL matches the actual login page filename.
|
||||
- [ ] No duplicate `Login.aspx` / `LogIn.aspx` pages exist.
|
||||
- [ ] No OWIN startup error exists, or OWIN automatic startup is disabled.
|
||||
- [ ] No missing CodeDom provider error exists.
|
||||
|
||||
---
|
||||
|
||||
## Preferred next evolution
|
||||
|
||||
After the starter works, the safest growth path is:
|
||||
|
||||
1. Replace dummy login with SQL-backed `IAuthContract`.
|
||||
2. Replace dummy menu with SQL-backed `IMenuContract`.
|
||||
3. Add permission contract.
|
||||
4. Add base page authorization checks.
|
||||
5. Add reusable controls one by one.
|
||||
6. Add catalog search and UI helpers.
|
||||
7. Add PDF viewer only after the base shell is stable.
|
||||
|
||||
Keep every new feature behind contracts so the WebForms UI remains thin and easier to migrate later if needed.
|
||||
|
||||
415
AGENTS_WEBFORMS_ESTRUCTURA.md
Normal file
415
AGENTS_WEBFORMS_ESTRUCTURA.md
Normal file
@@ -0,0 +1,415 @@
|
||||
# AGENTS_WEBFORMS_ESTRUCTURA.md
|
||||
|
||||
These rules complement `AGENTS.md` and are mandatory whenever the task changes WebForms pages, the master page, login, session behavior, bundles, assets, configuration, controls, or the application shell.
|
||||
|
||||
## Asset folder rules
|
||||
|
||||
The following folders are legacy visual dependencies and must be copied as complete folders:
|
||||
|
||||
```text
|
||||
Styles/
|
||||
Scripts/
|
||||
Metronic/
|
||||
```
|
||||
|
||||
Do not replace Metronic with Bootstrap-only layout.
|
||||
Do not upgrade Metronic unless the user explicitly asks.
|
||||
Do not remove old scripts just because they look unused; only remove references from bundles when they are not used by the master/login flow.
|
||||
|
||||
---
|
||||
|
||||
## Bundle rules
|
||||
|
||||
The project must implement only the bundle methods needed by the current `Site.master` and login page.
|
||||
|
||||
Do not bring every old bundle method from the legacy project.
|
||||
Do not add unused bundle groups just because they existed before.
|
||||
Do not add duplicate bundle keys.
|
||||
Do not add empty bundle methods.
|
||||
|
||||
Allowed current bundle keys are the ones actually rendered by master/login, especially:
|
||||
|
||||
```text
|
||||
~/bundles/modernizr
|
||||
~/bundles/scripts
|
||||
~/bundles/highcharts
|
||||
~/Metronic/assets/global/scripts/JSV1
|
||||
~/Metronic/assets/global/css/cssV1
|
||||
```
|
||||
|
||||
WebForms/AjaxControlToolkit support bundles are allowed only when referenced by `ScriptManager` or required by WebForms controls:
|
||||
|
||||
```text
|
||||
~/bundles/jquery
|
||||
~/bundles/WebFormsJs
|
||||
~/bundles/MsAjaxJs
|
||||
~/Content/AjaxControlToolkit/Styles/Bundle
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- If `Site.master` or `Login.aspx` does not render a bundle, do not add it.
|
||||
- If a bundle exists only for old pages not migrated yet, leave it out until the page needs it.
|
||||
- Prefer preserving original asset paths from `Styles`, `Scripts`, and `Metronic`.
|
||||
- Use `CssRewriteUrlTransform` for CSS bundles that reference fonts, images, or relative URLs.
|
||||
- Do not register CSS/JS from server controls when the style/script is global; use `BundleConfig` and the master page.
|
||||
|
||||
---
|
||||
|
||||
## WebForms page rules
|
||||
|
||||
All normal `.aspx` pages must use `Site.master`, except the login page.
|
||||
|
||||
Normal pages:
|
||||
|
||||
- Must include `MasterPageFile="~/Site.master"`.
|
||||
- Must not include `<html>`, `<head>`, `<body>`, or `<form>`.
|
||||
- Must use `<asp:Content>` controls.
|
||||
- Should inherit from `ClsPaginaBase` or the current C# page base class.
|
||||
- Must not connect directly to SQL classes.
|
||||
- Must call contracts/services for data, authentication, permissions, catalogs, menus, and user context.
|
||||
|
||||
Public registration exception:
|
||||
|
||||
- `Pages/Security/RegistroCliente.aspx`, `RegistroPendiente.aspx` and `VerificarCorreo.aspx` may be standalone public pages with their own `form runat="server"`.
|
||||
- `RegistroCliente.aspx` keeps its two-step draft in encrypted ViewState and persists only after all client/company validations pass.
|
||||
- All persistence continues through contracts/services/repositories and stored procedures.
|
||||
|
||||
Login page:
|
||||
|
||||
- Is the only page allowed to have its own full HTML structure.
|
||||
- May inherit from `System.Web.UI.Page` or its own login base class.
|
||||
- Must not inherit from `ClsPaginaBase` if that base class requires an authenticated session.
|
||||
- Must use `IAuthContract` or the current auth contract.
|
||||
- Must create a dummy session until real authentication is implemented.
|
||||
- Must not hardcode real database login logic in `Login.aspx.cs`.
|
||||
|
||||
Important naming rule:
|
||||
|
||||
- Do not create both `Login.aspx` and `LogIn.aspx`.
|
||||
- If the starter already uses `LogIn.aspx`, keep that name and keep `Web.config` consistent.
|
||||
- If creating from scratch, prefer `Login.aspx`, but update `Web.config`, redirects, and links consistently.
|
||||
|
||||
---
|
||||
|
||||
## Master page rules
|
||||
|
||||
`Site.master` owns the main HTML structure.
|
||||
|
||||
Rules:
|
||||
|
||||
- `Site.master` owns the only main `<form runat="server">`.
|
||||
- `Site.master` must keep the Metronic layout structure.
|
||||
- Keep the sidebar/header/page-content structure similar to the original Metronic project.
|
||||
- Do not restore the hidden search box from the old header.
|
||||
- Keep the actions button if it exists in the selected master layout.
|
||||
- Do not hardcode real user/menu database logic inside `Site.master.cs`.
|
||||
- User data must come from a contract/service.
|
||||
- Menu data must come from a contract/service.
|
||||
- Breadcrumb/title/layout data must come from a contract/service when dynamic.
|
||||
- Do not use `<title id="Titulo" runat="server">`.
|
||||
- Prefer `<title><%: Page.Title %></title>`.
|
||||
- If a generated starter currently uses a title literal, replace it with `Page.Title` unless there is a specific reason to keep the literal.
|
||||
|
||||
Current preferred contracts:
|
||||
|
||||
```text
|
||||
IAuthContract
|
||||
IUserSessionContract
|
||||
IMenuContract
|
||||
IMasterPageContract
|
||||
```
|
||||
|
||||
If old names such as `IUserContextProvider` or `IMenuProvider` exist, migrate them to the current contract naming or create adapters. Do not keep two competing naming systems.
|
||||
|
||||
---
|
||||
|
||||
## ContentPlaceHolder rules
|
||||
|
||||
`Site.master` must use short placeholder IDs.
|
||||
|
||||
Preferred final placeholder IDs:
|
||||
|
||||
```text
|
||||
H = page-specific head/CSS content
|
||||
C = main page content
|
||||
J = page-specific JavaScript
|
||||
```
|
||||
|
||||
Example in `Site.master`:
|
||||
|
||||
```aspx
|
||||
<asp:ContentPlaceHolder ID="H" runat="server" />
|
||||
<asp:ContentPlaceHolder ID="C" runat="server" />
|
||||
<asp:ContentPlaceHolder ID="J" runat="server" />
|
||||
```
|
||||
|
||||
Example in a normal page:
|
||||
|
||||
```aspx
|
||||
<asp:Content ID="ContentHead" ContentPlaceHolderID="H" runat="server">
|
||||
</asp:Content>
|
||||
|
||||
<asp:Content ID="ContentMain" ContentPlaceHolderID="C" runat="server">
|
||||
</asp:Content>
|
||||
|
||||
<asp:Content ID="ContentScripts" ContentPlaceHolderID="J" runat="server">
|
||||
</asp:Content>
|
||||
```
|
||||
|
||||
If the generated starter currently has `HeadContent`, `MainContent`, or `ScriptsContent`, rename them to `H`, `C`, and `J` before adding more pages.
|
||||
|
||||
Do not mix placeholder naming systems in the same project.
|
||||
|
||||
---
|
||||
|
||||
## WebForms tab and page-state rules
|
||||
|
||||
- Register AjaxControlToolkit once in `Web.config` under `system.web/pages/controls` with the exact prefix `ajax`; do not add `<%@ Register ... %>` directives for it in individual pages.
|
||||
- AjaxControlToolkit controls must use the `ajax:` prefix, for example `ajax:TabContainer` and `ajax:TabPanel`; do not use `ajaxToolkit:` or another page-specific prefix.
|
||||
- Tabs in WebForms pages must use `ajax:TabContainer` and `ajax:TabPanel`; do not build page tabs with Bootstrap `nav-tabs`, custom hidden panels, or JavaScript-only tab switching.
|
||||
- Use the `ScriptManager` owned by `Site.master` and the existing AjaxControlToolkit resources. Do not add another `ScriptManager` or duplicate Toolkit scripts/styles.
|
||||
- Server-side page state such as current entity keys, selected child keys, editing mode, flags, and the active tab must be stored in typed `ViewState` properties when it must survive postback.
|
||||
- Do not add `asp:HiddenField` merely to preserve server-side state across postbacks. A hidden field is allowed only when client-side JavaScript must read or change the value.
|
||||
- Hidden-field values are client-controlled and must never be trusted for authorization or sensitive decisions; validate them again on the server when their use is unavoidable.
|
||||
- Keep ViewState values small and serializable. Do not store database connections, commands, readers, services, repositories, or unnecessarily large result sets in ViewState.
|
||||
- ViewState property and key names must identify the entity and purpose, for example `CveFraccionamientoActual` and `CveFraccionamientoEtapaActual`.
|
||||
- When a postback needs to recover related values from an already loaded catalog, store the typed serializable object list in a typed `ViewState` property and locate the selected object by its key.
|
||||
- Do not copy server-owned catalog or model values into HTML `data-*` attributes, CSS classes, hidden fields, or other client-controlled markup merely to recover them during a postback. Read them from the typed object list stored in `ViewState`.
|
||||
|
||||
---
|
||||
|
||||
## Login and session rules
|
||||
|
||||
Authentication must go through a contract.
|
||||
|
||||
Required flow:
|
||||
|
||||
```text
|
||||
Login.aspx.cs
|
||||
↓
|
||||
IAuthContract
|
||||
↓
|
||||
DummyAuthContract now, real AuthService later
|
||||
↓
|
||||
IUserSessionContract
|
||||
↓
|
||||
Session user
|
||||
```
|
||||
|
||||
Initial login may be dummy.
|
||||
|
||||
Dummy session user should be safe and clearly fake, for example:
|
||||
|
||||
```text
|
||||
UserId: 15
|
||||
CompanyId: 1
|
||||
RoleId: 1
|
||||
RoleName: Administrador
|
||||
CompanyName: Empresa Demo
|
||||
DisplayName: Usuario Demo
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- Dummy login may accept any non-empty username and password during starter setup.
|
||||
- Mark dummy authentication clearly in code comments.
|
||||
- Do not mix real SQL authentication with dummy authentication in the same class.
|
||||
- When real login is implemented, create a new service such as `SqlAuthContract` or `AuthService`.
|
||||
- Do not store passwords in session.
|
||||
- Do not log raw passwords.
|
||||
- Use Forms Authentication if staying with classic WebForms auth.
|
||||
|
||||
---
|
||||
|
||||
## Global.asax rules
|
||||
|
||||
`Global.asax` / `Global.asax.cs` should:
|
||||
|
||||
- Register bundles through `BundleConfig.RegisterBundles(BundleTable.Bundles)`.
|
||||
- Configure basic application startup.
|
||||
- Avoid business logic.
|
||||
- Avoid direct database startup queries unless absolutely required.
|
||||
|
||||
If OWIN is not used, prevent startup errors by adding this to `Web.config`:
|
||||
|
||||
```xml
|
||||
<add key="owin:AutomaticAppStartup" value="false" />
|
||||
```
|
||||
|
||||
Do not add OWIN packages unless the project actually needs OWIN.
|
||||
|
||||
---
|
||||
|
||||
## Web.config rules
|
||||
|
||||
`Web.config` must stay compatible with ASP.NET WebForms on .NET Framework 4.8/4.8.1.
|
||||
|
||||
Rules:
|
||||
|
||||
- Use Forms Authentication unless a different auth system is explicitly requested.
|
||||
- Allow anonymous access only to the login page and required static assets.
|
||||
- Do not add ASP.NET Core middleware settings.
|
||||
- Do not add unsupported `.NET Core` config sections.
|
||||
- Do not add CodeDom provider entries unless the matching NuGet package is installed.
|
||||
- If this error appears: `No se pudo ubicar el tipo de proveedor CodeDom Microsoft.CodeDom.Providers.DotNetCompilerPlatform...`, either install the exact package version or remove/fix the `system.codedom` section.
|
||||
- Keep MIME mappings for fonts such as `.woff` and `.woff2` when Metronic requires them.
|
||||
|
||||
---
|
||||
|
||||
## OWIN rule
|
||||
|
||||
If the application shows this error:
|
||||
|
||||
```text
|
||||
No assembly found containing an OwinStartupAttribute
|
||||
```
|
||||
|
||||
And the project does not use OWIN, add this in `appSettings`:
|
||||
|
||||
```xml
|
||||
<add key="owin:AutomaticAppStartup" value="false" />
|
||||
```
|
||||
|
||||
Do not create an empty OWIN startup class just to silence the error unless OWIN is actually required.
|
||||
|
||||
---
|
||||
|
||||
## Site.master rendering rules
|
||||
|
||||
The master page should render bundles and scripts in this general order:
|
||||
|
||||
Inside `<head>`:
|
||||
|
||||
```aspx
|
||||
<%: Scripts.Render("~/bundles/modernizr") %>
|
||||
<%: Styles.Render("~/Content/AjaxControlToolkit/Styles/Bundle") %>
|
||||
<%: Styles.Render("~/Metronic/assets/global/css/cssV1") %>
|
||||
<asp:ContentPlaceHolder ID="H" runat="server" />
|
||||
```
|
||||
|
||||
Inside `<form>` near the top:
|
||||
|
||||
```aspx
|
||||
<asp:ScriptManager ID="TSM" runat="server" />
|
||||
<%: Scripts.Render("~/bundles/scripts") %>
|
||||
```
|
||||
|
||||
Before closing `</form>`:
|
||||
|
||||
```aspx
|
||||
<%: Scripts.Render("~/Metronic/assets/global/scripts/JSV1") %>
|
||||
<%: Scripts.Render("~/bundles/highcharts") %>
|
||||
<asp:ContentPlaceHolder ID="J" runat="server" />
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- Do not render the same script twice.
|
||||
- Do not render JQuery twice.
|
||||
- Keep `ScriptManager` if AjaxControlToolkit, UpdatePanel, or WebForms AJAX is used.
|
||||
- Keep `TSM_AsyncPostBackError` only if implemented in code-behind.
|
||||
- Remove or implement any event handler referenced by markup.
|
||||
|
||||
---
|
||||
|
||||
## Header/menu rules
|
||||
|
||||
The master header must preserve the selected Metronic layout.
|
||||
|
||||
Rules:
|
||||
|
||||
- Keep user dropdown.
|
||||
- Keep logout option.
|
||||
- Keep actions button when present.
|
||||
- Do not restore the hidden/old search box from legacy header.
|
||||
- Sidebar menu must be built from `IMenuContract`.
|
||||
- Do not build the menu from SQL inside `Site.master.cs`.
|
||||
- Menu items should use `MenuItemModel` or an equivalent model.
|
||||
- Encode text output when generating HTML menu strings.
|
||||
- Module visibility and page access are separate concerns: `Sis_Modulos.Visible` controls whether an item is shown in the menu, but it must not deny direct page access.
|
||||
- `PA_Sis_PaginaAccessCheck` must validate role assignment, `PuedeVer`, active state, and URL. It must not require `Sis_Modulos.Visible = 1`.
|
||||
|
||||
---
|
||||
|
||||
## Page title and breadcrumb rules
|
||||
|
||||
Page title and breadcrumb should be handled consistently.
|
||||
|
||||
Rules:
|
||||
|
||||
- Use `Page.Title` for the browser title.
|
||||
- Use a master/layout model for visible page title and breadcrumb.
|
||||
- Do not hardcode global breadcrumb logic in every page.
|
||||
- Normal pages may set page title in `Page_Load` or via properties.
|
||||
|
||||
Preferred model:
|
||||
|
||||
```text
|
||||
MasterLayoutModel
|
||||
PageTitle
|
||||
Breadcrumbs
|
||||
CurrentUser
|
||||
MenuItems
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## JavaScript and CSS rules
|
||||
|
||||
- Global scripts/styles must be registered in `BundleConfig` and rendered by master.
|
||||
- Page-specific scripts go in placeholder `J`.
|
||||
- Page-specific CSS/head content goes in placeholder `H`.
|
||||
- Do not inline large JavaScript blocks in `.aspx` unless page-specific and small.
|
||||
- Do not remove existing custom legacy files unless the user asks.
|
||||
- Fix null `addEventListener` errors by checking that the element exists before attaching events.
|
||||
- Avoid blocking Ctrl+V unless a specific feature requires it.
|
||||
|
||||
---
|
||||
|
||||
## User control rules
|
||||
|
||||
If server controls are migrated:
|
||||
|
||||
- Prefer C# classes under `App_Code/SigControls` when creating reusable server controls.
|
||||
- Do not mix WebForms `.ascx` user controls with App_Code server-control classes unless there is a clear reason.
|
||||
- Do not register global CSS/JS from the control when master bundles already include them.
|
||||
- Controls should expose properties/events and avoid direct SQL access.
|
||||
- Controls should call contracts/services when they need data.
|
||||
|
||||
---
|
||||
|
||||
## Home page rules
|
||||
|
||||
Use only one active home page convention.
|
||||
|
||||
For local development, the canonical home URL is:
|
||||
|
||||
```text
|
||||
http://localhost:52706/Inicio.aspx
|
||||
```
|
||||
|
||||
The application root must be equivalent and redirect explicitly to that page:
|
||||
|
||||
```text
|
||||
http://localhost:52706/ -> http://localhost:52706/Inicio.aspx
|
||||
```
|
||||
|
||||
Keep the root redirect and the `Inicio.aspx` default document consistent. Do not introduce another startup page.
|
||||
|
||||
Allowed options:
|
||||
|
||||
```text
|
||||
Default.aspx
|
||||
Inicio.aspx
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- Do not keep both as competing entry pages.
|
||||
- If using `Inicio.aspx`, redirect `Default.aspx` to `Inicio.aspx` or update Forms Authentication default URL.
|
||||
- If using `Default.aspx`, keep Web.config and menu links pointing to `Default.aspx`.
|
||||
- The home page must use `Site.master`.
|
||||
|
||||
---
|
||||
|
||||
@@ -129,13 +129,7 @@ BEGIN
|
||||
SET NOCOUNT ON;
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS (SELECT 1 FROM dbo.Sis_Usuarios WHERE CveUsuario = @CveUsuarioEjecuta AND CveRol IN (1, 2) AND Activo = 1)
|
||||
BEGIN
|
||||
SELECT @ErrorMostrar = 'No cuenta con permiso para consultar este catálogo.', @ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
|
||||
SELECT CveEstatusSolicitud, Codigo, EstatusSolicitud, Orden, EsFinal, EsActivo
|
||||
SELECT CveEstatusSolicitud, Codigo, EstatusSolicitud, Orden, EsFinal, EsActivo
|
||||
FROM dbo.Tra_EstatusSolicitud
|
||||
WHERE (@IncluirInactivos = 1 OR EsActivo = 1)
|
||||
AND (NULLIF(LTRIM(RTRIM(@Texto)), '') IS NULL
|
||||
@@ -163,12 +157,7 @@ BEGIN
|
||||
SET NOCOUNT ON;
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS (SELECT 1 FROM dbo.Sis_Usuarios WHERE CveUsuario = @CveUsuarioEjecuta AND CveRol IN (1, 2) AND Activo = 1)
|
||||
BEGIN
|
||||
SELECT @ErrorMostrar = 'No cuenta con permiso para consultar este catálogo.', @ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
SELECT CveEstatusSolicitud, Codigo, EstatusSolicitud, Orden, EsFinal, EsActivo
|
||||
SELECT CveEstatusSolicitud, Codigo, EstatusSolicitud, Orden, EsFinal, EsActivo
|
||||
FROM dbo.Tra_EstatusSolicitud
|
||||
WHERE CveEstatusSolicitud = @CveEstatusSolicitud;
|
||||
SET @Return = 1;
|
||||
@@ -196,12 +185,7 @@ BEGIN
|
||||
SET NOCOUNT ON;
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS (SELECT 1 FROM dbo.Sis_Usuarios WHERE CveUsuario = @CveUsuarioEjecuta AND CveRol IN (1, 2) AND Activo = 1)
|
||||
BEGIN
|
||||
SELECT @ErrorMostrar = 'No cuenta con permiso para modificar este catálogo.', @ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
SELECT @Codigo = LTRIM(RTRIM(@Codigo)), @EstatusSolicitud = LTRIM(RTRIM(@EstatusSolicitud));
|
||||
SELECT @Codigo = LTRIM(RTRIM(@Codigo)), @EstatusSolicitud = LTRIM(RTRIM(@EstatusSolicitud));
|
||||
IF NULLIF(@Codigo, '') IS NULL OR NULLIF(@EstatusSolicitud, '') IS NULL
|
||||
BEGIN
|
||||
SELECT @ErrorMostrar = 'Capture el código y el estatus de la solicitud.', @ErrorTipo = 2;
|
||||
@@ -252,12 +236,7 @@ BEGIN
|
||||
SET NOCOUNT ON;
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS (SELECT 1 FROM dbo.Sis_Usuarios WHERE CveUsuario = @CveUsuarioEjecuta AND CveRol IN (1, 2) AND Activo = 1)
|
||||
BEGIN
|
||||
SELECT @ErrorMostrar = 'No cuenta con permiso para eliminar este catálogo.', @ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
IF EXISTS (SELECT 1 FROM dbo.Tra_Solicitudes WHERE CveEstatusSolicitud = @CveEstatusSolicitud)
|
||||
IF EXISTS (SELECT 1 FROM dbo.Tra_Solicitudes WHERE CveEstatusSolicitud = @CveEstatusSolicitud)
|
||||
OR EXISTS (SELECT 1 FROM dbo.Tra_HistorialEstatusSolicitud WHERE CveEstatusSolicitud = @CveEstatusSolicitud)
|
||||
BEGIN
|
||||
SELECT @ErrorMostrar = 'El estatus ya se utiliza en solicitudes y no puede eliminarse. Puede desactivarlo.', @ErrorTipo = 2;
|
||||
@@ -286,12 +265,7 @@ BEGIN
|
||||
SET NOCOUNT ON;
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS (SELECT 1 FROM dbo.Sis_Usuarios WHERE CveUsuario = @CveUsuarioEjecuta AND CveRol IN (1, 2) AND Activo = 1)
|
||||
BEGIN
|
||||
SELECT @ErrorMostrar = 'No cuenta con permiso para consultar este catálogo.', @ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
SELECT T.CveTipoTramite, T.Codigo, T.TipoTramite, T.Descripcion, T.Orden, T.EsActivo,
|
||||
SELECT T.CveTipoTramite, T.Codigo, T.TipoTramite, T.Descripcion, T.Orden, T.EsActivo,
|
||||
COUNT(P.CvePregunta) AS NumeroPreguntas
|
||||
FROM dbo.Tra_TiposTramite AS T
|
||||
LEFT JOIN dbo.Tra_Preguntas AS P ON P.CveTipoTramite = T.CveTipoTramite
|
||||
@@ -323,12 +297,7 @@ BEGIN
|
||||
SET NOCOUNT ON;
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS (SELECT 1 FROM dbo.Sis_Usuarios WHERE CveUsuario = @CveUsuarioEjecuta AND CveRol IN (1, 2) AND Activo = 1)
|
||||
BEGIN
|
||||
SELECT @ErrorMostrar = 'No cuenta con permiso para consultar este catálogo.', @ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
SELECT T.CveTipoTramite, T.Codigo, T.TipoTramite, T.Descripcion, T.Orden, T.EsActivo,
|
||||
SELECT T.CveTipoTramite, T.Codigo, T.TipoTramite, T.Descripcion, T.Orden, T.EsActivo,
|
||||
(SELECT COUNT(*) FROM dbo.Tra_Preguntas AS P WHERE P.CveTipoTramite = T.CveTipoTramite) AS NumeroPreguntas
|
||||
FROM dbo.Tra_TiposTramite AS T
|
||||
WHERE T.CveTipoTramite = @CveTipoTramite;
|
||||
@@ -357,12 +326,7 @@ BEGIN
|
||||
SET NOCOUNT ON;
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS (SELECT 1 FROM dbo.Sis_Usuarios WHERE CveUsuario = @CveUsuarioEjecuta AND CveRol IN (1, 2) AND Activo = 1)
|
||||
BEGIN
|
||||
SELECT @ErrorMostrar = 'No cuenta con permiso para modificar este catálogo.', @ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
SELECT @Codigo = LTRIM(RTRIM(@Codigo)), @TipoTramite = LTRIM(RTRIM(@TipoTramite)), @Descripcion = NULLIF(LTRIM(RTRIM(@Descripcion)), '');
|
||||
SELECT @Codigo = LTRIM(RTRIM(@Codigo)), @TipoTramite = LTRIM(RTRIM(@TipoTramite)), @Descripcion = NULLIF(LTRIM(RTRIM(@Descripcion)), '');
|
||||
IF NULLIF(@Codigo, '') IS NULL OR NULLIF(@TipoTramite, '') IS NULL
|
||||
BEGIN
|
||||
SELECT @ErrorMostrar = 'Capture el código y el nombre del tipo de trámite.', @ErrorTipo = 2;
|
||||
@@ -411,12 +375,7 @@ BEGIN
|
||||
SET NOCOUNT ON;
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS (SELECT 1 FROM dbo.Sis_Usuarios WHERE CveUsuario = @CveUsuarioEjecuta AND CveRol IN (1, 2) AND Activo = 1)
|
||||
BEGIN
|
||||
SELECT @ErrorMostrar = 'No cuenta con permiso para eliminar este catálogo.', @ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
IF EXISTS (SELECT 1 FROM dbo.Tra_Solicitudes WHERE CveTipoTramite = @CveTipoTramite)
|
||||
IF EXISTS (SELECT 1 FROM dbo.Tra_Solicitudes WHERE CveTipoTramite = @CveTipoTramite)
|
||||
OR EXISTS (SELECT 1 FROM dbo.Tra_DocumentosRequeridos WHERE CveTipoTramite = @CveTipoTramite)
|
||||
OR EXISTS (SELECT 1 FROM dbo.Tra_Preguntas WHERE CveTipoTramite = @CveTipoTramite)
|
||||
BEGIN
|
||||
@@ -446,12 +405,7 @@ BEGIN
|
||||
SET NOCOUNT ON;
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS (SELECT 1 FROM dbo.Sis_Usuarios WHERE CveUsuario = @CveUsuarioEjecuta AND CveRol IN (1, 2) AND Activo = 1)
|
||||
BEGIN
|
||||
SELECT @ErrorMostrar = 'No cuenta con permiso para consultar este catálogo.', @ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
SELECT CveTipoDocumento, TipoDocumento, Descripcion, ExtensionesPermitidas, TamanoMaximoMb, EsActivo
|
||||
SELECT CveTipoDocumento, TipoDocumento, Descripcion, ExtensionesPermitidas, TamanoMaximoMb, EsActivo
|
||||
FROM dbo.Tra_TiposDocumento
|
||||
WHERE (@IncluirInactivos = 1 OR EsActivo = 1)
|
||||
AND (NULLIF(LTRIM(RTRIM(@Texto)), '') IS NULL
|
||||
@@ -480,12 +434,7 @@ BEGIN
|
||||
SET NOCOUNT ON;
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS (SELECT 1 FROM dbo.Sis_Usuarios WHERE CveUsuario = @CveUsuarioEjecuta AND CveRol IN (1, 2) AND Activo = 1)
|
||||
BEGIN
|
||||
SELECT @ErrorMostrar = 'No cuenta con permiso para consultar este catálogo.', @ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
SELECT CveTipoDocumento, TipoDocumento, Descripcion, ExtensionesPermitidas, TamanoMaximoMb, EsActivo
|
||||
SELECT CveTipoDocumento, TipoDocumento, Descripcion, ExtensionesPermitidas, TamanoMaximoMb, EsActivo
|
||||
FROM dbo.Tra_TiposDocumento
|
||||
WHERE CveTipoDocumento = @CveTipoDocumento;
|
||||
SET @Return = 1;
|
||||
@@ -514,12 +463,7 @@ BEGIN
|
||||
SET NOCOUNT ON;
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS (SELECT 1 FROM dbo.Sis_Usuarios WHERE CveUsuario = @CveUsuarioEjecuta AND CveRol IN (1, 2) AND Activo = 1)
|
||||
BEGIN
|
||||
SELECT @ErrorMostrar = 'No cuenta con permiso para modificar este catálogo.', @ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
SELECT @TipoDocumento = LTRIM(RTRIM(@TipoDocumento)),
|
||||
SELECT @TipoDocumento = LTRIM(RTRIM(@TipoDocumento)),
|
||||
@Descripcion = NULLIF(LTRIM(RTRIM(@Descripcion)), ''),
|
||||
@ExtensionesPermitidas = NULLIF(LTRIM(RTRIM(@ExtensionesPermitidas)), '');
|
||||
IF NULLIF(@TipoDocumento, '') IS NULL
|
||||
@@ -573,12 +517,7 @@ BEGIN
|
||||
SET NOCOUNT ON;
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS (SELECT 1 FROM dbo.Sis_Usuarios WHERE CveUsuario = @CveUsuarioEjecuta AND CveRol IN (1, 2) AND Activo = 1)
|
||||
BEGIN
|
||||
SELECT @ErrorMostrar = 'No cuenta con permiso para eliminar este catálogo.', @ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
IF EXISTS (SELECT 1 FROM dbo.Tra_DocumentosRequeridos WHERE CveTipoDocumento = @CveTipoDocumento)
|
||||
IF EXISTS (SELECT 1 FROM dbo.Tra_DocumentosRequeridos WHERE CveTipoDocumento = @CveTipoDocumento)
|
||||
OR EXISTS (SELECT 1 FROM dbo.Tra_DocumentosSolicitud WHERE CveTipoDocumento = @CveTipoDocumento)
|
||||
BEGIN
|
||||
SELECT @ErrorMostrar = 'El tipo de documento tiene información relacionada y no puede eliminarse. Puede desactivarlo.', @ErrorTipo = 2;
|
||||
@@ -607,12 +546,7 @@ BEGIN
|
||||
SET NOCOUNT ON;
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS (SELECT 1 FROM dbo.Sis_Usuarios WHERE CveUsuario = @CveUsuarioEjecuta AND CveRol IN (1, 2) AND Activo = 1)
|
||||
BEGIN
|
||||
SELECT @ErrorMostrar = 'No cuenta con permiso para consultar este catálogo.', @ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
SELECT D.CveDocumentoRequerido, D.CveTipoTramite, T.TipoTramite,
|
||||
SELECT D.CveDocumentoRequerido, D.CveTipoTramite, T.TipoTramite,
|
||||
D.CveTipoDocumento, TD.TipoDocumento, D.EsRequerido, D.Orden, D.EsActivo
|
||||
FROM dbo.Tra_DocumentosRequeridos AS D
|
||||
INNER JOIN dbo.Tra_TiposTramite AS T ON T.CveTipoTramite = D.CveTipoTramite
|
||||
@@ -641,12 +575,7 @@ BEGIN
|
||||
SET NOCOUNT ON;
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS (SELECT 1 FROM dbo.Sis_Usuarios WHERE CveUsuario = @CveUsuarioEjecuta AND CveRol IN (1, 2) AND Activo = 1)
|
||||
BEGIN
|
||||
SELECT @ErrorMostrar = 'No cuenta con permiso para consultar este catálogo.', @ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
SELECT D.CveDocumentoRequerido, D.CveTipoTramite, T.TipoTramite,
|
||||
SELECT D.CveDocumentoRequerido, D.CveTipoTramite, T.TipoTramite,
|
||||
D.CveTipoDocumento, TD.TipoDocumento, D.EsRequerido, D.Orden, D.EsActivo
|
||||
FROM dbo.Tra_DocumentosRequeridos AS D
|
||||
INNER JOIN dbo.Tra_TiposTramite AS T ON T.CveTipoTramite = D.CveTipoTramite
|
||||
@@ -677,12 +606,7 @@ BEGIN
|
||||
SET NOCOUNT ON;
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS (SELECT 1 FROM dbo.Sis_Usuarios WHERE CveUsuario = @CveUsuarioEjecuta AND CveRol IN (1, 2) AND Activo = 1)
|
||||
BEGIN
|
||||
SELECT @ErrorMostrar = 'No cuenta con permiso para modificar este catálogo.', @ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
IF NOT EXISTS (SELECT 1 FROM dbo.Tra_TiposTramite WHERE CveTipoTramite = @CveTipoTramite)
|
||||
IF NOT EXISTS (SELECT 1 FROM dbo.Tra_TiposTramite WHERE CveTipoTramite = @CveTipoTramite)
|
||||
OR NOT EXISTS (SELECT 1 FROM dbo.Tra_TiposDocumento WHERE CveTipoDocumento = @CveTipoDocumento)
|
||||
BEGIN
|
||||
SELECT @ErrorMostrar = 'Seleccione un tipo de trámite y un tipo de documento válidos.', @ErrorTipo = 2;
|
||||
@@ -755,12 +679,7 @@ BEGIN
|
||||
SET NOCOUNT ON;
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS (SELECT 1 FROM dbo.Sis_Usuarios WHERE CveUsuario = @CveUsuarioEjecuta AND CveRol IN (1, 2) AND Activo = 1)
|
||||
BEGIN
|
||||
SELECT @ErrorMostrar = 'No cuenta con permiso para eliminar este catálogo.', @ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
DELETE dbo.Tra_DocumentosRequeridos WHERE CveDocumentoRequerido = @CveDocumentoRequerido;
|
||||
DELETE dbo.Tra_DocumentosRequeridos WHERE CveDocumentoRequerido = @CveDocumentoRequerido;
|
||||
SET @Return = 1;
|
||||
END TRY
|
||||
BEGIN CATCH
|
||||
@@ -781,12 +700,7 @@ BEGIN
|
||||
SET NOCOUNT ON;
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS (SELECT 1 FROM dbo.Sis_Usuarios WHERE CveUsuario = @CveUsuarioEjecuta AND CveRol IN (1, 2) AND Activo = 1)
|
||||
BEGIN
|
||||
SELECT @ErrorMostrar = 'No cuenta con permiso para consultar este catálogo.', @ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
SELECT CveTipoPregunta, TipoPregunta, EsActivo
|
||||
SELECT CveTipoPregunta, TipoPregunta, EsActivo
|
||||
FROM dbo.Tra_TiposPregunta
|
||||
WHERE EsActivo = 1
|
||||
ORDER BY CveTipoPregunta;
|
||||
@@ -812,12 +726,7 @@ BEGIN
|
||||
SET NOCOUNT ON;
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS (SELECT 1 FROM dbo.Sis_Usuarios WHERE CveUsuario = @CveUsuarioEjecuta AND CveRol IN (1, 2) AND Activo = 1)
|
||||
BEGIN
|
||||
SELECT @ErrorMostrar = 'No cuenta con permiso para consultar este catálogo.', @ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
SELECT P.CvePregunta, P.CveTipoTramite, T.TipoTramite, P.CveTipoPregunta,
|
||||
SELECT P.CvePregunta, P.CveTipoTramite, T.TipoTramite, P.CveTipoPregunta,
|
||||
TP.TipoPregunta, P.Codigo, P.Pregunta, P.Descripcion, P.EsRequerida,
|
||||
P.Orden, P.EsActivo, COUNT(O.CveOpcionPregunta) AS NumeroOpciones
|
||||
FROM dbo.Tra_Preguntas AS P
|
||||
@@ -851,12 +760,7 @@ BEGIN
|
||||
SET NOCOUNT ON;
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS (SELECT 1 FROM dbo.Sis_Usuarios WHERE CveUsuario = @CveUsuarioEjecuta AND CveRol IN (1, 2) AND Activo = 1)
|
||||
BEGIN
|
||||
SELECT @ErrorMostrar = 'No cuenta con permiso para consultar este catálogo.', @ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
SELECT P.CvePregunta, P.CveTipoTramite, T.TipoTramite, P.CveTipoPregunta,
|
||||
SELECT P.CvePregunta, P.CveTipoTramite, T.TipoTramite, P.CveTipoPregunta,
|
||||
TP.TipoPregunta, P.Codigo, P.Pregunta, P.Descripcion, P.EsRequerida,
|
||||
P.Orden, P.EsActivo,
|
||||
(SELECT COUNT(*) FROM dbo.Tra_OpcionesPregunta AS O WHERE O.CvePregunta = P.CvePregunta) AS NumeroOpciones
|
||||
@@ -892,12 +796,7 @@ BEGIN
|
||||
SET NOCOUNT ON;
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS (SELECT 1 FROM dbo.Sis_Usuarios WHERE CveUsuario = @CveUsuarioEjecuta AND CveRol IN (1, 2) AND Activo = 1)
|
||||
BEGIN
|
||||
SELECT @ErrorMostrar = 'No cuenta con permiso para modificar este catálogo.', @ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
SELECT @Codigo = NULLIF(LTRIM(RTRIM(@Codigo)), ''),
|
||||
SELECT @Codigo = NULLIF(LTRIM(RTRIM(@Codigo)), ''),
|
||||
@Pregunta = LTRIM(RTRIM(@Pregunta)),
|
||||
@Descripcion = NULLIF(LTRIM(RTRIM(@Descripcion)), '');
|
||||
IF NULLIF(@Pregunta, '') IS NULL
|
||||
@@ -981,12 +880,7 @@ BEGIN
|
||||
SET NOCOUNT ON;
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS (SELECT 1 FROM dbo.Sis_Usuarios WHERE CveUsuario = @CveUsuarioEjecuta AND CveRol IN (1, 2) AND Activo = 1)
|
||||
BEGIN
|
||||
SELECT @ErrorMostrar = 'No cuenta con permiso para eliminar este catálogo.', @ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
IF EXISTS (SELECT 1 FROM dbo.Tra_RespuestasSolicitud WHERE CvePregunta = @CvePregunta)
|
||||
IF EXISTS (SELECT 1 FROM dbo.Tra_RespuestasSolicitud WHERE CvePregunta = @CvePregunta)
|
||||
BEGIN
|
||||
SELECT @ErrorMostrar = 'La pregunta ya tiene respuestas registradas y no puede eliminarse. Puede desactivarla.', @ErrorTipo = 2;
|
||||
RETURN;
|
||||
@@ -1014,12 +908,7 @@ BEGIN
|
||||
SET NOCOUNT ON;
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS (SELECT 1 FROM dbo.Sis_Usuarios WHERE CveUsuario = @CveUsuarioEjecuta AND CveRol IN (1, 2) AND Activo = 1)
|
||||
BEGIN
|
||||
SELECT @ErrorMostrar = 'No cuenta con permiso para consultar este catálogo.', @ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
SELECT O.CveOpcionPregunta, O.CvePregunta, P.Pregunta, O.TextoOpcion,
|
||||
SELECT O.CveOpcionPregunta, O.CvePregunta, P.Pregunta, O.TextoOpcion,
|
||||
O.ValorOpcion, O.Orden, O.EsActivo
|
||||
FROM dbo.Tra_OpcionesPregunta AS O
|
||||
INNER JOIN dbo.Tra_Preguntas AS P ON P.CvePregunta = O.CvePregunta
|
||||
@@ -1046,12 +935,7 @@ BEGIN
|
||||
SET NOCOUNT ON;
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS (SELECT 1 FROM dbo.Sis_Usuarios WHERE CveUsuario = @CveUsuarioEjecuta AND CveRol IN (1, 2) AND Activo = 1)
|
||||
BEGIN
|
||||
SELECT @ErrorMostrar = 'No cuenta con permiso para consultar este catálogo.', @ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
SELECT O.CveOpcionPregunta, O.CvePregunta, P.Pregunta, O.TextoOpcion,
|
||||
SELECT O.CveOpcionPregunta, O.CvePregunta, P.Pregunta, O.TextoOpcion,
|
||||
O.ValorOpcion, O.Orden, O.EsActivo
|
||||
FROM dbo.Tra_OpcionesPregunta AS O
|
||||
INNER JOIN dbo.Tra_Preguntas AS P ON P.CvePregunta = O.CvePregunta
|
||||
@@ -1081,12 +965,7 @@ BEGIN
|
||||
SET NOCOUNT ON;
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS (SELECT 1 FROM dbo.Sis_Usuarios WHERE CveUsuario = @CveUsuarioEjecuta AND CveRol IN (1, 2) AND Activo = 1)
|
||||
BEGIN
|
||||
SELECT @ErrorMostrar = 'No cuenta con permiso para modificar este catálogo.', @ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
SELECT @TextoOpcion = LTRIM(RTRIM(@TextoOpcion)),
|
||||
SELECT @TextoOpcion = LTRIM(RTRIM(@TextoOpcion)),
|
||||
@ValorOpcion = NULLIF(LTRIM(RTRIM(@ValorOpcion)), '');
|
||||
IF NULLIF(@TextoOpcion, '') IS NULL
|
||||
OR NOT EXISTS (SELECT 1 FROM dbo.Tra_Preguntas WHERE CvePregunta = @CvePregunta AND CveTipoPregunta IN (3, 4))
|
||||
@@ -1161,12 +1040,7 @@ BEGIN
|
||||
SET NOCOUNT ON;
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS (SELECT 1 FROM dbo.Sis_Usuarios WHERE CveUsuario = @CveUsuarioEjecuta AND CveRol IN (1, 2) AND Activo = 1)
|
||||
BEGIN
|
||||
SELECT @ErrorMostrar = 'No cuenta con permiso para eliminar este catálogo.', @ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
IF EXISTS (SELECT 1 FROM dbo.Tra_RespuestasSolicitud WHERE CveOpcionPregunta = @CveOpcionPregunta)
|
||||
IF EXISTS (SELECT 1 FROM dbo.Tra_RespuestasSolicitud WHERE CveOpcionPregunta = @CveOpcionPregunta)
|
||||
BEGIN
|
||||
SELECT @ErrorMostrar = 'La opción ya tiene respuestas registradas y no puede eliminarse. Puede desactivarla.', @ErrorTipo = 2;
|
||||
RETURN;
|
||||
@@ -1196,22 +1070,7 @@ BEGIN
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.Sis_Usuarios
|
||||
WHERE CveUsuario = @CveUsuarioEjecuta
|
||||
AND CveRol IN (1, 2)
|
||||
AND Activo = 1
|
||||
)
|
||||
BEGIN
|
||||
SELECT
|
||||
@ErrorMostrar = 'No cuenta con permiso para reordenar este catálogo.',
|
||||
@ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
|
||||
IF @CveRegistro <= 0
|
||||
IF @CveRegistro <= 0
|
||||
OR @CveReferencia <= 0
|
||||
OR @CveRegistro = @CveReferencia
|
||||
BEGIN
|
||||
@@ -1398,4 +1257,4 @@ BEGIN
|
||||
RAISERROR(N'%s', 10, 1, @ErrorTecnico);
|
||||
END CATCH;
|
||||
END;
|
||||
GO
|
||||
GO
|
||||
|
||||
@@ -526,31 +526,6 @@ BEGIN
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.Sis_Usuarios AS U
|
||||
WHERE U.CveUsuario = @CveUsuarioEjecuta
|
||||
AND U.Activo = 1
|
||||
AND
|
||||
(
|
||||
U.CveRol IN (1, 2)
|
||||
OR EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.Sis_UsuariosClientes AS UC
|
||||
WHERE UC.CveUsuario = U.CveUsuario
|
||||
AND UC.CveCliente = @CveCliente
|
||||
AND UC.Activo = 1
|
||||
)
|
||||
)
|
||||
)
|
||||
BEGIN
|
||||
SELECT
|
||||
@ErrorMostrar = 'No cuenta con permiso para consultar la información fiscal del cliente.',
|
||||
@ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
|
||||
IF NOT EXISTS
|
||||
(
|
||||
@@ -642,31 +617,6 @@ BEGIN
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.Sis_Usuarios AS U
|
||||
WHERE U.CveUsuario = @CveUsuarioEjecuta
|
||||
AND U.Activo = 1
|
||||
AND
|
||||
(
|
||||
U.CveRol IN (1, 2)
|
||||
OR EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.Sis_UsuariosClientes AS UC
|
||||
WHERE UC.CveUsuario = U.CveUsuario
|
||||
AND UC.CveCliente = @CveCliente
|
||||
AND UC.Activo = 1
|
||||
)
|
||||
)
|
||||
)
|
||||
BEGIN
|
||||
SELECT
|
||||
@ErrorMostrar = 'No cuenta con permiso para guardar el CFDI del cliente.',
|
||||
@ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
|
||||
IF NOT EXISTS
|
||||
(
|
||||
@@ -860,30 +810,16 @@ BEGIN
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
|
||||
BEGIN TRY
|
||||
|
||||
IF NOT EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.Fac_CfdiDocumentos AS D
|
||||
INNER JOIN dbo.Sis_Usuarios AS U
|
||||
ON U.CveUsuario = @CveUsuarioEjecuta
|
||||
AND U.Activo = 1
|
||||
WHERE D.CveCfdiDocumento = @CveCfdiDocumento
|
||||
AND
|
||||
(
|
||||
U.CveRol IN (1, 2)
|
||||
OR EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.Sis_UsuariosClientes AS UC
|
||||
WHERE UC.CveUsuario = U.CveUsuario
|
||||
AND UC.CveCliente = D.CveCliente
|
||||
AND UC.Activo = 1
|
||||
)
|
||||
)
|
||||
FROM dbo.Fac_CfdiDocumentos
|
||||
WHERE CveCfdiDocumento = @CveCfdiDocumento
|
||||
)
|
||||
BEGIN
|
||||
SELECT
|
||||
@ErrorMostrar = 'No se encontró el CFDI o no cuenta con permiso para consultarlo.',
|
||||
@ErrorMostrar = 'No se encontró el CFDI solicitado.',
|
||||
@ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
@@ -985,31 +921,6 @@ BEGIN
|
||||
RETURN;
|
||||
END;
|
||||
|
||||
IF NOT EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.Sis_Usuarios AS U
|
||||
WHERE U.CveUsuario = @CveUsuarioEjecuta
|
||||
AND U.Activo = 1
|
||||
AND
|
||||
(
|
||||
U.CveRol IN (1, 2)
|
||||
OR EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.Sis_UsuariosClientes AS UC
|
||||
WHERE UC.CveUsuario = U.CveUsuario
|
||||
AND UC.CveCliente = @CveCliente
|
||||
AND UC.Activo = 1
|
||||
)
|
||||
)
|
||||
)
|
||||
BEGIN
|
||||
SELECT
|
||||
@ErrorMostrar = 'No cuenta con permiso para timbrar el CFDI.',
|
||||
@ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
|
||||
IF EXISTS
|
||||
(
|
||||
@@ -1181,31 +1092,6 @@ BEGIN
|
||||
RETURN;
|
||||
END;
|
||||
|
||||
IF NOT EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.Sis_Usuarios AS U
|
||||
WHERE U.CveUsuario = @CveUsuarioEjecuta
|
||||
AND U.Activo = 1
|
||||
AND
|
||||
(
|
||||
U.CveRol IN (1, 2)
|
||||
OR EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.Sis_UsuariosClientes AS UC
|
||||
WHERE UC.CveUsuario = U.CveUsuario
|
||||
AND UC.CveCliente = @CveCliente
|
||||
AND UC.Activo = 1
|
||||
)
|
||||
)
|
||||
)
|
||||
BEGIN
|
||||
SELECT
|
||||
@ErrorMostrar = 'No cuenta con permiso para guardar el resultado del timbrado.',
|
||||
@ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
|
||||
IF @EstadoActual <> 'PENDIENTE'
|
||||
BEGIN
|
||||
@@ -1402,30 +1288,16 @@ BEGIN
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
|
||||
BEGIN TRY
|
||||
|
||||
IF NOT EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.Fac_CfdiDocumentos AS D
|
||||
INNER JOIN dbo.Sis_Usuarios AS U
|
||||
ON U.CveUsuario = @CveUsuarioEjecuta
|
||||
AND U.Activo = 1
|
||||
WHERE D.CveCfdiDocumento = @CveCfdiDocumento
|
||||
AND
|
||||
(
|
||||
U.CveRol IN (1, 2)
|
||||
OR EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.Sis_UsuariosClientes AS UC
|
||||
WHERE UC.CveUsuario = U.CveUsuario
|
||||
AND UC.CveCliente = D.CveCliente
|
||||
AND UC.Activo = 1
|
||||
)
|
||||
)
|
||||
FROM dbo.Fac_CfdiDocumentos
|
||||
WHERE CveCfdiDocumento = @CveCfdiDocumento
|
||||
)
|
||||
BEGIN
|
||||
SELECT
|
||||
@ErrorMostrar = 'No se encontró el CFDI o no cuenta con permiso para consultarlo.',
|
||||
@ErrorMostrar = 'No se encontró el CFDI solicitado.',
|
||||
@ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
@@ -1494,30 +1366,16 @@ BEGIN
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
|
||||
BEGIN TRY
|
||||
|
||||
IF NOT EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.Fac_CfdiDocumentos AS D
|
||||
INNER JOIN dbo.Sis_Usuarios AS U
|
||||
ON U.CveUsuario = @CveUsuarioEjecuta
|
||||
AND U.Activo = 1
|
||||
WHERE D.CveCfdiDocumento = @CveCfdiDocumento
|
||||
AND
|
||||
(
|
||||
U.CveRol IN (1, 2)
|
||||
OR EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.Sis_UsuariosClientes AS UC
|
||||
WHERE UC.CveUsuario = U.CveUsuario
|
||||
AND UC.CveCliente = D.CveCliente
|
||||
AND UC.Activo = 1
|
||||
)
|
||||
)
|
||||
FROM dbo.Fac_CfdiDocumentos
|
||||
WHERE CveCfdiDocumento = @CveCfdiDocumento
|
||||
)
|
||||
BEGIN
|
||||
SELECT
|
||||
@ErrorMostrar = 'No se encontró el CFDI o no cuenta con permiso para descargarlo.',
|
||||
@ErrorMostrar = 'No se encontró el CFDI solicitado.',
|
||||
@ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
|
||||
@@ -175,17 +175,17 @@ BEGIN
|
||||
UM.UnidadMedida AS Unidad,
|
||||
PS.PS AS Descripcion,
|
||||
VD.PrecioUnitario AS ValorUnitario,
|
||||
VD.PrecioUnitario AS PU,
|
||||
VD.Importe AS Total,
|
||||
VD.Descuento,
|
||||
OI.CodigoObjetoImpuesto AS ObjetoImpuesto,
|
||||
CONVERT(
|
||||
decimal(19, 6),
|
||||
ROUND(VD.Cantidad * VD.PrecioUnitario, 6) - VD.Descuento
|
||||
VD.Importe - VD.Descuento
|
||||
) AS BaseIVA,
|
||||
CONVERT(
|
||||
decimal(19, 6),
|
||||
ISNULL(PS.IVA, 0) / 100.0
|
||||
) AS TasaIVA,
|
||||
CONVERT(decimal(19, 6), VD.IVA) AS ImporteIVA
|
||||
CONVERT(decimal(19, 6), 0.16) AS TasaIVA,
|
||||
CONVERT(decimal(19, 6), VD.IVA) AS ImporteIVA,
|
||||
CONVERT(decimal(19, 6), 0.16) AS PorcentajeIVA
|
||||
FROM dbo.VentasDetalle AS VD
|
||||
INNER JOIN dbo.ProductosServicios AS PS
|
||||
ON PS.CvePS = VD.CvePS
|
||||
|
||||
@@ -579,10 +579,9 @@ BEGIN
|
||||
DECLARE @Total decimal(18, 2);
|
||||
|
||||
SELECT
|
||||
@SubTotal = CONVERT(decimal(18, 2), SUM(ROUND(Cantidad * PrecioUnitario, 2))),
|
||||
@SubTotal = CONVERT(decimal(18, 2), SUM(Importe)),
|
||||
@Descuento = CONVERT(decimal(18, 2), SUM(Descuento)),
|
||||
@IVA = CONVERT(decimal(18, 2), SUM(IVA)),
|
||||
@Total = CONVERT(decimal(18, 2), SUM(Importe))
|
||||
@IVA = CONVERT(decimal(18, 2), SUM(IVA))
|
||||
FROM dbo.VentasDetalle
|
||||
WHERE CveVenta = @CveVenta;
|
||||
|
||||
@@ -592,11 +591,17 @@ BEGIN
|
||||
RETURN;
|
||||
END;
|
||||
|
||||
SET @Descuento = ISNULL(@Descuento, 0);
|
||||
SET @IVA = ISNULL(@IVA, 0);
|
||||
SET @Total = CONVERT(
|
||||
decimal(18, 2),
|
||||
ROUND(@SubTotal - @Descuento + @IVA, 2));
|
||||
|
||||
UPDATE dbo.Ventas
|
||||
SET
|
||||
SubTotal = @SubTotal,
|
||||
Descuento = ISNULL(@Descuento, 0),
|
||||
IVA = ISNULL(@IVA, 0),
|
||||
Descuento = @Descuento,
|
||||
IVA = @IVA,
|
||||
Total = @Total,
|
||||
CveUsuarioModifico = @CveUsuarioEjecuta
|
||||
WHERE CveVenta = @CveVenta;
|
||||
@@ -738,20 +743,6 @@ BEGIN
|
||||
RETURN;
|
||||
END;
|
||||
|
||||
IF NOT EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.Vta_Pagos
|
||||
WHERE CveVenta = @CveVenta
|
||||
AND CveSolicitud = @CveSolicitud
|
||||
AND CveTramitePago = @CveTramitePago
|
||||
AND EsActivo = 1
|
||||
)
|
||||
BEGIN
|
||||
SELECT @ErrorMostrar = 'La venta debe estar pagada antes de timbrarla.', @ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
|
||||
IF EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
@@ -817,11 +808,17 @@ BEGIN
|
||||
UM.UnidadMedida AS Unidad,
|
||||
PS.PS AS Descripcion,
|
||||
VD.PrecioUnitario AS ValorUnitario,
|
||||
VD.PrecioUnitario AS PU,
|
||||
VD.Importe AS Total,
|
||||
VD.Descuento,
|
||||
OI.CodigoObjetoImpuesto AS ObjetoImpuesto,
|
||||
CONVERT(decimal(19, 6), ROUND(VD.Cantidad * VD.PrecioUnitario, 6) - VD.Descuento) AS BaseIVA,
|
||||
CONVERT(decimal(19, 6), ISNULL(PS.IVA, 0) / 100.0) AS TasaIVA,
|
||||
CONVERT(decimal(19, 6), VD.IVA) AS ImporteIVA
|
||||
CONVERT(
|
||||
decimal(19, 6),
|
||||
VD.Importe - VD.Descuento
|
||||
) AS BaseIVA,
|
||||
CONVERT(decimal(19, 6), 0.16) AS TasaIVA,
|
||||
CONVERT(decimal(19, 6), VD.IVA) AS ImporteIVA,
|
||||
CONVERT(decimal(19, 6), 0.16) AS PorcentajeIVA
|
||||
FROM dbo.VentasDetalle AS VD
|
||||
INNER JOIN dbo.ProductosServicios AS PS
|
||||
ON PS.CvePS = VD.CvePS
|
||||
@@ -860,6 +857,7 @@ BEGIN
|
||||
|
||||
BEGIN TRY
|
||||
DECLARE @CveVenta int;
|
||||
DECLARE @PorcentajeIVA decimal(9, 6) = 0.16;
|
||||
|
||||
SELECT @CveVenta = SP.CveVenta
|
||||
FROM dbo.Tra_SolicitudesPagos AS SP
|
||||
@@ -935,11 +933,17 @@ BEGIN
|
||||
ELSE PS.Codigo COLLATE DATABASE_DEFAULT +
|
||||
' - ' + PS.PS COLLATE DATABASE_DEFAULT
|
||||
END AS ProductoServicio,
|
||||
CONVERT(decimal(18, 4), D.Cantidad) AS Cantidad,
|
||||
CONVERT(decimal(18, 2), PS.Precio) AS PrecioUnitario,
|
||||
CONVERT(decimal(18, 4), 1) AS Cantidad,
|
||||
CONVERT(decimal(18, 2), Costo.Importe) AS PrecioUnitario,
|
||||
CONVERT(decimal(18, 2), 0) AS Descuento,
|
||||
CONVERT(decimal(18, 2), ROUND(D.Cantidad * PS.Precio * ISNULL(PS.IVA, 0) / 100, 2)) AS IVA,
|
||||
CONVERT(decimal(18, 2), ROUND(D.Cantidad * PS.Precio, 2) + ROUND(D.Cantidad * PS.Precio * ISNULL(PS.IVA, 0) / 100, 2)) AS Importe
|
||||
CONVERT(
|
||||
decimal(18, 2),
|
||||
ROUND(Costo.Importe * @PorcentajeIVA, 2)
|
||||
) AS IVA,
|
||||
CONVERT(
|
||||
decimal(18, 2),
|
||||
ROUND(Costo.Importe, 2)
|
||||
) AS Importe
|
||||
FROM dbo.Tra_Solicitudes AS S
|
||||
INNER JOIN dbo.Tra_Pagos AS P
|
||||
ON P.CveTramitePago = @CveTramitePago
|
||||
@@ -949,6 +953,30 @@ BEGIN
|
||||
ON D.CveTramitePago = P.CveTramitePago
|
||||
INNER JOIN dbo.ProductosServicios AS PS
|
||||
ON PS.CvePS = D.CvePS
|
||||
CROSS APPLY
|
||||
(
|
||||
SELECT TOP (1)
|
||||
CT.Importe
|
||||
FROM dbo.Tra_CostosTramite AS CT
|
||||
WHERE CT.CveTipoTramite = S.CveTipoTramite
|
||||
AND CT.CvePS = D.CvePS
|
||||
AND CT.EsActivo = 1
|
||||
AND
|
||||
(
|
||||
CT.FechaInicioVigencia IS NULL
|
||||
OR CT.FechaInicioVigencia <= CONVERT(date, GETDATE())
|
||||
)
|
||||
AND
|
||||
(
|
||||
CT.FechaFinVigencia IS NULL
|
||||
OR CT.FechaFinVigencia >= CONVERT(date, GETDATE())
|
||||
)
|
||||
ORDER BY
|
||||
ISNULL(
|
||||
CT.FechaInicioVigencia,
|
||||
CONVERT(date, '19000101')) DESC,
|
||||
CT.CveCostoTramite DESC
|
||||
) AS Costo
|
||||
INNER JOIN dbo.UnidadesMedida AS UM
|
||||
ON UM.CveUnidadMedida = D.CveUM
|
||||
INNER JOIN dbo.Clasificaciones AS C
|
||||
@@ -992,7 +1020,8 @@ BEGIN
|
||||
|
||||
BEGIN TRY
|
||||
DECLARE @CveVenta int;
|
||||
DECLARE @PorcentajeIVA decimal(18, 6);
|
||||
DECLARE @PorcentajeIVA decimal(9, 6) = 0.16;
|
||||
DECLARE @Descuento decimal(18, 2) = 0;
|
||||
DECLARE @IVA decimal(18, 2);
|
||||
DECLARE @Importe decimal(18, 2);
|
||||
|
||||
@@ -1021,19 +1050,43 @@ BEGIN
|
||||
RETURN;
|
||||
END;
|
||||
|
||||
SELECT @PorcentajeIVA = CONVERT(decimal(18, 6), ISNULL(IVA, 0))
|
||||
FROM dbo.ProductosServicios
|
||||
WHERE CvePS = @CvePS
|
||||
AND Estado = 1;
|
||||
|
||||
IF @PorcentajeIVA IS NULL OR @Cantidad <= 0 OR @PrecioUnitario < 0
|
||||
IF NOT EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.ProductosServicios
|
||||
WHERE CvePS = @CvePS
|
||||
AND Estado = 1
|
||||
)
|
||||
OR @Cantidad <= 0
|
||||
OR @PrecioUnitario < 0
|
||||
BEGIN
|
||||
SELECT @ErrorMostrar = 'Capture un producto activo, cantidad y precio unitario válidos.', @ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
|
||||
SET @IVA = CONVERT(decimal(18, 2), ROUND(@Cantidad * @PrecioUnitario * @PorcentajeIVA / 100, 2));
|
||||
SET @Importe = CONVERT(decimal(18, 2), ROUND(@Cantidad * @PrecioUnitario, 2) + @IVA);
|
||||
IF @CveVentaDetalle IS NOT NULL
|
||||
BEGIN
|
||||
SELECT @Descuento = Descuento
|
||||
FROM dbo.VentasDetalle
|
||||
WHERE CveVentaDetalle = @CveVentaDetalle
|
||||
AND CveVenta = @CveVenta;
|
||||
END;
|
||||
|
||||
SET @Importe = CONVERT(
|
||||
decimal(18, 2),
|
||||
ROUND(@Cantidad * @PrecioUnitario, 2));
|
||||
|
||||
IF @Descuento > @Importe
|
||||
BEGIN
|
||||
SELECT
|
||||
@ErrorMostrar = 'El descuento del concepto no puede ser mayor que su importe.',
|
||||
@ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
|
||||
SET @IVA = CONVERT(
|
||||
decimal(18, 2),
|
||||
ROUND((@Importe - @Descuento) * @PorcentajeIVA, 2));
|
||||
|
||||
IF @CveVentaDetalle IS NULL
|
||||
BEGIN
|
||||
|
||||
@@ -104,6 +104,8 @@ BEGIN
|
||||
@Return = 0;
|
||||
|
||||
BEGIN TRY
|
||||
DECLARE @PorcentajeIVA decimal(9, 6) = 0.16;
|
||||
|
||||
IF NOT EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
@@ -125,16 +127,14 @@ BEGIN
|
||||
COUNT_BIG(*) AS NumeroConceptos,
|
||||
SUM(
|
||||
ROUND(
|
||||
CONVERT(decimal(18, 4), D.Cantidad) *
|
||||
CONVERT(decimal(18, 4), PS.Precio),
|
||||
CONVERT(decimal(18, 4), Costo.Importe),
|
||||
2
|
||||
)
|
||||
) AS SubTotal,
|
||||
SUM(
|
||||
ROUND(
|
||||
CONVERT(decimal(18, 4), D.Cantidad) *
|
||||
CONVERT(decimal(18, 4), PS.Precio) *
|
||||
CONVERT(decimal(18, 6), ISNULL(PS.IVA, 0)) / 100,
|
||||
CONVERT(decimal(18, 4), Costo.Importe) *
|
||||
@PorcentajeIVA,
|
||||
2
|
||||
)
|
||||
) AS IVA
|
||||
@@ -146,6 +146,30 @@ BEGIN
|
||||
ON D.CveTramitePago = P.CveTramitePago
|
||||
INNER JOIN dbo.ProductosServicios AS PS
|
||||
ON PS.CvePS = D.CvePS
|
||||
OUTER APPLY
|
||||
(
|
||||
SELECT TOP (1)
|
||||
CT.Importe
|
||||
FROM dbo.Tra_CostosTramite AS CT
|
||||
WHERE CT.CveTipoTramite = S.CveTipoTramite
|
||||
AND CT.CvePS = D.CvePS
|
||||
AND CT.EsActivo = 1
|
||||
AND
|
||||
(
|
||||
CT.FechaInicioVigencia IS NULL
|
||||
OR CT.FechaInicioVigencia <= CONVERT(date, GETDATE())
|
||||
)
|
||||
AND
|
||||
(
|
||||
CT.FechaFinVigencia IS NULL
|
||||
OR CT.FechaFinVigencia >= CONVERT(date, GETDATE())
|
||||
)
|
||||
ORDER BY
|
||||
ISNULL(
|
||||
CT.FechaInicioVigencia,
|
||||
CONVERT(date, '19000101')) DESC,
|
||||
CT.CveCostoTramite DESC
|
||||
) AS Costo
|
||||
WHERE S.CveFraccionamiento = @CveFraccionamiento
|
||||
GROUP BY
|
||||
S.CveSolicitud,
|
||||
|
||||
@@ -214,6 +214,8 @@ BEGIN
|
||||
@Return = 0;
|
||||
|
||||
BEGIN TRY
|
||||
DECLARE @PorcentajeIVA decimal(9, 6) = 0.16;
|
||||
|
||||
IF NOT EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
@@ -235,16 +237,14 @@ BEGIN
|
||||
COUNT_BIG(*) AS NumeroConceptos,
|
||||
SUM(
|
||||
ROUND(
|
||||
CONVERT(decimal(18, 4), D.Cantidad) *
|
||||
CONVERT(decimal(18, 4), PS.Precio),
|
||||
CONVERT(decimal(18, 4), Costo.Importe),
|
||||
2
|
||||
)
|
||||
) AS SubTotal,
|
||||
SUM(
|
||||
ROUND(
|
||||
CONVERT(decimal(18, 4), D.Cantidad) *
|
||||
CONVERT(decimal(18, 4), PS.Precio) *
|
||||
CONVERT(decimal(18, 6), ISNULL(PS.IVA, 0)) / 100,
|
||||
CONVERT(decimal(18, 4), Costo.Importe) *
|
||||
@PorcentajeIVA,
|
||||
2
|
||||
)
|
||||
) AS IVA
|
||||
@@ -256,6 +256,30 @@ BEGIN
|
||||
ON D.CveTramitePago = P.CveTramitePago
|
||||
INNER JOIN dbo.ProductosServicios AS PS
|
||||
ON PS.CvePS = D.CvePS
|
||||
OUTER APPLY
|
||||
(
|
||||
SELECT TOP (1)
|
||||
CT.Importe
|
||||
FROM dbo.Tra_CostosTramite AS CT
|
||||
WHERE CT.CveTipoTramite = S.CveTipoTramite
|
||||
AND CT.CvePS = D.CvePS
|
||||
AND CT.EsActivo = 1
|
||||
AND
|
||||
(
|
||||
CT.FechaInicioVigencia IS NULL
|
||||
OR CT.FechaInicioVigencia <= CONVERT(date, GETDATE())
|
||||
)
|
||||
AND
|
||||
(
|
||||
CT.FechaFinVigencia IS NULL
|
||||
OR CT.FechaFinVigencia >= CONVERT(date, GETDATE())
|
||||
)
|
||||
ORDER BY
|
||||
ISNULL(
|
||||
CT.FechaInicioVigencia,
|
||||
CONVERT(date, '19000101')) DESC,
|
||||
CT.CveCostoTramite DESC
|
||||
) AS Costo
|
||||
WHERE S.CveFraccionamiento = @CveFraccionamiento
|
||||
AND NOT EXISTS
|
||||
(
|
||||
@@ -555,6 +579,8 @@ BEGIN
|
||||
@Return = 0;
|
||||
|
||||
BEGIN TRY
|
||||
DECLARE @PorcentajeIVA decimal(9, 6) = 0.16;
|
||||
|
||||
SELECT
|
||||
D.CveTramitePagoDetalle,
|
||||
D.CvePS,
|
||||
@@ -585,29 +611,21 @@ BEGIN
|
||||
' - ' +
|
||||
PS.PS COLLATE DATABASE_DEFAULT
|
||||
END AS ProductoServicio,
|
||||
CONVERT(decimal(18, 4), D.Cantidad) AS Cantidad,
|
||||
CONVERT(decimal(18, 2), PS.Precio) AS PrecioUnitario,
|
||||
CONVERT(decimal(18, 4), 1) AS Cantidad,
|
||||
CONVERT(decimal(18, 2), Costo.Importe) AS PrecioUnitario,
|
||||
CONVERT(decimal(18, 2), 0) AS Descuento,
|
||||
CONVERT(
|
||||
decimal(18, 2),
|
||||
ROUND(
|
||||
CONVERT(decimal(18, 4), D.Cantidad) *
|
||||
CONVERT(decimal(18, 4), PS.Precio) *
|
||||
CONVERT(decimal(18, 6), ISNULL(PS.IVA, 0)) / 100,
|
||||
CONVERT(decimal(18, 4), Costo.Importe) *
|
||||
@PorcentajeIVA,
|
||||
2
|
||||
)
|
||||
) AS IVA,
|
||||
CONVERT(
|
||||
decimal(18, 2),
|
||||
ROUND(
|
||||
CONVERT(decimal(18, 4), D.Cantidad) *
|
||||
CONVERT(decimal(18, 4), PS.Precio),
|
||||
2
|
||||
) +
|
||||
ROUND(
|
||||
CONVERT(decimal(18, 4), D.Cantidad) *
|
||||
CONVERT(decimal(18, 4), PS.Precio) *
|
||||
CONVERT(decimal(18, 6), ISNULL(PS.IVA, 0)) / 100,
|
||||
CONVERT(decimal(18, 4), Costo.Importe),
|
||||
2
|
||||
)
|
||||
) AS Importe
|
||||
@@ -620,6 +638,33 @@ BEGIN
|
||||
ON D.CveTramitePago = P.CveTramitePago
|
||||
INNER JOIN dbo.ProductosServicios AS PS
|
||||
ON PS.CvePS = D.CvePS
|
||||
CROSS APPLY
|
||||
(
|
||||
SELECT TOP (1)
|
||||
CT.Importe
|
||||
FROM dbo.Tra_CostosTramite AS CT
|
||||
WHERE CT.CveTipoTramite =
|
||||
(
|
||||
SELECT S.CveTipoTramite
|
||||
FROM dbo.Tra_Solicitudes AS S
|
||||
WHERE S.CveSolicitud = @CveSolicitud
|
||||
)
|
||||
AND CT.CvePS = D.CvePS
|
||||
AND CT.EsActivo = 1
|
||||
AND
|
||||
(
|
||||
CT.FechaInicioVigencia IS NULL
|
||||
OR CT.FechaInicioVigencia <= CONVERT(date, GETDATE())
|
||||
)
|
||||
AND
|
||||
(
|
||||
CT.FechaFinVigencia IS NULL
|
||||
OR CT.FechaFinVigencia >= CONVERT(date, GETDATE())
|
||||
)
|
||||
ORDER BY
|
||||
ISNULL(CT.FechaInicioVigencia, CONVERT(date, '19000101')) DESC,
|
||||
CT.CveCostoTramite DESC
|
||||
) AS Costo
|
||||
INNER JOIN dbo.UnidadesMedida AS UM
|
||||
ON UM.CveUnidadMedida = D.CveUM
|
||||
INNER JOIN dbo.Clasificaciones AS C
|
||||
@@ -669,12 +714,15 @@ BEGIN
|
||||
|
||||
BEGIN TRY
|
||||
DECLARE
|
||||
@PorcentajeIVA decimal(9, 6) = 0.16,
|
||||
@CveVendedor int = 1,
|
||||
@CveCliente int,
|
||||
@CveSubProyecto int,
|
||||
@CveEstatusFactura int,
|
||||
@CveVenta int,
|
||||
@Folio int,
|
||||
@SubTotal decimal(18, 2),
|
||||
@Descuento decimal(18, 2) = 0,
|
||||
@IVA decimal(18, 2),
|
||||
@Total decimal(18, 2),
|
||||
@Fecha datetime = GETDATE();
|
||||
@@ -698,6 +746,43 @@ BEGIN
|
||||
RETURN;
|
||||
END;
|
||||
|
||||
IF EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.Tra_Solicitudes AS S
|
||||
INNER JOIN dbo.Tra_Pagos AS P
|
||||
ON P.CveTramitePago = @CveTramitePago
|
||||
AND P.CveTipoTramite = S.CveTipoTramite
|
||||
AND P.EsActivo = 1
|
||||
INNER JOIN dbo.Tra_PagosDetalle AS D
|
||||
ON D.CveTramitePago = P.CveTramitePago
|
||||
WHERE S.CveSolicitud = @CveSolicitud
|
||||
AND NOT EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.Tra_CostosTramite AS CT
|
||||
WHERE CT.CveTipoTramite = S.CveTipoTramite
|
||||
AND CT.CvePS = D.CvePS
|
||||
AND CT.EsActivo = 1
|
||||
AND
|
||||
(
|
||||
CT.FechaInicioVigencia IS NULL
|
||||
OR CT.FechaInicioVigencia <= CONVERT(date, @Fecha)
|
||||
)
|
||||
AND
|
||||
(
|
||||
CT.FechaFinVigencia IS NULL
|
||||
OR CT.FechaFinVigencia >= CONVERT(date, @Fecha)
|
||||
)
|
||||
)
|
||||
)
|
||||
BEGIN
|
||||
SELECT
|
||||
@ErrorMostrar = 'Uno o más conceptos no tienen un costo vigente configurado.',
|
||||
@ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
|
||||
IF EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
@@ -740,8 +825,7 @@ BEGIN
|
||||
decimal(18, 2),
|
||||
SUM(
|
||||
ROUND(
|
||||
CONVERT(decimal(18, 4), D.Cantidad) *
|
||||
CONVERT(decimal(18, 4), PS.Precio),
|
||||
CONVERT(decimal(18, 4), Costo.Importe),
|
||||
2
|
||||
)
|
||||
)
|
||||
@@ -750,9 +834,8 @@ BEGIN
|
||||
decimal(18, 2),
|
||||
SUM(
|
||||
ROUND(
|
||||
CONVERT(decimal(18, 4), D.Cantidad) *
|
||||
CONVERT(decimal(18, 4), PS.Precio) *
|
||||
CONVERT(decimal(18, 6), ISNULL(PS.IVA, 0)) / 100,
|
||||
CONVERT(decimal(18, 4), Costo.Importe) *
|
||||
@PorcentajeIVA,
|
||||
2
|
||||
)
|
||||
)
|
||||
@@ -760,6 +843,33 @@ BEGIN
|
||||
FROM dbo.Tra_PagosDetalle AS D
|
||||
INNER JOIN dbo.ProductosServicios AS PS
|
||||
ON PS.CvePS = D.CvePS
|
||||
CROSS APPLY
|
||||
(
|
||||
SELECT TOP (1)
|
||||
CT.Importe
|
||||
FROM dbo.Tra_CostosTramite AS CT
|
||||
WHERE CT.CveTipoTramite =
|
||||
(
|
||||
SELECT S.CveTipoTramite
|
||||
FROM dbo.Tra_Solicitudes AS S
|
||||
WHERE S.CveSolicitud = @CveSolicitud
|
||||
)
|
||||
AND CT.CvePS = D.CvePS
|
||||
AND CT.EsActivo = 1
|
||||
AND
|
||||
(
|
||||
CT.FechaInicioVigencia IS NULL
|
||||
OR CT.FechaInicioVigencia <= CONVERT(date, @Fecha)
|
||||
)
|
||||
AND
|
||||
(
|
||||
CT.FechaFinVigencia IS NULL
|
||||
OR CT.FechaFinVigencia >= CONVERT(date, @Fecha)
|
||||
)
|
||||
ORDER BY
|
||||
ISNULL(CT.FechaInicioVigencia, CONVERT(date, '19000101')) DESC,
|
||||
CT.CveCostoTramite DESC
|
||||
) AS Costo
|
||||
WHERE D.CveTramitePago = @CveTramitePago;
|
||||
|
||||
IF @SubTotal IS NULL
|
||||
@@ -771,7 +881,7 @@ BEGIN
|
||||
END;
|
||||
|
||||
SET @IVA = ISNULL(@IVA, 0);
|
||||
SET @Total = @SubTotal + @IVA;
|
||||
SET @Total = @SubTotal - @Descuento + @IVA;
|
||||
|
||||
SELECT
|
||||
@Folio = ISNULL(MAX(Folio), 0) + 1
|
||||
@@ -787,10 +897,12 @@ BEGIN
|
||||
Folio,
|
||||
Fecha,
|
||||
CveCliente,
|
||||
CveVendedor,
|
||||
CveMetodoPago,
|
||||
CondicionesPago,
|
||||
FormaPago,
|
||||
SubTotal,
|
||||
Descuento,
|
||||
IVA,
|
||||
Total,
|
||||
Observaciones,
|
||||
@@ -813,10 +925,12 @@ BEGIN
|
||||
@Folio,
|
||||
@Fecha,
|
||||
@CveCliente,
|
||||
@CveVendedor,
|
||||
2,
|
||||
0,
|
||||
99,
|
||||
@SubTotal,
|
||||
@Descuento,
|
||||
@IVA,
|
||||
@Total,
|
||||
ISNULL(@Observaciones, ''),
|
||||
@@ -854,30 +968,22 @@ BEGIN
|
||||
@CveVenta,
|
||||
D.CvePS,
|
||||
@CveSolicitud,
|
||||
NULL,
|
||||
D.Cantidad,
|
||||
CONVERT(decimal(18, 2), PS.Precio),
|
||||
Costo.CveCostoTramite,
|
||||
CONVERT(decimal(18, 4), 1),
|
||||
CONVERT(decimal(18, 2), Costo.Importe),
|
||||
CONVERT(decimal(18, 2), 0),
|
||||
CONVERT(
|
||||
decimal(18, 2),
|
||||
ROUND(
|
||||
CONVERT(decimal(18, 4), D.Cantidad) *
|
||||
CONVERT(decimal(18, 4), PS.Precio) *
|
||||
CONVERT(decimal(18, 6), ISNULL(PS.IVA, 0)) / 100,
|
||||
CONVERT(decimal(18, 4), Costo.Importe) *
|
||||
@PorcentajeIVA,
|
||||
2
|
||||
)
|
||||
),
|
||||
CONVERT(
|
||||
decimal(18, 2),
|
||||
ROUND(
|
||||
CONVERT(decimal(18, 4), D.Cantidad) *
|
||||
CONVERT(decimal(18, 4), PS.Precio),
|
||||
2
|
||||
) +
|
||||
ROUND(
|
||||
CONVERT(decimal(18, 4), D.Cantidad) *
|
||||
CONVERT(decimal(18, 4), PS.Precio) *
|
||||
CONVERT(decimal(18, 6), ISNULL(PS.IVA, 0)) / 100,
|
||||
CONVERT(decimal(18, 4), Costo.Importe),
|
||||
2
|
||||
)
|
||||
),
|
||||
@@ -887,6 +993,34 @@ BEGIN
|
||||
FROM dbo.Tra_PagosDetalle AS D
|
||||
INNER JOIN dbo.ProductosServicios AS PS
|
||||
ON PS.CvePS = D.CvePS
|
||||
CROSS APPLY
|
||||
(
|
||||
SELECT TOP (1)
|
||||
CT.CveCostoTramite,
|
||||
CT.Importe
|
||||
FROM dbo.Tra_CostosTramite AS CT
|
||||
WHERE CT.CveTipoTramite =
|
||||
(
|
||||
SELECT S.CveTipoTramite
|
||||
FROM dbo.Tra_Solicitudes AS S
|
||||
WHERE S.CveSolicitud = @CveSolicitud
|
||||
)
|
||||
AND CT.CvePS = D.CvePS
|
||||
AND CT.EsActivo = 1
|
||||
AND
|
||||
(
|
||||
CT.FechaInicioVigencia IS NULL
|
||||
OR CT.FechaInicioVigencia <= CONVERT(date, @Fecha)
|
||||
)
|
||||
AND
|
||||
(
|
||||
CT.FechaFinVigencia IS NULL
|
||||
OR CT.FechaFinVigencia >= CONVERT(date, @Fecha)
|
||||
)
|
||||
ORDER BY
|
||||
ISNULL(CT.FechaInicioVigencia, CONVERT(date, '19000101')) DESC,
|
||||
CT.CveCostoTramite DESC
|
||||
) AS Costo
|
||||
WHERE D.CveTramitePago = @CveTramitePago;
|
||||
|
||||
INSERT INTO dbo.Tra_SolicitudesPagos
|
||||
|
||||
2824
Impuestos_Costos_Ventas_Tramites_20260901.sql
Normal file
2824
Impuestos_Costos_Ventas_Tramites_20260901.sql
Normal file
File diff suppressed because it is too large
Load Diff
185
PA_Vta_FraccionamientoPagoPendienteList_Actualizar_20260901.sql
Normal file
185
PA_Vta_FraccionamientoPagoPendienteList_Actualizar_20260901.sql
Normal file
@@ -0,0 +1,185 @@
|
||||
CREATE OR ALTER PROCEDURE dbo.PA_Vta_FraccionamientoPagoPendienteList
|
||||
@CveFraccionamiento int,
|
||||
@CveUsuarioEjecuta int,
|
||||
@ErrorMostrar varchar(max) OUTPUT,
|
||||
@ErrorTipo int OUTPUT,
|
||||
@Return bit OUTPUT
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
|
||||
SELECT
|
||||
@ErrorMostrar = NULL,
|
||||
@ErrorTipo = 0,
|
||||
@Return = 0;
|
||||
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.Fraccionamientos
|
||||
WHERE CveFraccionamiento = @CveFraccionamiento
|
||||
)
|
||||
BEGIN
|
||||
SELECT
|
||||
@ErrorMostrar = 'El fraccionamiento solicitado no existe.',
|
||||
@ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
|
||||
;WITH Conceptos AS
|
||||
(
|
||||
SELECT
|
||||
S.CveSolicitud,
|
||||
P.CveTramitePago,
|
||||
COUNT_BIG(*) AS NumeroConceptos,
|
||||
SUM(
|
||||
ROUND(
|
||||
CONVERT(decimal(18, 4), Costo.Importe),
|
||||
2
|
||||
) * D.Cantidad
|
||||
) AS SubTotal,
|
||||
SUM(
|
||||
ROUND(
|
||||
CONVERT(decimal(18, 4), Costo.Importe)
|
||||
* D.Cantidad
|
||||
* ISNULL(ImpuestoIVA.TasaOCuota, 0),
|
||||
2
|
||||
)
|
||||
) AS IVA
|
||||
FROM dbo.Tra_Solicitudes AS S
|
||||
INNER JOIN dbo.Tra_Pagos AS P
|
||||
ON P.CveTipoTramite = S.CveTipoTramite
|
||||
AND P.EsActivo = 1
|
||||
INNER JOIN dbo.Tra_PagosDetalle AS D
|
||||
ON D.CveTramitePago = P.CveTramitePago
|
||||
INNER JOIN dbo.ProductosServicios AS PS
|
||||
ON PS.CvePS = D.CvePS
|
||||
OUTER APPLY
|
||||
(
|
||||
SELECT TOP (1)
|
||||
CT.CveCostoTramite,
|
||||
CT.Importe
|
||||
FROM dbo.Tra_CostosTramite AS CT
|
||||
WHERE CT.CveTipoTramite = S.CveTipoTramite
|
||||
AND CT.CvePS = D.CvePS
|
||||
AND CT.EsActivo = 1
|
||||
AND
|
||||
(
|
||||
CT.FechaInicioVigencia IS NULL
|
||||
OR CT.FechaInicioVigencia <= CONVERT(date, GETDATE())
|
||||
)
|
||||
AND
|
||||
(
|
||||
CT.FechaFinVigencia IS NULL
|
||||
OR CT.FechaFinVigencia >= CONVERT(date, GETDATE())
|
||||
)
|
||||
ORDER BY
|
||||
ISNULL(
|
||||
CT.FechaInicioVigencia,
|
||||
CONVERT(date, '19000101')) DESC,
|
||||
CT.CveCostoTramite DESC
|
||||
) AS Costo
|
||||
OUTER APPLY
|
||||
(
|
||||
SELECT TOP (1) CTI.TasaOCuota
|
||||
FROM dbo.Tra_CostosTramiteImpuestos AS CTI
|
||||
WHERE CTI.CveCostoTramite = Costo.CveCostoTramite
|
||||
AND CTI.EsRetencion = 0
|
||||
AND CTI.Impuesto = '002'
|
||||
AND CTI.TipoFactor = 'Tasa'
|
||||
) AS ImpuestoIVA
|
||||
WHERE S.CveFraccionamiento = @CveFraccionamiento
|
||||
GROUP BY
|
||||
S.CveSolicitud,
|
||||
P.CveTramitePago
|
||||
)
|
||||
SELECT
|
||||
S.CveSolicitud,
|
||||
P.CveTramitePago,
|
||||
SP.CveVenta,
|
||||
CONVERT(
|
||||
bit,
|
||||
CASE
|
||||
WHEN SP.CveSolicitudPago IS NOT NULL
|
||||
AND V.CveVenta IS NOT NULL THEN 1
|
||||
ELSE 0
|
||||
END
|
||||
) AS VentaGenerada,
|
||||
S.Folio AS FolioSolicitud,
|
||||
E.Etapa,
|
||||
TT.TipoTramite,
|
||||
P.Nombre AS NombrePago,
|
||||
CONVERT(int, C.NumeroConceptos) AS NumeroConceptos,
|
||||
CONVERT(
|
||||
decimal(18, 2),
|
||||
CASE
|
||||
WHEN V.CveVenta IS NULL THEN C.SubTotal
|
||||
ELSE V.SubTotal
|
||||
END
|
||||
) AS SubTotal,
|
||||
CONVERT(
|
||||
decimal(18, 2),
|
||||
CASE
|
||||
WHEN V.CveVenta IS NULL THEN C.IVA
|
||||
ELSE V.IVA
|
||||
END
|
||||
) AS IVA,
|
||||
CONVERT(
|
||||
decimal(18, 2),
|
||||
CASE
|
||||
WHEN V.CveVenta IS NULL THEN C.SubTotal + C.IVA
|
||||
ELSE V.Total
|
||||
END
|
||||
) AS Total
|
||||
FROM Conceptos AS C
|
||||
INNER JOIN dbo.Tra_Solicitudes AS S
|
||||
ON S.CveSolicitud = C.CveSolicitud
|
||||
INNER JOIN dbo.FraccionamientosEtapas AS E
|
||||
ON E.CveFraccionamientoEtapa = S.CveFraccionamientoEtapa
|
||||
INNER JOIN dbo.Tra_TiposTramite AS TT
|
||||
ON TT.CveTipoTramite = S.CveTipoTramite
|
||||
INNER JOIN dbo.Tra_Pagos AS P
|
||||
ON P.CveTramitePago = C.CveTramitePago
|
||||
LEFT JOIN dbo.Tra_SolicitudesPagos AS SP
|
||||
ON SP.CveSolicitud = S.CveSolicitud
|
||||
AND SP.CveTramitePago = P.CveTramitePago
|
||||
LEFT JOIN dbo.Ventas AS V
|
||||
ON V.CveVenta = SP.CveVenta
|
||||
WHERE NOT EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.Vta_Pagos AS VP
|
||||
WHERE VP.CveSolicitud = S.CveSolicitud
|
||||
AND VP.CveTramitePago = P.CveTramitePago
|
||||
AND VP.CveVenta = SP.CveVenta
|
||||
AND VP.EsActivo = 1
|
||||
)
|
||||
ORDER BY
|
||||
E.Orden,
|
||||
S.CveSolicitud,
|
||||
P.Orden,
|
||||
P.CveTramitePago;
|
||||
|
||||
SET @Return = 1;
|
||||
END TRY
|
||||
BEGIN CATCH
|
||||
SELECT
|
||||
@ErrorMostrar = 'Ocurrió un error al consultar los pagos pendientes; favor de contactar a Sistemas.',
|
||||
@ErrorTipo = 1,
|
||||
@Return = 0;
|
||||
|
||||
DECLARE @ErrorTecnico nvarchar(2048) = CONCAT(
|
||||
'Número: ', ERROR_NUMBER(),
|
||||
'; Procedimiento: ', COALESCE(
|
||||
ERROR_PROCEDURE(),
|
||||
'PA_Vta_FraccionamientoPagoPendienteList'
|
||||
),
|
||||
'; Línea: ', ERROR_LINE(),
|
||||
'; Detalle: ', ERROR_MESSAGE()
|
||||
);
|
||||
|
||||
RAISERROR(N'%s', 10, 1, @ErrorTecnico);
|
||||
END CATCH;
|
||||
END;
|
||||
GO
|
||||
144
SIG.Web/App_Code/Handlers/Facturacion/DescargaXmlCfdi.cs
Normal file
144
SIG.Web/App_Code/Handlers/Facturacion/DescargaXmlCfdi.cs
Normal file
@@ -0,0 +1,144 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Web;
|
||||
using System.Web.SessionState;
|
||||
using SIG.Web.AppCode.Configuration;
|
||||
using SIG.Web.AppCode.Models.Common;
|
||||
using SIG.Web.AppCode.Models.Facturacion;
|
||||
using SIG.Web.AppCode.Session;
|
||||
|
||||
namespace SIG.Web.Pages.Facturacion
|
||||
{
|
||||
public sealed class DescargaXmlCfdi
|
||||
: IHttpHandler, IRequiresSessionState
|
||||
{
|
||||
public bool IsReusable
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public void ProcessRequest(HttpContext contexto)
|
||||
{
|
||||
UserSessionModel usuarioActual = ObtenerUsuarioActual();
|
||||
|
||||
if (usuarioActual == null)
|
||||
{
|
||||
EscribirError(
|
||||
contexto,
|
||||
401,
|
||||
"Su sesión no está disponible. Inicie sesión nuevamente.");
|
||||
return;
|
||||
}
|
||||
|
||||
long cveCfdiDocumento;
|
||||
|
||||
if (!IntentarLeerEnteroLargo(
|
||||
contexto.Request.QueryString["documento"],
|
||||
out cveCfdiDocumento))
|
||||
{
|
||||
EscribirError(
|
||||
contexto,
|
||||
400,
|
||||
"El documento CFDI solicitado no es válido.");
|
||||
return;
|
||||
}
|
||||
|
||||
DbResult<ModeloArchivoCfdi> resultado =
|
||||
AppServices.ServicioTimbradoCfdi.ObtenerXml(
|
||||
cveCfdiDocumento,
|
||||
false,
|
||||
usuarioActual.CveUsuario,
|
||||
usuarioActual.NombreDominio);
|
||||
|
||||
if (!resultado.Success ||
|
||||
resultado.Data == null ||
|
||||
resultado.Data.Contenido == null ||
|
||||
resultado.Data.Contenido.Length == 0)
|
||||
{
|
||||
EscribirError(
|
||||
contexto,
|
||||
404,
|
||||
resultado == null ||
|
||||
string.IsNullOrWhiteSpace(resultado.UserMessage)
|
||||
? "No se encontró el XML sin timbrar."
|
||||
: resultado.UserMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
ModeloArchivoCfdi archivo = resultado.Data;
|
||||
byte[] contenido = archivo.Contenido;
|
||||
|
||||
contexto.Response.Clear();
|
||||
contexto.Response.ClearHeaders();
|
||||
contexto.Response.TrySkipIisCustomErrors = true;
|
||||
contexto.Response.Cache.SetCacheability(HttpCacheability.NoCache);
|
||||
contexto.Response.Cache.SetNoStore();
|
||||
contexto.Response.ContentType =
|
||||
string.IsNullOrWhiteSpace(archivo.TipoContenido)
|
||||
? "application/xml"
|
||||
: archivo.TipoContenido;
|
||||
contexto.Response.AddHeader(
|
||||
"Content-Disposition",
|
||||
"attachment; filename=\"" +
|
||||
SanitizarNombreArchivo(archivo.NombreArchivo) +
|
||||
"\"");
|
||||
contexto.Response.AddHeader(
|
||||
"Content-Length",
|
||||
contenido.Length.ToString(CultureInfo.InvariantCulture));
|
||||
contexto.Response.OutputStream.Write(
|
||||
contenido,
|
||||
0,
|
||||
contenido.Length);
|
||||
contexto.ApplicationInstance.CompleteRequest();
|
||||
}
|
||||
|
||||
private static UserSessionModel ObtenerUsuarioActual()
|
||||
{
|
||||
return AppServices.UserContext != null &&
|
||||
AppServices.UserContext.IsAuthenticated()
|
||||
? AppServices.UserContext.GetCurrentUser()
|
||||
: null;
|
||||
}
|
||||
|
||||
private static bool IntentarLeerEnteroLargo(
|
||||
string valor,
|
||||
out long resultado)
|
||||
{
|
||||
return long.TryParse(
|
||||
valor,
|
||||
NumberStyles.Integer,
|
||||
CultureInfo.InvariantCulture,
|
||||
out resultado) &&
|
||||
resultado > 0;
|
||||
}
|
||||
|
||||
private static string SanitizarNombreArchivo(string nombreArchivo)
|
||||
{
|
||||
string nombre = Path.GetFileName(
|
||||
string.IsNullOrWhiteSpace(nombreArchivo)
|
||||
? "CFDI-SinTimbrar.xml"
|
||||
: nombreArchivo);
|
||||
|
||||
return nombre
|
||||
.Replace("\"", string.Empty)
|
||||
.Replace("\r", string.Empty)
|
||||
.Replace("\n", string.Empty);
|
||||
}
|
||||
|
||||
private static void EscribirError(
|
||||
HttpContext contexto,
|
||||
int codigoEstado,
|
||||
string mensaje)
|
||||
{
|
||||
contexto.Response.Clear();
|
||||
contexto.Response.TrySkipIisCustomErrors = true;
|
||||
contexto.Response.StatusCode = codigoEstado;
|
||||
contexto.Response.ContentType = "text/plain";
|
||||
contexto.Response.ContentEncoding =
|
||||
System.Text.Encoding.UTF8;
|
||||
contexto.Response.Write(mensaje);
|
||||
contexto.ApplicationInstance.CompleteRequest();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,11 @@ namespace SIG.Web.AppCode.Models.General
|
||||
public int CveUnidadMedida { get; set; }
|
||||
public string UnidadMedida { get; set; }
|
||||
public decimal Precio { get; set; }
|
||||
public byte CveObjetoImpuesto { get; set; }
|
||||
public string ObjetoImpuesto { get; set; }
|
||||
public string CodigoObjetoImpuesto { get; set; }
|
||||
public decimal? IVA { get; set; }
|
||||
public string TratamientoIVA { get; set; }
|
||||
public bool EsActivo { get; set; }
|
||||
}
|
||||
|
||||
@@ -24,6 +29,7 @@ namespace SIG.Web.AppCode.Models.General
|
||||
{
|
||||
Clasificaciones = new List<ModeloOpcionClasificacionProducto>();
|
||||
UnidadesMedida = new List<ModeloOpcionUnidadMedida>();
|
||||
ObjetosImpuesto = new List<ModeloOpcionObjetoImpuesto>();
|
||||
}
|
||||
|
||||
public List<ModeloOpcionClasificacionProducto> Clasificaciones
|
||||
@@ -37,6 +43,12 @@ namespace SIG.Web.AppCode.Models.General
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public List<ModeloOpcionObjetoImpuesto> ObjetosImpuesto
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class ModeloOpcionClasificacionProducto
|
||||
@@ -50,4 +62,10 @@ namespace SIG.Web.AppCode.Models.General
|
||||
public int CveUnidadMedida { get; set; }
|
||||
public string UnidadMedida { get; set; }
|
||||
}
|
||||
|
||||
public sealed class ModeloOpcionObjetoImpuesto
|
||||
{
|
||||
public byte CveObjetoImpuesto { get; set; }
|
||||
public string ObjetoImpuesto { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,7 +130,15 @@ namespace SIG.Web.AppCode.Models.Tramites
|
||||
public string UnidadMedida { get; set; }
|
||||
public string Abreviatura { get; set; }
|
||||
public decimal Cantidad { get; set; }
|
||||
public decimal Precio { get; set; }
|
||||
public decimal PrecioProducto { get; set; }
|
||||
public decimal Importe { get; set; }
|
||||
public byte CveObjetoImpuesto { get; set; }
|
||||
public string CodigoObjetoImpuesto { get; set; }
|
||||
public string ObjetoImpuesto { get; set; }
|
||||
public decimal PorcentajeIVA { get; set; }
|
||||
public decimal ImporteIVA { get; set; }
|
||||
public DateTime? FechaInicioVigencia { get; set; }
|
||||
public DateTime? FechaFinVigencia { get; set; }
|
||||
public decimal Total { get; set; }
|
||||
|
||||
public string UnidadMedidaTexto
|
||||
@@ -154,6 +162,9 @@ namespace SIG.Web.AppCode.Models.Tramites
|
||||
public string UnidadMedida { get; set; }
|
||||
public string Abreviatura { get; set; }
|
||||
public decimal Precio { get; set; }
|
||||
public byte CveObjetoImpuesto { get; set; }
|
||||
public string CodigoObjetoImpuesto { get; set; }
|
||||
public decimal PorcentajeIVA { get; set; }
|
||||
public bool EsActivo { get; set; }
|
||||
|
||||
public string ProductoDisplay
|
||||
|
||||
@@ -129,6 +129,12 @@ namespace SIG.Web.AppCode.Models.Ventas
|
||||
|
||||
public sealed class ModeloConceptoCfdiVentaTramite
|
||||
{
|
||||
public ModeloConceptoCfdiVentaTramite()
|
||||
{
|
||||
Impuestos = new List<ModeloImpuestoCfdiVentaTramite>();
|
||||
}
|
||||
|
||||
public int CveVentaDetalle { get; set; }
|
||||
public string ClaveProductoServicio { get; set; }
|
||||
public string NumeroIdentificacion { get; set; }
|
||||
public decimal Cantidad { get; set; }
|
||||
@@ -141,6 +147,18 @@ namespace SIG.Web.AppCode.Models.Ventas
|
||||
public decimal BaseIVA { get; set; }
|
||||
public decimal TasaIVA { get; set; }
|
||||
public decimal ImporteIVA { get; set; }
|
||||
public List<ModeloImpuestoCfdiVentaTramite> Impuestos { get; set; }
|
||||
}
|
||||
|
||||
public sealed class ModeloImpuestoCfdiVentaTramite
|
||||
{
|
||||
public int CveVentaDetalle { get; set; }
|
||||
public bool EsRetencion { get; set; }
|
||||
public decimal Base { get; set; }
|
||||
public string Impuesto { get; set; }
|
||||
public string TipoFactor { get; set; }
|
||||
public decimal? TasaOCuota { get; set; }
|
||||
public decimal Importe { get; set; }
|
||||
}
|
||||
|
||||
public sealed class ModeloTimbradoVentaTramite
|
||||
|
||||
@@ -62,7 +62,9 @@ namespace SIG.Web.AppCode.Repositories.Database
|
||||
catch (StoredProcedureException ex)
|
||||
{
|
||||
string diagnostic = StoredProcedureDiagnostics.BuildDiagnostic();
|
||||
if(ex.ErrorType != 1) {
|
||||
ExceptionLogger.Log(CreateDiagnosticException(ex), "DbExecutor.StoredProcedure", ex.UserMessage + diagnostic);
|
||||
}
|
||||
return DbResult<T>.Fail(ex.UserMessage, BuildTechnicalMessage(ex), ex);
|
||||
}
|
||||
catch (SqlException ex)
|
||||
@@ -148,7 +150,7 @@ namespace SIG.Web.AppCode.Repositories.Database
|
||||
}
|
||||
|
||||
return new InvalidOperationException(
|
||||
exception.Message + Environment.NewLine + diagnostic,
|
||||
string.Format("{0}{1}{2}",exception.Message ,Environment.NewLine, diagnostic),
|
||||
exception);
|
||||
}
|
||||
|
||||
|
||||
@@ -87,6 +87,12 @@ namespace SIG.Web.AppCode.Repositories.General
|
||||
lector.ToList<ModeloOpcionUnidadMedida>();
|
||||
}
|
||||
|
||||
if (lector.NextResult())
|
||||
{
|
||||
opciones.ObjetosImpuesto =
|
||||
lector.ToList<ModeloOpcionObjetoImpuesto>();
|
||||
}
|
||||
|
||||
return opciones;
|
||||
});
|
||||
}
|
||||
@@ -135,6 +141,16 @@ namespace SIG.Web.AppCode.Repositories.General
|
||||
"@Precio",
|
||||
productoServicio.Precio,
|
||||
DbType.Decimal);
|
||||
Agregar(
|
||||
comando,
|
||||
"@CveObjetoImpuesto",
|
||||
productoServicio.CveObjetoImpuesto,
|
||||
DbType.Byte);
|
||||
Agregar(
|
||||
comando,
|
||||
"@IVA",
|
||||
productoServicio.IVA,
|
||||
DbType.Decimal);
|
||||
Agregar(
|
||||
comando,
|
||||
"@EsActivo",
|
||||
|
||||
@@ -306,6 +306,18 @@ namespace SIG.Web.AppCode.Repositories.Tramites
|
||||
Add(command, "@CvePS", model.CvePS, DbType.Int32);
|
||||
Add(command, "@CveUM", model.CveUM, DbType.Int32);
|
||||
Add(command, "@Cantidad", model.Cantidad, DbType.Decimal);
|
||||
Add(command, "@Importe", model.Importe, DbType.Decimal);
|
||||
Add(
|
||||
command,
|
||||
"@CveObjetoImpuesto",
|
||||
model.CveObjetoImpuesto,
|
||||
DbType.Byte);
|
||||
Add(
|
||||
command,
|
||||
"@PorcentajeIVA",
|
||||
model.PorcentajeIVA,
|
||||
DbType.Decimal);
|
||||
Add(command, "@FechaInicioVigencia", model.FechaInicioVigencia, DbType.Date);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -361,6 +361,34 @@ namespace SIG.Web.AppCode.Repositories.Ventas
|
||||
lector.ToList<ModeloConceptoCfdiVentaTramite>();
|
||||
}
|
||||
|
||||
if (datos != null && lector.NextResult())
|
||||
{
|
||||
List<ModeloImpuestoCfdiVentaTramite> impuestos =
|
||||
lector.ToList<ModeloImpuestoCfdiVentaTramite>();
|
||||
var conceptosPorDetalle =
|
||||
new Dictionary<int, ModeloConceptoCfdiVentaTramite>();
|
||||
|
||||
foreach (ModeloConceptoCfdiVentaTramite concepto
|
||||
in datos.Conceptos)
|
||||
{
|
||||
conceptosPorDetalle[concepto.CveVentaDetalle] =
|
||||
concepto;
|
||||
}
|
||||
|
||||
foreach (ModeloImpuestoCfdiVentaTramite impuesto
|
||||
in impuestos)
|
||||
{
|
||||
ModeloConceptoCfdiVentaTramite concepto;
|
||||
|
||||
if (conceptosPorDetalle.TryGetValue(
|
||||
impuesto.CveVentaDetalle,
|
||||
out concepto))
|
||||
{
|
||||
concepto.Impuestos.Add(impuesto);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return datos;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -138,7 +138,8 @@ namespace SIG.Web.AppCode.Services.Facturacion
|
||||
if (solicitud.TipoCambio.HasValue)
|
||||
{
|
||||
comprobante.TipoCambio =
|
||||
solicitud.TipoCambio.Value;
|
||||
NormalizarTipoCambio(
|
||||
solicitud.TipoCambio.Value);
|
||||
comprobante.TipoCambioSpecified = true;
|
||||
}
|
||||
|
||||
@@ -260,7 +261,8 @@ namespace SIG.Web.AppCode.Services.Facturacion
|
||||
|
||||
if (!EsExento(impuesto.TipoFactor))
|
||||
{
|
||||
resultado.Importe = impuesto.Importe;
|
||||
resultado.Importe =
|
||||
RedondearMoneda(impuesto.Importe);
|
||||
resultado.ImporteSpecified = true;
|
||||
}
|
||||
|
||||
@@ -325,7 +327,9 @@ namespace SIG.Web.AppCode.Services.Facturacion
|
||||
var traslado =
|
||||
new ComprobanteImpuestosTraslado
|
||||
{
|
||||
Base = grupo.Sum(elemento => elemento.Base),
|
||||
Base = RedondearMoneda(
|
||||
grupo.Sum(
|
||||
elemento => elemento.Base)),
|
||||
Impuesto = grupo.Key.Impuesto,
|
||||
TipoFactor = grupo.Key.TipoFactor
|
||||
};
|
||||
@@ -340,7 +344,9 @@ namespace SIG.Web.AppCode.Services.Facturacion
|
||||
if (!EsExento(grupo.Key.TipoFactor))
|
||||
{
|
||||
traslado.Importe =
|
||||
grupo.Sum(elemento => elemento.Importe);
|
||||
RedondearMoneda(
|
||||
grupo.Sum(
|
||||
elemento => elemento.Importe));
|
||||
traslado.ImporteSpecified = true;
|
||||
}
|
||||
|
||||
@@ -605,6 +611,17 @@ namespace SIG.Web.AppCode.Services.Facturacion
|
||||
MidpointRounding.AwayFromZero);
|
||||
}
|
||||
|
||||
private static decimal NormalizarTipoCambio(decimal tipoCambio)
|
||||
{
|
||||
string valorNormalizado = tipoCambio.ToString(
|
||||
"0.######",
|
||||
System.Globalization.CultureInfo.InvariantCulture);
|
||||
|
||||
return decimal.Parse(
|
||||
valorNormalizado,
|
||||
System.Globalization.CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
private static string TextoOpcional(string valor)
|
||||
{
|
||||
return string.IsNullOrWhiteSpace(valor)
|
||||
|
||||
@@ -92,6 +92,16 @@ namespace SIG.Web.AppCode.Services.General
|
||||
"Precio",
|
||||
ObtenerValor(anterior, elemento => elemento.Precio),
|
||||
actual.Precio),
|
||||
CrearCampo(
|
||||
"CveObjetoImpuesto",
|
||||
ObtenerValor(
|
||||
anterior,
|
||||
elemento => elemento.CveObjetoImpuesto),
|
||||
actual.CveObjetoImpuesto),
|
||||
CrearCampo(
|
||||
"IVA",
|
||||
ObtenerValor(anterior, elemento => elemento.IVA),
|
||||
actual.IVA),
|
||||
CrearCampo(
|
||||
"Estado",
|
||||
ObtenerValor(anterior, elemento => elemento.EsActivo),
|
||||
|
||||
@@ -238,6 +238,20 @@ namespace SIG.Web.AppCode.Services.General
|
||||
return Fallar<int>("El precio no puede ser negativo.");
|
||||
}
|
||||
|
||||
if (productoServicio.CveObjetoImpuesto <= 0)
|
||||
{
|
||||
return Fallar<int>(
|
||||
"Seleccione el objeto de impuesto del producto o servicio.");
|
||||
}
|
||||
|
||||
if (productoServicio.IVA.HasValue &&
|
||||
productoServicio.IVA.Value != -1m &&
|
||||
productoServicio.IVA.Value != 0m)
|
||||
{
|
||||
return Fallar<int>(
|
||||
"Seleccione IVA general o sin IVA.");
|
||||
}
|
||||
|
||||
return DbResult<int>.Ok(productoServicio.CvePS);
|
||||
}
|
||||
|
||||
|
||||
@@ -183,7 +183,15 @@ namespace SIG.Web.AppCode.Services.Tramites
|
||||
Field("CveTramitePago", Value(anterior, item => item.CveTramitePago), actual.CveTramitePago),
|
||||
Field("CvePS", Value(anterior, item => item.CvePS), actual.CvePS),
|
||||
Field("CveUM", Value(anterior, item => item.CveUM), actual.CveUM),
|
||||
Field("Cantidad", Value(anterior, item => item.Cantidad), actual.Cantidad)));
|
||||
Field("Cantidad", Value(anterior, item => item.Cantidad), actual.Cantidad),
|
||||
Field(
|
||||
"CveObjetoImpuesto",
|
||||
Value(anterior, item => item.CveObjetoImpuesto),
|
||||
actual.CveObjetoImpuesto),
|
||||
Field(
|
||||
"PorcentajeIVA",
|
||||
Value(anterior, item => item.PorcentajeIVA),
|
||||
actual.PorcentajeIVA)));
|
||||
|
||||
evento.Relaciones.Add(Relation(
|
||||
"Tra_Pagos",
|
||||
|
||||
@@ -329,10 +329,15 @@ namespace SIG.Web.AppCode.Services.Tramites
|
||||
model.CveTramitePago <= 0 ||
|
||||
model.CvePS <= 0 ||
|
||||
model.CveUM <= 0 ||
|
||||
model.Cantidad <= 0)
|
||||
model.Cantidad <= 0 ||
|
||||
model.Importe < 0 ||
|
||||
model.CveObjetoImpuesto <= 0 ||
|
||||
model.PorcentajeIVA < 0 ||
|
||||
model.PorcentajeIVA > 1 ||
|
||||
!model.FechaInicioVigencia.HasValue)
|
||||
{
|
||||
return Fail<int>(
|
||||
"Seleccione el producto o servicio, la unidad de medida y capture una cantidad mayor que cero.");
|
||||
"Seleccione el producto o servicio, la unidad de medida, el objeto de impuesto y capture una cantidad, un importe, un IVA y una fecha de inicio de vigencia válidos.");
|
||||
}
|
||||
|
||||
return Save(
|
||||
|
||||
@@ -11,6 +11,8 @@ namespace SIG.Web.AppCode.Services.Ventas
|
||||
{
|
||||
public sealed class ServicioVentaTramite : IServicioVentaTramite
|
||||
{
|
||||
private const int CveEmpresaTimbradoPredeterminada = 1;
|
||||
|
||||
private readonly IRepositorioVentaTramite _repositorio;
|
||||
private readonly IServicioTimbradoCfdi _servicioTimbrado;
|
||||
|
||||
@@ -324,13 +326,16 @@ namespace SIG.Web.AppCode.Services.Ventas
|
||||
{
|
||||
if (timbrado == null ||
|
||||
timbrado.CveSolicitud <= 0 ||
|
||||
timbrado.CveTramitePago <= 0 ||
|
||||
timbrado.CveEmpresa <= 0)
|
||||
timbrado.CveTramitePago <= 0)
|
||||
{
|
||||
return Fallar<string>(
|
||||
"Seleccione una venta generada válida para timbrar.");
|
||||
}
|
||||
|
||||
int cveEmpresaTimbrado = timbrado.CveEmpresa > 0
|
||||
? timbrado.CveEmpresa
|
||||
: CveEmpresaTimbradoPredeterminada;
|
||||
|
||||
DbResult<ModeloDatosCfdiVentaTramite> datosResultado =
|
||||
_repositorio.ObtenerDatosCfdi(
|
||||
timbrado.CveSolicitud,
|
||||
@@ -350,7 +355,7 @@ namespace SIG.Web.AppCode.Services.Ventas
|
||||
ModeloDatosCfdiVentaTramite datos = datosResultado.Data;
|
||||
ModeloSolicitudCfdi solicitud = CrearSolicitudCfdi(
|
||||
datos,
|
||||
timbrado.CveEmpresa);
|
||||
cveEmpresaTimbrado);
|
||||
DbResult<long> borradorResultado =
|
||||
_servicioTimbrado.GuardarBorrador(
|
||||
solicitud,
|
||||
@@ -536,17 +541,18 @@ namespace SIG.Web.AppCode.Services.Ventas
|
||||
ObjetoImpuesto = origen.ObjetoImpuesto
|
||||
};
|
||||
|
||||
if (origen.ObjetoImpuesto != "01")
|
||||
foreach (ModeloImpuestoCfdiVentaTramite impuesto
|
||||
in origen.Impuestos)
|
||||
{
|
||||
concepto.Impuestos.Add(
|
||||
new ModeloImpuestoConceptoCfdi
|
||||
{
|
||||
EsRetencion = false,
|
||||
Base = origen.BaseIVA,
|
||||
Impuesto = "002",
|
||||
TipoFactor = "Tasa",
|
||||
TasaOCuota = origen.TasaIVA,
|
||||
Importe = origen.ImporteIVA
|
||||
EsRetencion = impuesto.EsRetencion,
|
||||
Base = impuesto.Base,
|
||||
Impuesto = impuesto.Impuesto,
|
||||
TipoFactor = impuesto.TipoFactor,
|
||||
TasaOCuota = impuesto.TasaOCuota,
|
||||
Importe = impuesto.Importe
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><cfdi:Comprobante xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Moneda="MXN" TipoCambio="1" Total="2000.00" xsi:schemaLocation="http://www.sat.gob.mx/cfd/4 http://www.sat.gob.mx/sitio_internet/cfd/4/cfdv40.xsd" Exportacion="01" MetodoPago="PPD" TipoDeComprobante="I" SubTotal="2000.00" Sello="s24IV21tMl2+E6eeDSq9FEaNF8sA2AaPX3bmjafU76ItSVn8ojWP4c5+9uJIJ1y0q03K7GcBo53xQ/5cSmpP9x9LggAo6jQyMnNiMS9CJUQ4LXUajJMnUyzyIJiIrfZst+cfauBsxzL+nv1cnRmDp+47VHJ14oegYXKlF+avb3HhBz63dBjSHa0x1J84+v/e8h7HoO1zdOOwGjOuhXFn93Ok+rgBiFoZhuLMUGw5zphRsf0DtzqpG1TCwIGAp7YyAZTDN27+icgkl0NzJrRrhIqTzaMx2Q+rTdzSPTjLsYGEtKIdzDcD/DDdZ/TB/3ANXVr5/gFcYNebVi+oMSmS6w==" Certificado="MIIFsDCCA5igAwIBAgIUMzAwMDEwMDAwMDA1MDAwMDM0MTYwDQYJKoZIhvcNAQELBQAwggErMQ8wDQYDVQQDDAZBQyBVQVQxLjAsBgNVBAoMJVNFUlZJQ0lPIERFIEFETUlOSVNUUkFDSU9OIFRSSUJVVEFSSUExGjAYBgNVBAsMEVNBVC1JRVMgQXV0aG9yaXR5MSgwJgYJKoZIhvcNAQkBFhlvc2Nhci5tYXJ0aW5lekBzYXQuZ29iLm14MR0wGwYDVQQJDBQzcmEgY2VycmFkYSBkZSBjYWxpejEOMAwGA1UEEQwFMDYzNzAxCzAJBgNVBAYTAk1YMRkwFwYDVQQIDBBDSVVEQUQgREUgTUVYSUNPMREwDwYDVQQHDAhDT1lPQUNBTjERMA8GA1UELRMIMi41LjQuNDUxJTAjBgkqhkiG9w0BCQITFnJlc3BvbnNhYmxlOiBBQ0RNQS1TQVQwHhcNMjMwNTE4MTE0MzUxWhcNMjcwNTE4MTE0MzUxWjCB1zEnMCUGA1UEAxMeRVNDVUVMQSBLRU1QRVIgVVJHQVRFIFNBIERFIENWMScwJQYDVQQpEx5FU0NVRUxBIEtFTVBFUiBVUkdBVEUgU0EgREUgQ1YxJzAlBgNVBAoTHkVTQ1VFTEEgS0VNUEVSIFVSR0FURSBTQSBERSBDVjElMCMGA1UELRMcRUtVOTAwMzE3M0M5IC8gVkFEQTgwMDkyN0RKMzEeMBwGA1UEBRMVIC8gVkFEQTgwMDkyN0hTUlNSTDA1MRMwEQYDVQQLEwpTdWN1cnNhbCAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtmecO6n2GS0zL025gbHGQVxznPDICoXzR2uUngz4DqxVUC/w9cE6FxSiXm2ap8Gcjg7wmcZfm85EBaxCx/0J2u5CqnhzIoGCdhBPuhWQnIh5TLgj/X6uNquwZkKChbNe9aeFirU/JbyN7Egia9oKH9KZUsodiM/pWAH00PCtoKJ9OBcSHMq8Rqa3KKoBcfkg1ZrgueffwRLws9yOcRWLb02sDOPzGIm/jEFicVYt2Hw1qdRE5xmTZ7AGG0UHs+unkGjpCVeJ+BEBn0JPLWVvDKHZAQMj6s5Bku35+d/MyATkpOPsGT/VTnsouxekDfikJD1f7A1ZpJbqDpkJnss3vQIDAQABox0wGzAMBgNVHRMBAf8EAjAAMAsGA1UdDwQEAwIGwDANBgkqhkiG9w0BAQsFAAOCAgEAFaUgj5PqgvJigNMgtrdXZnbPfVBbukAbW4OGnUhNrA7SRAAfv2BSGk16PI0nBOr7qF2mItmBnjgEwk+DTv8Zr7w5qp7vleC6dIsZFNJoa6ZndrE/f7KO1CYruLXr5gwEkIyGfJ9NwyIagvHHMszzyHiSZIA850fWtbqtythpAliJ2jF35M5pNS+YTkRB+T6L/c6m00ymN3q9lT1rB03YywxrLreRSFZOSrbwWfg34EJbHfbFXpCSVYdJRfiVdvHnewN0r5fUlPtR9stQHyuqewzdkyb5jTTw02D2cUfL57vlPStBj7SEi3uOWvLrsiDnnCIxRMYJ2UA2ktDKHk+zWnsDmaeleSzonv2CHW42yXYPCvWi88oE1DJNYLNkIjua7MxAnkNZbScNw01A6zbLsZ3y8G6eEYnxSTRfwjd8EP4kdiHNJftm7Z4iRU7HOVh79/lRWB+gd171s3d/mI9kte3MRy6V8MMEMCAnMboGpaooYwgAmwclI2XZCczNWXfhaWe0ZS5PmytD/GDpXzkX0oEgY9K/uYo5V77NdZbGAjmyi8cE2B2ogvyaN2XfIInrZPgEffJ4AB7kFA2mwesdLOCh0BLD9itmCve3A1FGR4+stO2ANUoiI3w3Tv2yQSg4bjeDlJ08lXaaFCLW2peEXMXjQUk7fmpb5MNuOUTW6BE=" NoCertificado="30001000000500003416" FormaPago="99" LugarExpedicion="42501" Fecha="2026-09-01T16:44:07" Folio="1" Serie="TRA" Version="4.0" xmlns:cfdi="http://www.sat.gob.mx/cfd/4"><cfdi:Emisor Rfc="EKU9003173C9" Nombre="ESCUELA KEMPER URGATE" RegimenFiscal="601" /><cfdi:Receptor Rfc="EKU9003173C9" Nombre="ESCUELA KEMPER URGATE" DomicilioFiscalReceptor="42501" RegimenFiscalReceptor="601" UsoCFDI="G03" /><cfdi:Conceptos><cfdi:Concepto ClaveProdServ="83101500" NoIdentificacion="00001" Cantidad="1.0000" ClaveUnidad="MTQ" Unidad="NO APLICA" Descripcion="Pago adelantado de derechos y aportaciones" ValorUnitario="2000.00" Importe="2000.000000" ObjetoImp="01" /></cfdi:Conceptos><cfdi:Complemento><tfd:TimbreFiscalDigital xsi:schemaLocation="http://www.sat.gob.mx/TimbreFiscalDigital http://www.sat.gob.mx/sitio_internet/cfd/TimbreFiscalDigital/TimbreFiscalDigitalv11.xsd" FechaTimbrado="2026-09-01T19:30:26" NoCertificadoSAT="30001000000500003456" RfcProvCertif="SPR190613I52" SelloCFD="s24IV21tMl2+E6eeDSq9FEaNF8sA2AaPX3bmjafU76ItSVn8ojWP4c5+9uJIJ1y0q03K7GcBo53xQ/5cSmpP9x9LggAo6jQyMnNiMS9CJUQ4LXUajJMnUyzyIJiIrfZst+cfauBsxzL+nv1cnRmDp+47VHJ14oegYXKlF+avb3HhBz63dBjSHa0x1J84+v/e8h7HoO1zdOOwGjOuhXFn93Ok+rgBiFoZhuLMUGw5zphRsf0DtzqpG1TCwIGAp7YyAZTDN27+icgkl0NzJrRrhIqTzaMx2Q+rTdzSPTjLsYGEtKIdzDcD/DDdZ/TB/3ANXVr5/gFcYNebVi+oMSmS6w==" SelloSAT="QG0Bzz9PrmELg2w5bVc+hFOAn52CZzaV1kKjZhYUFEcOKMg9mSb34g9TGYqlYtvXmBJcKjL27Q8L4htXMCYP5Uya7alS9wWSiiZkrFyDxzkuHkydUPnCqU9g/RdCHG80lgXxt8Ov3lOLFZYZWme8GLlhcFa2Ns528dp+jTg2Rxz9SfmzIsHepoufgXcWvGFgb+D5OPOKxnOenN3TS26Om6l+tErghx0EzvdBZI5LKsjspDv7X8VQGIQ3OwWASp3KS/iyB3/nnxzcRrXk3Cumw2M8fsuvd1GA3MoZ1vzAWh0Wz58XcNfTVHdIISJfpIrggTB6V8VrtjKDqrX2XUcT/g==" UUID="b203381c-7cd4-4298-93ce-c6a4bd168bad" Version="1.1" xmlns:tfd="http://www.sat.gob.mx/TimbreFiscalDigital" /></cfdi:Complemento></cfdi:Comprobante>
|
||||
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><cfdi:Comprobante xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Moneda="MXN" TipoCambio="1" Total="2320.00" xsi:schemaLocation="http://www.sat.gob.mx/cfd/4 http://www.sat.gob.mx/sitio_internet/cfd/4/cfdv40.xsd" Exportacion="01" MetodoPago="PPD" TipoDeComprobante="I" SubTotal="2000.00" Sello="UHzBuYL6HzjxQtncPYnZI6OPwEMFSFwvdsO2c6gyjAtYTqCQKyCt3h24z3zEBFlfroDgvXVi7t9uON/Xa+0S518QhWjopkPwISueMQ6OW+sPunnH9Cs8fyk0kaFI56Q6EpK5HU5dEy9wGbeyAKNEkitT3ktLaVx0WB1WNUWM+EJlXmqvdi6GVHOfcbXiBM1LgkzS0S3T3u/+kFgqQyDYuNz5cvcXCzVHZ2m1s2MOEA05CazdazuL/5Y5hGJd2d0HbQMd2JPlCQwxeRbx7LvprD2+c8f3QQYdkOHZMiNUdfKijr/7kbr7cWpizRVAU1AU7jchjvZozCM7chsnahezag==" Certificado="MIIFsDCCA5igAwIBAgIUMzAwMDEwMDAwMDA1MDAwMDM0MTYwDQYJKoZIhvcNAQELBQAwggErMQ8wDQYDVQQDDAZBQyBVQVQxLjAsBgNVBAoMJVNFUlZJQ0lPIERFIEFETUlOSVNUUkFDSU9OIFRSSUJVVEFSSUExGjAYBgNVBAsMEVNBVC1JRVMgQXV0aG9yaXR5MSgwJgYJKoZIhvcNAQkBFhlvc2Nhci5tYXJ0aW5lekBzYXQuZ29iLm14MR0wGwYDVQQJDBQzcmEgY2VycmFkYSBkZSBjYWxpejEOMAwGA1UEEQwFMDYzNzAxCzAJBgNVBAYTAk1YMRkwFwYDVQQIDBBDSVVEQUQgREUgTUVYSUNPMREwDwYDVQQHDAhDT1lPQUNBTjERMA8GA1UELRMIMi41LjQuNDUxJTAjBgkqhkiG9w0BCQITFnJlc3BvbnNhYmxlOiBBQ0RNQS1TQVQwHhcNMjMwNTE4MTE0MzUxWhcNMjcwNTE4MTE0MzUxWjCB1zEnMCUGA1UEAxMeRVNDVUVMQSBLRU1QRVIgVVJHQVRFIFNBIERFIENWMScwJQYDVQQpEx5FU0NVRUxBIEtFTVBFUiBVUkdBVEUgU0EgREUgQ1YxJzAlBgNVBAoTHkVTQ1VFTEEgS0VNUEVSIFVSR0FURSBTQSBERSBDVjElMCMGA1UELRMcRUtVOTAwMzE3M0M5IC8gVkFEQTgwMDkyN0RKMzEeMBwGA1UEBRMVIC8gVkFEQTgwMDkyN0hTUlNSTDA1MRMwEQYDVQQLEwpTdWN1cnNhbCAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtmecO6n2GS0zL025gbHGQVxznPDICoXzR2uUngz4DqxVUC/w9cE6FxSiXm2ap8Gcjg7wmcZfm85EBaxCx/0J2u5CqnhzIoGCdhBPuhWQnIh5TLgj/X6uNquwZkKChbNe9aeFirU/JbyN7Egia9oKH9KZUsodiM/pWAH00PCtoKJ9OBcSHMq8Rqa3KKoBcfkg1ZrgueffwRLws9yOcRWLb02sDOPzGIm/jEFicVYt2Hw1qdRE5xmTZ7AGG0UHs+unkGjpCVeJ+BEBn0JPLWVvDKHZAQMj6s5Bku35+d/MyATkpOPsGT/VTnsouxekDfikJD1f7A1ZpJbqDpkJnss3vQIDAQABox0wGzAMBgNVHRMBAf8EAjAAMAsGA1UdDwQEAwIGwDANBgkqhkiG9w0BAQsFAAOCAgEAFaUgj5PqgvJigNMgtrdXZnbPfVBbukAbW4OGnUhNrA7SRAAfv2BSGk16PI0nBOr7qF2mItmBnjgEwk+DTv8Zr7w5qp7vleC6dIsZFNJoa6ZndrE/f7KO1CYruLXr5gwEkIyGfJ9NwyIagvHHMszzyHiSZIA850fWtbqtythpAliJ2jF35M5pNS+YTkRB+T6L/c6m00ymN3q9lT1rB03YywxrLreRSFZOSrbwWfg34EJbHfbFXpCSVYdJRfiVdvHnewN0r5fUlPtR9stQHyuqewzdkyb5jTTw02D2cUfL57vlPStBj7SEi3uOWvLrsiDnnCIxRMYJ2UA2ktDKHk+zWnsDmaeleSzonv2CHW42yXYPCvWi88oE1DJNYLNkIjua7MxAnkNZbScNw01A6zbLsZ3y8G6eEYnxSTRfwjd8EP4kdiHNJftm7Z4iRU7HOVh79/lRWB+gd171s3d/mI9kte3MRy6V8MMEMCAnMboGpaooYwgAmwclI2XZCczNWXfhaWe0ZS5PmytD/GDpXzkX0oEgY9K/uYo5V77NdZbGAjmyi8cE2B2ogvyaN2XfIInrZPgEffJ4AB7kFA2mwesdLOCh0BLD9itmCve3A1FGR4+stO2ANUoiI3w3Tv2yQSg4bjeDlJ08lXaaFCLW2peEXMXjQUk7fmpb5MNuOUTW6BE=" NoCertificado="30001000000500003416" FormaPago="99" LugarExpedicion="42501" Fecha="2026-09-01T20:08:03" Folio="2" Serie="TRA" Version="4.0" xmlns:cfdi="http://www.sat.gob.mx/cfd/4"><cfdi:Emisor Rfc="EKU9003173C9" Nombre="ESCUELA KEMPER URGATE" RegimenFiscal="601" /><cfdi:Receptor Rfc="EKU9003173C9" Nombre="ESCUELA KEMPER URGATE" DomicilioFiscalReceptor="42501" RegimenFiscalReceptor="601" UsoCFDI="G03" /><cfdi:Conceptos><cfdi:Concepto ClaveProdServ="83101500" NoIdentificacion="00001" Cantidad="1.0000" ClaveUnidad="MTQ" Unidad="NO APLICA" Descripcion="Pago adelantado de derechos y aportaciones" ValorUnitario="2000.00" Importe="2000.000000" ObjetoImp="02"><cfdi:Impuestos><cfdi:Traslados><cfdi:Traslado Base="2000.000000" Impuesto="002" TipoFactor="Tasa" TasaOCuota="0.160000" Importe="320.00" /></cfdi:Traslados></cfdi:Impuestos></cfdi:Concepto></cfdi:Conceptos><cfdi:Impuestos TotalImpuestosTrasladados="320.00"><cfdi:Traslados><cfdi:Traslado Base="2000.00" Impuesto="002" TipoFactor="Tasa" TasaOCuota="0.160000" Importe="320.00" /></cfdi:Traslados></cfdi:Impuestos><cfdi:Complemento><tfd:TimbreFiscalDigital xsi:schemaLocation="http://www.sat.gob.mx/TimbreFiscalDigital http://www.sat.gob.mx/sitio_internet/cfd/TimbreFiscalDigital/TimbreFiscalDigitalv11.xsd" FechaTimbrado="2026-09-01T21:46:46" NoCertificadoSAT="30001000000500003456" RfcProvCertif="SPR190613I52" SelloCFD="UHzBuYL6HzjxQtncPYnZI6OPwEMFSFwvdsO2c6gyjAtYTqCQKyCt3h24z3zEBFlfroDgvXVi7t9uON/Xa+0S518QhWjopkPwISueMQ6OW+sPunnH9Cs8fyk0kaFI56Q6EpK5HU5dEy9wGbeyAKNEkitT3ktLaVx0WB1WNUWM+EJlXmqvdi6GVHOfcbXiBM1LgkzS0S3T3u/+kFgqQyDYuNz5cvcXCzVHZ2m1s2MOEA05CazdazuL/5Y5hGJd2d0HbQMd2JPlCQwxeRbx7LvprD2+c8f3QQYdkOHZMiNUdfKijr/7kbr7cWpizRVAU1AU7jchjvZozCM7chsnahezag==" SelloSAT="LD+t3J1eJ2Lldc/OYJv0kcHl0u/tLsqf4nLABwr/D6Mt/j5TPOpW3qnKsCZox1sMYzm9SCdaDqE3QWvRn5zSx+Wok5AOnmU3Ci+X3exJs3434jQOpqsQzf6YUX0V3S3JWOgpL4x9BlNueXNgY0tssH5tqOMxsIC73bK4OXemMJSeZGzzlerKZQBQuEYlONGPgB1CcDu6ps1w9aVRp3EB8nbOf6rJYWUHYD4N1qBswsyRXEGtYDuxpsXSDZ/wVntWlTbWtix1jJfn3SUsfpYURwayioVyZc/52C5Z3UA1pXCO+6JAin7Q8OjunuiHDaDr8zFX81UHgdc49yaP4mDsbQ==" UUID="d4d1a16b-3ae2-43e6-985a-7f01596b6050" Version="1.1" xmlns:tfd="http://www.sat.gob.mx/TimbreFiscalDigital" /></cfdi:Complemento></cfdi:Comprobante>
|
||||
@@ -65,6 +65,10 @@
|
||||
HeaderText="Precio"
|
||||
DataFormatString="{0:N2}"
|
||||
ItemStyle-HorizontalAlign="Right" />
|
||||
<asp:BoundField DataField="ObjetoImpuesto"
|
||||
HeaderText="Objeto de impuesto" />
|
||||
<asp:BoundField DataField="TratamientoIVA"
|
||||
HeaderText="IVA" />
|
||||
<asp:CheckBoxField DataField="EsActivo" HeaderText="Activo" />
|
||||
<asp:TemplateField HeaderText="Acciones">
|
||||
<ItemTemplate>
|
||||
@@ -276,6 +280,34 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<div class="tra-modal-field">
|
||||
<label for="<%= DdlObjetoImpuesto.ClientID %>">
|
||||
Objeto de impuesto *
|
||||
</label>
|
||||
<asp:DropDownList ID="DdlObjetoImpuesto"
|
||||
runat="server"
|
||||
CssClass="form-control input-sm select2me"
|
||||
DataTextField="ObjetoImpuesto"
|
||||
DataValueField="CveObjetoImpuesto" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="tra-modal-field">
|
||||
<label for="<%= DdlTratamientoIva.ClientID %>">
|
||||
Tratamiento de IVA *
|
||||
</label>
|
||||
<asp:DropDownList ID="DdlTratamientoIva"
|
||||
runat="server"
|
||||
CssClass="form-control input-sm select2me">
|
||||
<asp:ListItem Text="IVA general" Value="-1" />
|
||||
<asp:ListItem Text="Sin IVA" Value="0" />
|
||||
</asp:DropDownList>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button"
|
||||
|
||||
@@ -126,6 +126,8 @@ namespace SIG.Web.Pages.Catalogos
|
||||
TxtDescripcion.Text = string.Empty;
|
||||
DdlTipo.SelectedValue = string.Empty;
|
||||
TxtPrecio.Text = "0.00";
|
||||
SeleccionarValor(DdlObjetoImpuesto, "2");
|
||||
SeleccionarValor(DdlTratamientoIva, "-1");
|
||||
ChkActivo.Checked = true;
|
||||
UpEdicion.Update();
|
||||
MostrarModal("ModalEdit");
|
||||
@@ -224,12 +226,22 @@ namespace SIG.Web.Pages.Catalogos
|
||||
int tipo;
|
||||
int clasificacion;
|
||||
int unidadMedida;
|
||||
byte cveObjetoImpuesto;
|
||||
decimal iva;
|
||||
|
||||
int.TryParse(DdlTipo.SelectedValue, out tipo);
|
||||
int.TryParse(DdlClasificacion.SelectedValue, out clasificacion);
|
||||
int.TryParse(
|
||||
DdlUnidadMedida.SelectedValue,
|
||||
out unidadMedida);
|
||||
byte.TryParse(
|
||||
DdlObjetoImpuesto.SelectedValue,
|
||||
out cveObjetoImpuesto);
|
||||
decimal.TryParse(
|
||||
DdlTratamientoIva.SelectedValue,
|
||||
NumberStyles.Number,
|
||||
CultureInfo.InvariantCulture,
|
||||
out iva);
|
||||
|
||||
var productoServicio = new ModeloProductoServicio
|
||||
{
|
||||
@@ -240,6 +252,8 @@ namespace SIG.Web.Pages.Catalogos
|
||||
CveClasificacion = clasificacion,
|
||||
CveUnidadMedida = unidadMedida,
|
||||
Precio = precio,
|
||||
CveObjetoImpuesto = cveObjetoImpuesto,
|
||||
IVA = iva,
|
||||
EsActivo = ChkActivo.Checked
|
||||
};
|
||||
|
||||
@@ -317,6 +331,16 @@ namespace SIG.Web.Pages.Catalogos
|
||||
DdlUnidadMedida,
|
||||
productoServicio.CveUnidadMedida.ToString(
|
||||
CultureInfo.InvariantCulture));
|
||||
SeleccionarValor(
|
||||
DdlObjetoImpuesto,
|
||||
productoServicio.CveObjetoImpuesto.ToString(
|
||||
CultureInfo.InvariantCulture));
|
||||
SeleccionarValor(
|
||||
DdlTratamientoIva,
|
||||
productoServicio.IVA.HasValue &&
|
||||
productoServicio.IVA.Value == 0m
|
||||
? "0"
|
||||
: "-1");
|
||||
TxtPrecio.Text = productoServicio.Precio.ToString(
|
||||
"0.00",
|
||||
CultureInfo.CurrentCulture);
|
||||
@@ -357,6 +381,12 @@ namespace SIG.Web.Pages.Catalogos
|
||||
0,
|
||||
new ListItem("Seleccione", string.Empty));
|
||||
|
||||
DdlObjetoImpuesto.DataSource = opciones.ObjetosImpuesto;
|
||||
DdlObjetoImpuesto.DataBind();
|
||||
DdlObjetoImpuesto.Items.Insert(
|
||||
0,
|
||||
new ListItem("Seleccione", string.Empty));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -471,8 +471,17 @@
|
||||
NullDisplayText="—" />
|
||||
<asp:BoundField DataField="Cantidad" HeaderText="Cantidad"
|
||||
DataFormatString="{0:N4}" />
|
||||
<asp:BoundField DataField="Precio" HeaderText="Precio"
|
||||
<asp:BoundField DataField="Importe" HeaderText="Importe vigente"
|
||||
DataFormatString="{0:C2}" HtmlEncode="false" />
|
||||
<asp:BoundField DataField="ObjetoImpuesto"
|
||||
HeaderText="Objeto de impuesto" />
|
||||
<asp:BoundField DataField="PorcentajeIVA"
|
||||
HeaderText="IVA"
|
||||
DataFormatString="{0:P2}" />
|
||||
<asp:BoundField DataField="ImporteIVA"
|
||||
HeaderText="Importe IVA"
|
||||
DataFormatString="{0:C2}"
|
||||
HtmlEncode="false" />
|
||||
<asp:BoundField DataField="Total" HeaderText="Total"
|
||||
DataFormatString="{0:C2}" HtmlEncode="false" />
|
||||
<asp:TemplateField HeaderText="Acciones">
|
||||
@@ -486,15 +495,6 @@
|
||||
ToolTip="Editar concepto">
|
||||
<i class="fa fa-pencil"></i>
|
||||
</asp:LinkButton>
|
||||
<asp:LinkButton ID="BtnEditGlobalPrice"
|
||||
runat="server"
|
||||
CssClass="btn btn-circle btn-xs yellow"
|
||||
CommandName="EditarPrecioGlobal"
|
||||
CommandArgument='<%# Eval("CveTramitePagoDetalle") %>'
|
||||
CausesValidation="false"
|
||||
ToolTip="Editar precio global del producto o servicio">
|
||||
<i class="fa fa-dollar"></i>
|
||||
</asp:LinkButton>
|
||||
<asp:LinkButton ID="BtnDeletePaymentDetail"
|
||||
runat="server"
|
||||
CssClass="btn btn-circle btn-xs red"
|
||||
@@ -806,6 +806,49 @@
|
||||
Use una cantidad mayor que cero; se permiten hasta cuatro decimales.
|
||||
</span>
|
||||
</div>
|
||||
<div class="tra-modal-field">
|
||||
<label>Importe antes de IVA *</label>
|
||||
<asp:TextBox ID="TxtPaymentDetailAmount"
|
||||
runat="server"
|
||||
CssClass="form-control"
|
||||
MaxLength="20" />
|
||||
<span class="help-block">
|
||||
Al seleccionar el producto se propone su precio unitario actual.
|
||||
Los cambios posteriores generan una nueva vigencia para el trámite.
|
||||
</span>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-7">
|
||||
<div class="tra-modal-field">
|
||||
<label for="<%= DdlObjetoImpuestoDetallePago.ClientID %>">
|
||||
Objeto de impuesto *
|
||||
</label>
|
||||
<asp:DropDownList ID="DdlObjetoImpuestoDetallePago"
|
||||
runat="server"
|
||||
CssClass="form-control select2me"
|
||||
Width="100%">
|
||||
<asp:ListItem Text="Seleccione" Value="" />
|
||||
<asp:ListItem Text="01 - No objeto de impuesto" Value="1" />
|
||||
<asp:ListItem Text="02 - Sí objeto de impuesto" Value="2" />
|
||||
<asp:ListItem Text="03 - Sí objeto y no obligado al desglose" Value="3" />
|
||||
</asp:DropDownList>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-5">
|
||||
<div class="tra-modal-field">
|
||||
<label for="<%= TxtPorcentajeIvaDetallePago.ClientID %>">
|
||||
IVA (%) *
|
||||
</label>
|
||||
<asp:TextBox ID="TxtPorcentajeIvaDetallePago"
|
||||
runat="server"
|
||||
CssClass="form-control"
|
||||
MaxLength="10" />
|
||||
<span class="help-block">
|
||||
Capture 16 para una tasa del 16%.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn default" data-dismiss="modal">Cancelar</button>
|
||||
@@ -827,60 +870,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="ModalGlobalPrice" class="modal fade" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
<asp:UpdatePanel ID="UpGlobalPriceModal" runat="server"
|
||||
UpdateMode="Conditional" ChildrenAsTriggers="false">
|
||||
<ContentTemplate>
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||
<h4 class="modal-title">Actualizar precio global</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="alert alert-warning tra-global-price-warning">
|
||||
<i class="fa fa-warning"></i>
|
||||
<div>
|
||||
<strong>Este cambio es global.</strong>
|
||||
<p>
|
||||
El nuevo precio modificará directamente el producto o servicio y
|
||||
afectará todos los módulos que lo utilicen.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tra-modal-field">
|
||||
<label>Producto o servicio</label>
|
||||
<p class="form-control-static">
|
||||
<asp:Literal ID="LitGlobalPriceProduct" runat="server" />
|
||||
</p>
|
||||
</div>
|
||||
<div class="tra-modal-field">
|
||||
<label>Nuevo precio *</label>
|
||||
<asp:TextBox ID="TxtGlobalPrice"
|
||||
runat="server"
|
||||
CssClass="form-control"
|
||||
MaxLength="20" />
|
||||
</div>
|
||||
<asp:CheckBox ID="ChkConfirmGlobalPrice"
|
||||
runat="server"
|
||||
Text=" Confirmo que este precio cambiará a nivel global" />
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn default" data-dismiss="modal">Cancelar</button>
|
||||
<asp:Button ID="BtnSaveGlobalPrice"
|
||||
runat="server"
|
||||
CssClass="btn yellow"
|
||||
Text="Actualizar precio global"
|
||||
OnClick="BtnSaveGlobalPrice_Click" />
|
||||
</div>
|
||||
</div>
|
||||
</ContentTemplate>
|
||||
<Triggers>
|
||||
<asp:AsyncPostBackTrigger ControlID="BtnSaveGlobalPrice" EventName="Click" />
|
||||
</Triggers>
|
||||
</asp:UpdatePanel>
|
||||
</div>
|
||||
</div>
|
||||
</asp:Content>
|
||||
|
||||
<asp:Content ID="ContentScripts" ContentPlaceHolderID="J" runat="server">
|
||||
|
||||
@@ -65,12 +65,6 @@ namespace SIG.Web.Pages.Catalogos
|
||||
set { ViewState["CveTramitePagoDetalleActual"] = value; }
|
||||
}
|
||||
|
||||
private int CveProductoPrecioActual
|
||||
{
|
||||
get { return ViewState["CveProductoPrecioActual"] as int? ?? 0; }
|
||||
set { ViewState["CveProductoPrecioActual"] = value; }
|
||||
}
|
||||
|
||||
private List<ModeloProductoServicioTramite>
|
||||
ProductosServiciosDisponibles
|
||||
{
|
||||
@@ -700,6 +694,9 @@ namespace SIG.Web.Pages.Catalogos
|
||||
DdlProductService.SelectedIndex = 0;
|
||||
DdlUnidadMedidaDetallePago.SelectedIndex = 0;
|
||||
TxtPaymentDetailQuantity.Text = "1";
|
||||
TxtPaymentDetailAmount.Text = string.Empty;
|
||||
DdlObjetoImpuestoDetallePago.SelectedIndex = 0;
|
||||
TxtPorcentajeIvaDetallePago.Text = "16.00";
|
||||
UpPaymentDetailModal.Update();
|
||||
Show("ModalPaymentDetail");
|
||||
}
|
||||
@@ -719,10 +716,6 @@ namespace SIG.Web.Pages.Catalogos
|
||||
{
|
||||
EditPaymentDetail(id);
|
||||
}
|
||||
else if (e.CommandName == "EditarPrecioGlobal")
|
||||
{
|
||||
EditGlobalPrice(id);
|
||||
}
|
||||
else if (e.CommandName == "EliminarDetalle")
|
||||
{
|
||||
DeletePaymentDetail(id);
|
||||
@@ -735,6 +728,9 @@ namespace SIG.Web.Pages.Catalogos
|
||||
int cveProductoServicio;
|
||||
int cveUnidadMedida;
|
||||
decimal cantidad;
|
||||
decimal importe;
|
||||
byte cveObjetoImpuesto;
|
||||
decimal porcentajeIvaCapturado;
|
||||
if (!int.TryParse(
|
||||
DdlProductService.SelectedValue,
|
||||
out cveProductoServicio) ||
|
||||
@@ -746,10 +742,23 @@ namespace SIG.Web.Pages.Catalogos
|
||||
!TryParseDecimal(
|
||||
TxtPaymentDetailQuantity.Text,
|
||||
out cantidad) ||
|
||||
cantidad <= 0)
|
||||
cantidad <= 0 ||
|
||||
!TryParseDecimal(
|
||||
TxtPaymentDetailAmount.Text,
|
||||
out importe) ||
|
||||
importe < 0 ||
|
||||
!byte.TryParse(
|
||||
DdlObjetoImpuestoDetallePago.SelectedValue,
|
||||
out cveObjetoImpuesto) ||
|
||||
cveObjetoImpuesto <= 0 ||
|
||||
!TryParseDecimal(
|
||||
TxtPorcentajeIvaDetallePago.Text,
|
||||
out porcentajeIvaCapturado) ||
|
||||
porcentajeIvaCapturado < 0 ||
|
||||
porcentajeIvaCapturado > 100)
|
||||
{
|
||||
Alert(
|
||||
"Seleccione el producto o servicio, la unidad de medida y capture una cantidad mayor que cero.",
|
||||
"Seleccione el producto o servicio, la unidad de medida y el objeto de impuesto; capture una cantidad, un importe y un IVA válidos.",
|
||||
TipoMensaje.MsgAdvertencia);
|
||||
Show("ModalPaymentDetail");
|
||||
return;
|
||||
@@ -761,7 +770,15 @@ namespace SIG.Web.Pages.Catalogos
|
||||
CveTramitePago = CveTramitePagoSeleccionado,
|
||||
CvePS = cveProductoServicio,
|
||||
CveUM = cveUnidadMedida,
|
||||
Cantidad = decimal.Round(cantidad, 4)
|
||||
Cantidad = decimal.Round(cantidad, 4),
|
||||
Importe = decimal.Round(importe, 2),
|
||||
CveObjetoImpuesto = cveObjetoImpuesto,
|
||||
PorcentajeIVA = cveObjetoImpuesto == 1
|
||||
? 0m
|
||||
: decimal.Round(
|
||||
porcentajeIvaCapturado / 100m,
|
||||
6),
|
||||
FechaInicioVigencia = DateTime.Today
|
||||
};
|
||||
|
||||
DbResult<int> result =
|
||||
@@ -799,6 +816,9 @@ namespace SIG.Web.Pages.Catalogos
|
||||
cveProductoServicio <= 0)
|
||||
{
|
||||
DdlUnidadMedidaDetallePago.SelectedIndex = 0;
|
||||
TxtPaymentDetailAmount.Text = string.Empty;
|
||||
DdlObjetoImpuestoDetallePago.SelectedIndex = 0;
|
||||
TxtPorcentajeIvaDetallePago.Text = "16.00";
|
||||
UpPaymentDetailModal.Update();
|
||||
Show("ModalPaymentDetail");
|
||||
return;
|
||||
@@ -813,6 +833,9 @@ namespace SIG.Web.Pages.Catalogos
|
||||
productoServicio.CveUnidadMedida <= 0)
|
||||
{
|
||||
DdlUnidadMedidaDetallePago.SelectedIndex = 0;
|
||||
TxtPaymentDetailAmount.Text = string.Empty;
|
||||
DdlObjetoImpuestoDetallePago.SelectedIndex = 0;
|
||||
TxtPorcentajeIvaDetallePago.Text = "16.00";
|
||||
UpPaymentDetailModal.Update();
|
||||
Show("ModalPaymentDetail");
|
||||
return;
|
||||
@@ -821,58 +844,22 @@ namespace SIG.Web.Pages.Catalogos
|
||||
SelectDropDownValue(
|
||||
DdlUnidadMedidaDetallePago,
|
||||
productoServicio.CveUnidadMedida);
|
||||
TxtPaymentDetailAmount.Text =
|
||||
productoServicio.Precio.ToString(
|
||||
"0.00",
|
||||
CultureInfo.InvariantCulture);
|
||||
SelectDropDownValue(
|
||||
DdlObjetoImpuestoDetallePago,
|
||||
productoServicio.CveObjetoImpuesto);
|
||||
TxtPorcentajeIvaDetallePago.Text =
|
||||
(productoServicio.PorcentajeIVA * 100m).ToString(
|
||||
"0.####",
|
||||
CultureInfo.InvariantCulture);
|
||||
|
||||
UpPaymentDetailModal.Update();
|
||||
Show("ModalPaymentDetail");
|
||||
}
|
||||
|
||||
protected void BtnSaveGlobalPrice_Click(object sender, EventArgs e)
|
||||
{
|
||||
SetActiveTab(2);
|
||||
decimal price;
|
||||
if (!ChkConfirmGlobalPrice.Checked)
|
||||
{
|
||||
Alert(
|
||||
"Confirme que comprende que el precio cambiará a nivel global.",
|
||||
TipoMensaje.MsgAdvertencia);
|
||||
Show("ModalGlobalPrice");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!TryParseDecimal(TxtGlobalPrice.Text, out price) ||
|
||||
price < 0)
|
||||
{
|
||||
Alert(
|
||||
"Capture un precio válido mayor o igual que cero.",
|
||||
TipoMensaje.MsgAdvertencia);
|
||||
Show("ModalGlobalPrice");
|
||||
return;
|
||||
}
|
||||
|
||||
DbResult<int> result =
|
||||
AppServices.TramiteCatalogService.UpdateProductoServicioPrecio(
|
||||
CveProductoPrecioActual,
|
||||
decimal.Round(price, 2),
|
||||
CurrentUser.CveUsuario,
|
||||
CurrentUser.NombreDominio);
|
||||
|
||||
if (!result.Success)
|
||||
{
|
||||
Alert(result.UserMessage, TipoMensaje.MsgAdvertencia);
|
||||
Show("ModalGlobalPrice");
|
||||
return;
|
||||
}
|
||||
|
||||
BindProducts();
|
||||
BindPayments();
|
||||
BindPaymentDetails();
|
||||
UpTabs.Update();
|
||||
Hide("ModalGlobalPrice");
|
||||
Alert(
|
||||
"Precio global actualizado correctamente.",
|
||||
TipoMensaje.ToastExito);
|
||||
}
|
||||
|
||||
private void LoadProcedure()
|
||||
{
|
||||
DbResult<TipoTramiteModel> result =
|
||||
@@ -1426,6 +1413,17 @@ namespace SIG.Web.Pages.Catalogos
|
||||
result.Data.Cantidad.ToString(
|
||||
"0.####",
|
||||
CultureInfo.InvariantCulture);
|
||||
TxtPaymentDetailAmount.Text =
|
||||
result.Data.Importe.ToString(
|
||||
"0.00",
|
||||
CultureInfo.InvariantCulture);
|
||||
SelectDropDownValue(
|
||||
DdlObjetoImpuestoDetallePago,
|
||||
result.Data.CveObjetoImpuesto);
|
||||
TxtPorcentajeIvaDetallePago.Text =
|
||||
(result.Data.PorcentajeIVA * 100m).ToString(
|
||||
"0.####",
|
||||
CultureInfo.InvariantCulture);
|
||||
BindPaymentDetails();
|
||||
UpPaymentDetailModal.Update();
|
||||
Show("ModalPaymentDetail");
|
||||
@@ -1453,48 +1451,6 @@ namespace SIG.Web.Pages.Catalogos
|
||||
TipoMensaje.ToastExito);
|
||||
}
|
||||
|
||||
private void EditGlobalPrice(int paymentDetailId)
|
||||
{
|
||||
DbResult<TramitePagoDetalleModel> detailResult =
|
||||
AppServices.TramiteCatalogService.GetPagoDetalle(
|
||||
paymentDetailId,
|
||||
CurrentUser.CveUsuario,
|
||||
CurrentUser.NombreDominio);
|
||||
|
||||
if (!detailResult.Success || detailResult.Data == null)
|
||||
{
|
||||
Alert(
|
||||
detailResult.UserMessage,
|
||||
TipoMensaje.MsgAdvertencia);
|
||||
return;
|
||||
}
|
||||
|
||||
DbResult<ModeloProductoServicioTramite> productResult =
|
||||
AppServices.TramiteCatalogService.GetProductoServicio(
|
||||
detailResult.Data.CvePS,
|
||||
CurrentUser.CveUsuario,
|
||||
CurrentUser.NombreDominio);
|
||||
|
||||
if (!productResult.Success || productResult.Data == null)
|
||||
{
|
||||
Alert(
|
||||
productResult.UserMessage,
|
||||
TipoMensaje.MsgAdvertencia);
|
||||
return;
|
||||
}
|
||||
|
||||
CveProductoPrecioActual = productResult.Data.CvePS;
|
||||
LitGlobalPriceProduct.Text =
|
||||
Server.HtmlEncode(productResult.Data.ProductoDisplay);
|
||||
TxtGlobalPrice.Text =
|
||||
productResult.Data.Precio.ToString(
|
||||
"0.00",
|
||||
CultureInfo.InvariantCulture);
|
||||
ChkConfirmGlobalPrice.Checked = false;
|
||||
UpGlobalPriceModal.Update();
|
||||
Show("ModalGlobalPrice");
|
||||
}
|
||||
|
||||
private void ClearOptionsPanel()
|
||||
{
|
||||
CvePreguntaOpcionesSeleccionada = 0;
|
||||
|
||||
@@ -185,7 +185,7 @@
|
||||
HtmlEncode="false" />
|
||||
<asp:BoundField
|
||||
DataField="Importe"
|
||||
HeaderText="Total"
|
||||
HeaderText="Importe"
|
||||
DataFormatString="{0:C2}"
|
||||
HtmlEncode="false" />
|
||||
<asp:TemplateField HeaderText="Acciones">
|
||||
@@ -359,6 +359,24 @@
|
||||
<i class="fa fa-file-text-o"></i>
|
||||
Generar
|
||||
</asp:LinkButton>
|
||||
<asp:LinkButton ID="BtnTimbrar"
|
||||
runat="server"
|
||||
CssClass="btn purple venta-boton-pagar"
|
||||
CausesValidation="false"
|
||||
OnClick="BtnTimbrar_Click"
|
||||
OnClientClick="return window.SIGAlerts.confirmPostBack(this, '¿Desea timbrar esta venta?');">
|
||||
<i class="fa fa-certificate"></i>
|
||||
Timbrar
|
||||
</asp:LinkButton>
|
||||
|
||||
<asp:HyperLink ID="LnkDescargarXmlSinTimbrar"
|
||||
runat="server"
|
||||
CssClass="btn default venta-boton-pagar"
|
||||
Target="_blank"
|
||||
Visible="false">
|
||||
<i class="fa fa-download"></i>
|
||||
Descargar XML sin timbrar
|
||||
</asp:HyperLink>
|
||||
|
||||
<asp:LinkButton ID="BtnPagar"
|
||||
runat="server"
|
||||
@@ -369,15 +387,6 @@
|
||||
Pagar
|
||||
</asp:LinkButton>
|
||||
|
||||
<asp:LinkButton ID="BtnTimbrar"
|
||||
runat="server"
|
||||
CssClass="btn purple venta-boton-pagar"
|
||||
CausesValidation="false"
|
||||
OnClick="BtnTimbrar_Click"
|
||||
OnClientClick="return window.SIGAlerts.confirmPostBack(this, '¿Desea timbrar esta venta?');">
|
||||
<i class="fa fa-certificate"></i>
|
||||
Timbrar
|
||||
</asp:LinkButton>
|
||||
|
||||
<asp:Panel ID="PnlCancelarTimbre"
|
||||
runat="server"
|
||||
|
||||
@@ -648,16 +648,14 @@ namespace SIG.Web.Pages.Ventas
|
||||
GvConceptos.DataBind();
|
||||
|
||||
decimal subtotal = conceptos.Sum(
|
||||
concepto =>
|
||||
Math.Round(
|
||||
concepto.Cantidad * concepto.PrecioUnitario,
|
||||
2));
|
||||
concepto => concepto.Importe);
|
||||
decimal descuento = conceptos.Sum(
|
||||
concepto => concepto.Descuento);
|
||||
decimal iva = conceptos.Sum(
|
||||
concepto => concepto.IVA);
|
||||
decimal total = conceptos.Sum(
|
||||
concepto => concepto.Importe);
|
||||
decimal total = Math.Round(
|
||||
subtotal - descuento + iva,
|
||||
2);
|
||||
|
||||
TotalVentaActual = total;
|
||||
|
||||
@@ -689,6 +687,16 @@ namespace SIG.Web.Pages.Ventas
|
||||
venta.VentaGenerada &&
|
||||
!venta.VentaTimbrada &&
|
||||
TienePermiso(PermisoTimbrar);
|
||||
LnkDescargarXmlSinTimbrar.Visible =
|
||||
venta.CveCfdiDocumento.HasValue &&
|
||||
venta.CveCfdiDocumento.Value > 0;
|
||||
LnkDescargarXmlSinTimbrar.NavigateUrl =
|
||||
LnkDescargarXmlSinTimbrar.Visible
|
||||
? ResolveUrl(
|
||||
"~/DescargaXmlCfdi.ashx?documento=" +
|
||||
venta.CveCfdiDocumento.Value.ToString(
|
||||
CultureInfo.InvariantCulture))
|
||||
: string.Empty;
|
||||
PnlCancelarTimbre.Visible =
|
||||
venta.VentaTimbrada &&
|
||||
TienePermiso(PermisoCancelarTimbre);
|
||||
|
||||
@@ -242,7 +242,7 @@
|
||||
|
||||
.venta-boton-pagar {
|
||||
align-self: stretch;
|
||||
margin: auto 20px;
|
||||
margin: 10px 20px !important;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
<add key="SmtpPassword" value="nzwt zrnc zcvq ztpx" />
|
||||
<add key="EmailFrom" value="notificaciones@sig.adssistemas.mx" />
|
||||
<add key="EmailFromDisplayName" value="Agua de Hermosillo" />
|
||||
<add key="CredencialPacProfactPruebas" value="mvpNUXmQfK8=" />
|
||||
<!-- reCAPTCHA v2: al desactivarlo no se muestra ni se valida. La clave secreta nunca se envía al navegador. -->
|
||||
<add key="RecaptchaEnabled" value="true" />
|
||||
<add key="RecaptchaSiteKey" value="6LeVOFQtAAAAAOxZKnBiKFlnMnd90aR1PwJmUGgJ" />
|
||||
@@ -79,6 +80,7 @@
|
||||
<handlers>
|
||||
<add name="PdfViewerHandler" path="SigPdfViewerHandler.ashx" verb="*" type="SIG.Web.AppCode.SigControls.PDFViewer.PdfViewerHandler" resourceType="Unspecified" />
|
||||
<add name="PdfViewerUploadHandler" path="SigPdfViewerUploadHandler.ashx" verb="POST" type="SIG.Web.AppCode.SigControls.PDFViewer.PdfViewerUploadHandler" resourceType="Unspecified" />
|
||||
<add name="DescargaXmlCfdi" path="DescargaXmlCfdi.ashx" verb="GET" type="SIG.Web.Pages.Facturacion.DescargaXmlCfdi" resourceType="Unspecified" />
|
||||
</handlers>
|
||||
<defaultDocument enabled="true">
|
||||
<files>
|
||||
|
||||
@@ -6,8 +6,9 @@ GO
|
||||
|
||||
Tra_Pagos agrupa conceptos de cobro para un tipo de trámite.
|
||||
Tra_PagosDetalle relaciona cada grupo con ProductosServicios.
|
||||
El precio no se duplica en el detalle: siempre se obtiene de
|
||||
ProductosServicios.Precio para que el total refleje el precio global vigente.
|
||||
El importe aplicable al trámite se conserva por vigencias en
|
||||
Tra_CostosTramite. ProductosServicios.Precio se usa únicamente como
|
||||
valor inicial cuando todavía no existe un costo para el trámite.
|
||||
*/
|
||||
|
||||
IF OBJECT_ID(N'dbo.Tra_Pagos', N'U') IS NULL
|
||||
@@ -132,6 +133,88 @@ BEGIN
|
||||
END;
|
||||
GO
|
||||
|
||||
DECLARE @CveMonedaPesos int;
|
||||
|
||||
SELECT TOP (1) @CveMonedaPesos = CveMoneda
|
||||
FROM dbo.Gral_Monedas
|
||||
WHERE Estatus = 1
|
||||
AND
|
||||
(
|
||||
Abreviatura = 'MXN'
|
||||
OR AbreviaturaSAT = 'MXN'
|
||||
)
|
||||
ORDER BY
|
||||
CASE WHEN Abreviatura = 'MXN' THEN 0 ELSE 1 END,
|
||||
CveMoneda;
|
||||
|
||||
IF @CveMonedaPesos IS NULL
|
||||
BEGIN
|
||||
THROW 50001,
|
||||
'No se encuentra configurada la moneda MXN para inicializar los costos de los trámites.',
|
||||
1;
|
||||
END;
|
||||
|
||||
;WITH CostosIniciales AS
|
||||
(
|
||||
SELECT
|
||||
P.CveTipoTramite,
|
||||
D.CvePS,
|
||||
LEFT(PS.PS, 300) AS Descripcion,
|
||||
CONVERT(decimal(18, 2), PS.Precio) AS Importe,
|
||||
MIN(D.CveUsuario) AS CveUsuario
|
||||
FROM dbo.Tra_PagosDetalle AS D
|
||||
INNER JOIN dbo.Tra_Pagos AS P
|
||||
ON P.CveTramitePago = D.CveTramitePago
|
||||
INNER JOIN dbo.ProductosServicios AS PS
|
||||
ON PS.CvePS = D.CvePS
|
||||
WHERE NOT EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.Tra_CostosTramite AS CT
|
||||
WHERE CT.CveTipoTramite = P.CveTipoTramite
|
||||
AND CT.CvePS = D.CvePS
|
||||
AND CT.EsActivo = 1
|
||||
AND CT.FechaFinVigencia IS NULL
|
||||
)
|
||||
GROUP BY
|
||||
P.CveTipoTramite,
|
||||
D.CvePS,
|
||||
PS.PS,
|
||||
PS.Precio
|
||||
)
|
||||
INSERT dbo.Tra_CostosTramite
|
||||
(
|
||||
CveTipoTramite,
|
||||
CvePS,
|
||||
CveMoneda,
|
||||
Descripcion,
|
||||
Importe,
|
||||
FechaInicioVigencia,
|
||||
FechaFinVigencia,
|
||||
EsActivo,
|
||||
CveUsuario
|
||||
)
|
||||
SELECT
|
||||
CI.CveTipoTramite,
|
||||
CI.CvePS,
|
||||
@CveMonedaPesos,
|
||||
CI.Descripcion,
|
||||
CI.Importe,
|
||||
CONVERT(date, GETDATE()),
|
||||
NULL,
|
||||
1,
|
||||
CI.CveUsuario
|
||||
FROM CostosIniciales AS CI
|
||||
WHERE NOT EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.Tra_CostosTramite AS CT
|
||||
WHERE CT.CveTipoTramite = CI.CveTipoTramite
|
||||
AND CT.CvePS = CI.CvePS
|
||||
AND CT.FechaInicioVigencia = CONVERT(date, GETDATE())
|
||||
);
|
||||
GO
|
||||
|
||||
CREATE OR ALTER PROCEDURE dbo.PA_Tra_PagoList
|
||||
@CveTipoTramite int,
|
||||
@IncluirInactivos bit = 1,
|
||||
@@ -145,22 +228,7 @@ BEGIN
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.Sis_Usuarios
|
||||
WHERE CveUsuario = @CveUsuarioEjecuta
|
||||
AND CveRol IN (1, 2)
|
||||
AND Activo = 1
|
||||
)
|
||||
BEGIN
|
||||
SELECT
|
||||
@ErrorMostrar = 'No cuenta con permiso para consultar los pagos del trámite.',
|
||||
@ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
|
||||
SELECT
|
||||
SELECT
|
||||
P.CveTramitePago,
|
||||
P.CveTipoTramite,
|
||||
T.TipoTramite,
|
||||
@@ -178,7 +246,9 @@ BEGIN
|
||||
SUM
|
||||
(
|
||||
CONVERT(decimal(18, 4), D.Cantidad)
|
||||
* CONVERT(decimal(18, 2), PS.Precio)
|
||||
* CONVERT(
|
||||
decimal(18, 2),
|
||||
COALESCE(Costo.Importe, PS.Precio))
|
||||
),
|
||||
0
|
||||
)
|
||||
@@ -190,6 +260,28 @@ BEGIN
|
||||
ON D.CveTramitePago = P.CveTramitePago
|
||||
LEFT JOIN dbo.ProductosServicios AS PS
|
||||
ON PS.CvePS = D.CvePS
|
||||
OUTER APPLY
|
||||
(
|
||||
SELECT TOP (1)
|
||||
CT.Importe
|
||||
FROM dbo.Tra_CostosTramite AS CT
|
||||
WHERE CT.CveTipoTramite = P.CveTipoTramite
|
||||
AND CT.CvePS = D.CvePS
|
||||
AND CT.EsActivo = 1
|
||||
AND
|
||||
(
|
||||
CT.FechaInicioVigencia IS NULL
|
||||
OR CT.FechaInicioVigencia <= CONVERT(date, GETDATE())
|
||||
)
|
||||
AND
|
||||
(
|
||||
CT.FechaFinVigencia IS NULL
|
||||
OR CT.FechaFinVigencia >= CONVERT(date, GETDATE())
|
||||
)
|
||||
ORDER BY
|
||||
ISNULL(CT.FechaInicioVigencia, CONVERT(date, '19000101')) DESC,
|
||||
CT.CveCostoTramite DESC
|
||||
) AS Costo
|
||||
WHERE P.CveTipoTramite = @CveTipoTramite
|
||||
AND (@IncluirInactivos = 1 OR P.EsActivo = 1)
|
||||
GROUP BY
|
||||
@@ -234,22 +326,7 @@ BEGIN
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.Sis_Usuarios
|
||||
WHERE CveUsuario = @CveUsuarioEjecuta
|
||||
AND CveRol IN (1, 2)
|
||||
AND Activo = 1
|
||||
)
|
||||
BEGIN
|
||||
SELECT
|
||||
@ErrorMostrar = 'No cuenta con permiso para consultar el pago.',
|
||||
@ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
|
||||
SELECT
|
||||
SELECT
|
||||
P.CveTramitePago,
|
||||
P.CveTipoTramite,
|
||||
T.TipoTramite,
|
||||
@@ -267,7 +344,9 @@ BEGIN
|
||||
SUM
|
||||
(
|
||||
CONVERT(decimal(18, 4), D.Cantidad)
|
||||
* CONVERT(decimal(18, 2), PS.Precio)
|
||||
* CONVERT(
|
||||
decimal(18, 2),
|
||||
COALESCE(Costo.Importe, PS.Precio))
|
||||
),
|
||||
0
|
||||
)
|
||||
@@ -279,6 +358,28 @@ BEGIN
|
||||
ON D.CveTramitePago = P.CveTramitePago
|
||||
LEFT JOIN dbo.ProductosServicios AS PS
|
||||
ON PS.CvePS = D.CvePS
|
||||
OUTER APPLY
|
||||
(
|
||||
SELECT TOP (1)
|
||||
CT.Importe
|
||||
FROM dbo.Tra_CostosTramite AS CT
|
||||
WHERE CT.CveTipoTramite = P.CveTipoTramite
|
||||
AND CT.CvePS = D.CvePS
|
||||
AND CT.EsActivo = 1
|
||||
AND
|
||||
(
|
||||
CT.FechaInicioVigencia IS NULL
|
||||
OR CT.FechaInicioVigencia <= CONVERT(date, GETDATE())
|
||||
)
|
||||
AND
|
||||
(
|
||||
CT.FechaFinVigencia IS NULL
|
||||
OR CT.FechaFinVigencia >= CONVERT(date, GETDATE())
|
||||
)
|
||||
ORDER BY
|
||||
ISNULL(CT.FechaInicioVigencia, CONVERT(date, '19000101')) DESC,
|
||||
CT.CveCostoTramite DESC
|
||||
) AS Costo
|
||||
WHERE P.CveTramitePago = @CveTramitePago
|
||||
GROUP BY
|
||||
P.CveTramitePago,
|
||||
@@ -326,22 +427,7 @@ BEGIN
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.Sis_Usuarios
|
||||
WHERE CveUsuario = @CveUsuarioEjecuta
|
||||
AND CveRol IN (1, 2)
|
||||
AND Activo = 1
|
||||
)
|
||||
BEGIN
|
||||
SELECT
|
||||
@ErrorMostrar = 'No cuenta con permiso para modificar los pagos del trámite.',
|
||||
@ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
|
||||
SELECT
|
||||
SELECT
|
||||
@Nombre = LTRIM(RTRIM(@Nombre)),
|
||||
@Notas = NULLIF(LTRIM(RTRIM(@Notas)), '');
|
||||
|
||||
@@ -460,22 +546,7 @@ BEGIN
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.Sis_Usuarios
|
||||
WHERE CveUsuario = @CveUsuarioEjecuta
|
||||
AND CveRol IN (1, 2)
|
||||
AND Activo = 1
|
||||
)
|
||||
BEGIN
|
||||
SELECT
|
||||
@ErrorMostrar = 'No cuenta con permiso para eliminar el pago.',
|
||||
@ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
|
||||
IF EXISTS
|
||||
IF EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.Tra_PagosDetalle
|
||||
@@ -522,22 +593,7 @@ BEGIN
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.Sis_Usuarios
|
||||
WHERE CveUsuario = @CveUsuarioEjecuta
|
||||
AND CveRol IN (1, 2)
|
||||
AND Activo = 1
|
||||
)
|
||||
BEGIN
|
||||
SELECT
|
||||
@ErrorMostrar = 'No cuenta con permiso para consultar los conceptos del pago.',
|
||||
@ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
|
||||
SELECT
|
||||
SELECT
|
||||
D.CveTramitePagoDetalle,
|
||||
D.CveTramitePago,
|
||||
P.Nombre AS Pago,
|
||||
@@ -548,18 +604,50 @@ BEGIN
|
||||
UM.UnidadMedida,
|
||||
UM.Abreviatura,
|
||||
D.Cantidad,
|
||||
CONVERT(decimal(18, 2), PS.Precio) AS Precio,
|
||||
CONVERT(decimal(18, 2), PS.Precio) AS PrecioProducto,
|
||||
CONVERT(
|
||||
decimal(18, 2),
|
||||
COALESCE(Costo.Importe, PS.Precio)
|
||||
) AS Importe,
|
||||
Costo.FechaInicioVigencia,
|
||||
Costo.FechaFinVigencia,
|
||||
CONVERT
|
||||
(
|
||||
decimal(18, 2),
|
||||
CONVERT(decimal(18, 4), D.Cantidad)
|
||||
* CONVERT(decimal(18, 2), PS.Precio)
|
||||
* CONVERT(
|
||||
decimal(18, 2),
|
||||
COALESCE(Costo.Importe, PS.Precio))
|
||||
) AS Total
|
||||
FROM dbo.Tra_PagosDetalle AS D
|
||||
INNER JOIN dbo.Tra_Pagos AS P
|
||||
ON P.CveTramitePago = D.CveTramitePago
|
||||
INNER JOIN dbo.ProductosServicios AS PS
|
||||
ON PS.CvePS = D.CvePS
|
||||
OUTER APPLY
|
||||
(
|
||||
SELECT TOP (1)
|
||||
CT.Importe,
|
||||
CT.FechaInicioVigencia,
|
||||
CT.FechaFinVigencia
|
||||
FROM dbo.Tra_CostosTramite AS CT
|
||||
WHERE CT.CveTipoTramite = P.CveTipoTramite
|
||||
AND CT.CvePS = D.CvePS
|
||||
AND CT.EsActivo = 1
|
||||
AND
|
||||
(
|
||||
CT.FechaInicioVigencia IS NULL
|
||||
OR CT.FechaInicioVigencia <= CONVERT(date, GETDATE())
|
||||
)
|
||||
AND
|
||||
(
|
||||
CT.FechaFinVigencia IS NULL
|
||||
OR CT.FechaFinVigencia >= CONVERT(date, GETDATE())
|
||||
)
|
||||
ORDER BY
|
||||
ISNULL(CT.FechaInicioVigencia, CONVERT(date, '19000101')) DESC,
|
||||
CT.CveCostoTramite DESC
|
||||
) AS Costo
|
||||
LEFT JOIN dbo.UnidadesMedida AS UM
|
||||
ON UM.CveUnidadMedida = D.CveUM
|
||||
WHERE D.CveTramitePago = @CveTramitePago
|
||||
@@ -596,22 +684,7 @@ BEGIN
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.Sis_Usuarios
|
||||
WHERE CveUsuario = @CveUsuarioEjecuta
|
||||
AND CveRol IN (1, 2)
|
||||
AND Activo = 1
|
||||
)
|
||||
BEGIN
|
||||
SELECT
|
||||
@ErrorMostrar = 'No cuenta con permiso para consultar el concepto del pago.',
|
||||
@ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
|
||||
SELECT
|
||||
SELECT
|
||||
D.CveTramitePagoDetalle,
|
||||
D.CveTramitePago,
|
||||
P.Nombre AS Pago,
|
||||
@@ -622,18 +695,50 @@ BEGIN
|
||||
UM.UnidadMedida,
|
||||
UM.Abreviatura,
|
||||
D.Cantidad,
|
||||
CONVERT(decimal(18, 2), PS.Precio) AS Precio,
|
||||
CONVERT(decimal(18, 2), PS.Precio) AS PrecioProducto,
|
||||
CONVERT(
|
||||
decimal(18, 2),
|
||||
COALESCE(Costo.Importe, PS.Precio)
|
||||
) AS Importe,
|
||||
Costo.FechaInicioVigencia,
|
||||
Costo.FechaFinVigencia,
|
||||
CONVERT
|
||||
(
|
||||
decimal(18, 2),
|
||||
CONVERT(decimal(18, 4), D.Cantidad)
|
||||
* CONVERT(decimal(18, 2), PS.Precio)
|
||||
* CONVERT(
|
||||
decimal(18, 2),
|
||||
COALESCE(Costo.Importe, PS.Precio))
|
||||
) AS Total
|
||||
FROM dbo.Tra_PagosDetalle AS D
|
||||
INNER JOIN dbo.Tra_Pagos AS P
|
||||
ON P.CveTramitePago = D.CveTramitePago
|
||||
INNER JOIN dbo.ProductosServicios AS PS
|
||||
ON PS.CvePS = D.CvePS
|
||||
OUTER APPLY
|
||||
(
|
||||
SELECT TOP (1)
|
||||
CT.Importe,
|
||||
CT.FechaInicioVigencia,
|
||||
CT.FechaFinVigencia
|
||||
FROM dbo.Tra_CostosTramite AS CT
|
||||
WHERE CT.CveTipoTramite = P.CveTipoTramite
|
||||
AND CT.CvePS = D.CvePS
|
||||
AND CT.EsActivo = 1
|
||||
AND
|
||||
(
|
||||
CT.FechaInicioVigencia IS NULL
|
||||
OR CT.FechaInicioVigencia <= CONVERT(date, GETDATE())
|
||||
)
|
||||
AND
|
||||
(
|
||||
CT.FechaFinVigencia IS NULL
|
||||
OR CT.FechaFinVigencia >= CONVERT(date, GETDATE())
|
||||
)
|
||||
ORDER BY
|
||||
ISNULL(CT.FechaInicioVigencia, CONVERT(date, '19000101')) DESC,
|
||||
CT.CveCostoTramite DESC
|
||||
) AS Costo
|
||||
LEFT JOIN dbo.UnidadesMedida AS UM
|
||||
ON UM.CveUnidadMedida = D.CveUM
|
||||
WHERE D.CveTramitePagoDetalle = @CveTramitePagoDetalle;
|
||||
@@ -663,6 +768,8 @@ CREATE OR ALTER PROCEDURE dbo.PA_Tra_PagoDetalleSave
|
||||
@CvePS int,
|
||||
@CveUM int,
|
||||
@Cantidad decimal(18, 4),
|
||||
@Importe decimal(18, 2) = NULL,
|
||||
@FechaInicioVigencia date = NULL,
|
||||
@CveUsuarioEjecuta int,
|
||||
@ErrorMostrar varchar(max) OUTPUT,
|
||||
@ErrorTipo int OUTPUT,
|
||||
@@ -673,27 +780,20 @@ BEGIN
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.Sis_Usuarios
|
||||
WHERE CveUsuario = @CveUsuarioEjecuta
|
||||
AND CveRol IN (1, 2)
|
||||
AND Activo = 1
|
||||
)
|
||||
BEGIN
|
||||
SELECT
|
||||
@ErrorMostrar = 'No cuenta con permiso para modificar los conceptos del pago.',
|
||||
@ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
DECLARE
|
||||
@CveTipoTramite int,
|
||||
@CveMoneda int,
|
||||
@Descripcion varchar(300),
|
||||
@PrecioProducto decimal(18, 2),
|
||||
@CveCostoVigente int,
|
||||
@FechaInicioVigente date,
|
||||
@ImporteVigente decimal(18, 2);
|
||||
|
||||
IF NOT EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.Tra_Pagos
|
||||
WHERE CveTramitePago = @CveTramitePago
|
||||
)
|
||||
SELECT @CveTipoTramite = CveTipoTramite
|
||||
FROM dbo.Tra_Pagos
|
||||
WHERE CveTramitePago = @CveTramitePago;
|
||||
|
||||
IF @CveTipoTramite IS NULL
|
||||
BEGIN
|
||||
SELECT
|
||||
@ErrorMostrar = 'Seleccione un pago válido.',
|
||||
@@ -701,12 +801,13 @@ BEGIN
|
||||
RETURN;
|
||||
END;
|
||||
|
||||
IF NOT EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.ProductosServicios
|
||||
WHERE CvePS = @CvePS
|
||||
)
|
||||
SELECT
|
||||
@Descripcion = LEFT(PS, 300),
|
||||
@PrecioProducto = CONVERT(decimal(18, 2), Precio)
|
||||
FROM dbo.ProductosServicios
|
||||
WHERE CvePS = @CvePS;
|
||||
|
||||
IF @Descripcion IS NULL
|
||||
BEGIN
|
||||
SELECT
|
||||
@ErrorMostrar = 'Seleccione un producto o servicio válido.',
|
||||
@@ -714,6 +815,30 @@ BEGIN
|
||||
RETURN;
|
||||
END;
|
||||
|
||||
SELECT TOP (1) @CveMoneda = CveMoneda
|
||||
FROM dbo.Gral_Monedas
|
||||
WHERE Estatus = 1
|
||||
AND
|
||||
(
|
||||
Abreviatura = 'MXN'
|
||||
OR AbreviaturaSAT = 'MXN'
|
||||
)
|
||||
ORDER BY
|
||||
CASE WHEN Abreviatura = 'MXN' THEN 0 ELSE 1 END,
|
||||
CveMoneda;
|
||||
|
||||
IF @CveMoneda IS NULL
|
||||
BEGIN
|
||||
SELECT
|
||||
@ErrorMostrar = 'No se encuentra configurada la moneda MXN para guardar el importe.',
|
||||
@ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
|
||||
SET @Importe = ISNULL(@Importe, @PrecioProducto);
|
||||
SET @FechaInicioVigencia =
|
||||
ISNULL(@FechaInicioVigencia, CONVERT(date, GETDATE()));
|
||||
|
||||
IF @Cantidad <= 0
|
||||
BEGIN
|
||||
SELECT
|
||||
@@ -722,6 +847,14 @@ BEGIN
|
||||
RETURN;
|
||||
END;
|
||||
|
||||
IF @Importe < 0
|
||||
BEGIN
|
||||
SELECT
|
||||
@ErrorMostrar = 'El importe debe ser mayor o igual que cero.',
|
||||
@ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
|
||||
IF NOT EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
@@ -796,6 +929,102 @@ BEGIN
|
||||
WHERE CveTramitePagoDetalle = @CveTramitePagoDetalle;
|
||||
END;
|
||||
|
||||
SELECT TOP (1)
|
||||
@CveCostoVigente = CT.CveCostoTramite,
|
||||
@FechaInicioVigente = CT.FechaInicioVigencia,
|
||||
@ImporteVigente = CT.Importe
|
||||
FROM dbo.Tra_CostosTramite AS CT
|
||||
WHERE CT.CveTipoTramite = @CveTipoTramite
|
||||
AND CT.CvePS = @CvePS
|
||||
AND CT.EsActivo = 1
|
||||
AND CT.FechaFinVigencia IS NULL
|
||||
ORDER BY
|
||||
ISNULL(CT.FechaInicioVigencia, CONVERT(date, '19000101')) DESC,
|
||||
CT.CveCostoTramite DESC;
|
||||
|
||||
IF @CveCostoVigente IS NULL
|
||||
BEGIN
|
||||
INSERT dbo.Tra_CostosTramite
|
||||
(
|
||||
CveTipoTramite,
|
||||
CvePS,
|
||||
CveMoneda,
|
||||
Descripcion,
|
||||
Importe,
|
||||
FechaInicioVigencia,
|
||||
FechaFinVigencia,
|
||||
EsActivo,
|
||||
CveUsuario
|
||||
)
|
||||
VALUES
|
||||
(
|
||||
@CveTipoTramite,
|
||||
@CvePS,
|
||||
@CveMoneda,
|
||||
@Descripcion,
|
||||
@Importe,
|
||||
@FechaInicioVigencia,
|
||||
NULL,
|
||||
1,
|
||||
@CveUsuarioEjecuta
|
||||
);
|
||||
END
|
||||
ELSE IF @FechaInicioVigente IS NOT NULL
|
||||
AND @FechaInicioVigencia < @FechaInicioVigente
|
||||
BEGIN
|
||||
SELECT
|
||||
@ErrorMostrar = 'La nueva vigencia no puede iniciar antes de la vigencia actual.',
|
||||
@ErrorTipo = 2;
|
||||
RETURN;
|
||||
END
|
||||
ELSE IF ISNULL(@FechaInicioVigente, @FechaInicioVigencia) =
|
||||
@FechaInicioVigencia
|
||||
BEGIN
|
||||
UPDATE dbo.Tra_CostosTramite
|
||||
SET
|
||||
CveMoneda = @CveMoneda,
|
||||
Descripcion = @Descripcion,
|
||||
Importe = @Importe,
|
||||
FechaInicioVigencia = @FechaInicioVigencia,
|
||||
FechaModificacion = GETDATE(),
|
||||
CveUsuario = @CveUsuarioEjecuta
|
||||
WHERE CveCostoTramite = @CveCostoVigente;
|
||||
END
|
||||
ELSE IF @ImporteVigente <> @Importe
|
||||
BEGIN
|
||||
UPDATE dbo.Tra_CostosTramite
|
||||
SET
|
||||
FechaFinVigencia = DATEADD(day, -1, @FechaInicioVigencia),
|
||||
FechaModificacion = GETDATE(),
|
||||
CveUsuario = @CveUsuarioEjecuta
|
||||
WHERE CveCostoTramite = @CveCostoVigente;
|
||||
|
||||
INSERT dbo.Tra_CostosTramite
|
||||
(
|
||||
CveTipoTramite,
|
||||
CvePS,
|
||||
CveMoneda,
|
||||
Descripcion,
|
||||
Importe,
|
||||
FechaInicioVigencia,
|
||||
FechaFinVigencia,
|
||||
EsActivo,
|
||||
CveUsuario
|
||||
)
|
||||
VALUES
|
||||
(
|
||||
@CveTipoTramite,
|
||||
@CvePS,
|
||||
@CveMoneda,
|
||||
@Descripcion,
|
||||
@Importe,
|
||||
@FechaInicioVigencia,
|
||||
NULL,
|
||||
1,
|
||||
@CveUsuarioEjecuta
|
||||
);
|
||||
END;
|
||||
|
||||
SELECT @CveTramitePagoDetalle AS CveTramitePagoDetalle;
|
||||
SET @Return = 1;
|
||||
END TRY
|
||||
@@ -828,22 +1057,7 @@ BEGIN
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.Sis_Usuarios
|
||||
WHERE CveUsuario = @CveUsuarioEjecuta
|
||||
AND CveRol IN (1, 2)
|
||||
AND Activo = 1
|
||||
)
|
||||
BEGIN
|
||||
SELECT
|
||||
@ErrorMostrar = 'No cuenta con permiso para eliminar el concepto del pago.',
|
||||
@ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
|
||||
DELETE dbo.Tra_PagosDetalle
|
||||
DELETE dbo.Tra_PagosDetalle
|
||||
WHERE CveTramitePagoDetalle = @CveTramitePagoDetalle;
|
||||
|
||||
SET @Return = 1;
|
||||
@@ -878,22 +1092,7 @@ BEGIN
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.Sis_Usuarios
|
||||
WHERE CveUsuario = @CveUsuarioEjecuta
|
||||
AND CveRol IN (1, 2)
|
||||
AND Activo = 1
|
||||
)
|
||||
BEGIN
|
||||
SELECT
|
||||
@ErrorMostrar = 'No cuenta con permiso para consultar productos y servicios.',
|
||||
@ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
|
||||
SET @Texto = NULLIF(LTRIM(RTRIM(@Texto)), '');
|
||||
SET @Texto = NULLIF(LTRIM(RTRIM(@Texto)), '');
|
||||
|
||||
SELECT
|
||||
CvePS,
|
||||
@@ -948,22 +1147,7 @@ BEGIN
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.Sis_Usuarios
|
||||
WHERE CveUsuario = @CveUsuarioEjecuta
|
||||
AND CveRol IN (1, 2)
|
||||
AND Activo = 1
|
||||
)
|
||||
BEGIN
|
||||
SELECT
|
||||
@ErrorMostrar = 'No cuenta con permiso para consultar el producto o servicio.',
|
||||
@ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
|
||||
SELECT
|
||||
SELECT
|
||||
CvePS,
|
||||
ProductosServicios.CveUnidadMedida AS CveUnidadMedida,
|
||||
Unidad.UnidadMedida,
|
||||
@@ -1010,22 +1194,7 @@ BEGIN
|
||||
SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0;
|
||||
|
||||
BEGIN TRY
|
||||
IF NOT EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.Sis_Usuarios
|
||||
WHERE CveUsuario = @CveUsuarioEjecuta
|
||||
AND CveRol IN (1, 2)
|
||||
AND Activo = 1
|
||||
)
|
||||
BEGIN
|
||||
SELECT
|
||||
@ErrorMostrar = 'No cuenta con permiso para modificar el precio global.',
|
||||
@ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
|
||||
IF @Precio < 0
|
||||
IF @Precio < 0
|
||||
BEGIN
|
||||
SELECT
|
||||
@ErrorMostrar = 'El precio no puede ser negativo.',
|
||||
|
||||
86
Ventas_Prueba_Limpieza_20260901.sql
Normal file
86
Ventas_Prueba_Limpieza_20260901.sql
Normal file
@@ -0,0 +1,86 @@
|
||||
SET NOCOUNT ON;
|
||||
SET XACT_ABORT ON;
|
||||
|
||||
BEGIN TRANSACTION;
|
||||
|
||||
CREATE TABLE #VentasPrueba
|
||||
(
|
||||
CveVenta int NOT NULL PRIMARY KEY
|
||||
);
|
||||
|
||||
INSERT INTO #VentasPrueba
|
||||
(
|
||||
CveVenta
|
||||
)
|
||||
SELECT DISTINCT
|
||||
VD.CveVenta
|
||||
FROM dbo.VentasDetalle AS VD
|
||||
WHERE VD.CveSolicitud IS NOT NULL
|
||||
OR VD.CveCostoTramite IS NOT NULL
|
||||
OR VD.EsFondoInicial = 1;
|
||||
|
||||
SELECT
|
||||
V.CveVenta,
|
||||
V.Serie,
|
||||
V.Folio,
|
||||
V.Fecha,
|
||||
V.SubTotal,
|
||||
V.Descuento,
|
||||
V.IVA,
|
||||
V.Total
|
||||
FROM dbo.Ventas AS V
|
||||
INNER JOIN #VentasPrueba AS VP
|
||||
ON VP.CveVenta = V.CveVenta
|
||||
ORDER BY V.CveVenta;
|
||||
|
||||
IF EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.Vta_Pagos AS P
|
||||
INNER JOIN #VentasPrueba AS VP
|
||||
ON VP.CveVenta = P.CveVenta
|
||||
)
|
||||
BEGIN
|
||||
THROW 50002, 'La selección incluye ventas con pagos; la limpieza de prueba se canceló.', 1;
|
||||
END;
|
||||
|
||||
IF EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.Fac_CfdiDocumentos AS D
|
||||
INNER JOIN #VentasPrueba AS VP
|
||||
ON VP.CveVenta = D.CveOrigen
|
||||
WHERE D.TipoOrigen = 'VENTA'
|
||||
)
|
||||
BEGIN
|
||||
THROW 50003, 'La selección incluye ventas con documentos CFDI; la limpieza de prueba se canceló.', 1;
|
||||
END;
|
||||
|
||||
DELETE VDI
|
||||
FROM dbo.VentasDetalleImpuestos AS VDI
|
||||
INNER JOIN dbo.VentasDetalle AS VD
|
||||
ON VD.CveVentaDetalle = VDI.CveVentaDetalle
|
||||
INNER JOIN #VentasPrueba AS VP
|
||||
ON VP.CveVenta = VD.CveVenta;
|
||||
|
||||
DELETE VD
|
||||
FROM dbo.VentasDetalle AS VD
|
||||
INNER JOIN #VentasPrueba AS VP
|
||||
ON VP.CveVenta = VD.CveVenta;
|
||||
|
||||
DELETE SP
|
||||
FROM dbo.Tra_SolicitudesPagos AS SP
|
||||
INNER JOIN #VentasPrueba AS VP
|
||||
ON VP.CveVenta = SP.CveVenta;
|
||||
|
||||
DELETE V
|
||||
FROM dbo.Ventas AS V
|
||||
INNER JOIN #VentasPrueba AS VP
|
||||
ON VP.CveVenta = V.CveVenta;
|
||||
|
||||
SELECT
|
||||
@@ROWCOUNT AS VentasQueSeEliminarian;
|
||||
|
||||
ROLLBACK TRANSACTION;
|
||||
|
||||
-- Cambiar únicamente a COMMIT TRANSACTION después de revisar la selección.
|
||||
Reference in New Issue
Block a user