mirror of
https://git.imnavajas.es/jjimenez/safekat.git
synced 2025-07-25 22:52:08 +00:00
Merge branch 'main' into add/impresion_etiquetas_envios
This commit is contained in:
@ -0,0 +1,92 @@
|
||||
|
||||
class MaquinistaTareaList {
|
||||
constructor(domItem) {
|
||||
this.item = domItem
|
||||
this.maquinaId = this.item.data("id")
|
||||
this.datatableItem = $("#maquinista-tarea-table")
|
||||
this.btnTareasHoy = $("#btn-tareas-hoy")
|
||||
this.todayDate = $('#today-date')
|
||||
this.btnAllTareas = $("#btn-all-tareas")
|
||||
this.datatableColumns = [
|
||||
{ data: 'otId', searchable: false, sortable: false },
|
||||
{ data: 'tareaName', searchable: false, sortable: false },
|
||||
{ data: 'tareaEstado', searchable: false, sortable: false,render : this.renderStado.bind(this)},
|
||||
{ data: 'presupuesto_titulo', searchable: false, sortable: false },
|
||||
{ data: 'papel_impresion', searchable: false, sortable: false },
|
||||
{ data: 'papel_gramaje', searchable: false, sortable: false },
|
||||
{ data: 'fecha_impresion', searchable: false, sortable: false },
|
||||
{ data: 'action', searchable: false, sortable: false, width: "20rem" },
|
||||
]
|
||||
this.urlAll = '/produccion/ordentrabajo/maquinista/maquinas/tareas/datatable/all/' + this.maquinaId
|
||||
this.urlToday = '/produccion/ordentrabajo/maquinista/maquinas/tareas/datatable/today/' + this.maquinaId
|
||||
this.initTable()
|
||||
this.estadoClass = {
|
||||
I : 'primary',
|
||||
P : 'warning',
|
||||
S : 'warning',
|
||||
D : 'danger',
|
||||
F : 'success'
|
||||
}
|
||||
this.estadoNames = {
|
||||
I : 'Iniciada',
|
||||
P : 'Pendiente',
|
||||
S : 'Pausada',
|
||||
D : 'Aplazada',
|
||||
F : 'Finalizada'
|
||||
}
|
||||
|
||||
}
|
||||
init(){
|
||||
this.btnTareasHoy.on('click',this.loadToday.bind(this))
|
||||
this.btnAllTareas.on('click',this.loadAll.bind(this))
|
||||
}
|
||||
initTable() {
|
||||
|
||||
this.datatable = this.datatableItem.DataTable({
|
||||
processing: true,
|
||||
layout: {
|
||||
topStart: 'pageLength',
|
||||
topEnd: 'search',
|
||||
bottomStart: 'info',
|
||||
bottomEnd: 'paging'
|
||||
},
|
||||
serverSide: true,
|
||||
pageLength: 25,
|
||||
language: {
|
||||
url: "/themes/vuexy/vendor/libs/datatables-sk/plugins/i18n/es-ES.json"
|
||||
},
|
||||
columns: this.datatableColumns,
|
||||
ajax: this.urlToday
|
||||
});
|
||||
}
|
||||
loadToday() {
|
||||
this.btnTareasHoy.removeClass('active')
|
||||
this.btnTareasHoy.removeAttr('aria-pressed')
|
||||
this.btnAllTareas.removeClass('active')
|
||||
this.btnAllTareas.removeAttr('aria-pressed')
|
||||
this.todayDate.removeClass('d-none')
|
||||
this.btnTareasHoy.addClass('active')
|
||||
this.btnTareasHoy.attr('aria-pressed',true)
|
||||
this.datatable.ajax.url(this.urlToday)
|
||||
this.datatable.ajax.reload()
|
||||
|
||||
|
||||
}
|
||||
loadAll(){
|
||||
this.btnTareasHoy.removeClass('active')
|
||||
this.btnTareasHoy.removeAttr('aria-pressed')
|
||||
this.todayDate.addClass('d-none')
|
||||
this.btnAllTareas.addClass('active')
|
||||
this.btnAllTareas.attr('aria-pressed',true)
|
||||
this.datatable.ajax.url(this.urlAll)
|
||||
this.datatable.ajax.reload()
|
||||
|
||||
}
|
||||
renderStado(d){
|
||||
|
||||
return `<span class="badge text-bg-${this.estadoClass[d]}">${this.estadoNames[d]}</span>`
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default MaquinistaTareaList;
|
||||
@ -0,0 +1,201 @@
|
||||
|
||||
import Ajax from '../../../components/ajax.js'
|
||||
import { alertConfirmAction } from '../../../components/alerts/sweetAlert.js'
|
||||
class MaquinistaTareaView {
|
||||
constructor(domItem) {
|
||||
this.item = domItem
|
||||
this.tareaId = this.item.data("id");
|
||||
this.btnPlay = this.item.find("#btn-start-tarea")
|
||||
this.btnPause = this.item.find("#btn-pause-tarea")
|
||||
this.btnDelay = this.item.find("#btn-stop-tarea")
|
||||
this.btnFinish = this.item.find("#btn-finish-tarea")
|
||||
this.btnDeleteProgress = this.item.find("#btn-delete-tarea")
|
||||
this.actionButtons = this.item.find('.action-btn')
|
||||
this.tareaCardClass = '.tarea-card-action-block'
|
||||
this.inputClick = $('.ot-tarea-click')
|
||||
}
|
||||
init() {
|
||||
this.actionButtons.on('click', this.eventActionButton.bind(this))
|
||||
this.btnDelay.on('click', this.delayEventActionButton.bind(this))
|
||||
this.btnDeleteProgress.on('click', this.handleDeleteTareaProgress.bind(this))
|
||||
this.handleGetTareaProgress();
|
||||
this.inputClick.on('input', this.handleUpdateClickInput.bind(this))
|
||||
}
|
||||
|
||||
eventActionButton(event) {
|
||||
let statusClick = $(event.currentTarget).data('estado');
|
||||
this.showBasedOnStatus(statusClick);
|
||||
console.info(`Estado ${statusClick}`)
|
||||
this.handleUpdateTareaProgress(statusClick)
|
||||
}
|
||||
delayEventActionButton(event) {
|
||||
let statusClick = $(event.currentTarget).data('estado');
|
||||
this.delayTarea()
|
||||
}
|
||||
actionLoader(status = true) {
|
||||
if (status) {
|
||||
Notiflix.Block.circle(this.tareaCardClass);
|
||||
} else {
|
||||
Notiflix.Block.remove(this.tareaCardClass);
|
||||
}
|
||||
}
|
||||
showPlay() {
|
||||
this.btnPause.addClass('d-none')
|
||||
this.btnPlay.removeClass('d-none')
|
||||
this.btnFinish.removeClass('d-none')
|
||||
|
||||
}
|
||||
showPause() {
|
||||
this.btnPlay.addClass('d-none')
|
||||
this.btnFinish.addClass('d-none')
|
||||
this.btnPause.removeClass('d-none')
|
||||
|
||||
}
|
||||
disableButtons() {
|
||||
this.actionButtons.attr('disabled', 'disabled')
|
||||
}
|
||||
enableButtons() {
|
||||
this.actionButtons.removeAttr('disabled')
|
||||
}
|
||||
handleUpdateClickInput(event) {
|
||||
let tareaId = $(event.currentTarget).data('id');
|
||||
let name = $(event.currentTarget).attr('name')
|
||||
let value = $(event.currentTarget).val()
|
||||
let formData = {
|
||||
orden_trabajo_tarea_id: tareaId
|
||||
}
|
||||
|
||||
formData[name] = value;
|
||||
let ajax = new Ajax('/produccion/ordentrabajo/update/tarea',
|
||||
formData,
|
||||
null,
|
||||
this.handleUpdateClickInputSucess.bind(this),
|
||||
this.handleGetTareaProgressError.bind(this)
|
||||
)
|
||||
if (value) {
|
||||
ajax.post()
|
||||
}
|
||||
|
||||
}
|
||||
handleUpdateClickInputSucess(response) {
|
||||
popSuccessAlert(response.message)
|
||||
}
|
||||
handleUpdateClickInputError(error) {
|
||||
popErrorAlert(error)
|
||||
}
|
||||
handleDeleteTareaProgress() {
|
||||
let ajax = new Ajax('/produccion/ordentrabajo/tarea/progress/' + this.tareaId,
|
||||
null,
|
||||
null,
|
||||
this.handleDeleteTareaProgressSuccess.bind(this),
|
||||
this.handleDeleteTareaProgressError.bind(this)
|
||||
)
|
||||
alertConfirmAction('Se borrará todo el progreso y se reiniciará el progreso')
|
||||
.then(result => {
|
||||
if (result.isConfirmed) {
|
||||
this.actionLoader(true)
|
||||
ajax.delete()
|
||||
}
|
||||
})
|
||||
}
|
||||
handleDeleteTareaProgressSuccess() {
|
||||
window.location.reload()
|
||||
}
|
||||
handleDeleteTareaProgressError(error) {
|
||||
popErrorAlert(error)
|
||||
}
|
||||
|
||||
handleGetTareaProgress() {
|
||||
this.actionLoader()
|
||||
let ajax = new Ajax(`/produccion/ordentrabajo/tarea/progress/${this.tareaId}`, null, null,
|
||||
this.handleGetTareaProgressSuccess.bind(this),
|
||||
this.handleGetTareaProgressError.bind(this),
|
||||
|
||||
)
|
||||
if (this.tareaId) {
|
||||
ajax.get();
|
||||
}
|
||||
}
|
||||
handleGetTareaProgressSuccess(response) {
|
||||
if (response.progress_dates) {
|
||||
let lastStatus = response.progress_dates.findLast(e => e.estado != null).estado
|
||||
console.log("Last status :", lastStatus)
|
||||
this.showBasedOnStatus(lastStatus)
|
||||
}
|
||||
if (response.tiempo_trabajado) {
|
||||
this.item.find('#tiempo-real-info').html(response.tiempo_trabajado)
|
||||
}
|
||||
this.actionLoader(false)
|
||||
|
||||
}
|
||||
handleGetTareaProgressError(error) {
|
||||
this.actionLoader(false)
|
||||
}
|
||||
handleUpdateTareaProgress(status) {
|
||||
this.actionLoader(true)
|
||||
let ajax = new Ajax(`/produccion/ordentrabajo/update/tarea/progress`,
|
||||
{
|
||||
'ot_tarea_id': this.tareaId,
|
||||
'estado': status
|
||||
}, null,
|
||||
this.handleUpdateTareaProgressSuccess.bind(this),
|
||||
this.handleUpdateTareaProgressError.bind(this),
|
||||
)
|
||||
if (this.tareaId) {
|
||||
ajax.post();
|
||||
}
|
||||
}
|
||||
handleUpdateTareaProgressSuccess(response) {
|
||||
if (response.data) {
|
||||
if (response.data.estado == 'D') {
|
||||
window.location.href = '/produccion/ordentrabajo/maquinista/maquinas/view'
|
||||
}
|
||||
this.showBasedOnStatus(response.data.status)
|
||||
}
|
||||
this.actionLoader(false)
|
||||
}
|
||||
handleUpdateTareaProgressError(error) {
|
||||
popErrorAlert(error.error)
|
||||
this.actionLoader(false)
|
||||
}
|
||||
|
||||
showBasedOnStatus(status) {
|
||||
if (['P', 'S'].includes(status)) {
|
||||
this.enableButtons()
|
||||
this.showPlay()
|
||||
}
|
||||
if (['F', 'E'].includes(status)) {
|
||||
this.disableButtons()
|
||||
this.showPlay()
|
||||
}
|
||||
if (status == 'I') {
|
||||
this.enableButtons()
|
||||
this.showPause()
|
||||
}
|
||||
if (status == 'D') {
|
||||
window.href
|
||||
}
|
||||
}
|
||||
eventUnloadWindow(event) {
|
||||
// return confirm('¿Estás seguro de abandonar la página? La tarea se marcará como pausada')
|
||||
alertConfirmAction('La tarea se marcará como pausada')
|
||||
.then(result => {
|
||||
|
||||
if (result.isConfirmed) {
|
||||
return ""
|
||||
}
|
||||
})
|
||||
}
|
||||
delayTarea() {
|
||||
alertConfirmAction('La tarea se marcará como aplazada y podrás continuar después')
|
||||
.then(result => {
|
||||
if (result.isConfirmed) {
|
||||
this.handleUpdateTareaProgress('D')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
export default MaquinistaTareaView;
|
||||
@ -0,0 +1,7 @@
|
||||
import MaquinistaTareaList from "./maquinistaTareaList.js";
|
||||
|
||||
$(() => {
|
||||
console.info("MAQUINISTA TAREA LIST")
|
||||
let maquinistaTareaList = new MaquinistaTareaList($("#viewMaquinistaMaquinaTareas"))
|
||||
maquinistaTareaList.init();
|
||||
})
|
||||
@ -0,0 +1,7 @@
|
||||
import MaquinistaTareaView from "./maquinistaTareaView.js";
|
||||
|
||||
$(() => {
|
||||
console.info("MAQUINISTA TAREA VIEW")
|
||||
let mtv = new MaquinistaTareaView($("#viewMaquinistaMaquinaTarea"))
|
||||
mtv.init();
|
||||
})
|
||||
@ -3,8 +3,9 @@ import ClassSelect from '../../components/select2.js';
|
||||
|
||||
$(() => {
|
||||
|
||||
let otsFilter = '';
|
||||
|
||||
const selectPedidos = new ClassSelect($('#buscadorPedidos'), '/logistica/selectPedidosForEnvio', "");
|
||||
const selectPedidos = new ClassSelect($('#buscadorPedidos'), '/logistica/selectForNewEnvio', "");
|
||||
selectPedidos.init();
|
||||
const selectDirecciones = new ClassSelect($('#selectDirecciones'), '/logistica/selectDireccionForEnvio', "", true, {
|
||||
pedido_id: () => selectPedidos.getVal()
|
||||
@ -63,10 +64,13 @@ $(() => {
|
||||
"dom": 'lBrtip',
|
||||
"ajax": {
|
||||
"url": "/logistica/datatableEnvios",
|
||||
"data": function (d) {
|
||||
d.otsFilter = otsFilter;
|
||||
}
|
||||
},
|
||||
"columns": [
|
||||
{ "data": "id" },
|
||||
{ "data": "pedidos" },
|
||||
{ "data": "ots" },
|
||||
{ "data": "num_lineas" },
|
||||
{ "data": "att" },
|
||||
{ "data": "direccion" },
|
||||
@ -99,6 +103,26 @@ $(() => {
|
||||
window.location.href = '/logistica/envio/' + $(this).attr('data-id');
|
||||
});
|
||||
|
||||
$(document).on("keyup", ".envio-filter", (event) => {
|
||||
let columnName = $(event.currentTarget).attr("name");
|
||||
let columnIndex = $('#tableOfEnvios').DataTable().columns().eq(0).filter(function (index) {
|
||||
return $('#tableOfEnvios').DataTable().column(index).dataSrc() === columnName;
|
||||
})[0];
|
||||
$('#tableOfEnvios').DataTable().column(columnIndex).search($(event.currentTarget).val()).draw()
|
||||
})
|
||||
|
||||
|
||||
$(document).on("keyup", ".envio-filter-ots", (event) => {
|
||||
otsFilter = $(event.currentTarget).val();
|
||||
$('#tableOfEnvios').DataTable().ajax.reload();
|
||||
})
|
||||
|
||||
$(document).on("change", ".envio-filter-select", (event) => {
|
||||
let columnName = $(event.currentTarget).attr("name");
|
||||
let columnIndex = $('#tableOfEnvios').DataTable().columns().eq(0).filter(function (index) {
|
||||
return $('#tableOfEnvios').DataTable().column(index).dataSrc() === columnName;
|
||||
})[0];
|
||||
$('#tableOfEnvios').DataTable().column(columnIndex).search($(event.currentTarget).val()).draw();
|
||||
});
|
||||
|
||||
});
|
||||
@ -1,7 +1,7 @@
|
||||
import Ajax from "../../components/ajax.js"
|
||||
import ClassSelect from "../../components/select2.js";
|
||||
import DatePicker from "../../components/datepicker.js";
|
||||
import { alertConfirmAction, alertConfirmationDelete, alertSuccess } from "../../components/alerts/sweetAlert.js";
|
||||
import { alertConfirmAction, alertConfirmationDelete, alertError, alertSuccess } from "../../components/alerts/sweetAlert.js";
|
||||
import Modal from "../../components/modal.js"
|
||||
import FileUploadDropzone from '../../components/forms/fileUploadDropzone.js';
|
||||
class OrdenTrabajo {
|
||||
@ -17,6 +17,9 @@ class OrdenTrabajo {
|
||||
this.alertOrdenTrabajo = this.item.find("#alert-orden-trabajo");
|
||||
this.btnFinalizarPedido = this.item.find("#btn-finalizar-orden-pedido")
|
||||
this.btnReactivarOt = this.item.find("#btn-reactivar-orden-pedido")
|
||||
this.btnEraseDate = this.item.find('.btn-erase-date');
|
||||
this.btnErasePedidoDate = this.item.find('.btn-erase-pedido-date');
|
||||
|
||||
this.isOtFinalizada = false;
|
||||
|
||||
this.btnResetTareas = this.item.find("#btn-reset-tareas")
|
||||
@ -61,7 +64,7 @@ class OrdenTrabajo {
|
||||
altInput: true,
|
||||
altFormat: "d/m/Y",
|
||||
dateFormat: "Y-m-d",
|
||||
allowInput: true,
|
||||
allowInput: false,
|
||||
}
|
||||
this.tiempoProcesamiento = this.otForm.find("#ot-tiempo-procesamiento")
|
||||
this.fechaImpresion = new DatePicker(this.otForm.find("#ot-fecha-impresion"), option)
|
||||
@ -144,7 +147,8 @@ class OrdenTrabajo {
|
||||
this.otForm.on("click", "#btn-delete-portada", this.handleDeletePortada.bind(this))
|
||||
this.btnFinalizarPedido.on("click", this.handleFinalizarPedido.bind(this))
|
||||
this.btnReactivarOt.on("click", this.handleReactivarPedido.bind(this))
|
||||
|
||||
this.btnEraseDate.on('click', this.handleEraseDate.bind(this))
|
||||
this.btnErasePedidoDate.on('click', this.handleErasePedidoDate.bind(this))
|
||||
this.tareasTableItem.on("click", ".ot-tarea-btn-delete", this.handleTareaDeleteConfirmation.bind(this))
|
||||
this.item.on("click", "#btn-reset-tareas", this.handleResetTareasDeleteConfirmation.bind(this))
|
||||
this.otForm.on("click", ".ot-tarea-comment", this.handleNoteTarea.bind(this))
|
||||
@ -496,7 +500,8 @@ class OrdenTrabajo {
|
||||
const key = $(event.currentTarget).attr("name")
|
||||
const data = {}
|
||||
const element = $(event.currentTarget);
|
||||
data[key] = $(event.currentTarget).val()
|
||||
const value = $(event.currentTarget).val()
|
||||
data[key] = value
|
||||
data["orden_trabajo_id"] = this.modelId
|
||||
data["name"] = key;
|
||||
const ajax = new Ajax(
|
||||
@ -506,7 +511,12 @@ class OrdenTrabajo {
|
||||
this.handleDateChangeSuccess.bind(this, element),
|
||||
this.handleDateChangeError.bind(this)
|
||||
)
|
||||
ajax.post();
|
||||
if (value) {
|
||||
|
||||
ajax.post();
|
||||
} else {
|
||||
this.handleEraseDate(event)
|
||||
}
|
||||
|
||||
}
|
||||
handleDateChangeSuccess(formItem, response) {
|
||||
@ -514,8 +524,8 @@ class OrdenTrabajo {
|
||||
alertSuccess(response.message).fire()
|
||||
this._handleGetData();
|
||||
if (response.user) {
|
||||
formItem.parent().find(".form-text").remove()
|
||||
formItem.parent().append(`<div class="form-text">${[response.user.first_name, response.user.last_name].join(" ")}</div>`)
|
||||
formItem.parent().parent().find(".form-text").remove()
|
||||
formItem.parent().parent().append(`<div class="form-text">${[response.user.first_name, response.user.last_name].join(" ")}</div>`)
|
||||
}
|
||||
}
|
||||
handleDateChangeError(errors) { }
|
||||
@ -523,7 +533,8 @@ class OrdenTrabajo {
|
||||
const key = $(event.currentTarget).attr("name")
|
||||
const data = {}
|
||||
const element = $(event.currentTarget);
|
||||
data[key] = $(event.currentTarget).val()
|
||||
const value = element.val()
|
||||
data[key] = value
|
||||
data["orden_trabajo_id"] = this.modelId
|
||||
data["name"] = key;
|
||||
const ajax = new Ajax(
|
||||
@ -533,7 +544,11 @@ class OrdenTrabajo {
|
||||
this.handleDateChangeSuccess.bind(this, element),
|
||||
this.handleDateChangeError.bind(this)
|
||||
)
|
||||
ajax.post();
|
||||
if (value) {
|
||||
ajax.post();
|
||||
} else {
|
||||
this.handleErasePedidoDate(event)
|
||||
}
|
||||
}
|
||||
handlePedidoCheckChange(event) {
|
||||
const key = $(event.currentTarget).attr("name")
|
||||
@ -745,6 +760,68 @@ class OrdenTrabajo {
|
||||
this.tareaCommentModal.toggle()
|
||||
}
|
||||
}
|
||||
handleEraseDate(event) {
|
||||
let name = $(event.currentTarget).parent().find('input').attr('name')
|
||||
let ajax = new Ajax('/produccion/ordentrabajo/reset/date', {
|
||||
name: name,
|
||||
orden_trabajo_id: this.modelId
|
||||
},
|
||||
null,
|
||||
this.handleEraseDateSuccess.bind(this),
|
||||
this.handleEraseDateError.bind(this)
|
||||
)
|
||||
alertConfirmationDelete()
|
||||
.then(result => {
|
||||
if (result.isConfirmed) {
|
||||
console.log(name)
|
||||
ajax.post()
|
||||
}
|
||||
})
|
||||
}
|
||||
handleEraseDateSuccess(response) {
|
||||
this.item.find(`input[name="${response.data.name}"]`).val(null)
|
||||
if (response.user) {
|
||||
this.item.find(`input[name="${response.data.name}"]`).parent().parent().find(".form-text").remove()
|
||||
this.item.find(`input[name="${response.data.name}"]`).parent().parent().append(`<div class="form-text">${[response.user.first_name, response.user.last_name].join(" ")}</div>`)
|
||||
}
|
||||
alertSuccess(response.message).fire()
|
||||
this._handleGetData()
|
||||
}
|
||||
handleEraseDateError(error) {
|
||||
alertError(error.message).fire()
|
||||
this._handleGetData()
|
||||
}
|
||||
handleErasePedidoDate(event) {
|
||||
let name = $(event.currentTarget).parent().find('input').attr('name')
|
||||
let ajax = new Ajax('/produccion/ordentrabajo/reset/pedido/date', {
|
||||
name: name,
|
||||
orden_trabajo_id: this.modelId
|
||||
},
|
||||
null,
|
||||
this.handleErasePedidoDateSuccess.bind(this),
|
||||
this.handleErasePedidoDateError.bind(this)
|
||||
)
|
||||
alertConfirmationDelete()
|
||||
.then(result => {
|
||||
if (result.isConfirmed) {
|
||||
console.log(name)
|
||||
ajax.post()
|
||||
}
|
||||
})
|
||||
}
|
||||
handleErasePedidoDateSuccess(response) {
|
||||
this.item.find(`input[name="${response.data.name}"]`).val(null)
|
||||
if (response.user) {
|
||||
this.item.find(`input[name="${response.data.name}"]`).parent().parent().find(".form-text").remove()
|
||||
this.item.find(`input[name="${response.data.name}"]`).parent().parent().append(`<div class="form-text">${[response.user.first_name, response.user.last_name].join(" ")}</div>`)
|
||||
}
|
||||
alertSuccess(response.message).fire()
|
||||
this._handleGetData()
|
||||
}
|
||||
handleErasePedidoDateError(error) {
|
||||
alertError(error.message).fire()
|
||||
this._handleGetData()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
9
httpdocs/themes/vuexy/css/maquinista.css
Normal file
9
httpdocs/themes/vuexy/css/maquinista.css
Normal file
@ -0,0 +1,9 @@
|
||||
.maquina-btn
|
||||
{
|
||||
height : 5rem;
|
||||
width : 100%;
|
||||
font-size : 20px;
|
||||
}
|
||||
.table-maquinista td{
|
||||
height : 10rem;
|
||||
}
|
||||
Reference in New Issue
Block a user