$(function() { $(document).on("click", ".owner-ad-status-action", async function() { const button = $(this); const publicId = String(button.data("ad-id") || ""); const action = String(button.data("ad-action") || ""); const redirect = String(button.data("success-redirect") || ""); if (typeof closeDashboardAdMenus === "function") { closeDashboardAdMenus(); } if (button.prop("disabled") || button.data("loading")) { return; } if (!publicId || !action) { popZ("Não foi possível identificar este anúncio.", "warning"); return; } button.data("loading", true); const confirmation = await confirmOwnerAdStatusAction(action, button); if (!confirmation.confirmed) { button.data("loading", false); return; } button.prop("disabled", true).attr("aria-busy", "true"); $.ajax({ type: "POST", url: "/api/dashboard", data: { action: "update_ad_status", public_id: publicId, ad_action: action, ...confirmation.data }, dataType: "json", success: function(response) { if (response.result !== "ad_status_updated") { handleOwnerAdStatusResponse(response); return; } const message = action === "complete" ? (response.status === "traded" ? "Anúncio marcado como trocado." : "Anúncio marcado como vendido.") : "Anúncio atualizado com sucesso."; if (redirect) { button.data("keep-disabled", true); popZ(message, "success", redirect); return; } popZ(message, "success"); if (typeof updateDashboardAdRow === "function") { updateDashboardAdRow(publicId, response.rowHtml || ""); } if (typeof updateDashboardSummary === "function") { updateDashboardSummary(response.summary || {}); } }, error: function(jqXhr) { handleOwnerAdStatusResponse(jqXhr.responseJSON || {}); }, complete: function() { button.data("loading", false).removeAttr("aria-busy"); if (!button.data("keep-disabled")) { button.prop("disabled", false); } } }); }); }); async function confirmOwnerAdStatusAction(action, button) { if (action === "complete") { return confirmOwnerAdCompletionAction(button); } const messages = { pause: { title: "Pausar anúncio?", text: "Ele deixará de aparecer no catálogo até ser reativado.", confirmButtonText: "Sim, pausar" }, reactivate: { title: "Reativar anúncio?", text: "Ele voltará a aparecer no catálogo público.", confirmButtonText: "Sim, reativar" }, inactive: { title: "Inativar anúncio?", text: "Ele sairá do catálogo e não poderá ser editado pelo painel neste momento.", confirmButtonText: "Sim, inativar" } }; const options = messages[action] || { title: "Atualizar anúncio?", text: "Confirme para aplicar essa alteração.", confirmButtonText: "Sim, atualizar" }; const result = await Swal.fire({ icon: "warning", title: options.title, text: options.text, showCancelButton: true, confirmButtonText: options.confirmButtonText, cancelButtonText: "Cancelar" }); return { confirmed: result.isConfirmed, data: {} }; } async function confirmOwnerAdCompletionAction(button) { const askingPrice = formatOwnerAdMoney(button.data("ad-price")); const purchasePrice = formatOwnerAdMoney(button.data("ad-purchase-price"), true); const acceptsTrade = String(button.data("ad-negotiation-type") || "sale_only") === "sale_or_trade"; const completionTypeField = acceptsTrade ? ` ` : ''; const today = getOwnerAdLocalDate(); const result = await Swal.fire({ icon: "question", title: "Marcar como vendido", html: `
${completionTypeField}
O preço anunciado foi preenchido como sugestão. Ajuste se houve negociação.
Este dado é privado e ajuda a acompanhar o resultado da negociação. Já preenchemos com a data de hoje. Altere se a venda ocorreu anteriormente.
`, showCancelButton: true, confirmButtonText: "Sim, marcar como vendido", cancelButtonText: "Cancelar", focusConfirm: false, customClass: { popup: "owner-ad-sold-popup", confirmButton: "owner-ad-sold-confirm", cancelButton: "owner-ad-sold-cancel" }, didOpen: function() { $("#ownerAdSalePrice, #ownerAdTradeValue, #ownerAdPurchasePrice").mask("#.##0,00", { reverse: true }); $("#ownerAdCompletionType").on("change", syncOwnerAdCompletionFields); $("#ownerAdTradeInfoToggle").on("click", toggleOwnerAdTradeInfo); syncOwnerAdCompletionFields(); }, preConfirm: function() { const completionType = String($("#ownerAdCompletionType").val() || ""); const saleSource = String($("#ownerAdSaleSource").val() || ""); const salePrice = String($("#ownerAdSalePrice").val() || ""); const tradeEstimatedValue = String($("#ownerAdTradeValue").val() || ""); const purchasePriceValue = String($("#ownerAdPurchasePrice").val() || ""); const saleDate = String($("#ownerAdSaleDate").val() || ""); if (!saleSource) { Swal.showValidationMessage("Informe de onde veio o contato da negociação."); return false; } if (!["sale", "trade"].includes(completionType)) { Swal.showValidationMessage("Informe se o anúncio foi vendido ou trocado."); return false; } if (completionType === "sale" && normalizeOwnerAdMoney(salePrice) <= 0) { Swal.showValidationMessage("Informe um valor final de venda maior que zero."); return false; } if (!/^\d{4}-\d{2}-\d{2}$/.test(saleDate) || saleDate > today) { Swal.showValidationMessage("Informe uma data de conclusão válida, sem usar uma data futura."); return false; } return { sale_source: saleSource, sale_price: completionType === "sale" ? salePrice : "0", trade_estimated_value: completionType === "trade" ? tradeEstimatedValue : "0", purchase_price: purchasePriceValue, sale_date: saleDate, completion_type: completionType }; } }); return { confirmed: result.isConfirmed, data: result.isConfirmed ? result.value : {} }; } function toggleOwnerAdTradeInfo() { const button = $("#ownerAdTradeInfoToggle"); const panel = $("#ownerAdTradeInfo"); const willOpen = panel.prop("hidden"); panel.prop("hidden", !willOpen); button.attr("aria-expanded", willOpen ? "true" : "false"); } function syncOwnerAdCompletionFields() { const isTrade = $("#ownerAdCompletionType").val() === "trade"; $("#ownerAdSalePriceField").prop("hidden", isTrade); $("#ownerAdTradeValueField").prop("hidden", !isTrade); $("#ownerAdCompletionDateLabel").text(isTrade ? "Data da troca" : "Data da venda"); $("#ownerAdCompletionDateHelp").text( "Já preenchemos com a data de hoje. Altere se a "+(isTrade ? "troca" : "venda")+" ocorreu anteriormente." ); } function getOwnerAdLocalDate() { const now = new Date(); const year = now.getFullYear(); const month = String(now.getMonth() + 1).padStart(2, "0"); const day = String(now.getDate()).padStart(2, "0"); return `${year}-${month}-${day}`; } function formatOwnerAdMoney(value, emptyWhenZero = false) { const number = Number.parseFloat(String(value || "").replace(",", ".")); if (!Number.isFinite(number) || (emptyWhenZero && number <= 0)) { return ""; } return number.toLocaleString("pt-BR", { minimumFractionDigits: 2, maximumFractionDigits: 2 }); } function normalizeOwnerAdMoney(value) { const normalized = String(value || "") .replace(/R\$\s?/g, "") .replace(/\s/g, "") .replace(/\./g, "") .replace(",", "."); const number = Number.parseFloat(normalized); return Number.isFinite(number) ? number : 0; } function handleOwnerAdStatusResponse(response) { switch (response.result) { case "ad_not_found": popZ("Este anúncio não foi encontrado na sua conta.", "warning"); break; case "invalid_ad_status_transition": popZ("Este anúncio não permite essa alteração de status.", "warning"); break; case "active_ads_limit_reached": popZ("Limite atingido. Pause ou conclua outro anúncio para reativar este.", "warning"); break; case "plan_regularization_required": popZ("Seu plano precisa ser regularizado antes de reativar anúncios. O anúncio permanece preservado.", "warning", "/dashboard#plano-cobranca"); break; case "invalid_ad_action": popZ("A ação informada para o anúncio é inválida.", "warning"); break; case "invalid_sale_price": popZ("Informe um valor final de venda maior que zero.", "warning"); break; case "invalid_purchase_price": popZ("Informe um valor de compra válido.", "warning"); break; case "invalid_sale_source": popZ("Informe de onde veio o contato da negociação.", "warning"); break; case "invalid_sale_date": popZ("Informe uma data de conclusão válida, sem usar uma data futura.", "warning"); break; case "invalid_completion_type": popZ("Informe se o anúncio foi vendido ou trocado.", "warning"); break; case "trade_not_allowed": popZ("Este anúncio foi configurado somente para venda.", "warning"); break; case "invalid_trade_value": popZ("Informe um valor estimado de troca válido.", "warning"); break; default: popZ("Não foi possível atualizar o anúncio. Tente novamente.", "error"); break; } }