cmd exp date

This commit is contained in:
heama 2023-12-01 17:28:12 +05:30
commit f20c9c6967
36 changed files with 1346 additions and 253 deletions

6
.env
View File

@ -142,3 +142,9 @@ CI_ENVIRONMENT = development
# curlrequest.shareOptions = true
APP_TIMEZONE = 'Asia/Kolkata'
#--------------------------------------------------------------------
# Whatsapp Access Token And Instance ID
#--------------------------------------------------------------------
WAAI_TOKEN = '6568739969f28'
WAAI_INSTANCE = '656876690A9FD'

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -115,8 +115,17 @@ define('order_column', ["invoice_id","wp_api_order_id","invoice_child_id"]);
define('order_child','invoiceitems');
define('order_child_column', ["invoice_id","wp_api_line_items_id","customer_id"]);
define('WAAI_TOKEN', '652548474f4e4');
define('WAAI_INSTANCE', '65254894E4A88');
// define('WAAI_TOKEN', '652548474f4e4');
// define('WAAI_INSTANCE', '65254894E4A88');
// UAT - for testing Purpose..
// define('WAAI_TOKEN', '65685e954bcf6');
// define('WAAI_INSTANCE', '656863C54F90C');
// LIVE - Vel given.30th Nov.
// define('WAAI_TOKEN', '6568739969f28');
// define('WAAI_INSTANCE', '656876690A9FD');
define('SEND_WAAI_URL', 'https://waai.in/api/send');
define('SEND_WAAI_GROUP_URL', 'https://waai.in/api/send_group');
define('EXPIRAY_NOTIFY_TEMPLATE_EMAIL','EXPIRAY_NOTIFY_TEMPLATE_EMAIL');

View File

@ -119,6 +119,11 @@ $routes->get("delete_invoice/(:any)", "Invoice::delete_invoice/$1");
$routes->add('approve_invoice/(:num)', 'Invoice::approve_invoice/$1');
$routes->get('generate_invoice_pdf/(:num)', 'Invoice::generate_invoice_pdf/$1');
$routes->get('print_address/(:num)', 'Invoice::print_address/$1');
$routes->get('print_address/(:num)', 'Invoice::print_address/$1');
$routes->match(['get','post'],'/general_inv_rp','Invoice::general_inv_rp');
$routes->match(['get','post'],'/mem_inv_rp','Invoice::general_membership_inv_rp');
$routes->match(['get','post'],'/itemwise_report','Invoice::itemwise_report');
# Notifications Routes

View File

@ -586,7 +586,21 @@ class Invoice extends BaseController
$model = new InvoiceModel();
$invoiceData = $model->getInvoiceData($id);
// print_r($invoiceData);die();
$mpdf = new \Mpdf\Mpdf();
// Initialize an empty PDF with custom paper size (4x6 inches)
$config = [
'mode' => 'utf-8',
'format' => [101.6, 152.4],
'default_font_size' => 12,
'default_font' => 'Arial',
'margin_left' => 0,
'margin_right' => 0,
'margin_top' => 0,
'margin_bottom' => 0,
'margin_header' => 0,
'margin_footer' => 0,
'orientation' => 'P', // Portrait
];
$mpdf = new Mpdf($config);
$mpdf->SetTitle('Customer Address');
$mpdf->SetAuthor('Your Company Name');
$mpdf->SetCreator('');
@ -609,6 +623,88 @@ class Invoice extends BaseController
$pdfFileName = 'customer_address_' . date('Y-m-d H-i-s') . '.pdf';
$mpdf->Output($pdfFileName, 'D');
}
public function general_inv_rp()
{
if($this->request->getmethod() == 'get')
{
$model = new InvoiceModel();
$data['report_data'] = $model->get_general_invoice_data();
$this->logger->info("Invoice Report ");
$data['page_name'] = 'General Invoice Report';
$this->render_page('report_general_invoice', $data);
}
else
{
$dateParts = explode(' - ', $this->request->getVar('date') );
$fromDate = $dateParts[0];
$toDate = $dateParts[1];
$dateTime = \DateTime::createFromFormat('m/d/Y', $fromDate);
$dateTime1 = \DateTime::createFromFormat('m/d/Y', $toDate);
$model = new InvoiceModel();
$data['report_data'] = $model->get_general_invoice_data( $dateTime->format('Y-m-d') , $dateTime1->format('Y-m-d') );
$this->logger->info("Invoice Report ");
$data['page_name'] = 'General Invoice Report';
$data['selected_data'] = $this->request->getVar('date');
$this->render_page('report_general_invoice', $data);
}
}
public function general_membership_inv_rp()
{
if($this->request->getmethod() == 'get')
{
$model = new InvoiceModel();
$data['report_data'] = $model->get_mem_invoice_data();
$this->logger->info("Membership Invoice Report ");
$data['page_name'] = 'Membership Invoice Report';
$this->render_page('report_mem_invoice', $data);
}
else
{
$dateParts = explode(' - ', $this->request->getVar('date') );
$fromDate = $dateParts[0];
$toDate = $dateParts[1];
$dateTime = \DateTime::createFromFormat('m/d/Y', $fromDate);
$dateTime1 = \DateTime::createFromFormat('m/d/Y', $toDate);
$model = new InvoiceModel();
$data['report_data'] = $model->get_mem_invoice_data( $dateTime->format('Y-m-d') , $dateTime1->format('Y-m-d') );
$this->logger->info("Membership Invoice Report ");
$data['page_name'] = 'Membership Invoice Report';
$data['selected_data'] = $this->request->getVar('date');
$this->render_page('report_mem_invoice', $data);
}
}
public function itemwise_report()
{
if($this->request->getmethod() == 'get')
{
$model = new InvoiceModel();
$data['report_data'] = $model->itemwise_report_data();
$this->logger->info("Itemwise Report ");
$data['page_name'] = 'Itemwise Report';
$this->render_page('report_itemwise', $data);
}
else
{
$dateParts = explode(' - ', $this->request->getVar('date') );
$fromDate = $dateParts[0];
$toDate = $dateParts[1];
$dateTime = \DateTime::createFromFormat('m/d/Y', $fromDate);
$dateTime1 = \DateTime::createFromFormat('m/d/Y', $toDate);
$model = new InvoiceModel();
$data['report_data'] = $model->itemwise_report_data( $dateTime->format('Y-m-d') , $dateTime1->format('Y-m-d') );
$this->logger->info("Itemwise Report ");
$data['page_name'] = 'Itemwise Report';
$data['selected_data'] = $this->request->getVar('date');
$this->render_page('report_itemwise', $data);
}
}
}
// public function generate_invoice_pdf($id)
@ -642,3 +738,6 @@ class Invoice extends BaseController
// // Fetch invoice items related to the given invoice ID
// return $this->db->table('invoice_items')->where('invoice_id', $invoiceId)->get()->getResult();
// }

View File

