Pasajes del mes en trenes argentinos

July 23, 2022

Sacar pasajes en Trenes argentinos es mas dificil que saber que tiene sancor bebe 3.

Elegis fecha de partida, y te muestra 3 dias hacia adelante y hacia atras. Si sabes que a partir de tal dia podes salir, tenes que buscar 3 dias hacia adelante, para poder tener como inicial el que realmente queres salir, y aun asi solo podes ver pasajes de esa semana.

Capaz te das cuenta que podes elegir como fecha de vuelta la semana siguiente, para poder ver pasajes de la semana que queres salir y la siguiente. Pero asi perdes la posibilidad de tambien buscar pasajes para la vuelta.

Por que no puedo ver todos los pasajes del mes, es algo que escapa mi comprension. Asi que no me quedo otra opcion que hacer un script para buscar en los dos meses siguientes de la fecha elegida. Evitando tener que hacer todas estas sumas y calculos absurdos.

Si tenes conocimientos, podes ejecutarlo desde la consola del navegador (F12 o Ctrl+Shift+I).

(function() {
	function isBefore(date, dateToCompare){
		return date.getTime() < dateToCompare.getTime()
	}

	function format_date(date){
		const day = String(date.getDate()).padStart(2, "0");
		const month = String(date.getMonth() + 1).padStart(2, "0");
		const year = date.getFullYear();

		return `${day}/${month}/${year}`;
	}

	function parse(date){
		const tokens = date.split("/").map( t => parseInt(t, 10) );
		return new Date(tokens[2], tokens[1] - 1, tokens[0]);
	}

	function addDays(n){
		return function(date){
			let copy = new Date(date);
			copy.setDate( date.getDate() + n );
			return copy;
		}
	}

	function addMonths(n){
		return function(date){
			let copy = new Date(date);
			copy.setMonth( date.getMonth() + n );
			return copy;
		}
	}

	const add3Days = addDays(3);
	const add7Days = addDays(7);
	const add3Months = addMonths(3);

	const parser = new DOMParser();

	const $button = document.createElement("button");
	$button.className = "btn_gral btn btn-block";
	$button.innerText = "BUSCAR PROXIMO";
	$button.addEventListener("click", submit);
	document.getElementById("form_busqueda").appendChild($button);

	let $results = document.createElement("div");
	$results.style.background = "aliceblue";
	$results.style.padding = "1rem";
	$results.style.display = "flex";
	$results.id = "MY_SUPER_ID";
	$results.style.overflowX = "auto";
	$results.style.inset = 0;
	$results.style.zIndex = 2;
	document.body.prepend($results);

	function submit(e){
		document.body.style.cursor = "wait";
		$button.disabled = true;
		$results.style.position = "fixed";
		$results.innerHTML = "";

		const fecha_ida = document.getElementById("fecha_ida").value;
		const start_date = add3Days(parse(fecha_ida));
		const last_day = add3Months(start_date);
		const dates = [];

		let start = start_date;
		while( isBefore(start, last_day) ){
			let end = add7Days(start);
			dates.push([
				format_date(start),
				format_date(end),
			]);

			start = add7Days(end);
		}

		Promise.allSettled(
			dates.map( ([inicio,fin]) => ({ origen: document.getElementById("origen").value, destino: document.getElementById("destino").value, fecha_ida: inicio, fecha_vuelta: fin, adulto: document.getElementById("adulto").value }) ).map( obj => search(obj) )
		)
		.then( results => {
			let available = results.filter( p => p.status == "fulfilled" ).map( p => p.value ).flat();
			$results.innerHTML = [...new Map(available).entries()].map( ([dia,cant]) => `<div class="p-1"><div class="dia_disponible" style="background:#fff"><div class="py-2"><div class="pb-3"><span class="dia_numero">${dia}</span></div><div class="disponibles"><p>${cant}</p></div></div></div></div>`).join("");

			document.body.style.cursor = null;
			$button.disabled = false;
			$results.style.position = "initial";
			$results.scrollIntoView({ behavior: "smooth" });
		});

		e.preventDefault();
		e.stopPropagation();
		return false;
	}

	async function search({ origen, destino, fecha_ida, fecha_vuelta, adulto, jubilado, discapacitado, menor, bebe }){
		const query = new URLSearchParams({
			"busqueda[tipo_viaje]": "2",
			"busqueda[origen]": origen,
			"busqueda[destino]": destino,
			"busqueda[fecha_ida]": fecha_ida,
			"busqueda[fecha_vuelta]": fecha_vuelta,
			"busqueda[cantidad_pasajeros][adulto]": adulto,
			"busqueda[cantidad_pasajeros][jubilado]": 0,
			"busqueda[cantidad_pasajeros][discapacitado]": 0,
			"busqueda[cantidad_pasajeros][menor]": 0,
			"busqueda[cantidad_pasajeros][bebe]": 0
		});
		const req = await fetch("https://webventas.sofse.gob.ar/calendario.php", {
			"body": query,
			"method": "POST"
		}).then( r => r.text() );
		const doc = parser.parseFromString(req,"text/html");
		const dias_ida = [...doc.querySelectorAll("#calendario_ida .web div[class*=dia_]")]
			.filter( i => i.className.indexOf("dia_disponible") > -1 )
			.map( i => ([i.querySelector(".dia_numero").textContent.trim(),i.querySelector(".disponibles").textContent.trim() ]));
		const dias_vuelta = [...doc.querySelectorAll("#calendario_vuelta .web div[class*=dia_]")]
			.filter( i => i.className.indexOf("dia_disponible") > -1 )
			.map( i => ([i.querySelector(".dia_numero").textContent.trim(),i.querySelector(".disponibles").textContent.trim() ]));

		return dias_ida.concat(dias_vuelta);
	}
})()

Otra opcion es arrastrar el siguiente enlace a la barra de favoritos, y una vez en el sitio de Trenes argentinos clickearlo. Es importante que lo arrastres, ya que si lo clickeas desde aca, no va a suceder nada.

Una vez clickeado, en el formulario de busqueda va a aparecer un nuevo boton “Buscar proximo”.

Image

Despues de llenar origen, destino, fecha a partir de la cual buscar, y cantidad de pasajeros, al apretarlo, y esperar un momento, va a mostrar al inicio de la pagina, arriba de todo, los pasajes que encuentre. En caso de no mostrar nada, puede ser que no haya. Es importante saber que solo son indicativos, si queres sacar los pasajes, vas a tener que buscar esa fecha en concreto con el formulario normal.

Image

Leave your comment on the github issue, sending me an email or DMing me on twitter