Latte – výpočet počtu dní před stanovený datum

Alsatian
Člen | 163
+
0
-

Ahoj.

V databázi mám uloženo „datum_vystaveni“ (date) jako datum vystavení faktury.
Další „splatnost_dny“ (int) znamená počet dní splatnosti faktury.

Datum splatnosti si z těchto údajů v LATTE zjistím takto:

{var $datumSplatnost = new \DateTime($zaznam->datum_vystaveni)}
{$datumSplatnost->modify('+'.$zaznam->splatnost_dny.' days')|date:'j. n. Y'}

Jak nyní v LATTE vypsat počet dní, které je faktura po splatnosti? Něco jako nynější datum – $datumSplatnost. Nedaří se mi to :) Děkuji.

CZechBoY
Člen | 3608
+
0
-

Musí to být v Latte? Já nemám rád sebemenší logiku v Latte, není tam zvýrazňovač syntaxe, atd…
Co si na to udělat filtr?

Alsatian
Člen | 163
+
0
-

@CZechBoY – taky mě to napadlo. Je pravda, že to tam prostě nepatří :) Hold jsem stará škola :D Dobře, nesměji se :)

GEpic
Člen | 562
+
0
-

Proč si neukládáš DATUM vystavení a DATUM splatnosti? Pracuje se s tím všeobecně líp už i na úrovni databáze (různé filtrování, vyhledávání, atp.).

Počet dní po splatnosti zjistíš pak takto (if $dnuPoSplatnosti > 0)

	/** @var DateTime $datumSplatnosti **/
	$dnuPoSplatnosti = (new DateTime())->diff($datumSplatnosti)->format("%a");

Navíc se ti budou hledat lépe celkově faktury po splatnosti – stačí v databázi najít všechny záznamy, jejichž datum po splatnosti je starší než dnešní datum.

Editoval GEpic (4. 10. 2018 22:18)

Alsatian
Člen | 163
+
0
-

@GEpic – dost možná na to jdu špatně, to je pravda. Každopádně počet dní po splatnosti ukládám jako číslo proto, že jej takto zadávám do formuláře. Když tedy upravuji fakturu, číslo počet dní můžu jednoduše změnit. Zde by předpokládám zase vznikl problém, jak jej upravovat.

Fci DateTime diff jsem neznal, díky moc. Jdu to nějak zpytlíkovat :) Faktury po splatnosti „zatím“ vyjet nepotřebuji, filtruji pouze neuhrazené. Ale třeba mě to nemine.

Děkuji :)

Alsatian
Člen | 163
+
+1
-

Kdyby se to někomu hodilo, tady je výsledek.

Definice vlastního filtru v BasePresenter – beforeRender()

$this->template->addFilter('fakturaDnyPoSplatnosti', function($datum, $prictiDny) {
	$datumSplatnost = new DateTime($datum);
	$datumSplatnost = $datumSplatnost->modify('+' . $prictiDny . ' days');

	$datumRozdilSekundy = strtotime(date('Y-m-d 00:00:00', time() ) ) - $datumSplatnost->getTimestamp();
	$return = round($datumRozdilSekundy / (24 * 60 * 60), 0);
	return $return < 0 ? '0' : $return;
});

Zobrazení v šabloně v případě, že je FA po splatnosti.

{var $test = ($zaznam->datum_vystaveni|fakturaDnyPoSplatnosti:$zaznam->splatnost_dny)}
{if $test}
	<badge class="badge badge-outline-danger">{$test}</badge>
{/if}
David Matějka
Moderator | 6445
+
+2
-

@Alsatian proc ses nakonec rozhodl pracovat s timestampem namisto DateTime::diff? ty datetime metody dokazou lepe pracovat se zaludnostmi jako jsou zmeny casu (letni/normalni)

Alsatian
Člen | 163
+
0
-

@DavidMatějka zkoušel jsem, vypadalo to jednoduše, ale výsledky mi to vracelo velmi podivné. Nepřišel jsem na to, kde dělám chybu :(

GEpic
Člen | 562
+
0
-

A co takhle se zeptat tady s kusem kodu a co ti to dela / nedela?
Me by osobne stvalo kdyby mi neco nefungovalo a nevedel bych proc.

Editoval GEpic (5. 10. 2018 19:27)

Alsatian
Člen | 163
+
+1
-

@GEpic máš samozřejmě pravdu. Vrátil jsem se tedy k tomu a vyřešil zatím následovně.

$datumDnes = new DateTime();
$datumSplatnosti = (new DateTime($datum))->modify('+'.$prictiDny.' days');
$rozdilDny = $datumDnes->diff($datumSplatnosti)->format("%a");
return $datumSplatnosti < $datumDnes && $rozdilDny > 0 ? $rozdilDny : 0;

Poslední řádek vypadá složitě, ale diff nevrací zápornou hodnotu pokud odečítám budoucí datum od dnešního.
Dá se to udělat i jinak? Aby diff vrátil zápornou hodnotu?

MajklNajt
Člen | 470
+
0
-

@Alsatian mohol by si to zefektívniť takto nejako:

$datumDnes = new DateTime();
$datumSplatnosti = $datumVystavenia->modifyClone('+'.$prictiDny.' days');
return $datumSplatnosti < $datumDnes ? $datumDnes->diff($datumSplatnosti)->format("%a"): 0;

Predpokladám, že dátumy sú inštanciou Nette\Utils\DateTime

GEpic
Člen | 562
+
+3
-

Dá se to udělat i jinak? Aby diff vrátil zápornou hodnotu?

Zkus to takto:

	->format("%r%a"); // %r - Sign "-" when negative, empty when positive

nezapomeň si to přetypovat na integer.

EDIT:

@MajklNajt nebo takto:

$datumDnes = new DateTime();
$datumSplatnosti = $datumVystavenia->modifyClone('+'.$prictiDny.' days');
return max(0, (int) $datumDnes->diff($datumSplatnosti)->format("%r%a"));

Jen ještě jedno upozornění – U objektů typu DateTime, pokud nepracuješ s časem, je dobré ho ručně přenastavit tak, aby u každého objektu byl stejný – mohlo by se totiž stát, že ti výsledek nebude sedět. Popř. toto ošetřovat už při ukládání do databáze (ideálně).

Každopádně poté je nutné, pokud tvoříš objekt DateTime ručně (new DateTime()), čas přenastavit, např. takto:

	$datumDnes = (new DateTime())->setTime(0, 0);

	// nebo

	$datumDnes = new DateTime();
	$datumDnes->setTime(0, 0);

Jde totiž o to, že pokud tvoříš objekt z datumu „7.10.2018 13:00“ a chceš zjistit počet dní do „8.10.2018 12:00“, dostaneš zpět 0 dní, ale ty ve svém případě očekáváš 1 den.

Editoval GEpic (7. 10. 2018 12:49)