@ -35,9 +35,9 @@ class Notifications extends BaseController
if ($request->is('post')) {
$records = $request->getVar();
$params = (object) Null;
$this->logger->info("Whatsapp : sending message instance id = " . WAAI_INSTANCE);
$this->logger->info("Whatsapp : sending message instance id = " . $_ENV['WAAI_INSTANCE'] ." - ". $_ENV['WAAI_TOKEN']);
try {
$this->logger->info("Whatsapp : sending message instance id = " . WAAI_INSTANCE);
if ($records['categories'] == 'SEND_WAAI_GROUP_URL') {
if($records['group_id'] != ""){ $params->group_id = $records['group_id']; }
else{ throw new \Exception("Group Id Missing Please Try again.."); }
@ -54,9 +54,10 @@ class Notifications extends BaseController
$url = constant($records['categories']);
$params->type = $records['type'] == "" ? "text" : $records['type'];
$params->instance_id = WAAI_INSTANCE;
$params->access_token = WAAI_TOKEN;
$params->instance_id = $_ENV['WAAI_INSTANCE'];
$params->access_token = $_ENV['WAAI_TOKEN'];
$params->message = $records['description'];
$this->logger->info("Whatsapp : sending message request = " . json_encode($params));
$this->logger->info("Whatsapp : sending message request type b4 = " . gettype($params));
helper('notification');
$notification = new NotificationHelper();

View File

@ -12,6 +12,7 @@ use Mpdf\Mpdf;
class Subscription extends BaseController
{ public function index()
{
// echo base_url('public/uploads/vijayabharathampdf.png');die();
helper('session');
if (is_session_active()) {
$session_role = get_user_role();
@ -118,36 +119,79 @@ public function add_subscription() {
// echo 'Customer not found';
// }
// }
public function download_details()
{
$selectedSchemes = $this->request->getPost('selected_schemes');
$action = $this->request->getPost('action');
// Initialize an empty PDF with custom paper size (4x6 inches)
$config = [
'mode' => 'utf-8',
'format' => [101.6, 152.4],
'default_font_size' => 12,
'default_font' => 'Arial',
'margin_left' => 0,
'margin_right' => 0,
'margin_top' => 0,
'margin_bottom' => 0,
'margin_header' => 0,
'margin_footer' => 0,
'orientation' => 'P', // Portrait
];
// Initialize an empty PDF
$pdf = new Mpdf();
$configA4 = [
'mode' => 'utf-8',
'format' => [101.6 * 2, 152.4 * 4], // 2x4 inches for each label
'default_font_size' => 12,
'default_font' => 'Arial',
'margin_left' => 0,
'margin_right' => 0,
'margin_top' => 0,
'margin_bottom' => 0,
'margin_header' => 0,
'margin_footer' => 0,
'orientation' => 'P', // Portrait
];
if($action == 1) $pdf = new Mpdf($config);
else $pdf = new Mpdf();
$customerDetails = [];
// Iterate through selected schemes
if (!empty($selectedSchemes)) {
foreach ($selectedSchemes as $selectedScheme) {
// Call the model method to get customer details for each selected scheme
$subscriptionModel = new SubscriptionModel();
$customerDetails = $subscriptionModel->getAllCustomerDetailsBySchemeName($selectedScheme);
// Create an HTML content string for the current scheme
if (!empty($customerDetails)) {
$html = view('print_addresses_form', ['customerDetails' => $customerDetails]);
// Add the current scheme's details to the PDF
$pdf->WriteHTML($html);
}
$details = $subscriptionModel->getAllCustomerDetailsBySchemeName($selectedScheme);
$customerDetails = array_merge($customerDetails, $details);
}
if (!empty($customerDetails)) {
$html = view('print_addresses_form', ['customerDetails' => $customerDetails , 'action' => $action , 'pdf' => $pdf]);
// Add the current scheme's details to the PDF
// echo $html;die;
// $pdf->AddPage();
$pdf->WriteHTML($html);
// Set the PDF filename
$filename = 'CustomerDetails_' . date('YmdHis') . '.pdf';
// Set the PDF filename
$filename = 'CustomerDetails_' . date('YmdHis') . '.pdf';
// Output the PDF for download
$pdf->Output($filename, 'D');
// Output the PDF for download
$pdf->Output($filename, 'D');
$this->logger->info("Print Addresses (Scheme) : Downloaded = ".$filename);
} else {
echo "<script>alert('Customer Details Not Available.');</script>";
$this->logger->info("Print Addresses (Scheme) : Details Not Available ");
}
} else {
echo "<script>alert('Schemes Not Choosen.');</script>";
$this->logger->info("Print Addresses (Scheme) : Schemes Not Choosen ");
}
}
}
// public function generate_pdf()
// {

View File

@ -77,13 +77,15 @@ class NotificationHelper
$this->logger->info('Helper : Whatsapp');
$curl = curl_init();
$headers = array('Content-Type:application/json');
$jsonencoded = json_encode($data, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE);
curl_setopt( $curl,CURLOPT_URL, $url);
$this->logger->info('Helper : Whatsapp url = '.$url);
switch ($method) {
case "POST":
curl_setopt( $curl,CURLOPT_POST, true );
if ($data) {
curl_setopt( $curl,CURLOPT_POSTFIELDS, json_encode($data));
$this->logger->info('Helper : Whatsapp jsonencoded = '.$jsonencoded);
curl_setopt( $curl,CURLOPT_POSTFIELDS, $jsonencoded);
}
break;
case "PUT":
@ -123,4 +125,4 @@ class NotificationHelper
}
}
?>
?>

View File

@ -227,9 +227,84 @@ public function insertSubscriptionData($data)
{
return $this->db->table('subscription')->insert($data);
}
// ***********************REPORT**********************
public function get_general_invoice_data($f_date = null, $t_date = null)
{
// Fetch invoice data
$query = $this->db->table('invoice')
->select('invoice.*, customers.*, COUNT(invoiceitems.product) as item_count')
->where('invoice.isactive', 1)
->where('invoice.invoice_type', 1)
->where('invoiceitems.isactive', 1);
// Add date range filter if provided
if ($f_date !== null && $t_date !== null) {
$query->where('invoice.invoice_date >=', $f_date)
->where('invoice.invoice_date <=', $t_date);
}
$result = $query->join('customers', 'customers.customer_id = invoice.customer_id', 'left')
->join('invoiceitems', 'invoiceitems.invoice_id = invoice.invoice_id', 'left')
->join('books', 'books.book_id = invoiceitems.product', 'left')
->groupBy('invoice.invoice_id') // Assuming invoice_id is the primary key of the invoice table
->get()
->getResult();
return $result;
}
public function get_mem_invoice_data($f_date = null, $t_date = null)
{
// Fetch invoice data
$query = $this->db->table('invoice')
->select('invoice.*, customers.*, COUNT(invoiceitems.product) as item_count')
->where('invoice.isactive', 1)
->where('invoice.invoice_type', 2)
->where('invoiceitems.isactive', 1);
// Add date range filter if provided
if ($f_date !== null && $t_date !== null) {
$query->where('invoice.invoice_date >=', $f_date)
->where('invoice.invoice_date <=', $t_date);
}
$result = $query->join('customers', 'customers.customer_id = invoice.customer_id', 'left')
->join('invoiceitems', 'invoiceitems.invoice_id = invoice.invoice_id', 'left')
->join('books', 'books.book_id = invoiceitems.product', 'left')
->groupBy('invoice.invoice_id') // Assuming invoice_id is the primary key of the invoice table
->get()
->getResult();
return $result;
}
public function itemwise_report_data($f_date = null, $t_date = null)
{
// Fetch invoice data
$query = $this->db->table('invoice')
->select('invoice.*, books.* , COUNT(invoiceitems.product) as item_count , sum(invoiceitems.product * invoiceitems.unit_price) as item_cost')
->where('invoice.isactive', 1)
->where('books.isactive', 1);
// Add date range filter if provided
if ($f_date !== null && $t_date !== null) {
$query->where('invoice.invoice_date >=', $f_date)
->where('invoice.invoice_date <=', $t_date);
}
$result = $query->join('invoiceitems', 'invoiceitems.invoice_id = invoice.invoice_id', 'left')
->join('books', 'books.book_id = invoiceitems.product', 'left')
->groupBy('books.book_id')
->get()
->getResult();
return $result;
}
}

View File

@ -5,74 +5,70 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Shipping Label Template</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
body{
font-family:Helvetica!important;
line-height:24px;
color:#000!important;
}
.shipping-label {
width: 400px; /* Set the width */
height: 140px; /* Set the height to match the width for a square shape */
margin: 10px;
.invoice {
width: 4in;
/* height: 6in; */
margin: 20px auto;
border: 1px solid #000;
background-color: #fff;
padding: 10px;
padding:15px;
box-sizing: border-box;
}
.label-title {
font-size: 12px;
font-weight: bold;
margin-bottom: 10px;
}
.address {
font-size: 16px;
margin-top: 10px;
}
.barcode {
.header {
text-align: center;
margin-top: 20px;
}
.barcode img {
max-width: 100%;
}
.footer {
font-size: 14px;
text-align: center;
margin-top: 10px;
background:#fff!important;
}
.business-logo {
max-width: 150px;
max-width:175px;
height: auto;
width:100%;
}
.bill-details {
margin-bottom: 20px;
}
.customer-details {
margin-top: 20px;
}
.row {
clear: both;
}
</style>
</head>
<body>
<?php foreach ($invoiceData as $value) : ?>
<div class="shipping-label">
<div class="label-title">
<img src="https://vijayabharathambooks.com/wp-content/uploads/2021/09/vijaya-bharatham-logo-8pt.png" alt="Business Logo" class="business-logo"><br>
<?= $value->address ?>,<br><?= $value->city ?>, <?= $value->state ?>,
<?php
foreach ($invoiceData as $value) :
?>
<div class="invoice">
<div class="bill-details">
<?= $value->customer_name ?>
<?= $value->customer_bill_address ?>
<?= $value->customer_bill_city ?>&nbsp;<?= $value->customer_bill_state ?>
<?= $value->customer_bill_postal_code ?>
<?= $value->customer_bill_country ?>
</div>
<div class="header">
<!-- <img src="https://vijayabharathambooks.com/wp-content/uploads/2021/09/vijaya-bharatham-logo-8pt.png" alt="Business Logo" class="business-logo"><br> -->
<div style="float:left; width:80px;margin-right:10px;"><img src="<?= base_url('public/uploads/vijayabharathampdf.png') ?>" alt="Business Logo" class="business-logo"/></div>
<div style="text-align:left;font-size:12px;">From<br/>
<?= $value->address ?>,<br><?= $value->city ?>, <?= $value->state ?>,
<?= $value->postal_code ?>
</div>
<div class="address">
<p>To:</p>
<p><?= $value->customer_name ?></p>
<p><?= $value->customer_bill_address ?></p>
<p><?= $value->customer_bill_city ?>&nbsp;<?= $value->customer_bill_state ?></p>
<p><?= $value->customer_bill_postal_code ?></p>
<p><?= $value->customer_bill_country ?></p>
</div>
<div class="barcode">
<img src="barcode.png" alt="Barcode">
</div>
<div class="footer">Thank you for choosing our service</div>
</div>
<?php endforeach; ?>
</div>
</div>
<?php endforeach; ?>
</body>
</html>

View File

@ -146,7 +146,7 @@
</div>
</div>
</div>
<div id="fields-for-mobile" style="display: none;">
<div id="fields-for-mobile">
<div class="form-group row">
<label for="mobile" class="col-4 col-form-label">Mobile Number</label>
<div class="col-7">

View File

@ -1,89 +1,174 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Shipping Label Template</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
}
.shipping-label {
width: 600px; /* Set the width */
height: 140px; /* Set the height to match the width for a square shape */
margin: 10px;
border: 1px solid #000;
background-color: #fff;
padding: 10px;
}
<?php if($action == 2) { ?>
<style>
.aside-content{
border-bottom: 3px solid #ffffff;
}
.invoice {
width: 48%;
height: 150px;
margin-left: 2px;
float: left;
page-break-inside: avoid;
padding-right: 2px !important;
border: 2px solid #FFFF00;
box-sizing: border-box;
}
.header {
text-align: center;
background:#fff!important;
}
.label-title {
font-size: 10px;
font-weight: bold;
margin-bottom: 10px;
}
.bill-details {
margin-bottom: 20px;
}
.address {
font-size: 16px;
margin-top: 10px;
}
.customer-details {
margin-top: 20px;
}
.barcode {
text-align: center;
margin-top: 20px;
}
.row {
clear: both;
}
.barcode img {
max-width: 100%;
}
.page-container {
width: 98%; /* Set the width of the A4 sheet */
margin: 1%; /* Add margin for spacing between A4 sheet and labels */
}
.footer {
font-size: 14px;
text-align: center;
margin-top: 10px;
}
.business-logo {
max-width:175px;
height: auto;
width:100%;
}
</style>
</head>
<body>
.business-logo {
max-width: 150px;
}
</style>
</head>
<body>
<?php foreach ($customerDetails as $customer) : ?>
<div class="shipping-label">
<div class="label-title">
<img src="https://vijayabharathambooks.com/wp-content/uploads/2021/09/vijaya-bharatham-logo-8pt.png" alt="Business Logo" class="business-logo"><br>
&nbsp;
<?= $customer['address'] ?>
<?= $customer['city'] ?>- <?= $customer['postal_code'] ?>
</div>
<div class="address">
<p>To:</p>
<?= $customer['customer_name'] ?><br>
<?= $customer['address_1'] ?>
<?= $customer['address_2'] ?><br>
<?= $customer['postal_code'] ?><br>
<?= $customer['city'] ?><br>
<?= $customer['state'] ?>&nbsp;&nbsp;&nbsp;<br>
<?= $customer['mobile_no'] ?></p>
<div class="page-container">
<?php
// Assuming $customerDetails is an array of customer details
$customerCount = count($customerDetails);
$labelsPerRow = 2;
for ($i = 0; $i < $customerCount; $i++) :
if ($i % $labelsPerRow == 0) {
echo '<div class="row aside-content">';
}
?>
<div class="invoice">
<div class="bill-details">
<!-- <div style="margin-bottom:5px;">To:</div> -->
<?= $customerDetails[$i]['customer_name'] ?>
<?= $customerDetails[$i]['address_1'] ?>,
<?= $customerDetails[$i]['address_2'] ?>,
<?= $customerDetails[$i]['city'] ?>,
<?= $customerDetails[$i]['state'] ?> -
<?= $customerDetails[$i]['postal_code'] ?>
<?php if($customerDetails[$i]['mobile_no'])
{
echo'Mobile : '.$customerDetails[$i]['mobile_no'];
} ?>
</div>
</div>
<div class="barcode">
<img src="barcode.png" alt="Barcode">
</div>
<div class="footer">"<?= $customer['title'] ?>" Expires on "<?= date('d-m-Y', strtotime($customer['to_subscription'])) ?>" </div>
</div>
<?php endforeach; ?>
</body>
</html>
<div class="header">
<!-- <img src="https://vijayabharathambooks.com/wp-content/uploads/2021/09/vijaya-bharatham-logo-8pt.png" alt="Business Logo" class="business-logo"><br> -->
<div style="float:left; width:80px;margin-right:10px;"><img src="https://vbp.venbait.in/wp-content/uploads/2023/05/1111.png" alt="Business Logo" class="business-logo"/></div>
<div style="text-align:left;font-size:12px;">From<br/>
<?= $customerDetails[$i]['address'] ?>
<?= $customerDetails[$i]['city'] ?> - <?= $customerDetails[$i]['postal_code'] ?></div>
</div>
</div>
<?php
if (($i + 1) % $labelsPerRow == 0 || ($i + 1) == $customerCount) {
echo '</div>';
}
endfor; ?>
</div>
</body>
<?php } ?>
<?php if($action == 1) { ?>
<style>
body{
font-family:Helvetica!important;
line-height:24px;
color:#000!important;
}
.invoice {
width: 4in;
/* height: 6in; */
margin: 20px auto;
border: 1px solid #FFFF00;
padding:15px;
box-sizing: border-box;
}
.header {
text-align: center;
background:#fff!important;
}
.business-logo {
max-width:175px;
height: auto;
width:100%;
}
.bill-details {
margin-bottom: 20px;
}
.customer-details {
margin-top: 20px;
}
.row {
clear: both;
}
</style>
</head>
<body>
<div class="page-container">
<?php
// Assuming $customerDetails is an array of customer details
$customerCount = count($customerDetails);
for ($i = 0; $i < $customerCount; $i++) :
?>
<div class="invoice">
<div class="bill-details">
<!-- <div style="margin-bottom:5px;">To:</div> -->
<?= $customerDetails[$i]['customer_name'] ?>
<?= $customerDetails[$i]['address_1'] ?>,
<?= $customerDetails[$i]['address_2'] ?>,
<?= $customerDetails[$i]['city'] ?>,
<?= $customerDetails[$i]['state'] ?> -
<?= $customerDetails[$i]['postal_code'] ?>
<?php if($customerDetails[$i]['mobile_no'])
{
echo'Mobile : '.$customerDetails[$i]['mobile_no'];
} ?>
</div>
<div class="header">
<!-- <img src="https://vijayabharathambooks.com/wp-content/uploads/2021/09/vijaya-bharatham-logo-8pt.png" alt="Business Logo" class="business-logo"><br> -->
<!-- <div style="float:left; width:80px;margin-right:10px;"><img src="<?= base_url('public/uploads/vijayabharathampdf.png') ?>" alt="Business Logo" class="business-logo"/></div> -->
<div style="float:left; width:80px;margin-right:10px;"><img src="https://vbp.venbait.in/wp-content/uploads/2023/05/1111.png" alt="Business Logo" class="business-logo"/></div>
<div style="text-align:left;font-size:12px;">From<br/>
<?= $customerDetails[$i]['address'] ?>
<?= $customerDetails[$i]['city'] ?> - <?= $customerDetails[$i]['postal_code'] ?></div>
</div>
</div>
<?php endfor; ?>
</div>
</body>
<?php } ?>
</html>

View File

@ -0,0 +1,189 @@
<!-- start page title -->
<div class="row">
<div class="col-md-4">
<div class="page-title-box page-title-box-alt">
<h4 class="page-title"><?= $page_name ?></h4>
</div>
</div>
<div class="offset-md-3 col-md-5">
<form action="<?php echo base_url('general_inv_rp'); ?>" method="post">
<div class="form-group">
<div class="row">
<div class="col-md-7">
<input class="form-control input-daterange-datepicker" type="text" name="date" value="<?php if(isset($selected_data)) { echo $selected_data; } ?>"/>
</div>
<div class="col-md-5">
<button type="submit" class="btn btn-primary">Generate Report</button>
</div>
</div>
</div>
</form>
</div>
</div>
<!-- end page title -->
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-body">
<table id="datatable-buttons" class="table table-striped dt-responsive nowrap w-100">
<thead>
<tr>
<th hidden>id</th>
<th>Invoice No</th>
<th>Invoice Date</th>
<th>Customer Name</th>
<th>GST</th>
<th>Discount</th>
<th>Count</th>
<th>OT Charges</th>
<th>Total</th>
<th>payment</th>
</tr>
</thead>
<tbody>
<?php foreach ($report_data as $row)
{ ?>
<tr>
<td hidden><?php echo $row->invoice_id;?></td>
<td><?php echo $row->invoice_number;?></td>
<td><?php echo $row->invoice_date;?></td>
<td><?php echo $row->first_name." ".$row->last_name;?></td>
<td><?php echo $row->tax . '%'; ?></td>
<td><?php echo '₹' . number_format($row->discount, 2, '.', ','); ?></td>
<td><?php echo $row->item_count;?></td>
<td><?php echo '₹' . number_format($row->shipping_charge, 2, '.', ','); ?></td>
<td><?php echo '₹' . number_format($row->total_amount, 2, '.', ','); ?></td>
<td><?php echo $row->payment_method;?></td>
</tr>
<?php } ?>
</tbody>
</table>
</div> <!-- end card body-->
</div> <!-- end card -->
</div><!-- end col-->
</div>
<!-- end row-->
<script>
$(document).ready(function() {
var table = $('#datatable-buttons').DataTable({
"order": [[0, 'desc']],
"dom": 'Bfrtip',
buttons: [
{
extend: 'pdfHtml5',
title: 'General Invoice Report',
text: 'PDF',
customize: function(doc) {
// Exclude the first and last columns
doc.content[1].table.body.forEach(function(row) {
row.splice(0, 1); // Remove the first column
row.splice(-1, 1); // Remove the last column
});
}
},
{
extend: 'print',
title: 'General Invoice Report',
text: 'Print',
customize: function(win) {
// Exclude the first and last columns
$(win.document.body).find('table').find('th:first-child, td:first-child, th:last-child, td:last-child').remove();
}
},
{
extend: 'csv',
text: 'CSV',
title: 'General Invoice Report',
exportOptions: {
columns: ':not(:first-child):not(:last-child)' // Exclude the first and last columns
}
}
],
columnDefs: [
{ type: 'date', targets: [1,2,3,4,5,6,7,8,9], orderable: false } // Specify the column index for date sorting and disable sorting
]
});
// Add date range filter and dropdowns
$('#datatable-buttons thead tr').clone(true).appendTo('#datatable-buttons thead');
$('#datatable-buttons thead tr:eq(1) th').each(function (i) {
var title = $(this).text();
if (title != 'Invoice Date') {
// For non-"Invoice Date" columns, add a dropdown
var uniqueValues = table.column(i).data().unique().sort();
var select = $('<select class="form-control form-control-sm"><option value="">Search ' + title + '</option></select>')
.appendTo($(this).empty())
.on('change', function () {
var val = $.fn.dataTable.util.escapeRegex($(this).val());
table.column(i)
.search(val ? '^' + val + '$' : '', true, false)
.draw();
});
uniqueValues.each(function (d, j) {
select.append('<option value="' + d + '">' + d + '</option>');
});
} else {
// For "Invoice Date" column, add a date input
if (title != 'GST')
$(this).html('<input type="date" class="form-control form-control-sm" placeholder="Search ' + title + '" />');
}
$('input', this).on('keyup change', function () {
if (table.column(i).search() !== this.value) {
table
.column(i)
.search(this.value)
.draw();
}
});
});
// Add date range filter for "Invoice Date" column
var dateRangeFilter = $('<input type="text" class="form-control form-control-sm" placeholder="Select date range"/>')
.appendTo('#datatable-buttons thead tr:eq(2) th:eq(2)')
.daterangepicker({
autoUpdateInput: false,
locale: {
cancelLabel: 'Clear'
}
})
.on('click', function (e) {
// Prevent sorting when clicking on the date range filter input
e.stopPropagation();
});
dateRangeFilter.on('apply.daterangepicker', function (ev, picker) {
table.column(2)
.search(picker.startDate.format('YYYY-MM-DD') + ' to ' + picker.endDate.format('YYYY-MM-DD'))
.draw();
});
dateRangeFilter.on('cancel.daterangepicker', function () {
dateRangeFilter.val('');
table.column(2).search('').draw();
});
});
</script>

View File

@ -0,0 +1,105 @@
<style>
.custom-thead th,
.custom-tbody td {
white-space: initial !important;
}
</style>
<!-- start page title -->
<div class="row">
<div class="col-md-4">
<div class="page-title-box page-title-box-alt">
<h4 class="page-title"><?= $page_name ?></h4>
</div>
</div>
<div class="offset-md-3 col-md-5">
<form action="<?php echo base_url('itemwise_report'); ?>" method="post">
<div class="form-group">
<div class="row">
<div class="col-md-7">
<input class="form-control input-daterange-datepicker" type="text" name="date" value="<?php if(isset($selected_data)) { echo $selected_data; } ?>"/>
</div>
<div class="col-md-5">
<button type="submit" class="btn btn-primary">Generate Report</button>
</div>
</div>
</div>
</form>
</div>
</div>
<!-- end page title -->
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-body">
<table id="datatable-buttons" class="table table-striped dt-responsive nowrap w-100">
<thead class="custom-thead">
<tr>
<th>Product Name</th>
<th>Count</th>
<th>Value</th>
</tr>
</thead>
<tbody class="custom-tbody">
<?php foreach ($report_data as $row)
{ ?>
<tr>
<td><?php echo $row->title;?></td>
<td><?php echo $row->item_count;?></td>
<td><?php echo $row->item_cost;?></td>
</tr>
<?php } ?>
</tbody>
</table>
</div> <!-- end card body-->
</div> <!-- end card -->
</div><!-- end col-->
</div>
<!-- end row-->
<script>
$(document).ready(function() {
var table = $('#datatable-buttons').DataTable({
// "order": [[0, 'desc']],
"dom": 'Bfrtip',
buttons: [
{
extend: 'pdfHtml5',
title: 'General Invoice Report',
text: 'PDF',
customize: function(doc) {
// Exclude the first and last columns
doc.content[1].table.body.forEach(function(row) {
row.splice(0, 1); // Remove the first column
row.splice(-1, 1); // Remove the last column
});
}
},
{
extend: 'print',
title: 'General Invoice Report',
text: 'Print',
customize: function(win) {
// Exclude the first and last columns
$(win.document.body).find('table').find('th:first-child, td:first-child, th:last-child, td:last-child').remove();
}
},
{
extend: 'csv',
text: 'CSV',
title: 'General Invoice Report',
exportOptions: {
columns: ':not(:first-child):not(:last-child)' // Exclude the first and last columns
}
}
]
});
});
</script>

View File

@ -0,0 +1,183 @@
<!-- start page title -->
<div class="row">
<div class="col-md-4">
<div class="page-title-box page-title-box-alt">
<h4 class="page-title"><?= $page_name ?></h4>
</div>
</div>
<div class="offset-md-3 col-md-5">
<form action="<?php echo base_url('mem_inv_rp'); ?>" method="post">
<div class="form-group">
<div class="row">
<div class="col-md-7">
<input class="form-control input-daterange-datepicker" type="text" name="date" value="<?php if(isset($selected_data)) { echo $selected_data; } ?>"/>
</div>
<div class="col-md-5">
<button type="submit" class="btn btn-primary">Generate Report</button>
</div>
</div>
</div>
</form>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-body">
<table id="datatable-buttons" class="table table-striped dt-responsive nowrap w-100">
<thead>
<tr>
<th hidden>id</th>
<th>Invoice No</th>
<th>Invoice Date</th>
<!-- <th>scheme name</th> -->
<th>Customer Name</th>
<th>GST</th>
<th>Discount</th>
<th>Count</th>
<th>OT Charges</th>
<th>Total</th>
<th>payment</th>
</tr>
</thead>
<tbody>
<?php foreach ($report_data as $row)
{ ?>
<tr>
<td hidden><?php echo $row->invoice_id;?></td>
<td><?php echo $row->invoice_number;?></td>
<td><?php echo $row->invoice_date;?></td>
<!-- <td>scheme name</td> -->
<td><?php echo $row->first_name." ".$row->last_name;?></td>
<td><?php echo $row->tax . '%'; ?></td>
<td><?php echo '₹' . number_format($row->discount, 2, '.', ','); ?></td>
<td><?php echo $row->item_count;?></td>
<td><?php echo '₹' . number_format($row->shipping_charge, 2, '.', ','); ?></td>
<td><?php echo '₹' . number_format($row->total_amount, 2, '.', ','); ?></td>
<td><?php echo $row->payment_method;?></td>
</tr>
<?php } ?>
</tbody>
</table>
</div> <!-- end card body-->
</div> <!-- end card -->
</div><!-- end col-->
</div>
<!-- end row-->
<script>
$(document).ready(function() {
var table = $('#datatable-buttons').DataTable({
"order": [[0, 'desc']],
"dom": 'Bfrtip',
buttons: [
{
extend: 'pdfHtml5',
title: 'General Invoice Report',
text: 'PDF',
customize: function(doc) {
// Exclude the first and last columns
doc.content[1].table.body.forEach(function(row) {
row.splice(0, 1); // Remove the first column
row.splice(-1, 1); // Remove the last column
});
}
},
{
extend: 'print',
title: 'General Invoice Report',
text: 'Print',
customize: function(win) {
// Exclude the first and last columns
$(win.document.body).find('table').find('th:first-child, td:first-child, th:last-child, td:last-child').remove();
}
},
{
extend: 'csv',
text: 'CSV',
title: 'General Invoice Report',
exportOptions: {
columns: ':not(:first-child):not(:last-child)' // Exclude the first and last columns
}
}
],
columnDefs: [
{ type: 'date', targets: [1,2,3,4,5,6,7,8,9], orderable: false } // Specify the column index for date sorting and disable sorting
]
});
// Add date range filter and dropdowns
$('#datatable-buttons thead tr').clone(true).appendTo('#datatable-buttons thead');
$('#datatable-buttons thead tr:eq(1) th').each(function (i) {
var title = $(this).text();
if (title != 'Invoice Date') {
// For non-"Invoice Date" columns, add a dropdown
var uniqueValues = table.column(i).data().unique().sort();
var select = $('<select class="form-control form-control-sm"><option value="">Search ' + title + '</option></select>')
.appendTo($(this).empty())
.on('change', function () {
var val = $.fn.dataTable.util.escapeRegex($(this).val());
table.column(i)
.search(val ? '^' + val + '$' : '', true, false)
.draw();
});
uniqueValues.each(function (d, j) {
select.append('<option value="' + d + '">' + d + '</option>');
});
} else {
// For "Invoice Date" column, add a date input
if (title != 'GST')
$(this).html('<input type="date" class="form-control form-control-sm" placeholder="Search ' + title + '" />');
}
$('input', this).on('keyup change', function () {
if (table.column(i).search() !== this.value) {
table
.column(i)
.search(this.value)
.draw();
}
});
});
// Add date range filter for "Invoice Date" column
var dateRangeFilter = $('<input type="text" class="form-control form-control-sm" placeholder="Select date range"/>')
.appendTo('#datatable-buttons thead tr:eq(2) th:eq(2)')
.daterangepicker({
autoUpdateInput: false,
locale: {
cancelLabel: 'Clear'
}
})
.on('click', function (e) {
// Prevent sorting when clicking on the date range filter input
e.stopPropagation();
});
dateRangeFilter.on('apply.daterangepicker', function (ev, picker) {
table.column(2)
.search(picker.startDate.format('YYYY-MM-DD') + ' to ' + picker.endDate.format('YYYY-MM-DD'))
.draw();
});
dateRangeFilter.on('cancel.daterangepicker', function () {
dateRangeFilter.val('');
table.column(2).search('').draw();
});
});
</script>

View File

@ -74,31 +74,49 @@
<!-- ... Inside the modal in subscriber_list.php ... -->
<form action="<?= base_url('subscription/download_details'); ?>" method="post">
<div class="form-group">
<div class="form-group">
<?php
$uniqueSchemes = [];
foreach ($subscriber as $scheme) :
if (!in_array($scheme['title'], $uniqueSchemes)) {
$uniqueSchemes[] = $scheme['title'];
?>
<div class="form-check">
<input class="form-check-input" type="checkbox" name="selected_schemes[]" value="<?= $scheme['title']; ?>">
<label class="form-check-label"><?= $scheme['title']; ?></label>
</div>
<?php
}
endforeach;
?>
</div>
<?php
$uniqueSchemes = [];
foreach ($subscriber as $scheme) :
if (!in_array($scheme['title'], $uniqueSchemes)) {
$uniqueSchemes[] = $scheme['title'];
?>
<div class="form-check">
<input class="form-check-input" type="checkbox" name="selected_schemes[]" value="<?= $scheme['title']; ?>">
<label class="form-check-label"><?= $scheme['title']; ?></label>
</div>
<?php
}
endforeach;
?>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label class="form-check-label">Select Action:</label>
<div class="form-check">
<input class="form-check-input" type="radio" name="action" value="1" checked>
<label class="form-check-label">1</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="action" value="2">
<label class="form-check-label">2 x 4(A4)</label>
</div>
</div>
</div>
<div class="col-md-6">
<div style="text-align: end;margin-top: 2rem;"> <!-- Adjust the margin as needed -->
<button type="submit" class="btn btn-primary">Download Details</button>
</div>
</div>
</div>
<button type="submit" class="btn btn-primary">Download Details</button>
</form>
</div>
</div> <!-- end card body-->
</div> <!-- end card -->
</div><!-- end col-->
</div>
</div>
</div>

View File

@ -790,6 +790,19 @@
<script src="<?= base_url() . "public/assets/js/pages/form-summernote.init.js" ?>"></script>
<script src="<?= base_url() . "public/assets/js/pages/form-advanced.init.js" ?>"></script>
<!-- Plugins js-->
<script src="<?= base_url() . "public/assets/libs/bootstrap-colorpicker/js/bootstrap-colorpicker.min.js" ?>"></script>
<script src="<?= base_url() . "public/assets/libs/clockpicker/bootstrap-clockpicker.min.js" ?>"></script>
<script src="<?= base_url() . "public/assets/libs/bootstrap-datepicker/js/bootstrap-datepicker.min.js" ?>"></script>
<script src="<?= base_url() . "public/assets/libs/moment/min/moment.min.js" ?>"></script>
<script src="<?= base_url() . "public/assets/libs/bootstrap-daterangepicker/daterangepicker.js" ?>"></script>
<!-- Init js-->
<script src="<?= base_url() . "public/assets/js/pages/form-pickers.init.js" ?>"></script>
<script>
// Automatically close both success and error messages after 5 seconds (5000 milliseconds)
setTimeout(function() {

View File

@ -9,7 +9,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<!-- App favicon -->
<link rel="shortcut icon" href="<?= $favicon; ?>">
<!-- plugin css -->
<link href="<?= base_url()."public/assets/libs/multiselect/css/multi-select.css" ?>" rel="stylesheet" type="text/css" />
<link href="<?= base_url()."public/assets/libs/select2/css/select2.min.css" ?>" rel="stylesheet" type="text/css" />
@ -20,8 +20,14 @@
<link href="<?= base_url()."public/assets/libs/datatables.net-responsive-bs4/css/responsive.bootstrap4.min.css" ?>" rel="stylesheet" type="text/css" />
<link href="<?= base_url()."public/assets/libs/datatables.net-buttons-bs4/css/buttons.bootstrap4.min.css" ?>" rel="stylesheet" type="text/css" />
<link href="<?= base_url()."public/assets/libs/datatables.net-select-bs4/css//select.bootstrap4.min.css" ?>" rel="stylesheet" type="text/css" />
<link href="<?= base_url()."public/assets/libs/bootstrap-colorpicker/css/bootstrap-colorpicker.min.css" ?>" rel="stylesheet" type="text/css" />
<link href="<?= base_url()."public/assets/libs/clockpicker/bootstrap-clockpicker.min.css" ?>" rel="stylesheet" type="text/css" />
<link href="<?= base_url()."public/assets/libs/bootstrap-datepicker/css/bootstrap-datepicker.min.css" ?>" rel="stylesheet" type="text/css" />
<link href="<?= base_url()."public/assets/libs/bootstrap-daterangepicker/daterangepicker.css" ?>" rel="stylesheet" type="text/css">
<!-- third party css end -->
<!-- App css -->
<link href="<?= base_url()."public/assets/css/bootstrap.min.css" ?>" rel="stylesheet" type="text/css" id="bs-default-stylesheet" />
<link href="<?= base_url()."public/assets/css/app.min.css" ?>" rel="stylesheet" type="text/css" id="app-default-stylesheet" />
@ -193,6 +199,30 @@
</a>
</li>
<?php endif; ?>
<?php if ($loggedin_person_role !== 'manager') : ?>
<li>
<a href="#reportLayouts" data-toggle="collapse">
<i class="ri-file-chart-fill"></i>
<span> Report </span>
<span class="menu-arrow"></span>
</a>
<div class="collapse" id="reportLayouts">
<ul class="nav-second-level">
<li>
<a href="<?= base_url()."general_inv_rp"; ?>">General Invoice Report</a>
</li>
<li>
<a href="<?= base_url()."mem_inv_rp"; ?>">Membership invoice report</a>
</li>
<li>
<a href="<?= base_url()."itemwise_report"; ?>">Itemwise Report</a>
</li>
</ul>
</div>
</li>
<?php endif; ?>
<?php if ($loggedin_person_role !== 'manager') : ?>
<li>
<a href="#notificationsLayouts" data-toggle="collapse">

View File

@ -72,7 +72,7 @@ d=Y(a),e=a.oFeatures,f,g;if(e.bSort&&e.bSortClasses){e=0;for(f=b.length;e<f;e++)
d?e[j]:B(a,j,b,"sort"),c._aSortData[b]=g?g(f):f}function za(a){if(a.oFeatures.bStateSave&&!a.bDestroying){var b={time:+new Date,start:a._iDisplayStart,length:a._iDisplayLength,order:h.extend(!0,[],a.aaSorting),search:Cb(a.oPreviousSearch),columns:h.map(a.aoColumns,function(b,d){return{visible:b.bVisible,search:Cb(a.aoPreSearchCols[d])}})};t(a,"aoStateSaveParams","stateSaveParams",[a,b]);a.oSavedState=b;a.fnStateSaveCallback.call(a.oInstance,a,b)}}function Lb(a,b,c){var d,e,f=a.aoColumns,b=function(b){if(b&&
b.time){var g=t(a,"aoStateLoadParams","stateLoadParams",[a,b]);if(-1===h.inArray(!1,g)&&(g=a.iStateDuration,!(0<g&&b.time<+new Date-1E3*g)&&!(b.columns&&f.length!==b.columns.length))){a.oLoadedState=h.extend(!0,{},b);b.start!==k&&(a._iDisplayStart=b.start,a.iInitDisplayStart=b.start);b.length!==k&&(a._iDisplayLength=b.length);b.order!==k&&(a.aaSorting=[],h.each(b.order,function(b,c){a.aaSorting.push(c[0]>=f.length?[0,c[1]]:c)}));b.search!==k&&h.extend(a.oPreviousSearch,Db(b.search));if(b.columns){d=
0;for(e=b.columns.length;d<e;d++)g=b.columns[d],g.visible!==k&&(f[d].bVisible=g.visible),g.search!==k&&h.extend(a.aoPreSearchCols[d],Db(g.search))}t(a,"aoStateLoaded","stateLoaded",[a,b])}}c()};if(a.oFeatures.bStateSave){var g=a.fnStateLoadCallback.call(a.oInstance,a,b);g!==k&&b(g)}else c()}function Aa(a){var b=n.settings,a=h.inArray(a,C(b,"nTable"));return-1!==a?b[a]:null}function K(a,b,c,d){c="DataTables warning: "+(a?"table id="+a.sTableId+" - ":"")+c;d&&(c+=". For more information about this error, please see http://datatables.net/tn/"+
d);if(b)E.console&&console.log&&console.log(c);else if(b=n.ext,b=b.sErrMode||b.errMode,a&&t(a,null,"error",[a,d,c]),"alert"==b)alert(c);else{if("throw"==b)throw Error(c);"function"==typeof b&&b(a,d,c)}}function F(a,b,c,d){h.isArray(c)?h.each(c,function(c,d){h.isArray(d)?F(a,b,d[0],d[1]):F(a,b,d)}):(d===k&&(d=c),b[c]!==k&&(a[d]=b[c]))}function Ya(a,b,c){var d,e;for(e in b)b.hasOwnProperty(e)&&(d=b[e],h.isPlainObject(d)?(h.isPlainObject(a[e])||(a[e]={}),h.extend(!0,a[e],d)):a[e]=c&&"data"!==e&&"aaData"!==
d);if(b)E.console&&console.log&&console.log(c);else if(b=n.ext,b=b.sErrMode||b.errMode,a&&t(a,null,"error",[a,d,c]),"alert"==b);else{if("throw"==b)throw Error(c);"function"==typeof b&&b(a,d,c)}}function F(a,b,c,d){h.isArray(c)?h.each(c,function(c,d){h.isArray(d)?F(a,b,d[0],d[1]):F(a,b,d)}):(d===k&&(d=c),b[c]!==k&&(a[d]=b[c]))}function Ya(a,b,c){var d,e;for(e in b)b.hasOwnProperty(e)&&(d=b[e],h.isPlainObject(d)?(h.isPlainObject(a[e])||(a[e]={}),h.extend(!0,a[e],d)):a[e]=c&&"data"!==e&&"aaData"!==
e&&h.isArray(d)?d.slice():d);return a}function Xa(a,b,c){h(a).on("click.DT",b,function(b){h(a).trigger("blur");c(b)}).on("keypress.DT",b,function(a){13===a.which&&(a.preventDefault(),c(a))}).on("selectstart.DT",function(){return!1})}function z(a,b,c,d){c&&a[b].push({fn:c,sName:d})}function t(a,b,c,d){var e=[];b&&(e=h.map(a[b].slice().reverse(),function(b){return b.fn.apply(a.oInstance,d)}));null!==c&&(b=h.Event(c+".dt"),h(a.nTable).trigger(b,d),e.push(b.result));return e}function Ua(a){var b=a._iDisplayStart,
c=a.fnDisplayEnd(),d=a._iDisplayLength;b>=c&&(b=c-d);b-=b%d;if(-1===d||0>b)b=0;a._iDisplayStart=b}function Pa(a,b){var c=a.renderer,d=n.ext.renderer[b];return h.isPlainObject(c)&&c[b]?d[c[b]]||d._:"string"===typeof c?d[c]||d._:d._}function y(a){return a.oFeatures.bServerSide?"ssp":a.ajax||a.sAjaxSource?"ajax":"dom"}function ja(a,b){var c=[],c=Mb.numbers_length,d=Math.floor(c/2);b<=c?c=Z(0,b):a<=d?(c=Z(0,c-2),c.push("ellipsis"),c.push(b-1)):(a>=b-1-d?c=Z(b-(c-2),b):(c=Z(a-d+2,a+d-1),c.push("ellipsis"),
c.push(b-1)),c.splice(0,0,"ellipsis"),c.splice(0,0,0));c.DT_el="span";return c}function Fa(a){h.each({num:function(b){return Ba(b,a)},"num-fmt":function(b){return Ba(b,a,Za)},"html-num":function(b){return Ba(b,a,Ca)},"html-num-fmt":function(b){return Ba(b,a,Ca,Za)}},function(b,c){v.type.order[b+a+"-pre"]=c;b.match(/^html\-/)&&(v.type.search[b+a]=v.type.search.html)})}function Nb(a){return function(){var b=[Aa(this[n.ext.iApiIndex])].concat(Array.prototype.slice.call(arguments));return n.ext.internal[a].apply(this,

View File

@ -45,34 +45,35 @@ class ClassLoader
/** @var \Closure(string):void */
private static $includeFile;
/** @var string|null */
/** @var ?string */
private $vendorDir;
// PSR-4
/**
* @var array<string, array<string, int>>
* @var array[]
* @psalm-var array<string, array<string, int>>
*/
private $prefixLengthsPsr4 = array();
/**
* @var array<string, list<string>>
* @var array[]
* @psalm-var array<string, array<int, string>>
*/
private $prefixDirsPsr4 = array();
/**
* @var list<string>
* @var array[]
* @psalm-var array<string, string>
*/
private $fallbackDirsPsr4 = array();
// PSR-0
/**
* List of PSR-0 prefixes
*
* Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2')))
*
* @var array<string, array<string, list<string>>>
* @var array[]
* @psalm-var array<string, array<string, string[]>>
*/
private $prefixesPsr0 = array();
/**
* @var list<string>
* @var array[]
* @psalm-var array<string, string>
*/
private $fallbackDirsPsr0 = array();
@ -80,7 +81,8 @@ class ClassLoader
private $useIncludePath = false;
/**
* @var array<string, string>
* @var string[]
* @psalm-var array<string, string>
*/
private $classMap = array();
@ -88,20 +90,21 @@ class ClassLoader
private $classMapAuthoritative = false;
/**
* @var array<string, bool>
* @var bool[]
* @psalm-var array<string, bool>
*/
private $missingClasses = array();
/** @var string|null */
/** @var ?string */
private $apcuPrefix;
/**
* @var array<string, self>
* @var self[]
*/
private static $registeredLoaders = array();
/**
* @param string|null $vendorDir
* @param ?string $vendorDir
*/
public function __construct($vendorDir = null)
{
@ -110,7 +113,7 @@ class ClassLoader
}
/**
* @return array<string, list<string>>
* @return string[]
*/
public function getPrefixes()
{
@ -122,7 +125,8 @@ class ClassLoader
}
/**
* @return array<string, list<string>>
* @return array[]
* @psalm-return array<string, array<int, string>>
*/
public function getPrefixesPsr4()
{
@ -130,7 +134,8 @@ class ClassLoader
}
/**
* @return list<string>
* @return array[]
* @psalm-return array<string, string>
*/
public function getFallbackDirs()
{
@ -138,7 +143,8 @@ class ClassLoader
}
/**
* @return list<string>
* @return array[]
* @psalm-return array<string, string>
*/
public function getFallbackDirsPsr4()
{
@ -146,7 +152,8 @@ class ClassLoader
}
/**
* @return array<string, string> Array of classname => path
* @return string[] Array of classname => path
* @psalm-return array<string, string>
*/
public function getClassMap()
{
@ -154,7 +161,8 @@ class ClassLoader
}
/**
* @param array<string, string> $classMap Class to filename map
* @param string[] $classMap Class to filename map
* @psalm-param array<string, string> $classMap
*
* @return void
*/
@ -171,25 +179,24 @@ class ClassLoader
* Registers a set of PSR-0 directories for a given prefix, either
* appending or prepending to the ones previously set for this prefix.
*
* @param string $prefix The prefix
* @param list<string>|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
* @param string $prefix The prefix
* @param string[]|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
*
* @return void
*/
public function add($prefix, $paths, $prepend = false)
{
$paths = (array) $paths;
if (!$prefix) {
if ($prepend) {
$this->fallbackDirsPsr0 = array_merge(
$paths,
(array) $paths,
$this->fallbackDirsPsr0
);
} else {
$this->fallbackDirsPsr0 = array_merge(
$this->fallbackDirsPsr0,
$paths
(array) $paths
);
}
@ -198,19 +205,19 @@ class ClassLoader
$first = $prefix[0];
if (!isset($this->prefixesPsr0[$first][$prefix])) {
$this->prefixesPsr0[$first][$prefix] = $paths;
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
return;
}
if ($prepend) {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$paths,
(array) $paths,
$this->prefixesPsr0[$first][$prefix]
);
} else {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$this->prefixesPsr0[$first][$prefix],
$paths
(array) $paths
);
}
}
@ -219,9 +226,9 @@ class ClassLoader
* Registers a set of PSR-4 directories for a given namespace, either
* appending or prepending to the ones previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param list<string>|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param string[]|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
*
* @throws \InvalidArgumentException
*
@ -229,18 +236,17 @@ class ClassLoader
*/
public function addPsr4($prefix, $paths, $prepend = false)
{
$paths = (array) $paths;
if (!$prefix) {
// Register directories for the root namespace.
if ($prepend) {
$this->fallbackDirsPsr4 = array_merge(
$paths,
(array) $paths,
$this->fallbackDirsPsr4
);
} else {
$this->fallbackDirsPsr4 = array_merge(
$this->fallbackDirsPsr4,
$paths
(array) $paths
);
}
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
@ -250,18 +256,18 @@ class ClassLoader
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = $paths;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
} elseif ($prepend) {
// Prepend directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
$paths,
(array) $paths,
$this->prefixDirsPsr4[$prefix]
);
} else {
// Append directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
$this->prefixDirsPsr4[$prefix],
$paths
(array) $paths
);
}
}
@ -270,8 +276,8 @@ class ClassLoader
* Registers a set of PSR-0 directories for a given prefix,
* replacing any others previously set for this prefix.
*
* @param string $prefix The prefix
* @param list<string>|string $paths The PSR-0 base directories
* @param string $prefix The prefix
* @param string[]|string $paths The PSR-0 base directories
*
* @return void
*/
@ -288,8 +294,8 @@ class ClassLoader
* Registers a set of PSR-4 directories for a given namespace,
* replacing any others previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param list<string>|string $paths The PSR-4 base directories
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param string[]|string $paths The PSR-4 base directories
*
* @throws \InvalidArgumentException
*
@ -423,8 +429,7 @@ class ClassLoader
public function loadClass($class)
{
if ($file = $this->findFile($class)) {
$includeFile = self::$includeFile;
$includeFile($file);
(self::$includeFile)($file);
return true;
}
@ -475,9 +480,9 @@ class ClassLoader
}
/**
* Returns the currently registered loaders keyed by their corresponding vendor directories.
* Returns the currently registered loaders indexed by their corresponding vendor directories.
*
* @return array<string, self>
* @return self[]
*/
public static function getRegisteredLoaders()
{
@ -555,10 +560,7 @@ class ClassLoader
return false;
}
/**
* @return void
*/
private static function initializeIncludeClosure()
private static function initializeIncludeClosure(): void
{
if (self::$includeFile !== null) {
return;
@ -572,8 +574,8 @@ class ClassLoader
* @param string $file
* @return void
*/
self::$includeFile = \Closure::bind(static function($file) {
self::$includeFile = static function($file) {
include $file;
}, null, null);
};
}
}

View File

@ -98,7 +98,7 @@ class InstalledVersions
{
foreach (self::getInstalled() as $installed) {
if (isset($installed['versions'][$packageName])) {
return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false;
return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']);
}
}
@ -119,7 +119,7 @@ class InstalledVersions
*/
public static function satisfies(VersionParser $parser, $packageName, $constraint)
{
$constraint = $parser->parseConstraints((string) $constraint);
$constraint = $parser->parseConstraints($constraint);
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
return $provided->matches($constraint);
@ -328,9 +328,7 @@ class InstalledVersions
if (isset(self::$installedByVendor[$vendorDir])) {
$installed[] = self::$installedByVendor[$vendorDir];
} elseif (is_file($vendorDir.'/composer/installed.php')) {
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
$required = require $vendorDir.'/composer/installed.php';
$installed[] = self::$installedByVendor[$vendorDir] = $required;
$installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php';
if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
self::$installed = $installed[count($installed) - 1];
}
@ -342,17 +340,12 @@ class InstalledVersions
// only require the installed.php file if this file is loaded from its dumped location,
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
if (substr(__DIR__, -8, 1) !== 'C') {
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
$required = require __DIR__ . '/installed.php';
self::$installed = $required;
self::$installed = require __DIR__ . '/installed.php';
} else {
self::$installed = array();
}
}
if (self::$installed !== array()) {
$installed[] = self::$installed;
}
$installed[] = self::$installed;
return $installed;
}

View File

@ -34,15 +34,15 @@ class ComposerAutoloaderInitaf5d45949d7526726de1c031a6bdb085
$loader->register(true);
$filesToLoad = \Composer\Autoload\ComposerStaticInitaf5d45949d7526726de1c031a6bdb085::$files;
$requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
$requireFile = static function ($fileIdentifier, $file) {
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
require $file;
}
}, null, null);
};
foreach ($filesToLoad as $fileIdentifier => $file) {
$requireFile($fileIdentifier, $file);
($requireFile)($fileIdentifier, $file);
}
return $loader;

View File

@ -1,9 +1,9 @@
<?php return array(
'root' => array(
'name' => 'codeigniter4/framework',
'pretty_version' => '1.0.0+no-version-set',
'version' => '1.0.0.0',
'reference' => NULL,
'pretty_version' => 'dev-uat',
'version' => 'dev-uat',
'reference' => '32b69272aaf8c86b89bb6893fae5d885a379d060',
'type' => 'project',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@ -20,9 +20,9 @@
'dev_requirement' => true,
),
'codeigniter4/framework' => array(
'pretty_version' => '1.0.0+no-version-set',
'version' => '1.0.0.0',
'reference' => NULL,
'pretty_version' => 'dev-uat',
'version' => 'dev-uat',
'reference' => '32b69272aaf8c86b89bb6893fae5d885a379d060',
'type' => 'project',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),

View File

@ -265,7 +265,11 @@ final class Uri implements UriInterface
return !isset(self::$schemes[$scheme]) || $port !== self::$schemes[$scheme];
}
<<<<<<< HEAD
private function filterPort(int $port): ?bool
=======
private function filterPort(int $port): ?int
>>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
{
if (null === $port) {
return null;

View File

@ -30,5 +30,9 @@ class Fpdi extends FpdfTpl
*
* @string
*/
<<<<<<< HEAD
const VERSION = '2.4.1';
=======
const VERSION = '2.5.0';
>>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
}

View File

@ -25,6 +25,10 @@ use setasign\Fpdi\PdfParser\Type\PdfStream;
use setasign\Fpdi\PdfParser\Type\PdfString;
use setasign\Fpdi\PdfParser\Type\PdfToken;
use setasign\Fpdi\PdfParser\Type\PdfType;
<<<<<<< HEAD
=======
use setasign\Fpdi\PdfParser\Type\PdfTypeException;
>>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
/**
* A PDF parser class
@ -258,12 +262,17 @@ class PdfParser
switch ($token) {
case '(':
$this->ensureExpectedType($token, $expectedType);
<<<<<<< HEAD
return PdfString::parse($this->streamReader);
=======
return $this->parsePdfString();
>>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
case '<':
if ($this->streamReader->getByte() === '<') {
$this->ensureExpectedType('<<', $expectedType);
$this->streamReader->addOffset(1);
<<<<<<< HEAD
return PdfDictionary::parse($this->tokenizer, $this->streamReader, $this);
}
@ -277,6 +286,21 @@ class PdfParser
case '[':
$this->ensureExpectedType($token, $expectedType);
return PdfArray::parse($this->tokenizer, $this);
=======
return $this->parsePdfDictionary();
}
$this->ensureExpectedType($token, $expectedType);
return $this->parsePdfHexString();
case '/':
$this->ensureExpectedType($token, $expectedType);
return $this->parsePdfName();
case '[':
$this->ensureExpectedType($token, $expectedType);
return $this->parsePdfArray();
>>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
default:
if (\is_numeric($token)) {
@ -291,6 +315,7 @@ class PdfParser
);
}
<<<<<<< HEAD
return PdfIndirectObject::parse(
(int) $token,
(int) $token2,
@ -298,6 +323,9 @@ class PdfParser
$this->tokenizer,
$this->streamReader
);
=======
return $this->parsePdfIndirectObject((int)$token, (int)$token2);
>>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
case 'R':
if (
$expectedType !== null &&
@ -309,7 +337,11 @@ class PdfParser
);
}
<<<<<<< HEAD
return PdfIndirectObjectReference::create((int) $token, (int) $token2);
=======
return PdfIndirectObjectReference::create((int)$token, (int)$token2);
>>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
}
$this->tokenizer->pushStack($token3);
@ -352,6 +384,68 @@ class PdfParser
}
/**
<<<<<<< HEAD
=======
* @return PdfString
*/
protected function parsePdfString()
{
return PdfString::parse($this->streamReader);
}
/**
* @return false|PdfHexString
*/
protected function parsePdfHexString()
{
return PdfHexString::parse($this->streamReader);
}
/**
* @return bool|PdfDictionary
* @throws PdfTypeException
*/
protected function parsePdfDictionary()
{
return PdfDictionary::parse($this->tokenizer, $this->streamReader, $this);
}
/**
* @return PdfName
*/
protected function parsePdfName()
{
return PdfName::parse($this->tokenizer, $this->streamReader);
}
/**
* @return false|PdfArray
* @throws PdfTypeException
*/
protected function parsePdfArray()
{
return PdfArray::parse($this->tokenizer, $this);
}
/**
* @param int $objectNumber
* @param int $generationNumber
* @return false|PdfIndirectObject
* @throws Type\PdfTypeException
*/
protected function parsePdfIndirectObject($objectNumber, $generationNumber)
{
return PdfIndirectObject::parse(
$objectNumber,
$generationNumber,
$this,
$this->tokenizer,
$this->streamReader
);
}
/**
>>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
* Ensures that the token will evaluate to an expected object type (or not).
*
* @param string $token
@ -359,7 +453,11 @@ class PdfParser
* @return bool
* @throws Type\PdfTypeException
*/
<<<<<<< HEAD
private function ensureExpectedType($token, $expectedType)
=======
protected function ensureExpectedType($token, $expectedType)
>>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
{
static $mapping = [
'(' => PdfString::class,

View File

@ -113,6 +113,15 @@ class StreamReader
);
}
<<<<<<< HEAD
=======
if (fseek($stream, 0) === -1) {
throw new \InvalidArgumentException(
'Given stream is not seekable!'
);
}
>>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
$this->stream = $stream;
$this->closeStream = $closeStream;
$this->reset();

View File

@ -25,7 +25,11 @@ class PdfArray extends PdfType
*
* @param Tokenizer $tokenizer
* @param PdfParser $parser
<<<<<<< HEAD
* @return bool|self
=======
* @return false|self
>>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
* @throws PdfTypeException
*/
public static function parse(Tokenizer $tokenizer, PdfParser $parser)

View File

@ -21,7 +21,11 @@ class PdfHexString extends PdfType
* Parses a hexadecimal string object from the stream reader.
*
* @param StreamReader $streamReader
<<<<<<< HEAD
* @return bool|self
=======
* @return false|self
>>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
*/
public static function parse(StreamReader $streamReader)
{

View File

@ -22,6 +22,7 @@ class PdfIndirectObject extends PdfType
/**
* Parses an indirect object from a tokenizer, parser and stream-reader.
*
<<<<<<< HEAD
* @param int $objectNumberToken
* @param int $objectGenerationNumberToken
* @param PdfParser $parser
@ -33,6 +34,19 @@ class PdfIndirectObject extends PdfType
public static function parse(
$objectNumberToken,
$objectGenerationNumberToken,
=======
* @param int $objectNumber
* @param int $objectGenerationNumber
* @param PdfParser $parser
* @param Tokenizer $tokenizer
* @param StreamReader $reader
* @return self|false
* @throws PdfTypeException
*/
public static function parse(
$objectNumber,
$objectGenerationNumber,
>>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
PdfParser $parser,
Tokenizer $tokenizer,
StreamReader $reader
@ -50,8 +64,13 @@ class PdfIndirectObject extends PdfType
}
$v = new self();
<<<<<<< HEAD
$v->objectNumber = (int) $objectNumberToken;
$v->generationNumber = (int) $objectGenerationNumberToken;
=======
$v->objectNumber = (int) $objectNumber;
$v->generationNumber = (int) $objectGenerationNumber;
>>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
$v->value = $value;
return $v;

View File

@ -213,6 +213,31 @@ class PdfStream extends PdfType
}
/**
<<<<<<< HEAD
=======
* Get all filters defined for this stream.
*
* @return PdfType[]
* @throws PdfTypeException
*/
public function getFilters()
{
$filters = PdfDictionary::get($this->value, 'Filter');
if ($filters instanceof PdfNull) {
return [];
}
if ($filters instanceof PdfArray) {
$filters = $filters->value;
} else {
$filters = [$filters];
}
return $filters;
}
/**
>>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
* Get the unfiltered stream data.
*
* @return string
@ -222,6 +247,7 @@ class PdfStream extends PdfType
public function getUnfilteredStream()
{
$stream = $this->getStream();
<<<<<<< HEAD
$filters = PdfDictionary::get($this->value, 'Filter');
if ($filters instanceof PdfNull) {
return $stream;
@ -233,6 +259,13 @@ class PdfStream extends PdfType
$filters = [$filters];
}
=======
$filters = $this->getFilters();
if ($filters === []) {
return $stream;
}
>>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
$decodeParams = PdfDictionary::get($this->value, 'DecodeParms');
if ($decodeParams instanceof PdfArray) {
$decodeParams = $decodeParams->value;
@ -308,6 +341,24 @@ class PdfStream extends PdfType
$stream = $filterObject->decode($stream);
break;
<<<<<<< HEAD
=======
case 'Crypt':
if (!$decodeParam instanceof PdfDictionary) {
break;
}
// Filter is "Identity"
$name = PdfDictionary::get($decodeParam, 'Name');
if (!$name instanceof PdfName || $name->value !== 'Identity') {
break;
}
throw new FilterException(
'Support for Crypt filters other than "Identity" is not implemented.',
FilterException::UNSUPPORTED_FILTER
);
>>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
default:
throw new FilterException(
\sprintf('Unsupported filter "%s".', $filter->value),

View File

@ -79,6 +79,39 @@ class PdfString extends PdfType
}
/**
<<<<<<< HEAD
=======
* Escapes sequences in a string according to the PDF specification.
*
* @param string $s
* @return string
*/
public static function escape($s)
{
// Still a bit faster, than direct replacing
if (
\strpos($s, '\\') !== false ||
\strpos($s, ')') !== false ||
\strpos($s, '(') !== false ||
\strpos($s, "\x0D") !== false ||
\strpos($s, "\x0A") !== false ||
\strpos($s, "\x09") !== false ||
\strpos($s, "\x08") !== false ||
\strpos($s, "\x0C") !== false
) {
// is faster than strtr(...)
return \str_replace(
['\\', ')', '(', "\x0D", "\x0A", "\x09", "\x08", "\x0C"],
['\\\\', '\\)', '\\(', '\r', '\n', '\t', '\b', '\f'],
$s
);
}
return $s;
}
/**
>>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
* Unescapes escaped sequences in a PDF string according to the PDF specification.
*
* @param string $s

View File

@ -46,7 +46,11 @@ class Fpdi extends \TCPDF
*
* @string
*/
<<<<<<< HEAD
const VERSION = '2.4.1';
=======
const VERSION = '2.5.0';
>>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
/**
* A counter for template ids.
@ -251,7 +255,11 @@ class Fpdi extends \TCPDF
if ($value instanceof PdfString) {
$string = PdfString::unescape($value->value);
$string = $this->_encrypt_data($this->currentObjectNumber, $string);
<<<<<<< HEAD
$value->value = \TCPDF_STATIC::_escape($string);
=======
$value->value = PdfString::escape($string);
>>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
} elseif ($value instanceof PdfHexString) {
$filter = new AsciiHex();
$string = $filter->decode($value->value);

View File

@ -28,5 +28,9 @@ class Fpdi extends FpdfTpl
*
* @string
*/
<<<<<<< HEAD
const VERSION = '2.4.1';
=======
const VERSION = '2.5.0';
>>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
}