/** * * Completely reverse an invoice by creating a credit receipt * @param string $receiptId */ public function reverseInvoice($receiptId, $orderPositionData) { \org\sopen\dev\DebugLogger::openLogFileOverwrite(CSopen::instance()->getCustomerPath() . '/conf/logs/revinvoice.log'); if (!is_array($orderPositionData)) { $orderPositionData = Zend_Json::decode($orderPositionData); } $rController = Billing_Controller_Receipt::getInstance(); $receipt = $rController->get($receiptId); if ($receipt->__get('receipt_state') !== 'VALID') { throw new Billing_Exception_Receipt('Receipt cannot be reverted twice'); } $order = $receipt->getForeignRecord('order_id', $this); $rpController = Billing_Controller_ReceiptPosition::getInstance(); $opController = Billing_Controller_OrderPosition::getInstance(); $receiptPositions = $rpController->getByReceiptId($receiptId); $creditReceipt = Billing_Model_Receipt::createCredit(); $creditReceipt->__set('order_id', $order->getId()); $creditReceipt->__set('invoice_nr', $receipt->__get('invoice_nr')); $creditReceipt->__set('credit_date', $receipt->__get('invoice_date')); $creditReceipt->__set('invoice_date', $receipt->__get('invoice_date')); // take same payment method for credit receipt $creditReceipt->__set('payment_method_id', $receipt->getForeignId('payment_method_id')); $creditReceipt->__set('is_cancellation', true); $receipt->__set('is_cancelled', true); \org\sopen\dev\DebugLogger::log('RECHNUNG ' . print_r($receipt, true)); $creditReceipt = $rController->create($creditReceipt); $creditReceipt = $rController->get($creditReceipt->getId()); $countPos = count($receiptPositions); $creditPositions = array(); $opCount = count($orderPositionData); $aOrderPosData = null; if (is_array($orderPositionData)) { $aOrderPosData = org\sopen\app\util\arrays\ArrayHelper::getIndexedWithPropertyFromList($orderPositionData, 'id'); } $partReverse = false; foreach ($receiptPositions as $invoicePosition) { //print_r($invoicePosition); if (is_array($aOrderPosData) && $opCount > 0 && (!array_key_exists($invoicePosition->getId(), $aOrderPosData) || !$aOrderPosData[$invoicePosition->getId()]['invert_amount'])) { $partReverse = true; continue; } $creditPosition = clone $invoicePosition; $creditPosition->__set('id', null); $creditPosition->__set('position_nr', ++$countPos); $creditPosition->__set('name', $creditPosition->__get('name') . ' -STORNO'); if (is_array($aOrderPosData) && array_key_exists($invoicePosition->getId(), $aOrderPosData) && $aOrderPosData[$invoicePosition->getId()]['invert_amount']) { $creditPosition->__set('amount', $aOrderPosData[$invoicePosition->getId()]['invert_amount']); } $opController->invert($creditPosition); $creditPosition->flatten(); $creditPositions[] = $opController->create($creditPosition); } $rpController->addOrderPositions($creditReceipt, $creditPositions); $creditReceipt = Billing_Controller_Receipt::getInstance()->get($creditReceipt->getId()); /* <value>REVERTED</value> <value>PARTLYREVERTED</value> <value>ISREVERSION</value> <value>ISPARTREVERSION</value> */ $receipt->__set('receipt_state', 'REVERTED'); $creditReceipt->__set('receipt_state', 'ISREVERSION'); $receipt->__set('revision_receipt_id', $creditReceipt->getId()); $creditReceipt->__set('revision_receipt_id', $receipt->getId()); //$creditReceipt->__set('payment_state', 'PAYED'); $creditReceipt->__set('open_sum', -1 * (double) $receipt->__get('open_sum')); //$creditReceipt->__set('payed_sum',$creditReceipt->__get('total_brutto')); $creditReceipt->payTotal(); if ($partReverse) { $receipt->__set('payment_state', 'PARTLYPAYED'); $receipt->__set('receipt_state', 'PARTLYREVERTED'); $creditReceipt->__set('receipt_state', 'ISPARTREVERSION'); $receipt->payValue($creditReceipt->__get('total_brutto')); } else { try { $receipt->payTotal(); } catch (Exception $e) { // @todo: silent failure: check OK } } $creditReceipt->__set('donation_id', $receipt->getForeignId('donation_id')); $creditReceipt->__set('reversion_record_id', $receipt->getId()); $creditReceipt->__set('revision_receipt_id', $receipt->getId()); $receipt->__set('reversion_record_id', $creditReceipt->getId()); $receipt->__set('revision_receipt_id', $creditReceipt->getId()); $receipt = $rController->update($receipt); $tags = $receipt->__get('tags'); if ($tags) { $creditReceipt->__set('tags', $tags->toArray()); } $creditReceipt = $rController->update($creditReceipt); \org\sopen\dev\DebugLogger::log('RECHNUNG_update ' . print_r($receipt, true)); \org\sopen\dev\DebugLogger::log('GUTSCHRIFT ' . print_r($creditReceipt, true)); Tinebase_Event::fireEvent(new Billing_Events_BillableReceiptCreated($creditReceipt)); Tinebase_Event::fireEvent(new Billing_Events_BillableReceiptReverted($receipt, $creditReceipt)); \org\sopen\dev\DebugLogger::close(); return $creditReceipt; }
/** * get the basic select object to fetch records from the database * * @param array|string|Zend_Db_Expr $_cols columns to get, * per default * @param boolean $_getDeleted get deleted records (if modlog is active) * @return Zend_Db_Select */ protected function _getSelect($_cols = '*', $_getDeleted = FALSE, $fromDate = null, $untilDate = null, array $accountSystemIds = null) { if (is_array($_cols) && isset($_cols['count'])) { $cols = array('count' => 'COUNT(*)'); } else { $cols = (array) $_cols; } $select = parent::_getSelect($_cols, $_getDeleted); $strAddFrom = ''; if (!is_null($fromDate)) { $fromDate = new Zend_Date($fromDate); $strAddFrom = " AND ab.booking_date >= '" . $fromDate->toString('yyyy-MM-dd') . "'"; } $strAddUntil = ''; if (!is_null($untilDate)) { $untilDate = new Zend_Date($untilDate); $strAddUntil = " AND ab.booking_date <= '" . $untilDate->toString('yyyy-MM-dd') . "'"; } $strAccountSystems = ''; if (is_array($accountSystemIds) && count($accountSystemIds) > 0) { $strAccountSystems = " AND ab.account_system_id IN (" . org\sopen\app\util\arrays\ArrayHelper::explodeQuoted($accountSystemIds) . ") "; } $select->joinLeft(array('ab' => $this->_tablePrefix . 'bill_account_booking'), '(' . $this->_db->quoteIdentifier($this->_tableName . '.id') . ' = ' . $this->_db->quoteIdentifier('ab.account_system_id') . $strAddFrom . $strAddUntil . $strAccountSystems . ')', array()); $select->columns(array('sum_debit' => 'SUM(ab.debit_value)', 'sum_credit' => 'SUM(ab.credit_value)')); $select->group(array($this->_tableName . '.id', 'ab.account_system_id')); //echo $select->assemble(); return $select; }