public function autosDecomposition($contractIndex) { if (!isset($this->work->contracts[$contractIndex])) { throw new \Exception("Contrato não existente."); } // Get Contract $contract =& $this->work->contracts[$contractIndex]; // Get Payments Plan $paymentsPlan = []; ksort($contract['paymentsPlan']); foreach ($contract['paymentsPlan'] as $timestamp => $value) { $paymentsPlan[] = ['month' => $timestamp, 'value' => $value]; } // Get Autos $decomposedAutos = $contract['autos']; $cleanPP = function (&$paymentsPlan) { while (count($paymentsPlan) > 0 && $paymentsPlan[0]['value'] <= 0) { array_splice($paymentsPlan, 0, 1); } }; foreach ($decomposedAutos as &$auto) { $auto['_value'] = $auto['value']; $auto['label'] = Date::toMonthlyString($auto['referredMonth']); while ($auto['_value'] > 0) { // Remove Empty value months $cleanPP($paymentsPlan); // If Months Before if (isset($paymentsPlan[0]) && $paymentsPlan[0]['month'] < $auto['referredMonth']) { $ppMonth = $paymentsPlan[0]['month']; $value = min($paymentsPlan[0]['value'], $auto['_value']); $paymentsPlan[0]['value'] -= $value; // If Other Months } else { $ppMonth = $auto['referredMonth']; $value = $auto['_value']; $_value = $value; while ($_value > 0) { if (isset($paymentsPlan[0])) { $tmp = min($_value, $paymentsPlan[0]['value']); $paymentsPlan[0]['value'] -= $tmp; } else { $tmp = $_value; } $_value -= $tmp; $cleanPP($paymentsPlan); } } // Finalize $auto['_value'] -= $value; $auto['chunks'][] = ['month' => $ppMonth, 'label' => Date::toMonthlyString($ppMonth), 'value' => $value]; } } $this->autos[$contractIndex] = $decomposedAutos; return $decomposedAutos; }