$(function () {
const isPurchase = $('#is_compra').val() === '1';
if (isPurchase) {
return;
}
const state = {};
const trackable = [1, 2];
let activeKey = null;
const globalSelections = new Map();
const $modal = $('#modal-imei-sale');
const $table = $('#imei-sale-table tbody');
const $feedback = $('#imei-sale-feedback');
const $payloadInput = $('#sale_imeis_payload');
const $form = $('#form-nfe');
$('#inp-local_id').on('change', function () {
Object.keys(state).forEach((key) => {
releaseImeis(state[key].imeis || []);
state[key].imeis = [];
const row = getRowByKey(key);
if (row) {
updateBadge(row);
}
});
});
window.handleSaleProductSelection = function (row, product) {
const key = getRowKey(row);
ensureState(key);
if (state[key].product_id && state[key].product_id !== product.id) {
releaseImeis(state[key].imeis);
state[key].imeis = [];
}
state[key].product_id = product.id;
state[key].tracking = parseInt(product.tracking_type ?? 0, 10);
if (requiresTracking(state[key].tracking)) {
showButton(row);
} else {
hideButton(row);
state[key].imeis = [];
}
updateBadge(row);
};
syncRowKeys();
$(document).on('click', '.btn-add-tr-nfe', function () {
setTimeout(syncRowKeys, 200);
});
$(document).on('click', '.btn-remove-tr', function () {
const row = $(this).closest('tr');
const key = getRowKey(row);
releaseImeis(state[key]?.imeis || []);
delete state[key];
setTimeout(syncRowKeys, 200);
});
$(document).on('click', '.btn-manage-imei', function () {
const row = $(this).closest('tr');
const key = getRowKey(row);
ensureState(key);
if (!state[key].product_id) {
swal('Atenção', 'Selecione o produto antes de escolher os IMEIs/Seriais.', 'warning');
return;
}
if (!requiresTracking(state[key].tracking)) {
swal('Atenção', 'Este produto não exige IMEI/Serial.', 'info');
return;
}
const branchId = $('#inp-local_id').val();
if (!branchId) {
swal('Atenção', 'Selecione o local/filial da venda antes de continuar.', 'warning');
return;
}
activeKey = key;
$table.empty();
$feedback.text('Carregando IMEIs disponíveis...');
$.get(path_url + 'api/imei-units/available', {
product_id: state[key].product_id,
branch_id: branchId,
empresa_id: $('#empresa_id').val()
})
.done(function (response) {
if (!response.length) {
$feedback.text('Nenhum IMEI/Serial disponível neste local.');
return;
}
renderAvailable(response, key);
})
.fail(function () {
$feedback.text('Não foi possível carregar os IMEIs disponíveis.');
});
$modal.modal('show');
});
$('#btn-save-imei-sale').on('click', function () {
persistSaleSelection();
});
$(document).on('input blur', '.qtd', function () {
updateBadge($(this).closest('tr'));
});
$form.on('submit', function (e) {
if (!validateBeforeSubmit()) {
e.preventDefault();
return false;
}
const payload = buildPayload();
if (payload === null) {
e.preventDefault();
return false;
}
if (payload.length) {
$payloadInput.val(JSON.stringify(payload));
} else {
$payloadInput.val('');
}
return true;
});
function renderAvailable(units, key) {
$table.empty();
const selectedIds = new Set(state[key].imeis.map((item) => item.id));
units.forEach((unit) => {
const isSelected = selectedIds.has(unit.id);
const disabled = globalSelections.has(unit.id) && globalSelections.get(unit.id) !== key;
const branchName = unit.branch ? unit.branch.descricao : '';
const row = `
|
|
${unit.imei_or_serial} |
${branchName} |
`;
$table.append(row);
});
$feedback.text('Selecione os IMEIs/Seriais desejados.');
}
function persistSaleSelection() {
if (activeKey === null) {
$modal.modal('hide');
return;
}
const row = getRowByKey(activeKey);
const requiredQty = getRowQuantity(row);
const selections = [];
let hasError = false;
$table.find('.imei-sale-check:checked').each(function () {
const id = parseInt($(this).val(), 10);
const code = $(this).data('code');
selections.push({ id, code });
});
if (selections.length !== requiredQty) {
swal('Atenção', `Selecione ${requiredQty} IMEIs/Seriais para este item.`, 'warning');
return;
}
selections.forEach((item) => {
const other = globalSelections.get(item.id);
if (other && other !== activeKey) {
swal('Atenção', `O IMEI/Serial ${item.code} já foi utilizado em outro item.`, 'warning');
hasError = true;
}
});
if (hasError) {
return;
}
releaseImeis(state[activeKey].imeis);
state[activeKey].imeis = selections;
selections.forEach((item) => {
globalSelections.set(item.id, activeKey);
});
updateBadge(row);
activeKey = null;
$modal.modal('hide');
}
function releaseImeis(items) {
items.forEach((item) => {
if (globalSelections.get(item.id)) {
globalSelections.delete(item.id);
}
});
}
function buildPayload() {
const payload = [];
let hasError = false;
const usedCodes = new Set();
$('.table-produtos tbody tr.dynamic-form').each(function (index) {
const row = $(this);
const key = getRowKey(row);
const productId = row.find('.produto_id').val();
const quantity = getRowQuantity(row);
if (!productId) {
return;
}
ensureState(key);
if (!requiresTracking(state[key].tracking)) {
return;
}
if (!quantity || quantity < 1) {
swal('Atenção', `Informe a quantidade do item ${index + 1}.`, 'warning');
hasError = true;
return false;
}
if (state[key].imeis.length !== quantity) {
swal('Atenção', `O item ${index + 1} precisa ter ${quantity} IMEIs/Seriais selecionados.`, 'warning');
hasError = true;
return false;
}
state[key].imeis.forEach((item) => {
if (usedCodes.has(item.id)) {
swal('Atenção', `O IMEI/Serial ${item.code} foi associado a mais de um item.`, 'warning');
hasError = true;
}
usedCodes.add(item.id);
});
payload.push({
product_id: productId,
imei_unit_ids: state[key].imeis.map((item) => item.id),
});
});
if (hasError) {
return null;
}
return payload;
}
function validateBeforeSubmit() {
if (!$('.btn-manage-imei').length) {
return true;
}
if (!$('#inp-local_id').val()) {
swal('Atenção', 'Selecione o local/filial da venda.', 'warning');
return false;
}
return true;
}
function syncRowKeys() {
$('.table-produtos tbody tr.dynamic-form').each(function () {
const row = $(this);
const key = getRowKey(row);
ensureState(key);
row.attr('data-line', key);
row.find('.btn-manage-imei').attr('data-line', key);
const initialTracking = row.data('initial-tracking');
const initialProduct = row.data('initial-product');
if (typeof initialProduct !== 'undefined' && initialProduct && !state[key].product_id) {
state[key].product_id = initialProduct;
}
if (typeof initialTracking !== 'undefined' && state[key].tracking === null) {
state[key].tracking = parseInt(initialTracking, 10);
if (requiresTracking(state[key].tracking)) {
showButton(row);
}
}
updateBadge(row);
});
}
function showButton(row) {
row.find('.btn-manage-imei').removeClass('d-none');
}
function hideButton(row) {
row.find('.btn-manage-imei').addClass('d-none');
}
function getRowKey(row) {
return row.find('._key').val() ?? row.index();
}
function getRowByKey(key) {
let target = null;
$('.table-produtos tbody tr.dynamic-form').each(function () {
if (getRowKey($(this)) == key) {
target = $(this);
return false;
}
});
return target;
}
function updateBadge(row) {
const key = getRowKey(row);
ensureState(key);
const badge = row.find('.count-badge');
const count = state[key].imeis.length;
badge.text(count);
if (!requiresTracking(state[key].tracking)) {
return;
}
const quantity = getRowQuantity(row);
const btn = row.find('.btn-manage-imei');
if (count === quantity && quantity > 0) {
btn.removeClass('btn-outline-warning').addClass('btn-outline-secondary');
} else {
btn.removeClass('btn-outline-secondary').addClass('btn-outline-warning');
}
}
function getRowQuantity(row) {
const input = row.find('.qtd');
if (!input.length) {
return 0;
}
const value = input.val();
if (!value) {
return 0;
}
if (typeof convertMoedaToFloat === 'function') {
return Math.trunc(convertMoedaToFloat(value));
}
return parseInt(value.replace(/\D/g, ''), 10) || 0;
}
function ensureState(key) {
if (!state[key]) {
state[key] = {
product_id: null,
tracking: null,
imeis: [],
};
}
}
function requiresTracking(value) {
return trackable.includes(parseInt(value, 10));
}
});