File manager - Edit - /home/verseaumee/ptitsanes/plugins/solidres/invoice/invoice.php
Back
<?php /*------------------------------------------------------------------------ Solidres - Hotel booking extension for Joomla ------------------------------------------------------------------------ @Author Solidres Team @Website http://www.solidres.com @Copyright Copyright (C) 2013 - 2016 Solidres. All Rights Reserved. @License GNU General Public License version 3, or later ------------------------------------------------------------------------*/ defined('_JEXEC') or die; require_once JPATH_ADMINISTRATOR . '/components/com_solidres/helpers/layout.php'; require_once JPATH_PLUGINS . '/solidres/invoice/administrator/components/com_solidres/helpers/helper.php'; /** * Solidres Invoice * * @package Solidres * @subpackage Invoice * @since 0.6.0 */ class plgSolidresInvoice extends SRPlugin { protected $invoiceFolder; /** * Load the language file on instantiation. * * @var boolean * @since 3.1 */ protected $autoloadLanguage = true; /** * Initiate invoice folder path, pdf attachment folder path. * * @param $subject * @param array $config */ function __construct($subject, $config = array()) { $this->invoiceFolder = JPATH_ROOT . '/media/com_solidres/invoices/'; $this->pdfAttachmentFolder = JPATH_ROOT . '/media/com_solidres/pdfAttachment/'; parent::__construct($subject, $config); } /** * @return invoice table object. */ private function getTable() { JTable::addIncludePath($this->_getAdminPath() . '/tables'); $table = JTable::getInstance('Invoice', 'SolidresTable'); return $table; } /** * Load invoice of $reid reservation and prepare colorbox. * * @param $reid * * @return invoice infomations of $reid reservation. */ public function onSolidresLoadReservation($reid) { $this->authorise($reid); $invoiceTable = $this->getTable(); $invoiceTable->load(array('reservation_id' => $reid)); SRHtml::_('jquery.colorbox', 'show_pdf', '700px', '650px', 'true', 'false'); return $invoiceTable; } /** * Download invoice $id * * @param $id */ public function onSolidresDownloadInvoice($id) { $invoiceTable = $this->getTable(); $invoiceTable->load(array('id' => $id)); $this->authorise($invoiceTable->reservation_id); if (file_exists($this->invoiceFolder . $invoiceTable->filename)) { $fileData = file_get_contents($this->invoiceFolder . $invoiceTable->filename); } // Disable caching header("Pragma: public"); header("Expires: 0"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Cache-Control: public", false); // Send MIME headers header("Content-Description: File Transfer"); header('Content-Type: application/pdf'); header("Accept-Ranges: bytes"); header('Content-Disposition: attachment; filename="invoice_' . $invoiceTable->invoice_number . '.pdf" '); header('Content-Transfer-Encoding: binary'); header('Connection: close'); echo $fileData; } /** * Generate invoice of $reid reservation * * @param $reid * @param $createNew int Generate new invoice number or use existing one * * @return bool true if generate successful and store invoice information in #__sr_invoices * false if generate fail. */ public function onSolidresGenerateInvoice($reid, $createNew = 1) { $this->authorise($reid); JTable::addIncludePath($this->_getAdminPath() . '/tables'); JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_solidres/models', 'SolidresModel'); $assetModel = JModelLegacy::getInstance('ReservationAsset', 'SolidresModel', array('ignore_request' => true)); $reservationModel = JModelLegacy::getInstance('Reservation', 'SolidresModel', array('ignore_request' => true)); $invoiceTable = $this->getTable(); $invoiceTable->load(array('reservation_id' => $reid)); $reservation = $reservationModel->getItem($reid); $asset = $assetModel->getItem($reservation->reservation_asset_id); $language = JFactory::getLanguage(); $language->load('com_solidres', JPATH_ROOT . '/components/com_solidres'); $direction = JFactory::getDocument()->direction; // Load the parameters. $srConfig = JComponentHelper::getParams('com_solidres'); $numberOverride = $srConfig->get('solidres_invoice_number_override', ''); $config = JFactory::getConfig(); $tzoffset = $config->get('offset'); $timezone = new DateTimeZone($tzoffset); if ($numberOverride != '') { $number = $numberOverride; } else { if ($this->checkSrInvoices() == 0) { $number = $srConfig->get('solidres_invoice_number_start', 1); } else { if ($createNew) { $number = $this->getNextNumber($asset->id); } else { $number = $invoiceTable->invoice_number; } } } $prefixOverride = $srConfig->get('solidres_invoice_number_prefix_override', ''); if ($prefixOverride != '') { $formattedNumber = $prefixOverride; } else { $formattedNumber = $this->formatPrefix($srConfig->get('solidres_invoice_number_prefix', 'INV')); } $layout = SRLayoutHelper::getInstance(); $layout->addIncludePath(__DIR__ . '/layouts'); $digit = $srConfig->get('solidres_invoice_number_digit', '00'); $invoiceLayout = $srConfig->get('solidres_invoice_layout', '1'); $invoiceNote = !empty($asset->params['invoice_note']) ? $asset->params['invoice_note'] : ''; $stayLength = (int) SRUtilities::calculateDateDiff($reservation->checkin, $reservation->checkout); $reservedRooms = array(); $reservedRoomTypes = array(); $reservedAdults = 0; $reservedChildren = 0; foreach ($reservation->reserved_room_details as $room) { $reservedRooms[] = $room->room_label; $reservedRoomTypes[] = $room->room_type_name; $reservedAdults += $room->adults_number; $reservedChildren += $room->children_number; } $displayData = array( 'reservation' => $reservation, 'asset' => $asset, 'invoiceNumber' => $formattedNumber . $digit . $number, 'solidresConfig' => $srConfig, 'timezone' => $timezone, 'direction' => $direction, 'invoiceNote' => $invoiceNote, 'reservedRooms' => $reservedRooms, 'reservedRoomTypes' => $reservedRoomTypes, 'reservedAdults' => $reservedAdults, 'reservedChildren' => $reservedChildren, 'stayLength' => $stayLength ); $invContent = $layout->render('invoices.invoice_customer_pdf_layout_' . $invoiceLayout, $displayData); if (JFile::exists($this->invoiceFolder . $invoiceTable->filename)) { JFile::delete($this->invoiceFolder . $invoiceTable->filename); } $fileName = $this->createPDF($invContent, $reid, 2); $invoiceTable->bind(array( 'filename' => $fileName, 'html' => $invContent, 'invoice_date' => JFactory::getDate()->toSql(), 'invoice_number' => $number, 'reservation_id' => $reid) ); $invoiceTable->check(); if ($invoiceTable->store()) { return true; } return false; } /** * Hook to reservation email progress * * @param $mailBody mail content. * @param $id reservation id * * @return string file path to pdf file. */ public function onSolidresReservationEmail($mailBody, $id) { $filePath = $this->pdfAttachmentFolder . $this->createPDF($mailBody, $id, 1); return $filePath; } /** * Email invoice to reservation's email * * @param $reid reservation id. * * @return bool if store date and time sent invoice in #__sr_invoices and sent mail to customer. */ public function onSolidresEmailInvoice($reid) { $this->authorise($reid); JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_solidres/models/'); JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_solidres/tables'); $assetModel = JModelLegacy::getInstance('ReservationAsset', 'SolidresModel', array('ignore_request' => true)); $reservationTable = JTable::getInstance('Reservation', 'SolidresTable'); $config = JFactory::getConfig(); $solidresConfig = JComponentHelper::getParams('com_solidres'); $invoiceTable = $this->getTable(); $invoiceTable->load(array('reservation_id' => $reid)); $mail = JFactory::getMailer();; $direction = JFactory::getDocument()->direction; $reservationTable->load($reid); $asset = $assetModel->getItem($reservationTable->reservation_asset_id); $attachmentFileName = $solidresConfig->get('solidres_invoice_pdf_file_name', 'Invoice'); $cmsLanguage = JFactory::getLanguage(); $cmsLangTag = $cmsLanguage->getTag(); $customerLanguage = $reservationTable->customer_language; $overrideCmsLang = $customerLanguage && $customerLanguage !== $cmsLangTag; if ($overrideCmsLang) { $lang = JLanguage::getInstance($customerLanguage); foreach($cmsLanguage->getPaths() as $extension => $langPaths) { foreach ($langPaths as $langFile => $loaded) { $lang->load($extension, preg_replace('#/language/' . $cmsLangTag . '/.*$#', '', $langFile)); } } // Override CMS language JFactory::$language = $lang; } $layout = SRLayoutHelper::getInstance(); $layout->addIncludePath(__DIR__ . '/layouts'); $displayData = array( 'reservation' => $reservationTable, 'asset' => $asset, 'direction' => $direction ); $mailContent = $layout->render('emails.new_invoice_notification_customer_html_inliner', $displayData); $mail->setSender(array($config->get('mailfrom'), $config->get('fromname'))); $mail->addRecipient($reservationTable->customer_email); $mail->setSubject(JText::sprintf('SR_INVOICE_EMAIL_SUBJECT', $reservationTable->code)); $mail->setBody($mailContent); $mail->addAttachment( $this->invoiceFolder . $invoiceTable->filename, $attachmentFileName . '_' . $invoiceTable->invoice_number . '.pdf', 'base64', 'application/pdf' ); $mail->isHtml(true); $date = JFactory::getDate(); if ($overrideCmsLang) { // Revert CMS language JFactory::$language = $cmsLanguage; } if (!$mail->send()) { return false; } else { $invoiceTable->bind(array('sent_on' => $date->toSql())); if ($invoiceTable->store()) { return true; } else { return false; } } } /** * Format prefix of invoice number * Read symbol in [] then format single letter used by PHP's date() function. * * @param $formatStr * * @return string formatted string prefix */ private function formatPrefix($formatStr) { $date = JFactory::getDate(); $start = strpos($formatStr, "["); if ($start === false) { return $formatStr; } $formatted = ''; while ($start !== false) { if ($start != 0) { $pre = substr($formatStr, 0, $start); } else { $pre = ''; } $end = strpos($formatStr, "]", $start); if ($end == false) { $back = substr($formatStr, $start); } else { $back = ''; $innerContent = substr($formatStr, $start + 1, $end - $start - 1); $innerContent = $date->format($innerContent); $formatStr = substr($formatStr, $end + 1); } $formatted .= $pre . $innerContent . $back; $start = strpos($formatStr, "["); if (!$start) { $formatted .= $formatStr; } } return $formatted; } /** * Create pdf document and store it. * * @param $content HTML content. * @param $reid reservation id. * @param $option 1 if create pdf attachment, 2 if create invoice pdf. * * @return bool|string false if create PDF fail, file name of PDF document if create success. */ private function createPDF($content, $reid, $option) { $this->authorise($reid); JLoader::import('dompdf.vendor.autoload'); $params = JComponentHelper::getParams('com_solidres'); $font = $params->get('solidres_invoice_pdf_font_name_main', 'courier'); // For B/c switch ($font) { case 'cid0cs': case 'cid0ct': case 'cid0jp': case 'cid0kr': $font = 'mgenplus'; break; case 'dejavusans': $font = 'dejavu sans'; break; } $pdfOptions = new Dompdf\Options; $pdfOptions->set('isRemoteEnabled', true); $pdfOptions->setIsFontSubsettingEnabled(true); $pdfOptions->set('defaultFont', $font); $tempPath = $this->app->get('tmp_path'); if (!is_dir($tempPath)) { $tempPath = JPATH_SITE . '/tmp'; } $pdfOptions->set('tempDir', $tempPath); $domPdf = new Dompdf\Dompdf($pdfOptions); $domPdf->setPaper('A4', 'portrait'); $domPdf->loadHtml($content); //$domPdf->loadHtml(mb_convert_encoding($content, 'UTF-8', mb_detect_encoding($content))); $domPdf->render(); $pdfData = $domPdf->output(); unset($domPdf); // Write the PDF data to disk using JFile::write(); if (function_exists('openssl_random_pseudo_bytes')) { $rand = openssl_random_pseudo_bytes(16); if ($rand === false) { // Broken or old system $rand = mt_rand(); } } else { $rand = mt_rand(); } $hashThis = microtime() . $rand; if (function_exists('hash')) { $hash = hash('sha256', $hashThis); } else { if (function_exists('sha1')) { $hash = sha1($hashThis); } else { $hash = md5($hashThis); } } switch ($option) { case 1: $fileName = $reid . '_attachment' . $hash . '.pdf'; if (JFile::write($this->pdfAttachmentFolder . $fileName, $pdfData)) { return $fileName; } else { return false; } case 2: $fileName = $hash . '_' . $reid . '.pdf'; if (JFile::write($this->invoiceFolder . $fileName, $pdfData)) { return $fileName; } else { return false; } } } public function onSolidresPluginRegister() { if (JFactory::getApplication()->isClient('site') && JPluginHelper::isEnabled('solidres', 'hub') && SRUtilities::getPartnerId() ) { SRControllerLegacy::addIncludePath($this->_getAdminPath()); } parent::onSolidresPluginRegister(); } protected function authorise($reservationId) { $app = JFactory::getApplication(); if ($app->getName() == 'site') { $authorise = false; foreach (debug_backtrace() as $debug) { if (!empty($debug['class']) && strcasecmp($debug['class'], 'SolidresControllerInvoice') === 0) { $authorise = true; break; } } if (!$authorise) { return; } $db = JFactory::getDbo(); $query = $db->getQuery(true) ->select('COUNT(a.id)') ->from($db->qn('#__sr_reservation_assets', 'a')) ->innerJoin($db->qn('#__sr_reservations', 'a2') . ' ON a2.reservation_asset_id = a.id') ->where('a2.id = ' . (int) $reservationId); if ($app->input->get('customer', 0)) { $query->innerJoin($db->qn('#__sr_customers', 'a3') . ' ON a3.id = a2.customer_id') ->where('a3.user_id = ' . (int) JFactory::getUser()->id); } else { $partnerId = SRUtilities::getPartnerId(); if (!$partnerId) { throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); } $query->where('a.partner_id = ' . (int) $partnerId); } $db->setQuery($query); if (!$db->loadResult()) { throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); } } } public function onSolidresInvoiceLoadHtml() { JTable::addIncludePath(SRPlugin::getAdminPath('invoice') . '/tables'); $invoiceId = JFactory::getApplication()->input->getInt('id'); $invoiceTable = JTable::getInstance('Invoice', 'SolidresTable'); $invoiceTable->load($invoiceId); $this->authorise($invoiceTable->reservation_id); echo $invoiceTable->html; } /** * Allow to processing of Reservation data after it is saved. * * @param object $data * @param object $table * @param boolean $isNew * @param object $model * * @return boolean * * @since 1.6 */ function onReservationAfterSaveComplete($data, $table, $isNew, $model) { $config = JComponentHelper::getParams('com_solidres'); $app = JFactory::getApplication(); $result = true; if ($config->get('auto_create_invoice', 0)) { $result = $this->onSolidresGenerateInvoice($table->id, $isNew ? 1 : 0); if ($app->isAdmin()) { if ($result) { $app->enqueueMessage(JText::_('SR_INVOICE_YOUR_INVOICE_IS_GENERATED')); } else { $app->enqueueMessage(JText::_('SR_INVOICE_YOUR_INVOICE_IS_NOT_GENERATED')); } } } return $result; } /** * Check if there is invoice in Invoice table * * @return array if #__sr_invoices has invoices, false otherwise. */ public function checkSrInvoices() { $dbo = JFactory::getDbo(); $query = $dbo->getQuery(true); $query->select('COUNT(*)') ->from($dbo->quoteName('#__sr_invoices')); $dbo->setQuery($query); return $dbo->loadResult(); } /** * Get max invoice number exist in Invoice table for a specific property * * @param int $assetId The invoice's property * * @return int get exist Max value of invoice_number in #__sr_invoices then increase it by 1 */ public function getNextNumber($assetId = 0) { $dbo = JFactory::getDbo(); $query = $dbo->getQuery(true); $query->select('MAX(invoice_number) AS max') ->from($dbo->quoteName('#__sr_invoices', 'a')); if ($assetId > 0) { $query->where($assetId . ' = (SELECT reservation_asset_id FROM ' . $dbo->quoteName('#__sr_reservations', 'b') . ' WHERE b.id = a.reservation_id)'); } $dbo->setQuery($query); $result = $dbo->loadResult(); return $result + 1; } public function onSolidresInvoicePrepareDisplayData($reservationId, &$displayData) { JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_solidres/models', 'SolidresModel'); $reservationModel = JModelLegacy::getInstance('Reservation', 'SolidresModel', array('ignore_request' => true)); $reservationId = (int) $reservationId; $reservation = $reservationModel->getItem($reservationId); if (empty($reservation->reservation_asset_id)) { throw new RuntimeException('Invalid reservation.'); } $modelAsset = JModelLegacy::getInstance('ReservationAsset', 'SolidresModel', array('ignore_request' => true)); $asset = $modelAsset->getItem($reservation->reservation_asset_id); if (empty($asset->id)) { throw new RuntimeException('Invalid reservation asset.'); } if (SRPlugin::isEnabled('customfield')) { $customFieldContext = 'com_solidres.customer.' . $reservationId; $reservationCustomFields = SRCustomFieldHelper::getValues(array('context' => $customFieldContext)); require_once SRPlugin::getAdminPath('customfield') . '/helpers/customfieldvalue.php'; $reservationCustomerField = new SRCustomFieldValue($reservationCustomFields); } else { $reservationCustomerField = null; } $baseCurrency = new SRCurrency(0, $reservation->currency_id); $subTotal = clone $baseCurrency; $subTotal->setValue($reservation->total_price_tax_excl); $discountTotal = clone $baseCurrency; $discountTotal->setValue($reservation->total_discount); $tax = clone $baseCurrency; $tax->setValue($reservation->tax_amount); $touristTax = clone $baseCurrency; $touristTax->setValue($reservation->tourist_tax_amount); $paymentMethodSurcharge = clone $baseCurrency; $paymentMethodSurcharge->setValue($reservation->payment_method_surcharge); $paymentMethodDiscount = clone $baseCurrency; $paymentMethodDiscount->setValue($reservation->payment_method_discount); $totalExtraPriceTaxExcl = clone $baseCurrency; $totalExtraPriceTaxExcl->setValue($reservation->total_extra_price_tax_excl); $extraTax = clone $baseCurrency; $extraTax->setValue($reservation->total_extra_price_tax_incl - $reservation->total_extra_price_tax_excl); $grandTotal = clone $baseCurrency; if ($reservation->discount_pre_tax) { $grandTotalAmount = $reservation->total_price_tax_excl - $reservation->total_discount + $reservation->tax_amount + $reservation->total_extra_price; } else { $grandTotalAmount = $reservation->total_price_tax_excl + $reservation->tax_amount - $reservation->total_discount + $reservation->total_extra_price; } $grandTotalAmount += isset($reservation->tourist_tax_amount) ? $reservation->tourist_tax_amount : 0; $grandTotalAmount += isset($reservation->payment_method_surcharge) ? $reservation->payment_method_surcharge : 0; $grandTotalAmount -= isset($reservation->payment_method_discount) ? $reservation->payment_method_discount : 0; $grandTotal->setValue($grandTotalAmount); $depositAmount = clone $baseCurrency; $depositAmount->setValue(isset($reservation->deposit_amount) ? $reservation->deposit_amount : 0); $bankWireInstructions = array(); if ($reservation->payment_method_id == 'bankwire') { $solidresPaymentConfigData = new SRConfig(array('scope_id' => $reservation->reservation_asset_id)); $bankWireInstructions['account_name'] = SRUtilities::translateText($solidresPaymentConfigData->get('payments/bankwire/bankwire_accountname')); $bankWireInstructions['account_details'] = SRUtilities::translateText($solidresPaymentConfigData->get('payments/bankwire/bankwire_accountdetails')); } $solidresConfig = JComponentHelper::getParams('com_solidres'); $dateFormat = $solidresConfig->get('date_format', 'd-m-Y'); $config = JFactory::getConfig(); $tzoffset = $config->get('offset'); $timezone = new DateTimeZone($tzoffset); $displayData = array( 'reservation' => $reservation, 'reservationCustomerField' => $reservationCustomerField, 'subTotal' => $subTotal->format(), 'totalDiscount' => $reservation->total_discount > 0.00 ? $discountTotal->format() : null, 'tax' => $tax->format(), 'touristTax' => $touristTax->format(), 'totalExtraPriceTaxExcl' => $totalExtraPriceTaxExcl->format(), 'extraTax' => $extraTax->format(), 'grandTotal' => $grandTotal->format(), 'stayLength' => $stayLength = (int) SRUtilities::calculateDateDiff($reservation->checkin, $reservation->checkout), 'depositAmount' => $depositAmount->format(), 'bankwireInstructions' => $bankWireInstructions, 'asset' => $asset, 'dateFormat' => $dateFormat, 'timezone' => $timezone, 'baseCurrency' => $baseCurrency, 'paymentMethodCustomEmailContent' => '', 'discountPreTax' => $reservation->discount_pre_tax, 'direction' => JFactory::getDocument()->direction, 'enableTouristTax' => !empty($asset->params['enable_tourist_tax']) ? $asset->params['enable_tourist_tax'] : false, 'paymentMethodSurcharge' => $paymentMethodSurcharge->format(), 'paymentMethodDiscount' => $paymentMethodDiscount->format(), 'qrCode' => null, ); if (JPluginHelper::isEnabled('solidres', 'qrcode')) { $data = json_encode([ 'id' => $reservation->id, 'code' => $reservation->code, 'grandTotal' => $displayData['grandTotal'], ]); JPluginHelper::importPlugin('solidres', 'qrcode'); JFactory::getApplication()->triggerEvent('onSolidresGenerateQRCode', [$data, &$displayData['qrCode']]); } } public function onSolidresInvoiceDownloadVoucher($reservationId) { $this->onSolidresInvoicePrepareDisplayData($reservationId, $displayData); $solidresConfig = JComponentHelper::getParams('com_solidres'); SRLayoutHelper::addIncludePath(array( SRPlugin::getPluginPath('invoice') . '/layouts', JPATH_THEMES . '/' . $this->app->getTemplate() . '/html/layouts/com_solidres', JPATH_THEMES . '/' . $this->app->getTemplate() . '/html/layouts/com_solidres/invoice', )); $pdfContent = SRLayoutHelper::render('emails.reservation_complete_customer_pdf', $displayData, false); $pdfFile = $this->onSolidresReservationEmail($pdfContent, $reservationId); ob_end_clean(); if (is_file($pdfFile)) { $pdfFileName = $solidresConfig->get('solidres_voucher_pdf_file_name', 'voucher') . '_' . $displayData['reservation']->code . '.pdf'; $this->app->setHeader('Pragma', 'public'); $this->app->setHeader('Expires', '0'); $this->app->setHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0'); $this->app->setHeader('Cache-Control', 'public'); $this->app->setHeader('Content-Description', 'File Transfer'); $this->app->setHeader('Content-Type', 'application/pdf'); $this->app->setHeader('Accept-Ranges', 'bytes'); $this->app->setHeader('Content-Disposition', 'attachment; filename="' . $pdfFileName . '"'); $this->app->setHeader('Content-Transfer-Encoding', 'close'); $this->app->sendHeaders(); readfile($pdfFile); } $this->app->close(); } }
| ver. 1.4 |
Github
|
.
| PHP 8.5.7 | Generation time: 0.07 |
proxy
|
phpinfo
|
Settings