Sei ser um assunto já batido aqui, inclusive temos tópico com código a respeito.
Mas a pedido de um colega, cujo a necessidade é criar as parcelas de um contrato com a primeira parcela vencendo em data informada e as demais sempre no mesmo dia dos meses seguintes, adaptei o código para essa situação.
No caso, em específico, estamos prevendo o último dia do mês e anos bissextos, para que haja sempre uma parcela em cada mês obrigatóriamente.
Informando o primeiro vencimento para cair no dia 31, o método traz para o último dia de cada mês.
Se for dia 30,29 traz para o último dia de fevereiro correspondente.
O Código:
Evento onLoad:
sc_include_library('prj','actions','actions-master/class/DataGrid.class.php');
mostraParcelas();
Método mostraParcelas():
if (empty({nroParcelas}) or empty({valor}) or empty({primeiroVencto})) return;
$_parcelas = [];
$_valor = round({valor} / {nroParcelas},2);
$_valor1 = round($_valor+{valor}-($_valor*{nroParcelas}),2);
$dt = new DateTime({primeiroVencto});
$dia = $dt->format("d");
$mes = $dt->format("m");
$ano = $dt->format("Y");
for ($i=1;$i<={nroParcelas};$i++) {
//echo "$dia / $mes / $ano<br>";
if ($i==1) {
$_parcelas[]=[$i,$_valor1,{primeiroVencto}];
}else{
$mes++;
if ($mes == 13) {
$ano++;$mes=1;
}
if ($mes == 2 and in_array($dia, [29,30,31])) {
if (date('L', mktime(0, 0, 0, 1, 1, $ano))) {
$dia2 = 29;
}else{
$dia2 = 28;
}
}
if ($mes != 2) {
if (in_array($mes,[4,6,9,11]) and $dia == 31) {
$dia2 = 30;
}else{
$dia2 = $dia;
}
}
$dia = str_pad($dia, 2, "0", STR_PAD_LEFT);
$mes = str_pad($mes, 2, "0", STR_PAD_LEFT);
$_parcelas[]=[$i,$_valor,$ano.'-'.$mes.'-'.$dia2];
}
}
//echo '<pre>'; print_r($_parcelas); echo '</pre>';
$dg = new DataGrid(3);
$dg->addHeader(['N.Parc','Valor','Vencimento']);
$dg->setZebraColor('GRAY');
foreach ($_parcelas as $value) {
$value[1]='R$ '.number_format($value[1],2,',','.');
$dt = new DateTime($value[2]);
$value[2] = $dt->format("d/m/Y");
$dg->addCell($value);
}
{Parcelas} = $dg->create();
TGS: PARCELAS, CONTRATO, HAROLDO