public function fix() { $debe = 0; $haber = 0; foreach ($this->get_partidas() as $p) { $debe += $p->debe; $haber += $p->haber; } $total = $debe - $haber; /// corregimos descuadres de menos de 0.01 if ($this->floatcmp($debe, $haber, 2)) { $debe = 0; $haber = 0; $partidas = $this->get_partidas(); foreach ($partidas as $p) { $p->debe = bround($p->debe, 2); $debe += $p->debe; $p->haber = bround($p->haber, 2); $haber += $p->haber; } /// si con el redondeo se soluciona el problema, pues genial! if ($this->floatcmp($debe, $haber)) { $this->importe = max(array($debe, $haber)); foreach ($partidas as $p) { $p->save(); } } else { /// si no ha funcionado, intentamos arreglarlo $total = 0; $partidas = $this->get_partidas(); foreach ($partidas as $p) { $total += $p->debe - $p->haber; } if ($partidas[0]->debe != 0) { $partidas[0]->debe = $partidas[0]->debe - $total; } else { if ($partidas[0]->haber != 0) { $partidas[0]->haber += $total; } } $debe = 0; $haber = 0; foreach ($partidas as $p) { $debe += $p->debe; $haber += $p->haber; } /// si hemos resuelto el problema grabamos if ($this->floatcmp($debe, $haber)) { $this->importe = max(array($debe, $haber)); foreach ($partidas as $p) { $p->save(); } } } } $status = TRUE; /// comprobamos la factura asociada $fac = $this->get_factura(); if ($fac) { if (is_null($fac->idasiento)) { $fac->idasiento = $this->idasiento; $status = $fac->save(); } } if ($status) { return $this->full_test(); } else { return FALSE; } }
/** * Devuelve las líneas de IVA de la factura. * Si no hay, las crea. * @return \linea_iva_factura_proveedor */ public function get_lineas_iva() { $linea_iva = new linea_iva_factura_proveedor(); $lineasi = $linea_iva->all_from_factura($this->idfactura); /// si no hay lineas de IVA las generamos if (!$lineasi) { $lineas = $this->get_lineas(); if ($lineas) { foreach ($lineas as $l) { $i = 0; $encontrada = FALSE; while ($i < count($lineasi)) { if ($l->codimpuesto == $lineasi[$i]->codimpuesto) { $encontrada = TRUE; $lineasi[$i]->neto += $l->pvptotal; $lineasi[$i]->totaliva += $l->pvptotal * $l->iva / 100; $lineasi[$i]->totalrecargo += $l->pvptotal * $l->recargo / 100; } $i++; } if (!$encontrada) { $lineasi[$i] = new linea_iva_factura_proveedor(); $lineasi[$i]->idfactura = $this->idfactura; $lineasi[$i]->codimpuesto = $l->codimpuesto; $lineasi[$i]->iva = $l->iva; $lineasi[$i]->recargo = $l->recargo; $lineasi[$i]->neto = $l->pvptotal; $lineasi[$i]->totaliva = $l->pvptotal * $l->iva / 100; $lineasi[$i]->totalrecargo = $l->pvptotal * $l->recargo / 100; } } /// redondeamos y guardamos if (count($lineasi) == 1) { $lineasi[0]->neto = round($lineasi[0]->neto, FS_NF0); $lineasi[0]->totaliva = round($lineasi[0]->totaliva, FS_NF0); $lineasi[0]->totalrecargo = round($lineasi[0]->totalrecargo, FS_NF0); $lineasi[0]->totallinea = $lineasi[0]->neto + $lineasi[0]->totaliva + $lineasi[0]->totalrecargo; $lineasi[0]->save(); } else { /* * Como el neto y el iva se redondean en la factura, al dividirlo * en líneas de iva podemos encontrarnos con un descuadre que * hay que calcular y solucionar. */ $t_neto = 0; $t_iva = 0; foreach ($lineasi as $li) { $li->neto = bround($li->neto, FS_NF0); $li->totaliva = bround($li->totaliva, FS_NF0); $li->totallinea = $li->neto + $li->totaliva + $li->totalrecargo; $t_neto += $li->neto; $t_iva += $li->totaliva; } if (!$this->floatcmp($this->neto, $t_neto)) { /* * Sumamos o restamos un céntimo a los netos más altos * hasta que desaparezca el descuadre */ $diferencia = round(($this->neto - $t_neto) * 100); usort($lineasi, function ($a, $b) { if ($a->totallinea == $b->totallinea) { return 0; } else { return $a->totallinea < $b->totallinea ? 1 : -1; } }); foreach ($lineasi as $i => $value) { if ($diferencia > 0) { $lineasi[$i]->neto += 0.01; $diferencia--; } else { if ($diferencia < 0) { $lineasi[$i]->neto -= 0.01; $diferencia++; } else { break; } } } } if (!$this->floatcmp($this->totaliva, $t_iva)) { /* * Sumamos o restamos un céntimo a los netos más altos * hasta que desaparezca el descuadre */ $diferencia = round(($this->totaliva - $t_iva) * 100); usort($lineasi, function ($a, $b) { if ($a->totallinea == $b->totallinea) { return 0; } else { return $a->totallinea < $b->totallinea ? 1 : -1; } }); foreach ($lineasi as $i => $value) { if ($diferencia > 0) { $lineasi[$i]->totaliva += 0.01; $diferencia--; } else { if ($diferencia < 0) { $lineasi[$i]->totaliva -= 0.01; $diferencia++; } else { break; } } } } foreach ($lineasi as $i => $value) { $lineasi[$i]->totallinea = $value->neto + $value->totaliva + $value->totalrecargo; $lineasi[$i]->save(); } } } } return $lineasi; }
public function set_pvp($p) { $p = bround($p, FS_NF0_ART); if (!$this->floatcmp($this->pvp, $p, FS_NF0_ART + 2)) { $this->pvp_ant = $this->pvp; $this->factualizado = Date('d-m-Y'); $this->pvp = $p; } }