diff --git a/Core/Controller/ApiCreateFacturaRectificativaCliente.php b/Core/Controller/ApiCreateFacturaRectificativaCliente.php index 63df1eecd3..4836c93ef2 100644 --- a/Core/Controller/ApiCreateFacturaRectificativaCliente.php +++ b/Core/Controller/ApiCreateFacturaRectificativaCliente.php @@ -19,8 +19,9 @@ namespace FacturaScripts\Core\Controller; -use FacturaScripts\Core\Lib\Calculator; +use FacturaScripts\Core\Params\RefundInvoiceParams; use FacturaScripts\Core\Response; +use FacturaScripts\Core\Service\InvoiceManager; use FacturaScripts\Core\Template\ApiController; use FacturaScripts\Core\Tools; use FacturaScripts\Dinamic\Model\FacturaCliente; @@ -82,90 +83,18 @@ protected function newRefundAction(): ?FacturaCliente } } - // si no se especifican cantidades de las lineas, - // incluimos todas las lineas en la factura rectificativa. - if (empty($lines)) { - $lines = $invoiceLines; - } - - $this->db()->beginTransaction(); - - if ($invoice->editable) { - foreach ($invoice->getAvailableStatus() as $status) { - if ($status->editable || !$status->activo) { - continue; - } - - $invoice->idestado = $status->idestado; - if (false === $invoice->save()) { - $this->sendError('record-save-error', Response::HTTP_INTERNAL_SERVER_ERROR); - $this->db()->rollback(); - return null; - } - } - } - - $newRefund = new FacturaCliente(); - $newRefund->loadFromData($invoice->toArray(), $invoice::dontCopyFields()); - $newRefund->codigorect = $invoice->codigo; - $newRefund->codserie = $this->request->input('codserie') ?? $invoice->codserie; - $newRefund->idfacturarect = $invoice->idfactura; - $newRefund->nick = $this->request->input('nick'); - $newRefund->observaciones = $this->request->input('observaciones'); - - $date = $this->request->input('fecha'); - $hour = $this->request->input('hora'); - if (false === $newRefund->setDate($date, $hour)) { - $this->sendError('error-set-date', Response::HTTP_BAD_REQUEST); - $this->db()->rollback(); - return null; - } - - if (false === $newRefund->save()) { - $this->sendError('record-save-error', Response::HTTP_INTERNAL_SERVER_ERROR); - $this->db()->rollback(); - return null; - } - - foreach ($lines as $line) { - $newLine = $newRefund->getNewLine($line->toArray()); - $newLine->cantidad = 0 - (float)$this->request->input('refund_' . $line->id(), $line->cantidad); - $newLine->idlinearect = $line->idlinea; - if (false === $newLine->save()) { - $this->sendError('record-save-error', Response::HTTP_INTERNAL_SERVER_ERROR); - $this->db()->rollback(); - return null; - } - } - - $newLines = $newRefund->getLines(); - $newRefund->idestado = $invoice->idestado; - if (false === Calculator::calculate($newRefund, $newLines, true)) { - $this->sendError('record-save-error', Response::HTTP_INTERNAL_SERVER_ERROR); - $this->db()->rollback(); - return null; - } - - // si la factura estaba pagada, marcamos los recibos de la nueva como pagados - if ($invoice->pagada) { - foreach ($newRefund->getReceipts() as $receipt) { - $receipt->pagado = true; - $receipt->save(); - } - } - - // asignamos el estado de la factura - $newRefund->idestado = $this->request->input('idestado'); - if (false === $newRefund->save()) { - $this->sendError('record-save-error', Response::HTTP_INTERNAL_SERVER_ERROR); - $this->db()->rollback(); - return null; - } - - $this->db()->commit(); - Tools::log()->notice('record-updated-correctly'); - - return $newRefund; + $params = new RefundInvoiceParams( + lines: $lines, + codserie: $this->request->input('codserie', ''), + fecha: $this->request->input('fecha'), + hora: $this->request->input('hora'), + observaciones: $this->request->input('observaciones', ''), + idestado: $this->request->input('idestado', ''), + nick: $this->request->input('nick', ''), + includeAllLinesIfEmpty: true + ); + + return InvoiceManager::createRefund($invoice, $params); } private function sendError(string $message, int $http_code): void diff --git a/Core/Controller/EditFacturaCliente.php b/Core/Controller/EditFacturaCliente.php index 1058d59744..1950db1c96 100644 --- a/Core/Controller/EditFacturaCliente.php +++ b/Core/Controller/EditFacturaCliente.php @@ -7,8 +7,9 @@ use FacturaScripts\Core\Base\DataBase\DataBaseWhere; use FacturaScripts\Core\Lib\AjaxForms\SalesController; -use FacturaScripts\Core\Lib\Calculator; use FacturaScripts\Core\Lib\ExtendedController\BaseView; +use FacturaScripts\Core\Params\RefundInvoiceParams; +use FacturaScripts\Core\Service\InvoiceManager; use FacturaScripts\Core\Tools; use FacturaScripts\Dinamic\Lib\Accounting\InvoiceToAccounting; use FacturaScripts\Dinamic\Lib\ReceiptGenerator; @@ -306,78 +307,22 @@ protected function newRefundAction(): bool $lines[] = $line; } } - if (empty($lines)) { - Tools::log()->warning('no-selected-item'); - return true; - } - - $this->dataBase->beginTransaction(); - - if ($invoice->editable) { - foreach ($invoice->getAvailableStatus() as $status) { - if ($status->editable || !$status->activo) { - continue; - } - - $invoice->idestado = $status->idestado; - if (false === $invoice->save()) { - Tools::log()->error('record-save-error'); - $this->dataBase->rollback(); - return true; - } - } - } - - $newRefund = new FacturaCliente(); - $newRefund->loadFromData($invoice->toArray(), $invoice::dontCopyFields()); - $newRefund->codigorect = $invoice->codigo; - $newRefund->codserie = $this->request->input('codserie'); - $newRefund->idfacturarect = $invoice->idfactura; - $newRefund->nick = $this->user->nick; - $newRefund->observaciones = $this->request->input('observaciones'); - $newRefund->setDate($this->request->input('fecha'), date(Tools::HOUR_STYLE)); - if (false === $newRefund->save()) { - Tools::log()->error('record-save-error'); - $this->dataBase->rollback(); - return true; - } - foreach ($lines as $line) { - $newLine = $newRefund->getNewLine($line->toArray()); - $newLine->cantidad = 0 - (float)$this->request->input('refund_' . $line->id(), '0'); - $newLine->idlinearect = $line->idlinea; - if (false === $newLine->save()) { - Tools::log()->error('record-save-error'); - $this->dataBase->rollback(); - return true; - } - } - - $newLines = $newRefund->getLines(); - if (false === Calculator::calculate($newRefund, $newLines, true)) { - Tools::log()->error('record-save-error'); - $this->dataBase->rollback(); - return true; - } - - // si la factura estaba pagada, marcamos los recibos de la nueva como pagados - if ($invoice->pagada) { - foreach ($newRefund->getReceipts() as $receipt) { - $receipt->pagado = true; - $receipt->save(); - } - } - - // asignamos el estado de la factura - $newRefund->idestado = $this->request->input('idestado'); - if (false === $newRefund->save()) { - Tools::log()->error('record-save-error'); - $this->dataBase->rollback(); + $params = new RefundInvoiceParams( + lines: $lines, + codserie: $this->request->input('codserie', ''), + fecha: $this->request->input('fecha'), + observaciones: $this->request->input('observaciones', ''), + idestado: $this->request->input('idestado', ''), + nick: $this->user->nick, + includeAllLinesIfEmpty: false + ); + + $newRefund = InvoiceManager::createRefund($invoice, $params); + if ($newRefund === null) { return true; } - $this->dataBase->commit(); - Tools::log()->notice('record-updated-correctly'); $this->redirect($newRefund->url() . '&action=save-ok'); return false; } diff --git a/Core/Params/RefundInvoiceParams.php b/Core/Params/RefundInvoiceParams.php new file mode 100644 index 0000000000..4481e42689 --- /dev/null +++ b/Core/Params/RefundInvoiceParams.php @@ -0,0 +1,45 @@ +lines = $lines; + $this->codserie = $codserie; + $this->fecha = $fecha; + $this->hora = $hora; + $this->observaciones = $observaciones; + $this->idestado = $idestado; + $this->nick = $nick; + $this->includeAllLinesIfEmpty = $includeAllLinesIfEmpty; + } +} diff --git a/Core/Service/InvoiceManager.php b/Core/Service/InvoiceManager.php new file mode 100644 index 0000000000..01359102e7 --- /dev/null +++ b/Core/Service/InvoiceManager.php @@ -0,0 +1,164 @@ +lines) && $params->includeAllLinesIfEmpty) { + $params->lines = $invoice->getLines(); + } + + if (empty($params->lines)) { + Tools::log()->warning('no-selected-item'); + return null; + } + + self::dataBase()->beginTransaction(); + + if (false === self::updateOriginalInvoiceStatus($invoice)) { + self::dataBase()->rollback(); + return null; + } + + $newRefund = self::createRefundInvoice($invoice, $params); + if ($newRefund === null) { + self::dataBase()->rollback(); + return null; + } + + if (false === self::createRefundLines($newRefund, $params)) { + self::dataBase()->rollback(); + return null; + } + + if (false === self::calculateRefundTotals($newRefund)) { + self::dataBase()->rollback(); + return null; + } + + if ($invoice->pagada) { + self::markReceiptsAsPaid($newRefund); + } + + if (false === self::saveRefundState($newRefund, $invoice, $params)) { + self::dataBase()->rollback(); + return null; + } + + self::dataBase()->commit(); + Tools::log()->notice('record-updated-correctly'); + + return $newRefund; + } + + private static function dataBase(): DataBase + { + if (self::$dataBase === null) { + self::$dataBase = new DataBase(); + } + return self::$dataBase; + } + + private static function createRefundInvoice(FacturaCliente $invoice, RefundInvoiceParams $params): ?FacturaCliente + { + $newRefund = new FacturaCliente(); + $newRefund->loadFromData($invoice->toArray(), $invoice::dontCopyFields()); + $newRefund->codigorect = $invoice->codigo; + $newRefund->codserie = $params->codserie ?: $invoice->codserie; + $newRefund->idfacturarect = $invoice->idfactura; + $newRefund->nick = $params->nick; + $newRefund->observaciones = $params->observaciones; + + $hour = $params->hora ?? date(Tools::HOUR_STYLE); + if (false === $newRefund->setDate($params->fecha, $hour)) { + Tools::log()->error('error-set-date'); + return null; + } + + if (false === $newRefund->save()) { + Tools::log()->error('record-save-error'); + return null; + } + + return $newRefund; + } + + private static function createRefundLines(FacturaCliente $newRefund, RefundInvoiceParams $params): bool + { + foreach ($params->lines as $line) { + $quantity = $line->cantidad; + + $newLine = $newRefund->getNewLine($line->toArray()); + $newLine->cantidad = 0 - $quantity; + $newLine->idlinearect = $line->idlinea; + + if (false === $newLine->save()) { + Tools::log()->error('record-save-error'); + return false; + } + } + + return true; + } + + private static function calculateRefundTotals(FacturaCliente $newRefund): bool + { + $newLines = $newRefund->getLines(); + if (false === Calculator::calculate($newRefund, $newLines, true)) { + Tools::log()->error('record-save-error'); + return false; + } + + return true; + } + + private static function markReceiptsAsPaid(FacturaCliente $newRefund): void + { + foreach ($newRefund->getReceipts() as $receipt) { + $receipt->pagado = true; + $receipt->save(); + } + } + + private static function saveRefundState(FacturaCliente $newRefund, FacturaCliente $originalInvoice, RefundInvoiceParams $params): bool + { + $newRefund->idestado = $params->idestado ?: $originalInvoice->idestado; + if (false === $newRefund->save()) { + Tools::log()->error('record-save-error'); + return false; + } + + return true; + } + + private static function updateOriginalInvoiceStatus(FacturaCliente $invoice): bool + { + if (false === $invoice->editable) { + return true; + } + + foreach ($invoice->getAvailableStatus() as $status) { + if ($status->editable || !$status->activo) { + continue; + } + + $invoice->idestado = $status->idestado; + if (false === $invoice->save()) { + Tools::log()->error('record-save-error'); + return false; + } + } + + return true; + } +}