first commit

This commit is contained in:
2025-03-05 20:44:45 -06:00
commit 06dbf8e2a7
74 changed files with 9681 additions and 0 deletions

View File

@ -0,0 +1,516 @@
<section id="crm-warehouse-index">
<div class="crm-warehouse-index alert-errors"></div>
<div wire:ignore>
<div class="query-filters" id="toolbar">
<div class="d-flex flex-wrap">
<div class="pt-1 pr-2 pb-1" style="min-width: 175px; max-width: 225px">
<button data-bs-toggle='offcanvas' data-bs-target='#offcanvasUser' class="btn btn-primary waves-effect waves-light">Agregar almacén</button>
</div>
<button type="button" class="accordion-button collapsed" data-bs-toggle="collapse" data-bs-target="#accordionFiltrado" aria-expanded="false" aria-controls="accordionFiltrado">
Filtrado
</button>
<div class="px-2 pt-1">
<button class="btn btn-label-secondary waves-effect py-3 btn-refresh" disabled><i class="fa-solid fa-rotate"></i></button>
</div>
<div class="pr-2" style="width: 60px;">
<a href="javascript:void(0)" class="clear-filters">Limpiar Filtrado</a>
</div>
</div>
</div>
<table id="bt-warehouses"></table>
</div>
</section>
@push('page-script')
<script>
const store_route = '{{ route('admin.core.users.store') }}',
route_show = '{{ route('admin.inventory.warehouse.show', ['warehouse' => '~warehouse~']) }}',
route_destroy = '{{ route('admin.inventory.warehouse.destroy', ['warehouse' => '~warehouse~']) }}',
statusList = {!! json_encode($status_list) !!},
statusIntCatalogCss = {!! json_encode($status_list_class) !!};
var btt_height;
// BootstrapTable Petición AJAX
function ajaxRequest(params) {
let url = '{{ url()->current() }}' +
'?' +
$.param(params.data) +
'&' +
$('.query-filters :input').serialize();
$.get(url).then(function (res) {
params.success(res)
})
}
// BootstrapTable Formatter
function userAvatarFormatter(value, row, index) {
if(row.id){
let show_href = route_show.replace('~warehouseo~', row.id);
return [
'<div class="d-flex justify-content-start align-items-center user-name">',
'<div class="avatar-wrapper">',
'<div class="avatar avatar-sm me-4">' +
'<img src="' + row.profile_photo_url + '" alt="Avatar" class="rounded-circle">' +
'</div>',
'</div>',
'<div class="d-flex flex-column">',
'<a href="' + show_href + '" class="text-heading text-truncate"><span class="fw-medium">' + row.name + '</span></a>',
'<small>' + row.email + '</small>',
'</div>',
'</div>',
].join('')
}
}
function uidFormatter(value, row, index) {
if(row.id){
let show_href = route_show.replace('~warehouseo~', row.id);
return [
'<div class="d-flex align-items-center justify-content-center">',
'<a href="' + show_href + '" class="whitespace-nowrap" title="Ver warehouseo"> ' + row.id + '</a>',
@can('crm.warehouses.update')
'<a href="javascript:;" class="btn btn-icon btn-text-secondary waves-effect waves-light rounded-pill dropdown-toggle hide-arrow" data-bs-toggle="dropdown"><i class="ti ti-dots-vertical ti-md"></i></a>',
'<div class="dropdown-menu dropdown-menu-end m-0">',
'<a href="javascript:deleteRow(' + row.id + ');" class="dropdown-item delete-record">Eliminar</a>',
'</div>',
@endcan
'</div>'
].join('')
}
}
// BootstrapTable Init
function initTable(table) {
$(table)
.bootstrapTable('destroy')
.bootstrapTable({
height: btt_height,
locale: 'es-MX',
ajax: "ajaxRequest",
toolbar: "#toolbar",
search: true,
showColumns: true,
showColumnsToggleAll: true,
showExport: true,
showFullscreen: true,
showPaginationSwitch: true,
showRefresh: true,
showToggle: true,
clickToSelect: true,
minimumCountColumns: 4,
fixedColumns: true,
fixedNumber: 1,
idField: "id",
pagination: true,
pageList: [10, 25, 50, 100, 500],
sidePagination: "server",
exportTypes: ['csv', 'txt', 'excel'],
exportOptions: {
fileName: 'warehouseos',
},
sortName: 'users.id',
sortOrder: 'desc',
mobileResponsive: true,
cookie: true,
resizable: true,
cookieIdTable:"crm-warehouse-index",
columns: [
{
field: 'id',
title: 'UID',
align: 'center',
sortable: true,
sortName: 'users.id',
switchable: false,
formatter: uidFormatter
},
{
field: 'name',
title: 'Nombre',
formatter: userAvatarFormatter,
},
{
field: 'email',
title: 'Correo electrónico',
sortable: true,
visible: false,
},
{
field: 'tipo_persona',
title: 'Tipo persona',
visible: false,
sortable: true,
formatter: window.btFormatter.tipoPersona,
},
{
field: 'rfc',
title: 'RFC',
sortable: true,
},
{
field: 'nombre_fiscal',
title: 'Nombre fiscal',
sortable: true,
},
{
field: 'c_regimen_fiscal',
title: 'Regimen fiscal',
sortable: true,
visible: false,
formatter: window.btFormatter.regimenFiscal,
},
{
field: 'domicilio_fiscal',
title: 'Domicilio fiscal',
sortable: true,
visible: false,
},
{
field: 'estado',
title: 'Estado',
sortable: true,
},
{
field: 'municipio',
title: 'Municipio',
sortable: true,
},
{
field: 'localidad',
title: 'Localidad',
sortable: true,
visible: false,
},
{
field: 'c_uso_cfdi',
title: 'Uso de CFDI',
sortable: true,
visible: false,
formatter: window.btFormatter.usoCfdi,
},
{
field: 'cargo',
title: 'Cargo',
visible: false,
sortable: true,
},
{
field: 'is_prospect',
title: 'Es prospecto',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'is_customer',
title: 'Es cliente',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'is_provider',
title: 'Es proveedor',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'is_user',
title: 'Es usuario',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'status',
title: 'Estado',
align: 'center',
sortable: true,
formatter: window.btFormatter.status,
},
{
field: 'created_at',
title: 'Creado &nbsp; &nbsp; &nbsp; &nbsp;',
align: 'center',
sortable: true,
visible: false,
},
{
field: 'created_by_name',
title: 'Creado por',
align: 'center',
sortable: true,
visible: false,
sortName: 'created_by_name',
},
{
field: 'updated_at',
title: 'Modificado &nbsp; ',
align: 'center',
sortable: true,
visible: false,
},
]
})
}
function toggleSections() {
const isProspect = $('#is_prospect').is(':checked');
const isCustomer = $('#is_customer').is(':checked');
const isProvider = $('#is_provider').is(':checked');
const isUser = $('#is_user').is(':checked');
$('.div-sat').toggle(isCustomer || isProvider);
$('.div-sat-customer').toggle(isCustomer);
$('.div-user-auth').toggle(isCustomer || isUser);
$('.div-roles').toggle(isUser);
}
function toggleCheckboxes(status) {
const isDisabled = status == 1;
$('#is_prospect, #is_customer, #is_provider, #is_user').prop('disabled', isDisabled);
}
load_js_form = () => {
$('#userForm .select2')
.each(function() {
var $this = $(this)
$this.wrap('<div class="position-relative"></div>')
$this.select2({
dropdownAutoWidth: true,
width: '100%',
dropdownParent: $this.parent()
});
});
// Evento para los checkboxes
$('#is_prospect, #is_customer, #is_provider, #is_user').on('change', toggleSections);
// Evento para el select de estado
$('.div-status').on('change', 'select[name="status"]', function() {
toggleCheckboxes($(this).val());
});
// Previo de imagenes
document.getElementById("photo").addEventListener('change', updatePreviewImage);
// Reset form
$("#userForm")
.on('reset', function(){
var form = $("#userForm");
form.validate().resetForm();
setTimeout(function(){
$('#roles').trigger('change');
toggleSections();
}, 250)
$('#user-image').prop("src", "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
$('#userForm .alert-errors').html('');
$('.pdf-dropzone-div').show();
$("#pdf-dropzone").removeAllFiles(true);
});
$("#userForm")
.validate({
errorClass: 'error',
highlight: function(element, errorClass, validClass) {
// Agrega la clase de error a la fila (contenedor del campo)
$(element).closest('.mb-3').addClass('has-error');
},
unhighlight: function(element, errorClass, validClass) {
// Elimina la clase de error de la fila (contenedor del campo)
$(element).closest('.mb-3').removeClass('has-error');
},
errorPlacement: function(error, element) {
// Controla dónde se colocan los mensajes de error
error.appendTo(element.closest('.mb-3').find('.error-message'));
},
rules: {
name: {
required: true,
minlength: 5
},
email: {
required: true,
email: true
},
password: {
required: function(element) {
return !$("#userForm input[name=id]").val() && ($('#is_user').is(':checked') || $('#is_customer').is(':checked'));
},
minlength: 6
}
},
messages: {
name: {
required: "Por favor ingrese su nombre completo",
minlength: "El nombre completo debe tener al menos 8 caracteres"
},
email: {
required: "Por favor ingrese su correo electrónico",
email: "El valor no es una dirección de correo válida"
},
password: {
required: "La contraseña es obligatoria para nuevos usuarios",
minlength: "La contraseña debe tener al menos 6 caracteres"
}
},
submitHandler: function(form, event) {
// Evita que el formulario se envíe automáticamente
event.preventDefault();
var form = $("#userForm")[0],
data = new FormData(form);
$('#userForm :input').prop('disabled', true);
$('#userForm .alert-errors').html('');
$.ajax({
url: store_route,
method: 'POST',
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
data: data,
contentType: false,
processData: false,
cache: false,
timeout: 3000,
success: function(data) {
$('#userForm :input').prop('disabled', false);
if (data.errors) {
$('#userForm .alert-errors').html('<div class="alert alert-danger alert-dismissible fade show" role="alert">' +
'<div class="alert-body">' + data.errors + '</div>' +
'<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' +
'</div>');
} else {
let $usersIndexAlert = $('.crm-warehouse-index.alert-errors');
$usersIndexAlert.html('<div class="alert alert-success alert-dismissible fade show" role="alert">' +
'<div class="alert-body">' +
'<p class="mb-0"><strong>' + data.success + '</strong></p>' +
'</div>' +
'<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' +
'</div>');
$('#userForm button[type=reset]').trigger('click');
$('#toolbar .clear-filters').trigger('click');
}
},
error: function(e) {
$('#userForm :input').prop('disabled', false);
$('#userForm .alert-errors').html('<div class="alert alert-danger alert-dismissible fade show" role="alert">' +
'<div class="alert-body">' + e.responseJSON.message + '</div>' +
'<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' +
'</div>');
}
});
}
});
// Inicializar el estado al cargar la página
toggleSections();
toggleCheckboxes($('select[name="status"]').val());
}
// Previo de imagen de perfil
updatePreviewImage = (event) => {
var file = event.target.files[0],
reader = new FileReader();
reader.onload = event => {
document.getElementById('user-image').setAttribute('src', event.target.result);
};
reader.readAsDataURL(file);
}
document.addEventListener('DOMContentLoaded', function() {
$(document).ready(function() {
var $table = $('#bt-warehouses'),
$btnRefresh = $('#toolbar .btn-refresh'),
$clearFilters = $('a.clear-filters');
var btt_rest_height = 220,
btt_min_height = 600;
btt_height = (window.innerHeight - btt_rest_height) < btt_min_height?
btt_height:
window.innerHeight - btt_rest_height;
var offcanvasElement = document.getElementById('offcanvasUser'),
offcanvasUser = new bootstrap.Offcanvas(offcanvasElement);
const refreshButton = document.querySelector('.btn-refresh');
const inputs = document.querySelectorAll('#toolbar input, #toolbar select');
inputs.forEach(input => {
input.addEventListener('change', () => {
refreshButton.disabled = false;
refreshButton.classList.remove('btn-label-secondary');
refreshButton.classList.add('btn-label-success');
});
});
// Button Refresh
$btnRefresh
.on('click', () => {
$table.bootstrapTable('refresh');
refreshButton.disabled = true;
refreshButton.classList.remove('btn-label-success');
refreshButton.classList.add('btn-label-secondary');
});
// Button clear filters
$clearFilters
.on('click', () => {
$table.bootstrapTable('resetSearch', ''); // Inicializa la búsqueda con cadena vacía
refreshButton.disabled = true;
refreshButton.classList.remove('btn-label-success');
refreshButton.classList.add('btn-label-secondary');
});
initTable('#bt-warehouses'); // Una vez que todos los scripts estén cargados, inicializa Bootstrap Table
load_js_form();
});
});
</script>
@endpush

View File

@ -0,0 +1,516 @@
<section id="crm-warehouse-index">
<div class="crm-warehouse-index alert-errors"></div>
<div wire:ignore>
<div class="query-filters" id="toolbar">
<div class="d-flex flex-wrap">
<div class="pt-1 pr-2 pb-1" style="min-width: 175px; max-width: 225px">
<button data-bs-toggle='offcanvas' data-bs-target='#offcanvasUser' class="btn btn-primary waves-effect waves-light">Agregar almacén</button>
</div>
<button type="button" class="accordion-button collapsed" data-bs-toggle="collapse" data-bs-target="#accordionFiltrado" aria-expanded="false" aria-controls="accordionFiltrado">
Filtrado
</button>
<div class="px-2 pt-1">
<button class="btn btn-label-secondary waves-effect py-3 btn-refresh" disabled><i class="fa-solid fa-rotate"></i></button>
</div>
<div class="pr-2" style="width: 60px;">
<a href="javascript:void(0)" class="clear-filters">Limpiar Filtrado</a>
</div>
</div>
</div>
<table id="bt-warehouses"></table>
</div>
</section>
@push('page-script')
<script>
const store_route = '{{ route('admin.core.users.store') }}',
route_show = '{{ route('admin.inventory.warehouse.show', ['warehouse' => '~warehouse~']) }}',
route_destroy = '{{ route('admin.inventory.warehouse.destroy', ['warehouse' => '~warehouse~']) }}',
statusList = {!! json_encode($status_list) !!},
statusIntCatalogCss = {!! json_encode($status_list_class) !!};
var btt_height;
// BootstrapTable Petición AJAX
function ajaxRequest(params) {
let url = '{{ url()->current() }}' +
'?' +
$.param(params.data) +
'&' +
$('.query-filters :input').serialize();
$.get(url).then(function (res) {
params.success(res)
})
}
// BootstrapTable Formatter
function userAvatarFormatter(value, row, index) {
if(row.id){
let show_href = route_show.replace('~warehouseo~', row.id);
return [
'<div class="d-flex justify-content-start align-items-center user-name">',
'<div class="avatar-wrapper">',
'<div class="avatar avatar-sm me-4">' +
'<img src="' + row.profile_photo_url + '" alt="Avatar" class="rounded-circle">' +
'</div>',
'</div>',
'<div class="d-flex flex-column">',
'<a href="' + show_href + '" class="text-heading text-truncate"><span class="fw-medium">' + row.name + '</span></a>',
'<small>' + row.email + '</small>',
'</div>',
'</div>',
].join('')
}
}
function uidFormatter(value, row, index) {
if(row.id){
let show_href = route_show.replace('~warehouseo~', row.id);
return [
'<div class="d-flex align-items-center justify-content-center">',
'<a href="' + show_href + '" class="whitespace-nowrap" title="Ver warehouseo"> ' + row.id + '</a>',
@can('crm.warehouses.update')
'<a href="javascript:;" class="btn btn-icon btn-text-secondary waves-effect waves-light rounded-pill dropdown-toggle hide-arrow" data-bs-toggle="dropdown"><i class="ti ti-dots-vertical ti-md"></i></a>',
'<div class="dropdown-menu dropdown-menu-end m-0">',
'<a href="javascript:deleteRow(' + row.id + ');" class="dropdown-item delete-record">Eliminar</a>',
'</div>',
@endcan
'</div>'
].join('')
}
}
// BootstrapTable Init
function initTable(table) {
$(table)
.bootstrapTable('destroy')
.bootstrapTable({
height: btt_height,
locale: 'es-MX',
ajax: "ajaxRequest",
toolbar: "#toolbar",
search: true,
showColumns: true,
showColumnsToggleAll: true,
showExport: true,
showFullscreen: true,
showPaginationSwitch: true,
showRefresh: true,
showToggle: true,
clickToSelect: true,
minimumCountColumns: 4,
fixedColumns: true,
fixedNumber: 1,
idField: "id",
pagination: true,
pageList: [10, 25, 50, 100, 500],
sidePagination: "server",
exportTypes: ['csv', 'txt', 'excel'],
exportOptions: {
fileName: 'warehouseos',
},
sortName: 'users.id',
sortOrder: 'desc',
mobileResponsive: true,
cookie: true,
resizable: true,
cookieIdTable:"crm-warehouse-index",
columns: [
{
field: 'id',
title: 'UID',
align: 'center',
sortable: true,
sortName: 'users.id',
switchable: false,
formatter: uidFormatter
},
{
field: 'name',
title: 'Nombre',
formatter: userAvatarFormatter,
},
{
field: 'email',
title: 'Correo electrónico',
sortable: true,
visible: false,
},
{
field: 'tipo_persona',
title: 'Tipo persona',
visible: false,
sortable: true,
formatter: window.btFormatter.tipoPersona,
},
{
field: 'rfc',
title: 'RFC',
sortable: true,
},
{
field: 'nombre_fiscal',
title: 'Nombre fiscal',
sortable: true,
},
{
field: 'c_regimen_fiscal',
title: 'Regimen fiscal',
sortable: true,
visible: false,
formatter: window.btFormatter.regimenFiscal,
},
{
field: 'domicilio_fiscal',
title: 'Domicilio fiscal',
sortable: true,
visible: false,
},
{
field: 'estado',
title: 'Estado',
sortable: true,
},
{
field: 'municipio',
title: 'Municipio',
sortable: true,
},
{
field: 'localidad',
title: 'Localidad',
sortable: true,
visible: false,
},
{
field: 'c_uso_cfdi',
title: 'Uso de CFDI',
sortable: true,
visible: false,
formatter: window.btFormatter.usoCfdi,
},
{
field: 'cargo',
title: 'Cargo',
visible: false,
sortable: true,
},
{
field: 'is_prospect',
title: 'Es prospecto',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'is_customer',
title: 'Es cliente',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'is_provider',
title: 'Es proveedor',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'is_user',
title: 'Es usuario',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'status',
title: 'Estado',
align: 'center',
sortable: true,
formatter: window.btFormatter.status,
},
{
field: 'created_at',
title: 'Creado &nbsp; &nbsp; &nbsp; &nbsp;',
align: 'center',
sortable: true,
visible: false,
},
{
field: 'created_by_name',
title: 'Creado por',
align: 'center',
sortable: true,
visible: false,
sortName: 'created_by_name',
},
{
field: 'updated_at',
title: 'Modificado &nbsp; ',
align: 'center',
sortable: true,
visible: false,
},
]
})
}
function toggleSections() {
const isProspect = $('#is_prospect').is(':checked');
const isCustomer = $('#is_customer').is(':checked');
const isProvider = $('#is_provider').is(':checked');
const isUser = $('#is_user').is(':checked');
$('.div-sat').toggle(isCustomer || isProvider);
$('.div-sat-customer').toggle(isCustomer);
$('.div-user-auth').toggle(isCustomer || isUser);
$('.div-roles').toggle(isUser);
}
function toggleCheckboxes(status) {
const isDisabled = status == 1;
$('#is_prospect, #is_customer, #is_provider, #is_user').prop('disabled', isDisabled);
}
load_js_form = () => {
$('#userForm .select2')
.each(function() {
var $this = $(this)
$this.wrap('<div class="position-relative"></div>')
$this.select2({
dropdownAutoWidth: true,
width: '100%',
dropdownParent: $this.parent()
});
});
// Evento para los checkboxes
$('#is_prospect, #is_customer, #is_provider, #is_user').on('change', toggleSections);
// Evento para el select de estado
$('.div-status').on('change', 'select[name="status"]', function() {
toggleCheckboxes($(this).val());
});
// Previo de imagenes
document.getElementById("photo").addEventListener('change', updatePreviewImage);
// Reset form
$("#userForm")
.on('reset', function(){
var form = $("#userForm");
form.validate().resetForm();
setTimeout(function(){
$('#roles').trigger('change');
toggleSections();
}, 250)
$('#user-image').prop("src", "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
$('#userForm .alert-errors').html('');
$('.pdf-dropzone-div').show();
$("#pdf-dropzone").removeAllFiles(true);
});
$("#userForm")
.validate({
errorClass: 'error',
highlight: function(element, errorClass, validClass) {
// Agrega la clase de error a la fila (contenedor del campo)
$(element).closest('.mb-3').addClass('has-error');
},
unhighlight: function(element, errorClass, validClass) {
// Elimina la clase de error de la fila (contenedor del campo)
$(element).closest('.mb-3').removeClass('has-error');
},
errorPlacement: function(error, element) {
// Controla dónde se colocan los mensajes de error
error.appendTo(element.closest('.mb-3').find('.error-message'));
},
rules: {
name: {
required: true,
minlength: 5
},
email: {
required: true,
email: true
},
password: {
required: function(element) {
return !$("#userForm input[name=id]").val() && ($('#is_user').is(':checked') || $('#is_customer').is(':checked'));
},
minlength: 6
}
},
messages: {
name: {
required: "Por favor ingrese su nombre completo",
minlength: "El nombre completo debe tener al menos 8 caracteres"
},
email: {
required: "Por favor ingrese su correo electrónico",
email: "El valor no es una dirección de correo válida"
},
password: {
required: "La contraseña es obligatoria para nuevos usuarios",
minlength: "La contraseña debe tener al menos 6 caracteres"
}
},
submitHandler: function(form, event) {
// Evita que el formulario se envíe automáticamente
event.preventDefault();
var form = $("#userForm")[0],
data = new FormData(form);
$('#userForm :input').prop('disabled', true);
$('#userForm .alert-errors').html('');
$.ajax({
url: store_route,
method: 'POST',
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
data: data,
contentType: false,
processData: false,
cache: false,
timeout: 3000,
success: function(data) {
$('#userForm :input').prop('disabled', false);
if (data.errors) {
$('#userForm .alert-errors').html('<div class="alert alert-danger alert-dismissible fade show" role="alert">' +
'<div class="alert-body">' + data.errors + '</div>' +
'<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' +
'</div>');
} else {
let $usersIndexAlert = $('.crm-warehouse-index.alert-errors');
$usersIndexAlert.html('<div class="alert alert-success alert-dismissible fade show" role="alert">' +
'<div class="alert-body">' +
'<p class="mb-0"><strong>' + data.success + '</strong></p>' +
'</div>' +
'<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' +
'</div>');
$('#userForm button[type=reset]').trigger('click');
$('#toolbar .clear-filters').trigger('click');
}
},
error: function(e) {
$('#userForm :input').prop('disabled', false);
$('#userForm .alert-errors').html('<div class="alert alert-danger alert-dismissible fade show" role="alert">' +
'<div class="alert-body">' + e.responseJSON.message + '</div>' +
'<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' +
'</div>');
}
});
}
});
// Inicializar el estado al cargar la página
toggleSections();
toggleCheckboxes($('select[name="status"]').val());
}
// Previo de imagen de perfil
updatePreviewImage = (event) => {
var file = event.target.files[0],
reader = new FileReader();
reader.onload = event => {
document.getElementById('user-image').setAttribute('src', event.target.result);
};
reader.readAsDataURL(file);
}
document.addEventListener('DOMContentLoaded', function() {
$(document).ready(function() {
var $table = $('#bt-warehouses'),
$btnRefresh = $('#toolbar .btn-refresh'),
$clearFilters = $('a.clear-filters');
var btt_rest_height = 220,
btt_min_height = 600;
btt_height = (window.innerHeight - btt_rest_height) < btt_min_height?
btt_height:
window.innerHeight - btt_rest_height;
var offcanvasElement = document.getElementById('offcanvasUser'),
offcanvasUser = new bootstrap.Offcanvas(offcanvasElement);
const refreshButton = document.querySelector('.btn-refresh');
const inputs = document.querySelectorAll('#toolbar input, #toolbar select');
inputs.forEach(input => {
input.addEventListener('change', () => {
refreshButton.disabled = false;
refreshButton.classList.remove('btn-label-secondary');
refreshButton.classList.add('btn-label-success');
});
});
// Button Refresh
$btnRefresh
.on('click', () => {
$table.bootstrapTable('refresh');
refreshButton.disabled = true;
refreshButton.classList.remove('btn-label-success');
refreshButton.classList.add('btn-label-secondary');
});
// Button clear filters
$clearFilters
.on('click', () => {
$table.bootstrapTable('resetSearch', ''); // Inicializa la búsqueda con cadena vacía
refreshButton.disabled = true;
refreshButton.classList.remove('btn-label-success');
refreshButton.classList.add('btn-label-secondary');
});
initTable('#bt-warehouses'); // Una vez que todos los scripts estén cargados, inicializa Bootstrap Table
load_js_form();
});
});
</script>
@endpush

View File

@ -0,0 +1,516 @@
<section id="crm-warehouse-index">
<div class="crm-warehouse-index alert-errors"></div>
<div wire:ignore>
<div class="query-filters" id="toolbar">
<div class="d-flex flex-wrap">
<div class="pt-1 pr-2 pb-1" style="min-width: 175px; max-width: 225px">
<button data-bs-toggle='offcanvas' data-bs-target='#offcanvasUser' class="btn btn-primary waves-effect waves-light">Agregar almacén</button>
</div>
<button type="button" class="accordion-button collapsed" data-bs-toggle="collapse" data-bs-target="#accordionFiltrado" aria-expanded="false" aria-controls="accordionFiltrado">
Filtrado
</button>
<div class="px-2 pt-1">
<button class="btn btn-label-secondary waves-effect py-3 btn-refresh" disabled><i class="fa-solid fa-rotate"></i></button>
</div>
<div class="pr-2" style="width: 60px;">
<a href="javascript:void(0)" class="clear-filters">Limpiar Filtrado</a>
</div>
</div>
</div>
<table id="bt-warehouses"></table>
</div>
</section>
@push('page-script')
<script>
const store_route = '{{ route('admin.core.users.store') }}',
route_show = '{{ route('admin.inventory.warehouse.show', ['warehouse' => '~warehouse~']) }}',
route_destroy = '{{ route('admin.inventory.warehouse.destroy', ['warehouse' => '~warehouse~']) }}',
statusList = {!! json_encode($status_list) !!},
statusIntCatalogCss = {!! json_encode($status_list_class) !!};
var btt_height;
// BootstrapTable Petición AJAX
function ajaxRequest(params) {
let url = '{{ url()->current() }}' +
'?' +
$.param(params.data) +
'&' +
$('.query-filters :input').serialize();
$.get(url).then(function (res) {
params.success(res)
})
}
// BootstrapTable Formatter
function userAvatarFormatter(value, row, index) {
if(row.id){
let show_href = route_show.replace('~warehouseo~', row.id);
return [
'<div class="d-flex justify-content-start align-items-center user-name">',
'<div class="avatar-wrapper">',
'<div class="avatar avatar-sm me-4">' +
'<img src="' + row.profile_photo_url + '" alt="Avatar" class="rounded-circle">' +
'</div>',
'</div>',
'<div class="d-flex flex-column">',
'<a href="' + show_href + '" class="text-heading text-truncate"><span class="fw-medium">' + row.name + '</span></a>',
'<small>' + row.email + '</small>',
'</div>',
'</div>',
].join('')
}
}
function uidFormatter(value, row, index) {
if(row.id){
let show_href = route_show.replace('~warehouseo~', row.id);
return [
'<div class="d-flex align-items-center justify-content-center">',
'<a href="' + show_href + '" class="whitespace-nowrap" title="Ver warehouseo"> ' + row.id + '</a>',
@can('crm.warehouses.update')
'<a href="javascript:;" class="btn btn-icon btn-text-secondary waves-effect waves-light rounded-pill dropdown-toggle hide-arrow" data-bs-toggle="dropdown"><i class="ti ti-dots-vertical ti-md"></i></a>',
'<div class="dropdown-menu dropdown-menu-end m-0">',
'<a href="javascript:deleteRow(' + row.id + ');" class="dropdown-item delete-record">Eliminar</a>',
'</div>',
@endcan
'</div>'
].join('')
}
}
// BootstrapTable Init
function initTable(table) {
$(table)
.bootstrapTable('destroy')
.bootstrapTable({
height: btt_height,
locale: 'es-MX',
ajax: "ajaxRequest",
toolbar: "#toolbar",
search: true,
showColumns: true,
showColumnsToggleAll: true,
showExport: true,
showFullscreen: true,
showPaginationSwitch: true,
showRefresh: true,
showToggle: true,
clickToSelect: true,
minimumCountColumns: 4,
fixedColumns: true,
fixedNumber: 1,
idField: "id",
pagination: true,
pageList: [10, 25, 50, 100, 500],
sidePagination: "server",
exportTypes: ['csv', 'txt', 'excel'],
exportOptions: {
fileName: 'warehouseos',
},
sortName: 'users.id',
sortOrder: 'desc',
mobileResponsive: true,
cookie: true,
resizable: true,
cookieIdTable:"crm-warehouse-index",
columns: [
{
field: 'id',
title: 'UID',
align: 'center',
sortable: true,
sortName: 'users.id',
switchable: false,
formatter: uidFormatter
},
{
field: 'name',
title: 'Nombre',
formatter: userAvatarFormatter,
},
{
field: 'email',
title: 'Correo electrónico',
sortable: true,
visible: false,
},
{
field: 'tipo_persona',
title: 'Tipo persona',
visible: false,
sortable: true,
formatter: window.btFormatter.tipoPersona,
},
{
field: 'rfc',
title: 'RFC',
sortable: true,
},
{
field: 'nombre_fiscal',
title: 'Nombre fiscal',
sortable: true,
},
{
field: 'c_regimen_fiscal',
title: 'Regimen fiscal',
sortable: true,
visible: false,
formatter: window.btFormatter.regimenFiscal,
},
{
field: 'domicilio_fiscal',
title: 'Domicilio fiscal',
sortable: true,
visible: false,
},
{
field: 'estado',
title: 'Estado',
sortable: true,
},
{
field: 'municipio',
title: 'Municipio',
sortable: true,
},
{
field: 'localidad',
title: 'Localidad',
sortable: true,
visible: false,
},
{
field: 'c_uso_cfdi',
title: 'Uso de CFDI',
sortable: true,
visible: false,
formatter: window.btFormatter.usoCfdi,
},
{
field: 'cargo',
title: 'Cargo',
visible: false,
sortable: true,
},
{
field: 'is_prospect',
title: 'Es prospecto',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'is_customer',
title: 'Es cliente',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'is_provider',
title: 'Es proveedor',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'is_user',
title: 'Es usuario',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'status',
title: 'Estado',
align: 'center',
sortable: true,
formatter: window.btFormatter.status,
},
{
field: 'created_at',
title: 'Creado &nbsp; &nbsp; &nbsp; &nbsp;',
align: 'center',
sortable: true,
visible: false,
},
{
field: 'created_by_name',
title: 'Creado por',
align: 'center',
sortable: true,
visible: false,
sortName: 'created_by_name',
},
{
field: 'updated_at',
title: 'Modificado &nbsp; ',
align: 'center',
sortable: true,
visible: false,
},
]
})
}
function toggleSections() {
const isProspect = $('#is_prospect').is(':checked');
const isCustomer = $('#is_customer').is(':checked');
const isProvider = $('#is_provider').is(':checked');
const isUser = $('#is_user').is(':checked');
$('.div-sat').toggle(isCustomer || isProvider);
$('.div-sat-customer').toggle(isCustomer);
$('.div-user-auth').toggle(isCustomer || isUser);
$('.div-roles').toggle(isUser);
}
function toggleCheckboxes(status) {
const isDisabled = status == 1;
$('#is_prospect, #is_customer, #is_provider, #is_user').prop('disabled', isDisabled);
}
load_js_form = () => {
$('#userForm .select2')
.each(function() {
var $this = $(this)
$this.wrap('<div class="position-relative"></div>')
$this.select2({
dropdownAutoWidth: true,
width: '100%',
dropdownParent: $this.parent()
});
});
// Evento para los checkboxes
$('#is_prospect, #is_customer, #is_provider, #is_user').on('change', toggleSections);
// Evento para el select de estado
$('.div-status').on('change', 'select[name="status"]', function() {
toggleCheckboxes($(this).val());
});
// Previo de imagenes
document.getElementById("photo").addEventListener('change', updatePreviewImage);
// Reset form
$("#userForm")
.on('reset', function(){
var form = $("#userForm");
form.validate().resetForm();
setTimeout(function(){
$('#roles').trigger('change');
toggleSections();
}, 250)
$('#user-image').prop("src", "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
$('#userForm .alert-errors').html('');
$('.pdf-dropzone-div').show();
$("#pdf-dropzone").removeAllFiles(true);
});
$("#userForm")
.validate({
errorClass: 'error',
highlight: function(element, errorClass, validClass) {
// Agrega la clase de error a la fila (contenedor del campo)
$(element).closest('.mb-3').addClass('has-error');
},
unhighlight: function(element, errorClass, validClass) {
// Elimina la clase de error de la fila (contenedor del campo)
$(element).closest('.mb-3').removeClass('has-error');
},
errorPlacement: function(error, element) {
// Controla dónde se colocan los mensajes de error
error.appendTo(element.closest('.mb-3').find('.error-message'));
},
rules: {
name: {
required: true,
minlength: 5
},
email: {
required: true,
email: true
},
password: {
required: function(element) {
return !$("#userForm input[name=id]").val() && ($('#is_user').is(':checked') || $('#is_customer').is(':checked'));
},
minlength: 6
}
},
messages: {
name: {
required: "Por favor ingrese su nombre completo",
minlength: "El nombre completo debe tener al menos 8 caracteres"
},
email: {
required: "Por favor ingrese su correo electrónico",
email: "El valor no es una dirección de correo válida"
},
password: {
required: "La contraseña es obligatoria para nuevos usuarios",
minlength: "La contraseña debe tener al menos 6 caracteres"
}
},
submitHandler: function(form, event) {
// Evita que el formulario se envíe automáticamente
event.preventDefault();
var form = $("#userForm")[0],
data = new FormData(form);
$('#userForm :input').prop('disabled', true);
$('#userForm .alert-errors').html('');
$.ajax({
url: store_route,
method: 'POST',
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
data: data,
contentType: false,
processData: false,
cache: false,
timeout: 3000,
success: function(data) {
$('#userForm :input').prop('disabled', false);
if (data.errors) {
$('#userForm .alert-errors').html('<div class="alert alert-danger alert-dismissible fade show" role="alert">' +
'<div class="alert-body">' + data.errors + '</div>' +
'<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' +
'</div>');
} else {
let $usersIndexAlert = $('.crm-warehouse-index.alert-errors');
$usersIndexAlert.html('<div class="alert alert-success alert-dismissible fade show" role="alert">' +
'<div class="alert-body">' +
'<p class="mb-0"><strong>' + data.success + '</strong></p>' +
'</div>' +
'<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' +
'</div>');
$('#userForm button[type=reset]').trigger('click');
$('#toolbar .clear-filters').trigger('click');
}
},
error: function(e) {
$('#userForm :input').prop('disabled', false);
$('#userForm .alert-errors').html('<div class="alert alert-danger alert-dismissible fade show" role="alert">' +
'<div class="alert-body">' + e.responseJSON.message + '</div>' +
'<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' +
'</div>');
}
});
}
});
// Inicializar el estado al cargar la página
toggleSections();
toggleCheckboxes($('select[name="status"]').val());
}
// Previo de imagen de perfil
updatePreviewImage = (event) => {
var file = event.target.files[0],
reader = new FileReader();
reader.onload = event => {
document.getElementById('user-image').setAttribute('src', event.target.result);
};
reader.readAsDataURL(file);
}
document.addEventListener('DOMContentLoaded', function() {
$(document).ready(function() {
var $table = $('#bt-warehouses'),
$btnRefresh = $('#toolbar .btn-refresh'),
$clearFilters = $('a.clear-filters');
var btt_rest_height = 220,
btt_min_height = 600;
btt_height = (window.innerHeight - btt_rest_height) < btt_min_height?
btt_height:
window.innerHeight - btt_rest_height;
var offcanvasElement = document.getElementById('offcanvasUser'),
offcanvasUser = new bootstrap.Offcanvas(offcanvasElement);
const refreshButton = document.querySelector('.btn-refresh');
const inputs = document.querySelectorAll('#toolbar input, #toolbar select');
inputs.forEach(input => {
input.addEventListener('change', () => {
refreshButton.disabled = false;
refreshButton.classList.remove('btn-label-secondary');
refreshButton.classList.add('btn-label-success');
});
});
// Button Refresh
$btnRefresh
.on('click', () => {
$table.bootstrapTable('refresh');
refreshButton.disabled = true;
refreshButton.classList.remove('btn-label-success');
refreshButton.classList.add('btn-label-secondary');
});
// Button clear filters
$clearFilters
.on('click', () => {
$table.bootstrapTable('resetSearch', ''); // Inicializa la búsqueda con cadena vacía
refreshButton.disabled = true;
refreshButton.classList.remove('btn-label-success');
refreshButton.classList.add('btn-label-secondary');
});
initTable('#bt-warehouses'); // Una vez que todos los scripts estén cargados, inicializa Bootstrap Table
load_js_form();
});
});
</script>
@endpush

View File

@ -0,0 +1,516 @@
<section id="crm-warehouse-index">
<div class="crm-warehouse-index alert-errors"></div>
<div wire:ignore>
<div class="query-filters" id="toolbar">
<div class="d-flex flex-wrap">
<div class="pt-1 pr-2 pb-1" style="min-width: 175px; max-width: 225px">
<button data-bs-toggle='offcanvas' data-bs-target='#offcanvasUser' class="btn btn-primary waves-effect waves-light">Agregar almacén</button>
</div>
<button type="button" class="accordion-button collapsed" data-bs-toggle="collapse" data-bs-target="#accordionFiltrado" aria-expanded="false" aria-controls="accordionFiltrado">
Filtrado
</button>
<div class="px-2 pt-1">
<button class="btn btn-label-secondary waves-effect py-3 btn-refresh" disabled><i class="fa-solid fa-rotate"></i></button>
</div>
<div class="pr-2" style="width: 60px;">
<a href="javascript:void(0)" class="clear-filters">Limpiar Filtrado</a>
</div>
</div>
</div>
<table id="bt-warehouses"></table>
</div>
</section>
@push('page-script')
<script>
const store_route = '{{ route('admin.core.users.store') }}',
route_show = '{{ route('admin.inventory.warehouse.show', ['warehouse' => '~warehouse~']) }}',
route_destroy = '{{ route('admin.inventory.warehouse.destroy', ['warehouse' => '~warehouse~']) }}',
statusList = {!! json_encode($status_list) !!},
statusIntCatalogCss = {!! json_encode($status_list_class) !!};
var btt_height;
// BootstrapTable Petición AJAX
function ajaxRequest(params) {
let url = '{{ url()->current() }}' +
'?' +
$.param(params.data) +
'&' +
$('.query-filters :input').serialize();
$.get(url).then(function (res) {
params.success(res)
})
}
// BootstrapTable Formatter
function userAvatarFormatter(value, row, index) {
if(row.id){
let show_href = route_show.replace('~warehouseo~', row.id);
return [
'<div class="d-flex justify-content-start align-items-center user-name">',
'<div class="avatar-wrapper">',
'<div class="avatar avatar-sm me-4">' +
'<img src="' + row.profile_photo_url + '" alt="Avatar" class="rounded-circle">' +
'</div>',
'</div>',
'<div class="d-flex flex-column">',
'<a href="' + show_href + '" class="text-heading text-truncate"><span class="fw-medium">' + row.name + '</span></a>',
'<small>' + row.email + '</small>',
'</div>',
'</div>',
].join('')
}
}
function uidFormatter(value, row, index) {
if(row.id){
let show_href = route_show.replace('~warehouseo~', row.id);
return [
'<div class="d-flex align-items-center justify-content-center">',
'<a href="' + show_href + '" class="whitespace-nowrap" title="Ver warehouseo"> ' + row.id + '</a>',
@can('crm.warehouses.update')
'<a href="javascript:;" class="btn btn-icon btn-text-secondary waves-effect waves-light rounded-pill dropdown-toggle hide-arrow" data-bs-toggle="dropdown"><i class="ti ti-dots-vertical ti-md"></i></a>',
'<div class="dropdown-menu dropdown-menu-end m-0">',
'<a href="javascript:deleteRow(' + row.id + ');" class="dropdown-item delete-record">Eliminar</a>',
'</div>',
@endcan
'</div>'
].join('')
}
}
// BootstrapTable Init
function initTable(table) {
$(table)
.bootstrapTable('destroy')
.bootstrapTable({
height: btt_height,
locale: 'es-MX',
ajax: "ajaxRequest",
toolbar: "#toolbar",
search: true,
showColumns: true,
showColumnsToggleAll: true,
showExport: true,
showFullscreen: true,
showPaginationSwitch: true,
showRefresh: true,
showToggle: true,
clickToSelect: true,
minimumCountColumns: 4,
fixedColumns: true,
fixedNumber: 1,
idField: "id",
pagination: true,
pageList: [10, 25, 50, 100, 500],
sidePagination: "server",
exportTypes: ['csv', 'txt', 'excel'],
exportOptions: {
fileName: 'warehouseos',
},
sortName: 'users.id',
sortOrder: 'desc',
mobileResponsive: true,
cookie: true,
resizable: true,
cookieIdTable:"crm-warehouse-index",
columns: [
{
field: 'id',
title: 'UID',
align: 'center',
sortable: true,
sortName: 'users.id',
switchable: false,
formatter: uidFormatter
},
{
field: 'name',
title: 'Nombre',
formatter: userAvatarFormatter,
},
{
field: 'email',
title: 'Correo electrónico',
sortable: true,
visible: false,
},
{
field: 'tipo_persona',
title: 'Tipo persona',
visible: false,
sortable: true,
formatter: window.btFormatter.tipoPersona,
},
{
field: 'rfc',
title: 'RFC',
sortable: true,
},
{
field: 'nombre_fiscal',
title: 'Nombre fiscal',
sortable: true,
},
{
field: 'c_regimen_fiscal',
title: 'Regimen fiscal',
sortable: true,
visible: false,
formatter: window.btFormatter.regimenFiscal,
},
{
field: 'domicilio_fiscal',
title: 'Domicilio fiscal',
sortable: true,
visible: false,
},
{
field: 'estado',
title: 'Estado',
sortable: true,
},
{
field: 'municipio',
title: 'Municipio',
sortable: true,
},
{
field: 'localidad',
title: 'Localidad',
sortable: true,
visible: false,
},
{
field: 'c_uso_cfdi',
title: 'Uso de CFDI',
sortable: true,
visible: false,
formatter: window.btFormatter.usoCfdi,
},
{
field: 'cargo',
title: 'Cargo',
visible: false,
sortable: true,
},
{
field: 'is_prospect',
title: 'Es prospecto',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'is_customer',
title: 'Es cliente',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'is_provider',
title: 'Es proveedor',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'is_user',
title: 'Es usuario',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'status',
title: 'Estado',
align: 'center',
sortable: true,
formatter: window.btFormatter.status,
},
{
field: 'created_at',
title: 'Creado &nbsp; &nbsp; &nbsp; &nbsp;',
align: 'center',
sortable: true,
visible: false,
},
{
field: 'created_by_name',
title: 'Creado por',
align: 'center',
sortable: true,
visible: false,
sortName: 'created_by_name',
},
{
field: 'updated_at',
title: 'Modificado &nbsp; ',
align: 'center',
sortable: true,
visible: false,
},
]
})
}
function toggleSections() {
const isProspect = $('#is_prospect').is(':checked');
const isCustomer = $('#is_customer').is(':checked');
const isProvider = $('#is_provider').is(':checked');
const isUser = $('#is_user').is(':checked');
$('.div-sat').toggle(isCustomer || isProvider);
$('.div-sat-customer').toggle(isCustomer);
$('.div-user-auth').toggle(isCustomer || isUser);
$('.div-roles').toggle(isUser);
}
function toggleCheckboxes(status) {
const isDisabled = status == 1;
$('#is_prospect, #is_customer, #is_provider, #is_user').prop('disabled', isDisabled);
}
load_js_form = () => {
$('#userForm .select2')
.each(function() {
var $this = $(this)
$this.wrap('<div class="position-relative"></div>')
$this.select2({
dropdownAutoWidth: true,
width: '100%',
dropdownParent: $this.parent()
});
});
// Evento para los checkboxes
$('#is_prospect, #is_customer, #is_provider, #is_user').on('change', toggleSections);
// Evento para el select de estado
$('.div-status').on('change', 'select[name="status"]', function() {
toggleCheckboxes($(this).val());
});
// Previo de imagenes
document.getElementById("photo").addEventListener('change', updatePreviewImage);
// Reset form
$("#userForm")
.on('reset', function(){
var form = $("#userForm");
form.validate().resetForm();
setTimeout(function(){
$('#roles').trigger('change');
toggleSections();
}, 250)
$('#user-image').prop("src", "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
$('#userForm .alert-errors').html('');
$('.pdf-dropzone-div').show();
$("#pdf-dropzone").removeAllFiles(true);
});
$("#userForm")
.validate({
errorClass: 'error',
highlight: function(element, errorClass, validClass) {
// Agrega la clase de error a la fila (contenedor del campo)
$(element).closest('.mb-3').addClass('has-error');
},
unhighlight: function(element, errorClass, validClass) {
// Elimina la clase de error de la fila (contenedor del campo)
$(element).closest('.mb-3').removeClass('has-error');
},
errorPlacement: function(error, element) {
// Controla dónde se colocan los mensajes de error
error.appendTo(element.closest('.mb-3').find('.error-message'));
},
rules: {
name: {
required: true,
minlength: 5
},
email: {
required: true,
email: true
},
password: {
required: function(element) {
return !$("#userForm input[name=id]").val() && ($('#is_user').is(':checked') || $('#is_customer').is(':checked'));
},
minlength: 6
}
},
messages: {
name: {
required: "Por favor ingrese su nombre completo",
minlength: "El nombre completo debe tener al menos 8 caracteres"
},
email: {
required: "Por favor ingrese su correo electrónico",
email: "El valor no es una dirección de correo válida"
},
password: {
required: "La contraseña es obligatoria para nuevos usuarios",
minlength: "La contraseña debe tener al menos 6 caracteres"
}
},
submitHandler: function(form, event) {
// Evita que el formulario se envíe automáticamente
event.preventDefault();
var form = $("#userForm")[0],
data = new FormData(form);
$('#userForm :input').prop('disabled', true);
$('#userForm .alert-errors').html('');
$.ajax({
url: store_route,
method: 'POST',
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
data: data,
contentType: false,
processData: false,
cache: false,
timeout: 3000,
success: function(data) {
$('#userForm :input').prop('disabled', false);
if (data.errors) {
$('#userForm .alert-errors').html('<div class="alert alert-danger alert-dismissible fade show" role="alert">' +
'<div class="alert-body">' + data.errors + '</div>' +
'<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' +
'</div>');
} else {
let $usersIndexAlert = $('.crm-warehouse-index.alert-errors');
$usersIndexAlert.html('<div class="alert alert-success alert-dismissible fade show" role="alert">' +
'<div class="alert-body">' +
'<p class="mb-0"><strong>' + data.success + '</strong></p>' +
'</div>' +
'<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' +
'</div>');
$('#userForm button[type=reset]').trigger('click');
$('#toolbar .clear-filters').trigger('click');
}
},
error: function(e) {
$('#userForm :input').prop('disabled', false);
$('#userForm .alert-errors').html('<div class="alert alert-danger alert-dismissible fade show" role="alert">' +
'<div class="alert-body">' + e.responseJSON.message + '</div>' +
'<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' +
'</div>');
}
});
}
});
// Inicializar el estado al cargar la página
toggleSections();
toggleCheckboxes($('select[name="status"]').val());
}
// Previo de imagen de perfil
updatePreviewImage = (event) => {
var file = event.target.files[0],
reader = new FileReader();
reader.onload = event => {
document.getElementById('user-image').setAttribute('src', event.target.result);
};
reader.readAsDataURL(file);
}
document.addEventListener('DOMContentLoaded', function() {
$(document).ready(function() {
var $table = $('#bt-warehouses'),
$btnRefresh = $('#toolbar .btn-refresh'),
$clearFilters = $('a.clear-filters');
var btt_rest_height = 220,
btt_min_height = 600;
btt_height = (window.innerHeight - btt_rest_height) < btt_min_height?
btt_height:
window.innerHeight - btt_rest_height;
var offcanvasElement = document.getElementById('offcanvasUser'),
offcanvasUser = new bootstrap.Offcanvas(offcanvasElement);
const refreshButton = document.querySelector('.btn-refresh');
const inputs = document.querySelectorAll('#toolbar input, #toolbar select');
inputs.forEach(input => {
input.addEventListener('change', () => {
refreshButton.disabled = false;
refreshButton.classList.remove('btn-label-secondary');
refreshButton.classList.add('btn-label-success');
});
});
// Button Refresh
$btnRefresh
.on('click', () => {
$table.bootstrapTable('refresh');
refreshButton.disabled = true;
refreshButton.classList.remove('btn-label-success');
refreshButton.classList.add('btn-label-secondary');
});
// Button clear filters
$clearFilters
.on('click', () => {
$table.bootstrapTable('resetSearch', ''); // Inicializa la búsqueda con cadena vacía
refreshButton.disabled = true;
refreshButton.classList.remove('btn-label-success');
refreshButton.classList.add('btn-label-secondary');
});
initTable('#bt-warehouses'); // Una vez que todos los scripts estén cargados, inicializa Bootstrap Table
load_js_form();
});
});
</script>
@endpush

View File

@ -0,0 +1,516 @@
<section id="crm-warehouse-index">
<div class="crm-warehouse-index alert-errors"></div>
<div wire:ignore>
<div class="query-filters" id="toolbar">
<div class="d-flex flex-wrap">
<div class="pt-1 pr-2 pb-1" style="min-width: 175px; max-width: 225px">
<button data-bs-toggle='offcanvas' data-bs-target='#offcanvasUser' class="btn btn-primary waves-effect waves-light">Agregar almacén</button>
</div>
<button type="button" class="accordion-button collapsed" data-bs-toggle="collapse" data-bs-target="#accordionFiltrado" aria-expanded="false" aria-controls="accordionFiltrado">
Filtrado
</button>
<div class="px-2 pt-1">
<button class="btn btn-label-secondary waves-effect py-3 btn-refresh" disabled><i class="fa-solid fa-rotate"></i></button>
</div>
<div class="pr-2" style="width: 60px;">
<a href="javascript:void(0)" class="clear-filters">Limpiar Filtrado</a>
</div>
</div>
</div>
<table id="bt-warehouses"></table>
</div>
</section>
@push('page-script')
<script>
const store_route = '{{ route('admin.core.users.store') }}',
route_show = '{{ route('admin.inventory.warehouse.show', ['warehouse' => '~warehouse~']) }}',
route_destroy = '{{ route('admin.inventory.warehouse.destroy', ['warehouse' => '~warehouse~']) }}',
statusList = {!! json_encode($status_list) !!},
statusIntCatalogCss = {!! json_encode($status_list_class) !!};
var btt_height;
// BootstrapTable Petición AJAX
function ajaxRequest(params) {
let url = '{{ url()->current() }}' +
'?' +
$.param(params.data) +
'&' +
$('.query-filters :input').serialize();
$.get(url).then(function (res) {
params.success(res)
})
}
// BootstrapTable Formatter
function userAvatarFormatter(value, row, index) {
if(row.id){
let show_href = route_show.replace('~warehouseo~', row.id);
return [
'<div class="d-flex justify-content-start align-items-center user-name">',
'<div class="avatar-wrapper">',
'<div class="avatar avatar-sm me-4">' +
'<img src="' + row.profile_photo_url + '" alt="Avatar" class="rounded-circle">' +
'</div>',
'</div>',
'<div class="d-flex flex-column">',
'<a href="' + show_href + '" class="text-heading text-truncate"><span class="fw-medium">' + row.name + '</span></a>',
'<small>' + row.email + '</small>',
'</div>',
'</div>',
].join('')
}
}
function uidFormatter(value, row, index) {
if(row.id){
let show_href = route_show.replace('~warehouseo~', row.id);
return [
'<div class="d-flex align-items-center justify-content-center">',
'<a href="' + show_href + '" class="whitespace-nowrap" title="Ver warehouseo"> ' + row.id + '</a>',
@can('crm.warehouses.update')
'<a href="javascript:;" class="btn btn-icon btn-text-secondary waves-effect waves-light rounded-pill dropdown-toggle hide-arrow" data-bs-toggle="dropdown"><i class="ti ti-dots-vertical ti-md"></i></a>',
'<div class="dropdown-menu dropdown-menu-end m-0">',
'<a href="javascript:deleteRow(' + row.id + ');" class="dropdown-item delete-record">Eliminar</a>',
'</div>',
@endcan
'</div>'
].join('')
}
}
// BootstrapTable Init
function initTable(table) {
$(table)
.bootstrapTable('destroy')
.bootstrapTable({
height: btt_height,
locale: 'es-MX',
ajax: "ajaxRequest",
toolbar: "#toolbar",
search: true,
showColumns: true,
showColumnsToggleAll: true,
showExport: true,
showFullscreen: true,
showPaginationSwitch: true,
showRefresh: true,
showToggle: true,
clickToSelect: true,
minimumCountColumns: 4,
fixedColumns: true,
fixedNumber: 1,
idField: "id",
pagination: true,
pageList: [10, 25, 50, 100, 500],
sidePagination: "server",
exportTypes: ['csv', 'txt', 'excel'],
exportOptions: {
fileName: 'warehouseos',
},
sortName: 'users.id',
sortOrder: 'desc',
mobileResponsive: true,
cookie: true,
resizable: true,
cookieIdTable:"crm-warehouse-index",
columns: [
{
field: 'id',
title: 'UID',
align: 'center',
sortable: true,
sortName: 'users.id',
switchable: false,
formatter: uidFormatter
},
{
field: 'name',
title: 'Nombre',
formatter: userAvatarFormatter,
},
{
field: 'email',
title: 'Correo electrónico',
sortable: true,
visible: false,
},
{
field: 'tipo_persona',
title: 'Tipo persona',
visible: false,
sortable: true,
formatter: window.btFormatter.tipoPersona,
},
{
field: 'rfc',
title: 'RFC',
sortable: true,
},
{
field: 'nombre_fiscal',
title: 'Nombre fiscal',
sortable: true,
},
{
field: 'c_regimen_fiscal',
title: 'Regimen fiscal',
sortable: true,
visible: false,
formatter: window.btFormatter.regimenFiscal,
},
{
field: 'domicilio_fiscal',
title: 'Domicilio fiscal',
sortable: true,
visible: false,
},
{
field: 'estado',
title: 'Estado',
sortable: true,
},
{
field: 'municipio',
title: 'Municipio',
sortable: true,
},
{
field: 'localidad',
title: 'Localidad',
sortable: true,
visible: false,
},
{
field: 'c_uso_cfdi',
title: 'Uso de CFDI',
sortable: true,
visible: false,
formatter: window.btFormatter.usoCfdi,
},
{
field: 'cargo',
title: 'Cargo',
visible: false,
sortable: true,
},
{
field: 'is_prospect',
title: 'Es prospecto',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'is_customer',
title: 'Es cliente',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'is_provider',
title: 'Es proveedor',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'is_user',
title: 'Es usuario',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'status',
title: 'Estado',
align: 'center',
sortable: true,
formatter: window.btFormatter.status,
},
{
field: 'created_at',
title: 'Creado &nbsp; &nbsp; &nbsp; &nbsp;',
align: 'center',
sortable: true,
visible: false,
},
{
field: 'created_by_name',
title: 'Creado por',
align: 'center',
sortable: true,
visible: false,
sortName: 'created_by_name',
},
{
field: 'updated_at',
title: 'Modificado &nbsp; ',
align: 'center',
sortable: true,
visible: false,
},
]
})
}
function toggleSections() {
const isProspect = $('#is_prospect').is(':checked');
const isCustomer = $('#is_customer').is(':checked');
const isProvider = $('#is_provider').is(':checked');
const isUser = $('#is_user').is(':checked');
$('.div-sat').toggle(isCustomer || isProvider);
$('.div-sat-customer').toggle(isCustomer);
$('.div-user-auth').toggle(isCustomer || isUser);
$('.div-roles').toggle(isUser);
}
function toggleCheckboxes(status) {
const isDisabled = status == 1;
$('#is_prospect, #is_customer, #is_provider, #is_user').prop('disabled', isDisabled);
}
load_js_form = () => {
$('#userForm .select2')
.each(function() {
var $this = $(this)
$this.wrap('<div class="position-relative"></div>')
$this.select2({
dropdownAutoWidth: true,
width: '100%',
dropdownParent: $this.parent()
});
});
// Evento para los checkboxes
$('#is_prospect, #is_customer, #is_provider, #is_user').on('change', toggleSections);
// Evento para el select de estado
$('.div-status').on('change', 'select[name="status"]', function() {
toggleCheckboxes($(this).val());
});
// Previo de imagenes
document.getElementById("photo").addEventListener('change', updatePreviewImage);
// Reset form
$("#userForm")
.on('reset', function(){
var form = $("#userForm");
form.validate().resetForm();
setTimeout(function(){
$('#roles').trigger('change');
toggleSections();
}, 250)
$('#user-image').prop("src", "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
$('#userForm .alert-errors').html('');
$('.pdf-dropzone-div').show();
$("#pdf-dropzone").removeAllFiles(true);
});
$("#userForm")
.validate({
errorClass: 'error',
highlight: function(element, errorClass, validClass) {
// Agrega la clase de error a la fila (contenedor del campo)
$(element).closest('.mb-3').addClass('has-error');
},
unhighlight: function(element, errorClass, validClass) {
// Elimina la clase de error de la fila (contenedor del campo)
$(element).closest('.mb-3').removeClass('has-error');
},
errorPlacement: function(error, element) {
// Controla dónde se colocan los mensajes de error
error.appendTo(element.closest('.mb-3').find('.error-message'));
},
rules: {
name: {
required: true,
minlength: 5
},
email: {
required: true,
email: true
},
password: {
required: function(element) {
return !$("#userForm input[name=id]").val() && ($('#is_user').is(':checked') || $('#is_customer').is(':checked'));
},
minlength: 6
}
},
messages: {
name: {
required: "Por favor ingrese su nombre completo",
minlength: "El nombre completo debe tener al menos 8 caracteres"
},
email: {
required: "Por favor ingrese su correo electrónico",
email: "El valor no es una dirección de correo válida"
},
password: {
required: "La contraseña es obligatoria para nuevos usuarios",
minlength: "La contraseña debe tener al menos 6 caracteres"
}
},
submitHandler: function(form, event) {
// Evita que el formulario se envíe automáticamente
event.preventDefault();
var form = $("#userForm")[0],
data = new FormData(form);
$('#userForm :input').prop('disabled', true);
$('#userForm .alert-errors').html('');
$.ajax({
url: store_route,
method: 'POST',
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
data: data,
contentType: false,
processData: false,
cache: false,
timeout: 3000,
success: function(data) {
$('#userForm :input').prop('disabled', false);
if (data.errors) {
$('#userForm .alert-errors').html('<div class="alert alert-danger alert-dismissible fade show" role="alert">' +
'<div class="alert-body">' + data.errors + '</div>' +
'<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' +
'</div>');
} else {
let $usersIndexAlert = $('.crm-warehouse-index.alert-errors');
$usersIndexAlert.html('<div class="alert alert-success alert-dismissible fade show" role="alert">' +
'<div class="alert-body">' +
'<p class="mb-0"><strong>' + data.success + '</strong></p>' +
'</div>' +
'<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' +
'</div>');
$('#userForm button[type=reset]').trigger('click');
$('#toolbar .clear-filters').trigger('click');
}
},
error: function(e) {
$('#userForm :input').prop('disabled', false);
$('#userForm .alert-errors').html('<div class="alert alert-danger alert-dismissible fade show" role="alert">' +
'<div class="alert-body">' + e.responseJSON.message + '</div>' +
'<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' +
'</div>');
}
});
}
});
// Inicializar el estado al cargar la página
toggleSections();
toggleCheckboxes($('select[name="status"]').val());
}
// Previo de imagen de perfil
updatePreviewImage = (event) => {
var file = event.target.files[0],
reader = new FileReader();
reader.onload = event => {
document.getElementById('user-image').setAttribute('src', event.target.result);
};
reader.readAsDataURL(file);
}
document.addEventListener('DOMContentLoaded', function() {
$(document).ready(function() {
var $table = $('#bt-warehouses'),
$btnRefresh = $('#toolbar .btn-refresh'),
$clearFilters = $('a.clear-filters');
var btt_rest_height = 220,
btt_min_height = 600;
btt_height = (window.innerHeight - btt_rest_height) < btt_min_height?
btt_height:
window.innerHeight - btt_rest_height;
var offcanvasElement = document.getElementById('offcanvasUser'),
offcanvasUser = new bootstrap.Offcanvas(offcanvasElement);
const refreshButton = document.querySelector('.btn-refresh');
const inputs = document.querySelectorAll('#toolbar input, #toolbar select');
inputs.forEach(input => {
input.addEventListener('change', () => {
refreshButton.disabled = false;
refreshButton.classList.remove('btn-label-secondary');
refreshButton.classList.add('btn-label-success');
});
});
// Button Refresh
$btnRefresh
.on('click', () => {
$table.bootstrapTable('refresh');
refreshButton.disabled = true;
refreshButton.classList.remove('btn-label-success');
refreshButton.classList.add('btn-label-secondary');
});
// Button clear filters
$clearFilters
.on('click', () => {
$table.bootstrapTable('resetSearch', ''); // Inicializa la búsqueda con cadena vacía
refreshButton.disabled = true;
refreshButton.classList.remove('btn-label-success');
refreshButton.classList.add('btn-label-secondary');
});
initTable('#bt-warehouses'); // Una vez que todos los scripts estén cargados, inicializa Bootstrap Table
load_js_form();
});
});
</script>
@endpush

View File

@ -0,0 +1,516 @@
<section id="crm-warehouse-index">
<div class="crm-warehouse-index alert-errors"></div>
<div wire:ignore>
<div class="query-filters" id="toolbar">
<div class="d-flex flex-wrap">
<div class="pt-1 pr-2 pb-1" style="min-width: 175px; max-width: 225px">
<button data-bs-toggle='offcanvas' data-bs-target='#offcanvasUser' class="btn btn-primary waves-effect waves-light">Agregar almacén</button>
</div>
<button type="button" class="accordion-button collapsed" data-bs-toggle="collapse" data-bs-target="#accordionFiltrado" aria-expanded="false" aria-controls="accordionFiltrado">
Filtrado
</button>
<div class="px-2 pt-1">
<button class="btn btn-label-secondary waves-effect py-3 btn-refresh" disabled><i class="fa-solid fa-rotate"></i></button>
</div>
<div class="pr-2" style="width: 60px;">
<a href="javascript:void(0)" class="clear-filters">Limpiar Filtrado</a>
</div>
</div>
</div>
<table id="bt-warehouses"></table>
</div>
</section>
@push('page-script')
<script>
const store_route = '{{ route('admin.core.users.store') }}',
route_show = '{{ route('admin.inventory.warehouse.show', ['warehouse' => '~warehouse~']) }}',
route_destroy = '{{ route('admin.inventory.warehouse.destroy', ['warehouse' => '~warehouse~']) }}',
statusList = {!! json_encode($status_list) !!},
statusIntCatalogCss = {!! json_encode($status_list_class) !!};
var btt_height;
// BootstrapTable Petición AJAX
function ajaxRequest(params) {
let url = '{{ url()->current() }}' +
'?' +
$.param(params.data) +
'&' +
$('.query-filters :input').serialize();
$.get(url).then(function (res) {
params.success(res)
})
}
// BootstrapTable Formatter
function userAvatarFormatter(value, row, index) {
if(row.id){
let show_href = route_show.replace('~warehouseo~', row.id);
return [
'<div class="d-flex justify-content-start align-items-center user-name">',
'<div class="avatar-wrapper">',
'<div class="avatar avatar-sm me-4">' +
'<img src="' + row.profile_photo_url + '" alt="Avatar" class="rounded-circle">' +
'</div>',
'</div>',
'<div class="d-flex flex-column">',
'<a href="' + show_href + '" class="text-heading text-truncate"><span class="fw-medium">' + row.name + '</span></a>',
'<small>' + row.email + '</small>',
'</div>',
'</div>',
].join('')
}
}
function uidFormatter(value, row, index) {
if(row.id){
let show_href = route_show.replace('~warehouseo~', row.id);
return [
'<div class="d-flex align-items-center justify-content-center">',
'<a href="' + show_href + '" class="whitespace-nowrap" title="Ver warehouseo"> ' + row.id + '</a>',
@can('crm.warehouses.update')
'<a href="javascript:;" class="btn btn-icon btn-text-secondary waves-effect waves-light rounded-pill dropdown-toggle hide-arrow" data-bs-toggle="dropdown"><i class="ti ti-dots-vertical ti-md"></i></a>',
'<div class="dropdown-menu dropdown-menu-end m-0">',
'<a href="javascript:deleteRow(' + row.id + ');" class="dropdown-item delete-record">Eliminar</a>',
'</div>',
@endcan
'</div>'
].join('')
}
}
// BootstrapTable Init
function initTable(table) {
$(table)
.bootstrapTable('destroy')
.bootstrapTable({
height: btt_height,
locale: 'es-MX',
ajax: "ajaxRequest",
toolbar: "#toolbar",
search: true,
showColumns: true,
showColumnsToggleAll: true,
showExport: true,
showFullscreen: true,
showPaginationSwitch: true,
showRefresh: true,
showToggle: true,
clickToSelect: true,
minimumCountColumns: 4,
fixedColumns: true,
fixedNumber: 1,
idField: "id",
pagination: true,
pageList: [10, 25, 50, 100, 500],
sidePagination: "server",
exportTypes: ['csv', 'txt', 'excel'],
exportOptions: {
fileName: 'warehouseos',
},
sortName: 'users.id',
sortOrder: 'desc',
mobileResponsive: true,
cookie: true,
resizable: true,
cookieIdTable:"crm-warehouse-index",
columns: [
{
field: 'id',
title: 'UID',
align: 'center',
sortable: true,
sortName: 'users.id',
switchable: false,
formatter: uidFormatter
},
{
field: 'name',
title: 'Nombre',
formatter: userAvatarFormatter,
},
{
field: 'email',
title: 'Correo electrónico',
sortable: true,
visible: false,
},
{
field: 'tipo_persona',
title: 'Tipo persona',
visible: false,
sortable: true,
formatter: window.btFormatter.tipoPersona,
},
{
field: 'rfc',
title: 'RFC',
sortable: true,
},
{
field: 'nombre_fiscal',
title: 'Nombre fiscal',
sortable: true,
},
{
field: 'c_regimen_fiscal',
title: 'Regimen fiscal',
sortable: true,
visible: false,
formatter: window.btFormatter.regimenFiscal,
},
{
field: 'domicilio_fiscal',
title: 'Domicilio fiscal',
sortable: true,
visible: false,
},
{
field: 'estado',
title: 'Estado',
sortable: true,
},
{
field: 'municipio',
title: 'Municipio',
sortable: true,
},
{
field: 'localidad',
title: 'Localidad',
sortable: true,
visible: false,
},
{
field: 'c_uso_cfdi',
title: 'Uso de CFDI',
sortable: true,
visible: false,
formatter: window.btFormatter.usoCfdi,
},
{
field: 'cargo',
title: 'Cargo',
visible: false,
sortable: true,
},
{
field: 'is_prospect',
title: 'Es prospecto',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'is_customer',
title: 'Es cliente',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'is_provider',
title: 'Es proveedor',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'is_user',
title: 'Es usuario',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'status',
title: 'Estado',
align: 'center',
sortable: true,
formatter: window.btFormatter.status,
},
{
field: 'created_at',
title: 'Creado &nbsp; &nbsp; &nbsp; &nbsp;',
align: 'center',
sortable: true,
visible: false,
},
{
field: 'created_by_name',
title: 'Creado por',
align: 'center',
sortable: true,
visible: false,
sortName: 'created_by_name',
},
{
field: 'updated_at',
title: 'Modificado &nbsp; ',
align: 'center',
sortable: true,
visible: false,
},
]
})
}
function toggleSections() {
const isProspect = $('#is_prospect').is(':checked');
const isCustomer = $('#is_customer').is(':checked');
const isProvider = $('#is_provider').is(':checked');
const isUser = $('#is_user').is(':checked');
$('.div-sat').toggle(isCustomer || isProvider);
$('.div-sat-customer').toggle(isCustomer);
$('.div-user-auth').toggle(isCustomer || isUser);
$('.div-roles').toggle(isUser);
}
function toggleCheckboxes(status) {
const isDisabled = status == 1;
$('#is_prospect, #is_customer, #is_provider, #is_user').prop('disabled', isDisabled);
}
load_js_form = () => {
$('#userForm .select2')
.each(function() {
var $this = $(this)
$this.wrap('<div class="position-relative"></div>')
$this.select2({
dropdownAutoWidth: true,
width: '100%',
dropdownParent: $this.parent()
});
});
// Evento para los checkboxes
$('#is_prospect, #is_customer, #is_provider, #is_user').on('change', toggleSections);
// Evento para el select de estado
$('.div-status').on('change', 'select[name="status"]', function() {
toggleCheckboxes($(this).val());
});
// Previo de imagenes
document.getElementById("photo").addEventListener('change', updatePreviewImage);
// Reset form
$("#userForm")
.on('reset', function(){
var form = $("#userForm");
form.validate().resetForm();
setTimeout(function(){
$('#roles').trigger('change');
toggleSections();
}, 250)
$('#user-image').prop("src", "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
$('#userForm .alert-errors').html('');
$('.pdf-dropzone-div').show();
$("#pdf-dropzone").removeAllFiles(true);
});
$("#userForm")
.validate({
errorClass: 'error',
highlight: function(element, errorClass, validClass) {
// Agrega la clase de error a la fila (contenedor del campo)
$(element).closest('.mb-3').addClass('has-error');
},
unhighlight: function(element, errorClass, validClass) {
// Elimina la clase de error de la fila (contenedor del campo)
$(element).closest('.mb-3').removeClass('has-error');
},
errorPlacement: function(error, element) {
// Controla dónde se colocan los mensajes de error
error.appendTo(element.closest('.mb-3').find('.error-message'));
},
rules: {
name: {
required: true,
minlength: 5
},
email: {
required: true,
email: true
},
password: {
required: function(element) {
return !$("#userForm input[name=id]").val() && ($('#is_user').is(':checked') || $('#is_customer').is(':checked'));
},
minlength: 6
}
},
messages: {
name: {
required: "Por favor ingrese su nombre completo",
minlength: "El nombre completo debe tener al menos 8 caracteres"
},
email: {
required: "Por favor ingrese su correo electrónico",
email: "El valor no es una dirección de correo válida"
},
password: {
required: "La contraseña es obligatoria para nuevos usuarios",
minlength: "La contraseña debe tener al menos 6 caracteres"
}
},
submitHandler: function(form, event) {
// Evita que el formulario se envíe automáticamente
event.preventDefault();
var form = $("#userForm")[0],
data = new FormData(form);
$('#userForm :input').prop('disabled', true);
$('#userForm .alert-errors').html('');
$.ajax({
url: store_route,
method: 'POST',
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
data: data,
contentType: false,
processData: false,
cache: false,
timeout: 3000,
success: function(data) {
$('#userForm :input').prop('disabled', false);
if (data.errors) {
$('#userForm .alert-errors').html('<div class="alert alert-danger alert-dismissible fade show" role="alert">' +
'<div class="alert-body">' + data.errors + '</div>' +
'<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' +
'</div>');
} else {
let $usersIndexAlert = $('.crm-warehouse-index.alert-errors');
$usersIndexAlert.html('<div class="alert alert-success alert-dismissible fade show" role="alert">' +
'<div class="alert-body">' +
'<p class="mb-0"><strong>' + data.success + '</strong></p>' +
'</div>' +
'<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' +
'</div>');
$('#userForm button[type=reset]').trigger('click');
$('#toolbar .clear-filters').trigger('click');
}
},
error: function(e) {
$('#userForm :input').prop('disabled', false);
$('#userForm .alert-errors').html('<div class="alert alert-danger alert-dismissible fade show" role="alert">' +
'<div class="alert-body">' + e.responseJSON.message + '</div>' +
'<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' +
'</div>');
}
});
}
});
// Inicializar el estado al cargar la página
toggleSections();
toggleCheckboxes($('select[name="status"]').val());
}
// Previo de imagen de perfil
updatePreviewImage = (event) => {
var file = event.target.files[0],
reader = new FileReader();
reader.onload = event => {
document.getElementById('user-image').setAttribute('src', event.target.result);
};
reader.readAsDataURL(file);
}
document.addEventListener('DOMContentLoaded', function() {
$(document).ready(function() {
var $table = $('#bt-warehouses'),
$btnRefresh = $('#toolbar .btn-refresh'),
$clearFilters = $('a.clear-filters');
var btt_rest_height = 220,
btt_min_height = 600;
btt_height = (window.innerHeight - btt_rest_height) < btt_min_height?
btt_height:
window.innerHeight - btt_rest_height;
var offcanvasElement = document.getElementById('offcanvasUser'),
offcanvasUser = new bootstrap.Offcanvas(offcanvasElement);
const refreshButton = document.querySelector('.btn-refresh');
const inputs = document.querySelectorAll('#toolbar input, #toolbar select');
inputs.forEach(input => {
input.addEventListener('change', () => {
refreshButton.disabled = false;
refreshButton.classList.remove('btn-label-secondary');
refreshButton.classList.add('btn-label-success');
});
});
// Button Refresh
$btnRefresh
.on('click', () => {
$table.bootstrapTable('refresh');
refreshButton.disabled = true;
refreshButton.classList.remove('btn-label-success');
refreshButton.classList.add('btn-label-secondary');
});
// Button clear filters
$clearFilters
.on('click', () => {
$table.bootstrapTable('resetSearch', ''); // Inicializa la búsqueda con cadena vacía
refreshButton.disabled = true;
refreshButton.classList.remove('btn-label-success');
refreshButton.classList.add('btn-label-secondary');
});
initTable('#bt-warehouses'); // Una vez que todos los scripts estén cargados, inicializa Bootstrap Table
load_js_form();
});
});
</script>
@endpush

View File

@ -0,0 +1,516 @@
<section id="crm-warehouse-index">
<div class="crm-warehouse-index alert-errors"></div>
<div wire:ignore>
<div class="query-filters" id="toolbar">
<div class="d-flex flex-wrap">
<div class="pt-1 pr-2 pb-1" style="min-width: 175px; max-width: 225px">
<button data-bs-toggle='offcanvas' data-bs-target='#offcanvasUser' class="btn btn-primary waves-effect waves-light">Agregar almacén</button>
</div>
<button type="button" class="accordion-button collapsed" data-bs-toggle="collapse" data-bs-target="#accordionFiltrado" aria-expanded="false" aria-controls="accordionFiltrado">
Filtrado
</button>
<div class="px-2 pt-1">
<button class="btn btn-label-secondary waves-effect py-3 btn-refresh" disabled><i class="fa-solid fa-rotate"></i></button>
</div>
<div class="pr-2" style="width: 60px;">
<a href="javascript:void(0)" class="clear-filters">Limpiar Filtrado</a>
</div>
</div>
</div>
<table id="bt-warehouses"></table>
</div>
</section>
@push('page-script')
<script>
const store_route = '{{ route('admin.core.users.store') }}',
route_show = '{{ route('admin.inventory.warehouse.show', ['warehouse' => '~warehouse~']) }}',
route_destroy = '{{ route('admin.inventory.warehouse.destroy', ['warehouse' => '~warehouse~']) }}',
statusList = {!! json_encode($status_list) !!},
statusIntCatalogCss = {!! json_encode($status_list_class) !!};
var btt_height;
// BootstrapTable Petición AJAX
function ajaxRequest(params) {
let url = '{{ url()->current() }}' +
'?' +
$.param(params.data) +
'&' +
$('.query-filters :input').serialize();
$.get(url).then(function (res) {
params.success(res)
})
}
// BootstrapTable Formatter
function userAvatarFormatter(value, row, index) {
if(row.id){
let show_href = route_show.replace('~warehouseo~', row.id);
return [
'<div class="d-flex justify-content-start align-items-center user-name">',
'<div class="avatar-wrapper">',
'<div class="avatar avatar-sm me-4">' +
'<img src="' + row.profile_photo_url + '" alt="Avatar" class="rounded-circle">' +
'</div>',
'</div>',
'<div class="d-flex flex-column">',
'<a href="' + show_href + '" class="text-heading text-truncate"><span class="fw-medium">' + row.name + '</span></a>',
'<small>' + row.email + '</small>',
'</div>',
'</div>',
].join('')
}
}
function uidFormatter(value, row, index) {
if(row.id){
let show_href = route_show.replace('~warehouseo~', row.id);
return [
'<div class="d-flex align-items-center justify-content-center">',
'<a href="' + show_href + '" class="whitespace-nowrap" title="Ver warehouseo"> ' + row.id + '</a>',
@can('crm.warehouses.update')
'<a href="javascript:;" class="btn btn-icon btn-text-secondary waves-effect waves-light rounded-pill dropdown-toggle hide-arrow" data-bs-toggle="dropdown"><i class="ti ti-dots-vertical ti-md"></i></a>',
'<div class="dropdown-menu dropdown-menu-end m-0">',
'<a href="javascript:deleteRow(' + row.id + ');" class="dropdown-item delete-record">Eliminar</a>',
'</div>',
@endcan
'</div>'
].join('')
}
}
// BootstrapTable Init
function initTable(table) {
$(table)
.bootstrapTable('destroy')
.bootstrapTable({
height: btt_height,
locale: 'es-MX',
ajax: "ajaxRequest",
toolbar: "#toolbar",
search: true,
showColumns: true,
showColumnsToggleAll: true,
showExport: true,
showFullscreen: true,
showPaginationSwitch: true,
showRefresh: true,
showToggle: true,
clickToSelect: true,
minimumCountColumns: 4,
fixedColumns: true,
fixedNumber: 1,
idField: "id",
pagination: true,
pageList: [10, 25, 50, 100, 500],
sidePagination: "server",
exportTypes: ['csv', 'txt', 'excel'],
exportOptions: {
fileName: 'warehouseos',
},
sortName: 'users.id',
sortOrder: 'desc',
mobileResponsive: true,
cookie: true,
resizable: true,
cookieIdTable:"crm-warehouse-index",
columns: [
{
field: 'id',
title: 'UID',
align: 'center',
sortable: true,
sortName: 'users.id',
switchable: false,
formatter: uidFormatter
},
{
field: 'name',
title: 'Nombre',
formatter: userAvatarFormatter,
},
{
field: 'email',
title: 'Correo electrónico',
sortable: true,
visible: false,
},
{
field: 'tipo_persona',
title: 'Tipo persona',
visible: false,
sortable: true,
formatter: window.btFormatter.tipoPersona,
},
{
field: 'rfc',
title: 'RFC',
sortable: true,
},
{
field: 'nombre_fiscal',
title: 'Nombre fiscal',
sortable: true,
},
{
field: 'c_regimen_fiscal',
title: 'Regimen fiscal',
sortable: true,
visible: false,
formatter: window.btFormatter.regimenFiscal,
},
{
field: 'domicilio_fiscal',
title: 'Domicilio fiscal',
sortable: true,
visible: false,
},
{
field: 'estado',
title: 'Estado',
sortable: true,
},
{
field: 'municipio',
title: 'Municipio',
sortable: true,
},
{
field: 'localidad',
title: 'Localidad',
sortable: true,
visible: false,
},
{
field: 'c_uso_cfdi',
title: 'Uso de CFDI',
sortable: true,
visible: false,
formatter: window.btFormatter.usoCfdi,
},
{
field: 'cargo',
title: 'Cargo',
visible: false,
sortable: true,
},
{
field: 'is_prospect',
title: 'Es prospecto',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'is_customer',
title: 'Es cliente',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'is_provider',
title: 'Es proveedor',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'is_user',
title: 'Es usuario',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'status',
title: 'Estado',
align: 'center',
sortable: true,
formatter: window.btFormatter.status,
},
{
field: 'created_at',
title: 'Creado &nbsp; &nbsp; &nbsp; &nbsp;',
align: 'center',
sortable: true,
visible: false,
},
{
field: 'created_by_name',
title: 'Creado por',
align: 'center',
sortable: true,
visible: false,
sortName: 'created_by_name',
},
{
field: 'updated_at',
title: 'Modificado &nbsp; ',
align: 'center',
sortable: true,
visible: false,
},
]
})
}
function toggleSections() {
const isProspect = $('#is_prospect').is(':checked');
const isCustomer = $('#is_customer').is(':checked');
const isProvider = $('#is_provider').is(':checked');
const isUser = $('#is_user').is(':checked');
$('.div-sat').toggle(isCustomer || isProvider);
$('.div-sat-customer').toggle(isCustomer);
$('.div-user-auth').toggle(isCustomer || isUser);
$('.div-roles').toggle(isUser);
}
function toggleCheckboxes(status) {
const isDisabled = status == 1;
$('#is_prospect, #is_customer, #is_provider, #is_user').prop('disabled', isDisabled);
}
load_js_form = () => {
$('#userForm .select2')
.each(function() {
var $this = $(this)
$this.wrap('<div class="position-relative"></div>')
$this.select2({
dropdownAutoWidth: true,
width: '100%',
dropdownParent: $this.parent()
});
});
// Evento para los checkboxes
$('#is_prospect, #is_customer, #is_provider, #is_user').on('change', toggleSections);
// Evento para el select de estado
$('.div-status').on('change', 'select[name="status"]', function() {
toggleCheckboxes($(this).val());
});
// Previo de imagenes
document.getElementById("photo").addEventListener('change', updatePreviewImage);
// Reset form
$("#userForm")
.on('reset', function(){
var form = $("#userForm");
form.validate().resetForm();
setTimeout(function(){
$('#roles').trigger('change');
toggleSections();
}, 250)
$('#user-image').prop("src", "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
$('#userForm .alert-errors').html('');
$('.pdf-dropzone-div').show();
$("#pdf-dropzone").removeAllFiles(true);
});
$("#userForm")
.validate({
errorClass: 'error',
highlight: function(element, errorClass, validClass) {
// Agrega la clase de error a la fila (contenedor del campo)
$(element).closest('.mb-3').addClass('has-error');
},
unhighlight: function(element, errorClass, validClass) {
// Elimina la clase de error de la fila (contenedor del campo)
$(element).closest('.mb-3').removeClass('has-error');
},
errorPlacement: function(error, element) {
// Controla dónde se colocan los mensajes de error
error.appendTo(element.closest('.mb-3').find('.error-message'));
},
rules: {
name: {
required: true,
minlength: 5
},
email: {
required: true,
email: true
},
password: {
required: function(element) {
return !$("#userForm input[name=id]").val() && ($('#is_user').is(':checked') || $('#is_customer').is(':checked'));
},
minlength: 6
}
},
messages: {
name: {
required: "Por favor ingrese su nombre completo",
minlength: "El nombre completo debe tener al menos 8 caracteres"
},
email: {
required: "Por favor ingrese su correo electrónico",
email: "El valor no es una dirección de correo válida"
},
password: {
required: "La contraseña es obligatoria para nuevos usuarios",
minlength: "La contraseña debe tener al menos 6 caracteres"
}
},
submitHandler: function(form, event) {
// Evita que el formulario se envíe automáticamente
event.preventDefault();
var form = $("#userForm")[0],
data = new FormData(form);
$('#userForm :input').prop('disabled', true);
$('#userForm .alert-errors').html('');
$.ajax({
url: store_route,
method: 'POST',
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
data: data,
contentType: false,
processData: false,
cache: false,
timeout: 3000,
success: function(data) {
$('#userForm :input').prop('disabled', false);
if (data.errors) {
$('#userForm .alert-errors').html('<div class="alert alert-danger alert-dismissible fade show" role="alert">' +
'<div class="alert-body">' + data.errors + '</div>' +
'<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' +
'</div>');
} else {
let $usersIndexAlert = $('.crm-warehouse-index.alert-errors');
$usersIndexAlert.html('<div class="alert alert-success alert-dismissible fade show" role="alert">' +
'<div class="alert-body">' +
'<p class="mb-0"><strong>' + data.success + '</strong></p>' +
'</div>' +
'<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' +
'</div>');
$('#userForm button[type=reset]').trigger('click');
$('#toolbar .clear-filters').trigger('click');
}
},
error: function(e) {
$('#userForm :input').prop('disabled', false);
$('#userForm .alert-errors').html('<div class="alert alert-danger alert-dismissible fade show" role="alert">' +
'<div class="alert-body">' + e.responseJSON.message + '</div>' +
'<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' +
'</div>');
}
});
}
});
// Inicializar el estado al cargar la página
toggleSections();
toggleCheckboxes($('select[name="status"]').val());
}
// Previo de imagen de perfil
updatePreviewImage = (event) => {
var file = event.target.files[0],
reader = new FileReader();
reader.onload = event => {
document.getElementById('user-image').setAttribute('src', event.target.result);
};
reader.readAsDataURL(file);
}
document.addEventListener('DOMContentLoaded', function() {
$(document).ready(function() {
var $table = $('#bt-warehouses'),
$btnRefresh = $('#toolbar .btn-refresh'),
$clearFilters = $('a.clear-filters');
var btt_rest_height = 220,
btt_min_height = 600;
btt_height = (window.innerHeight - btt_rest_height) < btt_min_height?
btt_height:
window.innerHeight - btt_rest_height;
var offcanvasElement = document.getElementById('offcanvasUser'),
offcanvasUser = new bootstrap.Offcanvas(offcanvasElement);
const refreshButton = document.querySelector('.btn-refresh');
const inputs = document.querySelectorAll('#toolbar input, #toolbar select');
inputs.forEach(input => {
input.addEventListener('change', () => {
refreshButton.disabled = false;
refreshButton.classList.remove('btn-label-secondary');
refreshButton.classList.add('btn-label-success');
});
});
// Button Refresh
$btnRefresh
.on('click', () => {
$table.bootstrapTable('refresh');
refreshButton.disabled = true;
refreshButton.classList.remove('btn-label-success');
refreshButton.classList.add('btn-label-secondary');
});
// Button clear filters
$clearFilters
.on('click', () => {
$table.bootstrapTable('resetSearch', ''); // Inicializa la búsqueda con cadena vacía
refreshButton.disabled = true;
refreshButton.classList.remove('btn-label-success');
refreshButton.classList.add('btn-label-secondary');
});
initTable('#bt-warehouses'); // Una vez que todos los scripts estén cargados, inicializa Bootstrap Table
load_js_form();
});
});
</script>
@endpush

View File

@ -0,0 +1,516 @@
<section id="crm-warehouse-index">
<div class="crm-warehouse-index alert-errors"></div>
<div wire:ignore>
<div class="query-filters" id="toolbar">
<div class="d-flex flex-wrap">
<div class="pt-1 pr-2 pb-1" style="min-width: 175px; max-width: 225px">
<button data-bs-toggle='offcanvas' data-bs-target='#offcanvasUser' class="btn btn-primary waves-effect waves-light">Agregar almacén</button>
</div>
<button type="button" class="accordion-button collapsed" data-bs-toggle="collapse" data-bs-target="#accordionFiltrado" aria-expanded="false" aria-controls="accordionFiltrado">
Filtrado
</button>
<div class="px-2 pt-1">
<button class="btn btn-label-secondary waves-effect py-3 btn-refresh" disabled><i class="fa-solid fa-rotate"></i></button>
</div>
<div class="pr-2" style="width: 60px;">
<a href="javascript:void(0)" class="clear-filters">Limpiar Filtrado</a>
</div>
</div>
</div>
<table id="bt-warehouses"></table>
</div>
</section>
@push('page-script')
<script>
const store_route = '{{ route('admin.core.users.store') }}',
route_show = '{{ route('admin.inventory.warehouse.show', ['warehouse' => '~warehouse~']) }}',
route_destroy = '{{ route('admin.inventory.warehouse.destroy', ['warehouse' => '~warehouse~']) }}',
statusList = {!! json_encode($status_list) !!},
statusIntCatalogCss = {!! json_encode($status_list_class) !!};
var btt_height;
// BootstrapTable Petición AJAX
function ajaxRequest(params) {
let url = '{{ url()->current() }}' +
'?' +
$.param(params.data) +
'&' +
$('.query-filters :input').serialize();
$.get(url).then(function (res) {
params.success(res)
})
}
// BootstrapTable Formatter
function userAvatarFormatter(value, row, index) {
if(row.id){
let show_href = route_show.replace('~warehouseo~', row.id);
return [
'<div class="d-flex justify-content-start align-items-center user-name">',
'<div class="avatar-wrapper">',
'<div class="avatar avatar-sm me-4">' +
'<img src="' + row.profile_photo_url + '" alt="Avatar" class="rounded-circle">' +
'</div>',
'</div>',
'<div class="d-flex flex-column">',
'<a href="' + show_href + '" class="text-heading text-truncate"><span class="fw-medium">' + row.name + '</span></a>',
'<small>' + row.email + '</small>',
'</div>',
'</div>',
].join('')
}
}
function uidFormatter(value, row, index) {
if(row.id){
let show_href = route_show.replace('~warehouseo~', row.id);
return [
'<div class="d-flex align-items-center justify-content-center">',
'<a href="' + show_href + '" class="whitespace-nowrap" title="Ver warehouseo"> ' + row.id + '</a>',
@can('crm.warehouses.update')
'<a href="javascript:;" class="btn btn-icon btn-text-secondary waves-effect waves-light rounded-pill dropdown-toggle hide-arrow" data-bs-toggle="dropdown"><i class="ti ti-dots-vertical ti-md"></i></a>',
'<div class="dropdown-menu dropdown-menu-end m-0">',
'<a href="javascript:deleteRow(' + row.id + ');" class="dropdown-item delete-record">Eliminar</a>',
'</div>',
@endcan
'</div>'
].join('')
}
}
// BootstrapTable Init
function initTable(table) {
$(table)
.bootstrapTable('destroy')
.bootstrapTable({
height: btt_height,
locale: 'es-MX',
ajax: "ajaxRequest",
toolbar: "#toolbar",
search: true,
showColumns: true,
showColumnsToggleAll: true,
showExport: true,
showFullscreen: true,
showPaginationSwitch: true,
showRefresh: true,
showToggle: true,
clickToSelect: true,
minimumCountColumns: 4,
fixedColumns: true,
fixedNumber: 1,
idField: "id",
pagination: true,
pageList: [10, 25, 50, 100, 500],
sidePagination: "server",
exportTypes: ['csv', 'txt', 'excel'],
exportOptions: {
fileName: 'warehouseos',
},
sortName: 'users.id',
sortOrder: 'desc',
mobileResponsive: true,
cookie: true,
resizable: true,
cookieIdTable:"crm-warehouse-index",
columns: [
{
field: 'id',
title: 'UID',
align: 'center',
sortable: true,
sortName: 'users.id',
switchable: false,
formatter: uidFormatter
},
{
field: 'name',
title: 'Nombre',
formatter: userAvatarFormatter,
},
{
field: 'email',
title: 'Correo electrónico',
sortable: true,
visible: false,
},
{
field: 'tipo_persona',
title: 'Tipo persona',
visible: false,
sortable: true,
formatter: window.btFormatter.tipoPersona,
},
{
field: 'rfc',
title: 'RFC',
sortable: true,
},
{
field: 'nombre_fiscal',
title: 'Nombre fiscal',
sortable: true,
},
{
field: 'c_regimen_fiscal',
title: 'Regimen fiscal',
sortable: true,
visible: false,
formatter: window.btFormatter.regimenFiscal,
},
{
field: 'domicilio_fiscal',
title: 'Domicilio fiscal',
sortable: true,
visible: false,
},
{
field: 'estado',
title: 'Estado',
sortable: true,
},
{
field: 'municipio',
title: 'Municipio',
sortable: true,
},
{
field: 'localidad',
title: 'Localidad',
sortable: true,
visible: false,
},
{
field: 'c_uso_cfdi',
title: 'Uso de CFDI',
sortable: true,
visible: false,
formatter: window.btFormatter.usoCfdi,
},
{
field: 'cargo',
title: 'Cargo',
visible: false,
sortable: true,
},
{
field: 'is_prospect',
title: 'Es prospecto',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'is_customer',
title: 'Es cliente',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'is_provider',
title: 'Es proveedor',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'is_user',
title: 'Es usuario',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'status',
title: 'Estado',
align: 'center',
sortable: true,
formatter: window.btFormatter.status,
},
{
field: 'created_at',
title: 'Creado &nbsp; &nbsp; &nbsp; &nbsp;',
align: 'center',
sortable: true,
visible: false,
},
{
field: 'created_by_name',
title: 'Creado por',
align: 'center',
sortable: true,
visible: false,
sortName: 'created_by_name',
},
{
field: 'updated_at',
title: 'Modificado &nbsp; ',
align: 'center',
sortable: true,
visible: false,
},
]
})
}
function toggleSections() {
const isProspect = $('#is_prospect').is(':checked');
const isCustomer = $('#is_customer').is(':checked');
const isProvider = $('#is_provider').is(':checked');
const isUser = $('#is_user').is(':checked');
$('.div-sat').toggle(isCustomer || isProvider);
$('.div-sat-customer').toggle(isCustomer);
$('.div-user-auth').toggle(isCustomer || isUser);
$('.div-roles').toggle(isUser);
}
function toggleCheckboxes(status) {
const isDisabled = status == 1;
$('#is_prospect, #is_customer, #is_provider, #is_user').prop('disabled', isDisabled);
}
load_js_form = () => {
$('#userForm .select2')
.each(function() {
var $this = $(this)
$this.wrap('<div class="position-relative"></div>')
$this.select2({
dropdownAutoWidth: true,
width: '100%',
dropdownParent: $this.parent()
});
});
// Evento para los checkboxes
$('#is_prospect, #is_customer, #is_provider, #is_user').on('change', toggleSections);
// Evento para el select de estado
$('.div-status').on('change', 'select[name="status"]', function() {
toggleCheckboxes($(this).val());
});
// Previo de imagenes
document.getElementById("photo").addEventListener('change', updatePreviewImage);
// Reset form
$("#userForm")
.on('reset', function(){
var form = $("#userForm");
form.validate().resetForm();
setTimeout(function(){
$('#roles').trigger('change');
toggleSections();
}, 250)
$('#user-image').prop("src", "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
$('#userForm .alert-errors').html('');
$('.pdf-dropzone-div').show();
$("#pdf-dropzone").removeAllFiles(true);
});
$("#userForm")
.validate({
errorClass: 'error',
highlight: function(element, errorClass, validClass) {
// Agrega la clase de error a la fila (contenedor del campo)
$(element).closest('.mb-3').addClass('has-error');
},
unhighlight: function(element, errorClass, validClass) {
// Elimina la clase de error de la fila (contenedor del campo)
$(element).closest('.mb-3').removeClass('has-error');
},
errorPlacement: function(error, element) {
// Controla dónde se colocan los mensajes de error
error.appendTo(element.closest('.mb-3').find('.error-message'));
},
rules: {
name: {
required: true,
minlength: 5
},
email: {
required: true,
email: true
},
password: {
required: function(element) {
return !$("#userForm input[name=id]").val() && ($('#is_user').is(':checked') || $('#is_customer').is(':checked'));
},
minlength: 6
}
},
messages: {
name: {
required: "Por favor ingrese su nombre completo",
minlength: "El nombre completo debe tener al menos 8 caracteres"
},
email: {
required: "Por favor ingrese su correo electrónico",
email: "El valor no es una dirección de correo válida"
},
password: {
required: "La contraseña es obligatoria para nuevos usuarios",
minlength: "La contraseña debe tener al menos 6 caracteres"
}
},
submitHandler: function(form, event) {
// Evita que el formulario se envíe automáticamente
event.preventDefault();
var form = $("#userForm")[0],
data = new FormData(form);
$('#userForm :input').prop('disabled', true);
$('#userForm .alert-errors').html('');
$.ajax({
url: store_route,
method: 'POST',
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
data: data,
contentType: false,
processData: false,
cache: false,
timeout: 3000,
success: function(data) {
$('#userForm :input').prop('disabled', false);
if (data.errors) {
$('#userForm .alert-errors').html('<div class="alert alert-danger alert-dismissible fade show" role="alert">' +
'<div class="alert-body">' + data.errors + '</div>' +
'<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' +
'</div>');
} else {
let $usersIndexAlert = $('.crm-warehouse-index.alert-errors');
$usersIndexAlert.html('<div class="alert alert-success alert-dismissible fade show" role="alert">' +
'<div class="alert-body">' +
'<p class="mb-0"><strong>' + data.success + '</strong></p>' +
'</div>' +
'<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' +
'</div>');
$('#userForm button[type=reset]').trigger('click');
$('#toolbar .clear-filters').trigger('click');
}
},
error: function(e) {
$('#userForm :input').prop('disabled', false);
$('#userForm .alert-errors').html('<div class="alert alert-danger alert-dismissible fade show" role="alert">' +
'<div class="alert-body">' + e.responseJSON.message + '</div>' +
'<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' +
'</div>');
}
});
}
});
// Inicializar el estado al cargar la página
toggleSections();
toggleCheckboxes($('select[name="status"]').val());
}
// Previo de imagen de perfil
updatePreviewImage = (event) => {
var file = event.target.files[0],
reader = new FileReader();
reader.onload = event => {
document.getElementById('user-image').setAttribute('src', event.target.result);
};
reader.readAsDataURL(file);
}
document.addEventListener('DOMContentLoaded', function() {
$(document).ready(function() {
var $table = $('#bt-warehouses'),
$btnRefresh = $('#toolbar .btn-refresh'),
$clearFilters = $('a.clear-filters');
var btt_rest_height = 220,
btt_min_height = 600;
btt_height = (window.innerHeight - btt_rest_height) < btt_min_height?
btt_height:
window.innerHeight - btt_rest_height;
var offcanvasElement = document.getElementById('offcanvasUser'),
offcanvasUser = new bootstrap.Offcanvas(offcanvasElement);
const refreshButton = document.querySelector('.btn-refresh');
const inputs = document.querySelectorAll('#toolbar input, #toolbar select');
inputs.forEach(input => {
input.addEventListener('change', () => {
refreshButton.disabled = false;
refreshButton.classList.remove('btn-label-secondary');
refreshButton.classList.add('btn-label-success');
});
});
// Button Refresh
$btnRefresh
.on('click', () => {
$table.bootstrapTable('refresh');
refreshButton.disabled = true;
refreshButton.classList.remove('btn-label-success');
refreshButton.classList.add('btn-label-secondary');
});
// Button clear filters
$clearFilters
.on('click', () => {
$table.bootstrapTable('resetSearch', ''); // Inicializa la búsqueda con cadena vacía
refreshButton.disabled = true;
refreshButton.classList.remove('btn-label-success');
refreshButton.classList.add('btn-label-secondary');
});
initTable('#bt-warehouses'); // Una vez que todos los scripts estén cargados, inicializa Bootstrap Table
load_js_form();
});
});
</script>
@endpush

View File

@ -0,0 +1,516 @@
<section id="crm-warehouse-index">
<div class="crm-warehouse-index alert-errors"></div>
<div wire:ignore>
<div class="query-filters" id="toolbar">
<div class="d-flex flex-wrap">
<div class="pt-1 pr-2 pb-1" style="min-width: 175px; max-width: 225px">
<button data-bs-toggle='offcanvas' data-bs-target='#offcanvasUser' class="btn btn-primary waves-effect waves-light">Agregar almacén</button>
</div>
<button type="button" class="accordion-button collapsed" data-bs-toggle="collapse" data-bs-target="#accordionFiltrado" aria-expanded="false" aria-controls="accordionFiltrado">
Filtrado
</button>
<div class="px-2 pt-1">
<button class="btn btn-label-secondary waves-effect py-3 btn-refresh" disabled><i class="fa-solid fa-rotate"></i></button>
</div>
<div class="pr-2" style="width: 60px;">
<a href="javascript:void(0)" class="clear-filters">Limpiar Filtrado</a>
</div>
</div>
</div>
<table id="bt-warehouses"></table>
</div>
</section>
@push('page-script')
<script>
const store_route = '{{ route('admin.core.users.store') }}',
route_show = '{{ route('admin.inventory.warehouse.show', ['warehouse' => '~warehouse~']) }}',
route_destroy = '{{ route('admin.inventory.warehouse.destroy', ['warehouse' => '~warehouse~']) }}',
statusList = {!! json_encode($status_list) !!},
statusIntCatalogCss = {!! json_encode($status_list_class) !!};
var btt_height;
// BootstrapTable Petición AJAX
function ajaxRequest(params) {
let url = '{{ url()->current() }}' +
'?' +
$.param(params.data) +
'&' +
$('.query-filters :input').serialize();
$.get(url).then(function (res) {
params.success(res)
})
}
// BootstrapTable Formatter
function userAvatarFormatter(value, row, index) {
if(row.id){
let show_href = route_show.replace('~warehouseo~', row.id);
return [
'<div class="d-flex justify-content-start align-items-center user-name">',
'<div class="avatar-wrapper">',
'<div class="avatar avatar-sm me-4">' +
'<img src="' + row.profile_photo_url + '" alt="Avatar" class="rounded-circle">' +
'</div>',
'</div>',
'<div class="d-flex flex-column">',
'<a href="' + show_href + '" class="text-heading text-truncate"><span class="fw-medium">' + row.name + '</span></a>',
'<small>' + row.email + '</small>',
'</div>',
'</div>',
].join('')
}
}
function uidFormatter(value, row, index) {
if(row.id){
let show_href = route_show.replace('~warehouseo~', row.id);
return [
'<div class="d-flex align-items-center justify-content-center">',
'<a href="' + show_href + '" class="whitespace-nowrap" title="Ver warehouseo"> ' + row.id + '</a>',
@can('crm.warehouses.update')
'<a href="javascript:;" class="btn btn-icon btn-text-secondary waves-effect waves-light rounded-pill dropdown-toggle hide-arrow" data-bs-toggle="dropdown"><i class="ti ti-dots-vertical ti-md"></i></a>',
'<div class="dropdown-menu dropdown-menu-end m-0">',
'<a href="javascript:deleteRow(' + row.id + ');" class="dropdown-item delete-record">Eliminar</a>',
'</div>',
@endcan
'</div>'
].join('')
}
}
// BootstrapTable Init
function initTable(table) {
$(table)
.bootstrapTable('destroy')
.bootstrapTable({
height: btt_height,
locale: 'es-MX',
ajax: "ajaxRequest",
toolbar: "#toolbar",
search: true,
showColumns: true,
showColumnsToggleAll: true,
showExport: true,
showFullscreen: true,
showPaginationSwitch: true,
showRefresh: true,
showToggle: true,
clickToSelect: true,
minimumCountColumns: 4,
fixedColumns: true,
fixedNumber: 1,
idField: "id",
pagination: true,
pageList: [10, 25, 50, 100, 500],
sidePagination: "server",
exportTypes: ['csv', 'txt', 'excel'],
exportOptions: {
fileName: 'warehouseos',
},
sortName: 'users.id',
sortOrder: 'desc',
mobileResponsive: true,
cookie: true,
resizable: true,
cookieIdTable:"crm-warehouse-index",
columns: [
{
field: 'id',
title: 'UID',
align: 'center',
sortable: true,
sortName: 'users.id',
switchable: false,
formatter: uidFormatter
},
{
field: 'name',
title: 'Nombre',
formatter: userAvatarFormatter,
},
{
field: 'email',
title: 'Correo electrónico',
sortable: true,
visible: false,
},
{
field: 'tipo_persona',
title: 'Tipo persona',
visible: false,
sortable: true,
formatter: window.btFormatter.tipoPersona,
},
{
field: 'rfc',
title: 'RFC',
sortable: true,
},
{
field: 'nombre_fiscal',
title: 'Nombre fiscal',
sortable: true,
},
{
field: 'c_regimen_fiscal',
title: 'Regimen fiscal',
sortable: true,
visible: false,
formatter: window.btFormatter.regimenFiscal,
},
{
field: 'domicilio_fiscal',
title: 'Domicilio fiscal',
sortable: true,
visible: false,
},
{
field: 'estado',
title: 'Estado',
sortable: true,
},
{
field: 'municipio',
title: 'Municipio',
sortable: true,
},
{
field: 'localidad',
title: 'Localidad',
sortable: true,
visible: false,
},
{
field: 'c_uso_cfdi',
title: 'Uso de CFDI',
sortable: true,
visible: false,
formatter: window.btFormatter.usoCfdi,
},
{
field: 'cargo',
title: 'Cargo',
visible: false,
sortable: true,
},
{
field: 'is_prospect',
title: 'Es prospecto',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'is_customer',
title: 'Es cliente',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'is_provider',
title: 'Es proveedor',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'is_user',
title: 'Es usuario',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'status',
title: 'Estado',
align: 'center',
sortable: true,
formatter: window.btFormatter.status,
},
{
field: 'created_at',
title: 'Creado &nbsp; &nbsp; &nbsp; &nbsp;',
align: 'center',
sortable: true,
visible: false,
},
{
field: 'created_by_name',
title: 'Creado por',
align: 'center',
sortable: true,
visible: false,
sortName: 'created_by_name',
},
{
field: 'updated_at',
title: 'Modificado &nbsp; ',
align: 'center',
sortable: true,
visible: false,
},
]
})
}
function toggleSections() {
const isProspect = $('#is_prospect').is(':checked');
const isCustomer = $('#is_customer').is(':checked');
const isProvider = $('#is_provider').is(':checked');
const isUser = $('#is_user').is(':checked');
$('.div-sat').toggle(isCustomer || isProvider);
$('.div-sat-customer').toggle(isCustomer);
$('.div-user-auth').toggle(isCustomer || isUser);
$('.div-roles').toggle(isUser);
}
function toggleCheckboxes(status) {
const isDisabled = status == 1;
$('#is_prospect, #is_customer, #is_provider, #is_user').prop('disabled', isDisabled);
}
load_js_form = () => {
$('#userForm .select2')
.each(function() {
var $this = $(this)
$this.wrap('<div class="position-relative"></div>')
$this.select2({
dropdownAutoWidth: true,
width: '100%',
dropdownParent: $this.parent()
});
});
// Evento para los checkboxes
$('#is_prospect, #is_customer, #is_provider, #is_user').on('change', toggleSections);
// Evento para el select de estado
$('.div-status').on('change', 'select[name="status"]', function() {
toggleCheckboxes($(this).val());
});
// Previo de imagenes
document.getElementById("photo").addEventListener('change', updatePreviewImage);
// Reset form
$("#userForm")
.on('reset', function(){
var form = $("#userForm");
form.validate().resetForm();
setTimeout(function(){
$('#roles').trigger('change');
toggleSections();
}, 250)
$('#user-image').prop("src", "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
$('#userForm .alert-errors').html('');
$('.pdf-dropzone-div').show();
$("#pdf-dropzone").removeAllFiles(true);
});
$("#userForm")
.validate({
errorClass: 'error',
highlight: function(element, errorClass, validClass) {
// Agrega la clase de error a la fila (contenedor del campo)
$(element).closest('.mb-3').addClass('has-error');
},
unhighlight: function(element, errorClass, validClass) {
// Elimina la clase de error de la fila (contenedor del campo)
$(element).closest('.mb-3').removeClass('has-error');
},
errorPlacement: function(error, element) {
// Controla dónde se colocan los mensajes de error
error.appendTo(element.closest('.mb-3').find('.error-message'));
},
rules: {
name: {
required: true,
minlength: 5
},
email: {
required: true,
email: true
},
password: {
required: function(element) {
return !$("#userForm input[name=id]").val() && ($('#is_user').is(':checked') || $('#is_customer').is(':checked'));
},
minlength: 6
}
},
messages: {
name: {
required: "Por favor ingrese su nombre completo",
minlength: "El nombre completo debe tener al menos 8 caracteres"
},
email: {
required: "Por favor ingrese su correo electrónico",
email: "El valor no es una dirección de correo válida"
},
password: {
required: "La contraseña es obligatoria para nuevos usuarios",
minlength: "La contraseña debe tener al menos 6 caracteres"
}
},
submitHandler: function(form, event) {
// Evita que el formulario se envíe automáticamente
event.preventDefault();
var form = $("#userForm")[0],
data = new FormData(form);
$('#userForm :input').prop('disabled', true);
$('#userForm .alert-errors').html('');
$.ajax({
url: store_route,
method: 'POST',
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
data: data,
contentType: false,
processData: false,
cache: false,
timeout: 3000,
success: function(data) {
$('#userForm :input').prop('disabled', false);
if (data.errors) {
$('#userForm .alert-errors').html('<div class="alert alert-danger alert-dismissible fade show" role="alert">' +
'<div class="alert-body">' + data.errors + '</div>' +
'<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' +
'</div>');
} else {
let $usersIndexAlert = $('.crm-warehouse-index.alert-errors');
$usersIndexAlert.html('<div class="alert alert-success alert-dismissible fade show" role="alert">' +
'<div class="alert-body">' +
'<p class="mb-0"><strong>' + data.success + '</strong></p>' +
'</div>' +
'<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' +
'</div>');
$('#userForm button[type=reset]').trigger('click');
$('#toolbar .clear-filters').trigger('click');
}
},
error: function(e) {
$('#userForm :input').prop('disabled', false);
$('#userForm .alert-errors').html('<div class="alert alert-danger alert-dismissible fade show" role="alert">' +
'<div class="alert-body">' + e.responseJSON.message + '</div>' +
'<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' +
'</div>');
}
});
}
});
// Inicializar el estado al cargar la página
toggleSections();
toggleCheckboxes($('select[name="status"]').val());
}
// Previo de imagen de perfil
updatePreviewImage = (event) => {
var file = event.target.files[0],
reader = new FileReader();
reader.onload = event => {
document.getElementById('user-image').setAttribute('src', event.target.result);
};
reader.readAsDataURL(file);
}
document.addEventListener('DOMContentLoaded', function() {
$(document).ready(function() {
var $table = $('#bt-warehouses'),
$btnRefresh = $('#toolbar .btn-refresh'),
$clearFilters = $('a.clear-filters');
var btt_rest_height = 220,
btt_min_height = 600;
btt_height = (window.innerHeight - btt_rest_height) < btt_min_height?
btt_height:
window.innerHeight - btt_rest_height;
var offcanvasElement = document.getElementById('offcanvasUser'),
offcanvasUser = new bootstrap.Offcanvas(offcanvasElement);
const refreshButton = document.querySelector('.btn-refresh');
const inputs = document.querySelectorAll('#toolbar input, #toolbar select');
inputs.forEach(input => {
input.addEventListener('change', () => {
refreshButton.disabled = false;
refreshButton.classList.remove('btn-label-secondary');
refreshButton.classList.add('btn-label-success');
});
});
// Button Refresh
$btnRefresh
.on('click', () => {
$table.bootstrapTable('refresh');
refreshButton.disabled = true;
refreshButton.classList.remove('btn-label-success');
refreshButton.classList.add('btn-label-secondary');
});
// Button clear filters
$clearFilters
.on('click', () => {
$table.bootstrapTable('resetSearch', ''); // Inicializa la búsqueda con cadena vacía
refreshButton.disabled = true;
refreshButton.classList.remove('btn-label-success');
refreshButton.classList.add('btn-label-secondary');
});
initTable('#bt-warehouses'); // Una vez que todos los scripts estén cargados, inicializa Bootstrap Table
load_js_form();
});
});
</script>
@endpush

View File

@ -0,0 +1,516 @@
<section id="crm-warehouse-index">
<div class="crm-warehouse-index alert-errors"></div>
<div wire:ignore>
<div class="query-filters" id="toolbar">
<div class="d-flex flex-wrap">
<div class="pt-1 pr-2 pb-1" style="min-width: 175px; max-width: 225px">
<button data-bs-toggle='offcanvas' data-bs-target='#offcanvasUser' class="btn btn-primary waves-effect waves-light">Agregar almacén</button>
</div>
<button type="button" class="accordion-button collapsed" data-bs-toggle="collapse" data-bs-target="#accordionFiltrado" aria-expanded="false" aria-controls="accordionFiltrado">
Filtrado
</button>
<div class="px-2 pt-1">
<button class="btn btn-label-secondary waves-effect py-3 btn-refresh" disabled><i class="fa-solid fa-rotate"></i></button>
</div>
<div class="pr-2" style="width: 60px;">
<a href="javascript:void(0)" class="clear-filters">Limpiar Filtrado</a>
</div>
</div>
</div>
<table id="bt-warehouses"></table>
</div>
</section>
@push('page-script')
<script>
const store_route = '{{ route('admin.core.users.store') }}',
route_show = '{{ route('admin.inventory.warehouse.show', ['warehouse' => '~warehouse~']) }}',
route_destroy = '{{ route('admin.inventory.warehouse.destroy', ['warehouse' => '~warehouse~']) }}',
statusList = {!! json_encode($status_list) !!},
statusIntCatalogCss = {!! json_encode($status_list_class) !!};
var btt_height;
// BootstrapTable Petición AJAX
function ajaxRequest(params) {
let url = '{{ url()->current() }}' +
'?' +
$.param(params.data) +
'&' +
$('.query-filters :input').serialize();
$.get(url).then(function (res) {
params.success(res)
})
}
// BootstrapTable Formatter
function userAvatarFormatter(value, row, index) {
if(row.id){
let show_href = route_show.replace('~warehouseo~', row.id);
return [
'<div class="d-flex justify-content-start align-items-center user-name">',
'<div class="avatar-wrapper">',
'<div class="avatar avatar-sm me-4">' +
'<img src="' + row.profile_photo_url + '" alt="Avatar" class="rounded-circle">' +
'</div>',
'</div>',
'<div class="d-flex flex-column">',
'<a href="' + show_href + '" class="text-heading text-truncate"><span class="fw-medium">' + row.name + '</span></a>',
'<small>' + row.email + '</small>',
'</div>',
'</div>',
].join('')
}
}
function uidFormatter(value, row, index) {
if(row.id){
let show_href = route_show.replace('~warehouseo~', row.id);
return [
'<div class="d-flex align-items-center justify-content-center">',
'<a href="' + show_href + '" class="whitespace-nowrap" title="Ver warehouseo"> ' + row.id + '</a>',
@can('crm.warehouses.update')
'<a href="javascript:;" class="btn btn-icon btn-text-secondary waves-effect waves-light rounded-pill dropdown-toggle hide-arrow" data-bs-toggle="dropdown"><i class="ti ti-dots-vertical ti-md"></i></a>',
'<div class="dropdown-menu dropdown-menu-end m-0">',
'<a href="javascript:deleteRow(' + row.id + ');" class="dropdown-item delete-record">Eliminar</a>',
'</div>',
@endcan
'</div>'
].join('')
}
}
// BootstrapTable Init
function initTable(table) {
$(table)
.bootstrapTable('destroy')
.bootstrapTable({
height: btt_height,
locale: 'es-MX',
ajax: "ajaxRequest",
toolbar: "#toolbar",
search: true,
showColumns: true,
showColumnsToggleAll: true,
showExport: true,
showFullscreen: true,
showPaginationSwitch: true,
showRefresh: true,
showToggle: true,
clickToSelect: true,
minimumCountColumns: 4,
fixedColumns: true,
fixedNumber: 1,
idField: "id",
pagination: true,
pageList: [10, 25, 50, 100, 500],
sidePagination: "server",
exportTypes: ['csv', 'txt', 'excel'],
exportOptions: {
fileName: 'warehouseos',
},
sortName: 'users.id',
sortOrder: 'desc',
mobileResponsive: true,
cookie: true,
resizable: true,
cookieIdTable:"crm-warehouse-index",
columns: [
{
field: 'id',
title: 'UID',
align: 'center',
sortable: true,
sortName: 'users.id',
switchable: false,
formatter: uidFormatter
},
{
field: 'name',
title: 'Nombre',
formatter: userAvatarFormatter,
},
{
field: 'email',
title: 'Correo electrónico',
sortable: true,
visible: false,
},
{
field: 'tipo_persona',
title: 'Tipo persona',
visible: false,
sortable: true,
formatter: window.btFormatter.tipoPersona,
},
{
field: 'rfc',
title: 'RFC',
sortable: true,
},
{
field: 'nombre_fiscal',
title: 'Nombre fiscal',
sortable: true,
},
{
field: 'c_regimen_fiscal',
title: 'Regimen fiscal',
sortable: true,
visible: false,
formatter: window.btFormatter.regimenFiscal,
},
{
field: 'domicilio_fiscal',
title: 'Domicilio fiscal',
sortable: true,
visible: false,
},
{
field: 'estado',
title: 'Estado',
sortable: true,
},
{
field: 'municipio',
title: 'Municipio',
sortable: true,
},
{
field: 'localidad',
title: 'Localidad',
sortable: true,
visible: false,
},
{
field: 'c_uso_cfdi',
title: 'Uso de CFDI',
sortable: true,
visible: false,
formatter: window.btFormatter.usoCfdi,
},
{
field: 'cargo',
title: 'Cargo',
visible: false,
sortable: true,
},
{
field: 'is_prospect',
title: 'Es prospecto',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'is_customer',
title: 'Es cliente',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'is_provider',
title: 'Es proveedor',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'is_user',
title: 'Es usuario',
align: 'center',
visible: false,
sortable: true,
formatter: window.btFormatter.check,
},
{
field: 'status',
title: 'Estado',
align: 'center',
sortable: true,
formatter: window.btFormatter.status,
},
{
field: 'created_at',
title: 'Creado &nbsp; &nbsp; &nbsp; &nbsp;',
align: 'center',
sortable: true,
visible: false,
},
{
field: 'created_by_name',
title: 'Creado por',
align: 'center',
sortable: true,
visible: false,
sortName: 'created_by_name',
},
{
field: 'updated_at',
title: 'Modificado &nbsp; ',
align: 'center',
sortable: true,
visible: false,
},
]
})
}
function toggleSections() {
const isProspect = $('#is_prospect').is(':checked');
const isCustomer = $('#is_customer').is(':checked');
const isProvider = $('#is_provider').is(':checked');
const isUser = $('#is_user').is(':checked');
$('.div-sat').toggle(isCustomer || isProvider);
$('.div-sat-customer').toggle(isCustomer);
$('.div-user-auth').toggle(isCustomer || isUser);
$('.div-roles').toggle(isUser);
}
function toggleCheckboxes(status) {
const isDisabled = status == 1;
$('#is_prospect, #is_customer, #is_provider, #is_user').prop('disabled', isDisabled);
}
load_js_form = () => {
$('#userForm .select2')
.each(function() {
var $this = $(this)
$this.wrap('<div class="position-relative"></div>')
$this.select2({
dropdownAutoWidth: true,
width: '100%',
dropdownParent: $this.parent()
});
});
// Evento para los checkboxes
$('#is_prospect, #is_customer, #is_provider, #is_user').on('change', toggleSections);
// Evento para el select de estado
$('.div-status').on('change', 'select[name="status"]', function() {
toggleCheckboxes($(this).val());
});
// Previo de imagenes
document.getElementById("photo").addEventListener('change', updatePreviewImage);
// Reset form
$("#userForm")
.on('reset', function(){
var form = $("#userForm");
form.validate().resetForm();
setTimeout(function(){
$('#roles').trigger('change');
toggleSections();
}, 250)
$('#user-image').prop("src", "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
$('#userForm .alert-errors').html('');
$('.pdf-dropzone-div').show();
$("#pdf-dropzone").removeAllFiles(true);
});
$("#userForm")
.validate({
errorClass: 'error',
highlight: function(element, errorClass, validClass) {
// Agrega la clase de error a la fila (contenedor del campo)
$(element).closest('.mb-3').addClass('has-error');
},
unhighlight: function(element, errorClass, validClass) {
// Elimina la clase de error de la fila (contenedor del campo)
$(element).closest('.mb-3').removeClass('has-error');
},
errorPlacement: function(error, element) {
// Controla dónde se colocan los mensajes de error
error.appendTo(element.closest('.mb-3').find('.error-message'));
},
rules: {
name: {
required: true,
minlength: 5
},
email: {
required: true,
email: true
},
password: {
required: function(element) {
return !$("#userForm input[name=id]").val() && ($('#is_user').is(':checked') || $('#is_customer').is(':checked'));
},
minlength: 6
}
},
messages: {
name: {
required: "Por favor ingrese su nombre completo",
minlength: "El nombre completo debe tener al menos 8 caracteres"
},
email: {
required: "Por favor ingrese su correo electrónico",
email: "El valor no es una dirección de correo válida"
},
password: {
required: "La contraseña es obligatoria para nuevos usuarios",
minlength: "La contraseña debe tener al menos 6 caracteres"
}
},
submitHandler: function(form, event) {
// Evita que el formulario se envíe automáticamente
event.preventDefault();
var form = $("#userForm")[0],
data = new FormData(form);
$('#userForm :input').prop('disabled', true);
$('#userForm .alert-errors').html('');
$.ajax({
url: store_route,
method: 'POST',
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
data: data,
contentType: false,
processData: false,
cache: false,
timeout: 3000,
success: function(data) {
$('#userForm :input').prop('disabled', false);
if (data.errors) {
$('#userForm .alert-errors').html('<div class="alert alert-danger alert-dismissible fade show" role="alert">' +
'<div class="alert-body">' + data.errors + '</div>' +
'<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' +
'</div>');
} else {
let $usersIndexAlert = $('.crm-warehouse-index.alert-errors');
$usersIndexAlert.html('<div class="alert alert-success alert-dismissible fade show" role="alert">' +
'<div class="alert-body">' +
'<p class="mb-0"><strong>' + data.success + '</strong></p>' +
'</div>' +
'<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' +
'</div>');
$('#userForm button[type=reset]').trigger('click');
$('#toolbar .clear-filters').trigger('click');
}
},
error: function(e) {
$('#userForm :input').prop('disabled', false);
$('#userForm .alert-errors').html('<div class="alert alert-danger alert-dismissible fade show" role="alert">' +
'<div class="alert-body">' + e.responseJSON.message + '</div>' +
'<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' +
'</div>');
}
});
}
});
// Inicializar el estado al cargar la página
toggleSections();
toggleCheckboxes($('select[name="status"]').val());
}
// Previo de imagen de perfil
updatePreviewImage = (event) => {
var file = event.target.files[0],
reader = new FileReader();
reader.onload = event => {
document.getElementById('user-image').setAttribute('src', event.target.result);
};
reader.readAsDataURL(file);
}
document.addEventListener('DOMContentLoaded', function() {
$(document).ready(function() {
var $table = $('#bt-warehouses'),
$btnRefresh = $('#toolbar .btn-refresh'),
$clearFilters = $('a.clear-filters');
var btt_rest_height = 220,
btt_min_height = 600;
btt_height = (window.innerHeight - btt_rest_height) < btt_min_height?
btt_height:
window.innerHeight - btt_rest_height;
var offcanvasElement = document.getElementById('offcanvasUser'),
offcanvasUser = new bootstrap.Offcanvas(offcanvasElement);
const refreshButton = document.querySelector('.btn-refresh');
const inputs = document.querySelectorAll('#toolbar input, #toolbar select');
inputs.forEach(input => {
input.addEventListener('change', () => {
refreshButton.disabled = false;
refreshButton.classList.remove('btn-label-secondary');
refreshButton.classList.add('btn-label-success');
});
});
// Button Refresh
$btnRefresh
.on('click', () => {
$table.bootstrapTable('refresh');
refreshButton.disabled = true;
refreshButton.classList.remove('btn-label-success');
refreshButton.classList.add('btn-label-secondary');
});
// Button clear filters
$clearFilters
.on('click', () => {
$table.bootstrapTable('resetSearch', ''); // Inicializa la búsqueda con cadena vacía
refreshButton.disabled = true;
refreshButton.classList.remove('btn-label-success');
refreshButton.classList.add('btn-label-secondary');
});
initTable('#bt-warehouses'); // Una vez que todos los scripts estén cargados, inicializa Bootstrap Table
load_js_form();
});
});
</script>
@endpush

View File

@ -0,0 +1,132 @@
<div>
<x-vuexy-admin::offcanvas.basic :id="$offcanvasId" :tag-name="$tagName">
<x-vuexy-admin::form :id="$formId" :mode="$mode" wireSubmit="onSubmit">
<x-slot name="actions">
<x-vuexy-admin::button.offcanvas-buttons :mode="$mode" :tagName="$tagName" />
</x-slot>
{{-- Selección de Sucursal --}}
<x-vuexy-admin::form.select :uid="$uniqueId" model="store_id" label="Sucursal" placeholder="Selecciona una sucursal" :options="$store_options" />
<x-vuexy-admin::form.select :uid="$uniqueId" model="work_center_id" label="Área de trabajo" placeholder="Selecciona el área de trabajo" :options="$work_center_options" />
{{-- Identificación y Configuración --}}
<div class="row">
<x-vuexy-admin::form.select :uid="$uniqueId" model="manager_id" label="Gerente" placeholder="Selecciona el gerente" :options="$manager_options" class="select2 form-select" />
</div>
{{-- Código y Prioridad --}}
<hr>
<div class="row">
<x-vuexy-admin::form.input :uid="$uniqueId" model="code" label="Código de almacén" icon="ti ti-tag" parentClass="col-md-8" autocomplete="off"/>
<x-vuexy-admin::form.input :uid="$uniqueId" model="priority" label="Prioridad" type="number" max="99" parentClass="col-md-4" class="text-center" />
</div>
{{-- Detalles del Almacén --}}
<x-vuexy-admin::form.input :uid="$uniqueId" model="name" label="Nombre del almacén" />
<x-vuexy-admin::form.textarea :uid="$uniqueId" model="description" label="Descripción" placeholder="Ingresa una breve descripción del almacén" helperText="Describe el propósito y características del almacén." />
{{-- Información de Contacto --}}
<hr>
<div class="row">
<x-vuexy-admin::form.input type="tel" :uid="$uniqueId" model="tel" label="Teléfono" icon="ti ti-phone" phoneMode="national" />
<x-vuexy-admin::form.input type="tel" :uid="$uniqueId" model="tel2" label="Teléfono 2" icon="ti ti-phone" phoneMode="national" />
</div>
{{-- Configuración Adicional --}}
<hr>
<x-vuexy-admin::form.checkbox :uid="$uniqueId" wire:model="status" label="Activo" switch switchType="square" size="lg" color="success" />
</x-vuexy-admin::form>
</x-vuexy-admin::offcanvas.basic>
</div>
@push('page-script')
<script>
const csrf_token = "{{ csrf_token() }}";
const initializeContactForm = () => {
// Inicializar Select2 sin jQuery
const initializeSelect2 = () => {
$("#manager_id_{{ $uniqueId }}")
.select2({
dropdownAutoWidth: true,
width: '100%',
dropdownParent: document.getElementById('warehouseForm')
}).on('select2:clear', function (e) {
@this.manager_id = null;
}).on('select2:select', function (e) {
@this.manager_id = e.params.data.id;
});
};
const storeIdElement = document.getElementById('store_id_{{ $uniqueId }}');
const workCenterIdElement = document.getElementById('work_center_id_{{ $uniqueId }}');
const managerIdElement = document.getElementById('manager_id_{{ $uniqueId }}');
// Evento de cambio en store_id
storeIdElement.addEventListener('change', async function () {
// Limpiar y deshabilitar el select
workCenterIdElement.innerHTML = '<option value="">Selecciona el área de trabajo</option>';
workCenterIdElement.disabled = true;
const storeIdValue = storeIdElement.value;
if (storeIdValue) {
try {
// Mostrar mensaje de carga
workCenterIdElement.innerHTML = '<option value="">Cargando áreas de trabajo...</option>';
const response = await fetch("{{ route('admin.store-manager.work-centers.ajax') }}", {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': csrf_token, // Agregar CSRF token
},
body: JSON.stringify({
store_id: storeIdValue,
responseType: 'keyValue',
limit: -1 // Sin límite
}),
});
if (!response.ok) {
throw new Error('Error en la solicitud');
}
const result = await response.json();
if (result && typeof result === 'object' && Object.keys(result).length > 0) {
// Limpiar y agregar nuevas opciones
workCenterIdElement.innerHTML = '<option value="">Selecciona el área de trabajo</option>';
Object.entries(result).forEach(([key, value]) => {
workCenterIdElement.append(new Option(value, key, false, false));
});
} else {
// Si no hay datos disponibles
workCenterIdElement.innerHTML = '<option value="">No hay áreas de trabajo disponibles</option>';
}
// Habilitar el select después de completar la carga
workCenterIdElement.disabled = false;
} catch (error) {
console.error('Error al cargar los centros de trabajo:', error);
// En caso de error, mostrar mensaje por defecto
workCenterIdElement.innerHTML = '<option value="">Selecciona el área de trabajo</option>';
workCenterIdElement.disabled = false;
}
}
});
setTimeout(() => {
// Inicializa los select2
initializeSelect2();
}, 1);
}
// Evento para inicializar el formulario cuando se carga la página
document.addEventListener("DOMContentLoaded", () => {
var myOffcanvas = document.getElementById('{{ $offcanvasId }}')
myOffcanvas.addEventListener('show.bs.offcanvas', function () {
initializeContactForm();
});
});
</script>
@endpush

View File

@ -0,0 +1,12 @@
<x-vuexy-admin::table.bootstrap.manager :tagName="$tagName" :datatableConfig="$bt_datatable">
<x-slot name="tools">
<div class="mb-4 pr-2">
<x-vuexy-admin::button.index-off-canvas :label="$singularName" :tagName="$tagName" />
</div>
@if(count($storeOptions) > 1)
<div class="mb-4 pr-2 pt-1" style="max-width: 320px; min-width: 220px;">
<x-vuexy-admin::form.select model="store_id" :options="$storeOptions" placeholder="[Sucursal]" size="sm" />
</div>
@endif
</x-slot>
</x-vuexy-admin::table.bootstrap.manager>