517 lines
22 KiB
PHP
517 lines
22 KiB
PHP
|
<section id="crm-warehouses-index">
|
||
|
<div class="crm-warehouses-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>
|
||
|
|
||
|
@section('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-warehouses-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 ',
|
||
|
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 ',
|
||
|
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-warehouses-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>
|
||
|
@endsection
|