Currency convert in category page - opencart

I want show in category multiple curency price
i have a code tike this
$this->currency->convert($price, 'RUB', 'CNY'),
Where to put this in caregory controller for working?

I resolve my problem like this
if ($this->customer->isLogged() || !$this->config->get('config_customer_price')) {
$price = $this->currency->format($this->tax->calculate($result['price'], $result['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency']);
$price_2 = $this->currency->format($this->tax->calculate($result['price'], $result['tax_class_id'], $this->config->get('config_tax')), 'CNY');
} else {
$price = false;
$price_2 = false;
}
Maybe someone have better way to make.

Related

Opencart 3.0.3.7 Trying to access array offset on value of type bool

I'm running Opencart 3.0.3.7 on PHP 7.4 and I'm getting this message in the error log:
PHP Notice: Trying to access array offset on value of type bool in /home/site/public_html/catalog/model/extension/module/so_filter_shop_by.php on line 313
PHP Notice: Trying to access array offset on value of type bool in /home/site/public_html/catalog/model/extension/module/so_filter_shop_by.php on line 314
The code is :
foreach($query->rows as $result)
{
$data = $this->model_catalog_product->getProduct($result['product_id']);
$price = $this->tax->calculate($data['price'], $data['tax_class_id'], $this->config->get('config_tax'));
if ((float)$data['special']) {
$price = $this->tax->calculate($data['special'], $data['tax_class_id'], $this->config->get('config_tax'));
}
$price = $this->currency->format($price, $this->session->data['currency']);
if ($this->language->get('decimal_point') == ',') {
$price = trim(str_replace(',', '.', $price));
}
else {
$price = trim(str_replace(',', '', $price));
}
$price = trim(str_replace($currencies, '', $price));
$data['price_soFilter'] = $price;
$product_data[] = $data;
}
return $product_data;
}
Could anyone suggest a solution to resolve this error.
you have to check if the $price NOT NULL try something like this:
if(is_null($price))
{
$price = '';
} else {
$price = $this->tax->calculate($data['price'], $data['tax_class_id'], $this->config->get('config_tax'));
}
You can try:
if(!empty($price)) {
$price = $this->tax->calculate((float)$data['price'], $data['tax_class_id'], $this->config->get('config_tax'));
} else {
$price = '';
}

How reuse formatted Doctrine 2 with QueryBuilder formatted query in other query

I have formatted query with doctrine query builder. It is kind of complicated because in that query there are some my own defined doctrine functions and doctrine extensions. Also very important to mention that this query using filter which is require some preselected values. The problem is when i want to count records from that query. Of course i Can write count(results), but it is very bad for performance.
I try to create new sql query with my own predefined query as source, but the problem that parameters are not injected.
Query which is formatted and which result i want to count :
private function getCategoriesQuery(Filter $filter = null, Sort $sort = null, Pagination $pagination = null)
{
$qb = $this->createQueryBuilder('c')
->select('c.id as id')
->addSelect('c.title as title')
->addSelect('DATE_FORMAT(c.updationDate, \'%Y-%m-%d %H:%i:%S\') as updationDate')
->addSelect('DATE_FORMAT(c.creationDate, \'%Y-%m-%d %H:%i:%S\') as creationDate')
->addSelect('coalesce(sum(r.amount), 0.00) as total')
->addSelect('round(AveragePerMonth(coalesce(sum(r.amount), 0.00), c.creationDate, CURRENT_DATE()), 2) as averagePerMonth')
->leftJoin('c.records', 'r')
->groupBy('c.id')
->andWhere('c.user = :user')->setParameter('user', $this->user);
if ($filter) $this->applyFilters($filter, $qb);
if ($sort) $this->applySort($sort, $qb);
if ($pagination) $this->applyPagination($pagination, $qb);
return $qb->getQuery();
}
I tried:
public function countUserCategories(Filter $filter = null)
{
$rsm = new ResultSetMapping();
$sql = $this->_em->createNativeQuery('select count(*) from ('.$this->getCategoriesQuery($filter)->getSQL().') as src', $rsm);
return $sql->getSingleScalarResult();
}
I expected the answer if there is possibility to combine these queries and if there is possiblity how i can do that. Thanks
ApplyFilter method:
private function applyFilters(Filter $filter, QueryBuilder $qb)
{
if ($filter->getCategories()) {
$qb->andWhere('c.id IN(:categories)')->setParameter('categories', $filter->getCategories());
}
if ($filter->getEndDate()) {
$qb->andWhere('r.date <= :endDate')->setParameter('endDate', $filter->getEndDate());
}
if ($filter->getStartDate()) {
$qb->andWhere('r.date >= :startDate')->setParameter('startDate', $filter->getStartDate());
}
if ($filter->getStartTotal() !== null) {
$qb->andHaving('total >= :startTotal')->setParameter('startTotal', $filter->getStartTotal());
}
if ($filter->getEndTotal() !== null) {
$qb->andHaving('total <= :endTotal')->setParameter('endTotal', $filter->getEndTotal());
}
if ($filter->getStartAveragePerMonth() !== null) {
$qb->andHaving('averagePerMonth >= :startAveragePerMonth')->setParameter('startAveragePerMonth', $filter->getStartAveragePerMonth());
}
if ($filter->getEndAveragePerMonth() !== null) {
$qb->andHaving('averagePerMonth <= :endAveragePerMonth')->setParameter('endAveragePerMonth', $filter->getEndAveragePerMonth());
}
}
Suggested way to solve this issue but return response : The query returned multiple rows. Change the query or use a different result function like getScalarResult().
public function countUserCategories(Filter $filter = null)
{
return (clone $this->getCategoriesQueryBuilder($filter))
->resetDQLPart('select')
->select('COUNT(c)')
->getQuery()
->getSingleScalarResult();
}
UPDATE
I make this work by using SQL query builder
Query builder creation
private function getCategoriesQueryBuilder(Filter $filter = null, Sort $sort = null, Pagination $pagination = null)
{
$qb = $this->_em->getConnection()->createQueryBuilder()
->select('c.id AS id')
->addSelect('c.title AS title')
->addSelect('DATE_FORMAT(c.updation_date, \'%Y-%m-%d %H:%i:%S\') AS updationDate')
->addSelect('DATE_FORMAT(c.creation_date, \'%Y-%m-%d %H:%i:%S\') AS creationDate')
->addSelect('COALESCE(SUM(r.amount), 0.00) AS total')
->addSelect('(SELECT ROUND(COALESCE(SUM(r.amount), 0.00) / COUNT(DISTINCT(DATE_FORMAT(calendar.date, \'%Y-%m\'))), 2)
FROM calendar as calendar
WHERE calendar.date BETWEEN DATE_FORMAT(c.creation_date, \'%Y-%m-%d\') AND DATE_FORMAT(CURRENT_DATE(), \'%Y-%m-%d\'))
AS averagePerMonth')
->from('category', 'c')
->leftJoin('c', 'record', 'r', 'r.category_id = c.id')
->join('c', 'users', 'u', 'u.id = c.user_id')
->where('u.id = :userId')->setParameter('userId', $this->user->getId())
->groupBy('c.id');
if ($sort) $this->applySort($sort, $qb);
if ($pagination) $this->applyPagination($pagination, $qb);
if ($filter) $this->applyFilter($filter, $qb);
return $qb;
}
Filter
private function applyFilter(Filter $filter, QueryBuilder $qb)
{
if ($filter->getCategories()) {
$qb->andWhere('c.id IN(:categories)')->setParameter('categories', $filter->getCategories());
}
if ($filter->getEndDate()) {
$qb->andWhere('r.date <= :endDate')->setParameter('endDate', $filter->getEndDate());
}
if ($filter->getStartDate()) {
$qb->andWhere('r.date >= :startDate')->setParameter('startDate', $filter->getStartDate());
}
if ($filter->getStartTotal() !== null) {
$qb->andHaving('total >= :startTotal')->setParameter('startTotal', $filter->getStartTotal());
}
if ($filter->getEndTotal() !== null) {
$qb->andHaving('total <= :endTotal')->setParameter('endTotal', $filter->getEndTotal());
}
if ($filter->getStartAveragePerMonth() !== null) {
$qb->andHaving('averagePerMonth >= :startAveragePerMonth')->setParameter('startAveragePerMonth', $filter->getStartAveragePerMonth());
}
if ($filter->getEndAveragePerMonth() !== null) {
$qb->andHaving('averagePerMonth <= :endAveragePerMonth')->setParameter('endAveragePerMonth', $filter->getEndAveragePerMonth());
}
}
Count
public function countUserCategories(Filter $filter = null)
{
$subQuery = $this->getCategoriesQueryBuilder($filter);
$params = $subQuery->getParameters();
return $this->_em->getConnection()->createQueryBuilder()
->select('COUNT(src.id)')
->from('(' . $subQuery . ')', 'src')
->setParameters($params)
->execute()
->fetchColumn(0);
}
Fetch
public function findUserCategories(Filter $filter = null, Sort $sort = null, Pagination $pagination = null)
{
return $this->getCategoriesQueryBuilder($filter, $sort, $pagination)->execute()->fetchAll();
}
You can use the original query as subquery to get count.
public function countUserCategories(Filter $filter = null)
{
$querysub = $this->getCategoriesQuery($filter);
$query = $this->getDoctrine()->getConnection()->createQueryBuilder();
$query
->select('COUNT(*)')
->from('(' . $querysub->getSQL() . ')', 'ttt');
$i = 0;
foreach ($querysub->getParameters() as $parameter) {
$query->setParameter($i++, $parameter->getValue(), $parameter->getType());
}
$count = $query->execute()->fetchColumn(0);
return $count;
}
This will work if parameters are set in order with their appearance in query.

Opencart 2 - For guests price with tax for logged in without tax

I need your help, now in Store settings prices with tax!
So it is okey.
But when customer logged in, i need it without tax only on product page and in category.
How can i do this?
Thank you!
Hello #Ivan go to the catalog/controller/product.php and in your public function index() search for the
if ($this->customer->isLogged() || !$this->config->get('config_customer_price')) {
$data['price'] = $this->currency->format($this->tax->calculate($product_info['price'], $product_info['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency']); `
}else {
$data['price'] = false;
}
Change it to :
if ($this->customer->isLogged() || !$this->config->get('config_customer_price')) {
$data['price'] = $this->currency->format($product_info['price'], $this->session->data['currency']);
}else {
$data['price'] = false;
}

Restrict coupon code buy chosen currency in OpenCart

Is it possible to restrict coupon code by chosen currency in OpenCart?
E.g.
Shop had two currency XX and YY. If buyer pick XX currency, Coupon code field is visible in Shopping Cart. In other case (currency YY chosen) not.
OpenCart 2.0.3.1
Yes, Open this file:
catalog/controller/checkout/coupon.php in version 2.0.3.1
find:
if (empty($this->request->post['coupon'])) {
$json['error'] = $this->language->get('error_empty');
unset($this->session->data['coupon']);
} elseif ($coupon_info) {
$this->session->data['coupon'] = $this->request->post['coupon'];
$this->session->data['success'] = $this->language->get('text_success');
$json['redirect'] = $this->url->link('checkout/cart');
} else {
$json['error'] = $this->language->get('error_coupon');
}
change it to:
if (empty($this->request->post['coupon'])) {
$json['error'] = $this->language->get('error_empty');
unset($this->session->data['coupon']);
} elseif ($coupon_info) {
// here I use USD for example
if($this->session->data['currency'] == 'USD'){
$this->session->data['coupon'] = $this->request->post['coupon'];
$this->session->data['success'] = $this->language->get('text_success');
$json['redirect'] = $this->url->link('checkout/cart');
} else {
// Write your custom error message here
$json['error'] = 'This coupon is only available in USD';
unset($this->session->data['coupon']);
}
} else {
$json['error'] = $this->language->get('error_coupon');
}

Regex to validate information (Letter & Number only)

Regex to validate information
I tried the following:
if(preg_match("/[A-Za-z0-9]+/", $ingame_name) == TRUE){
header("Location: newitem.php?username=". $ingame_name ."&email=". $email);
} else {
$invalidusername = '<font color=red>Oops, invalid username! Username
may only contain numbers and letters.</font><br>';
}
Which didn't work, also tried flipping the statements still didn't work...
And my final attempt
if ($_REQUEST['do'] == 'submit')
{
$ingame_name= trim($_POST['ingame_name']);
$email = trim($_POST['email']);
if(eregi("/[A-Za-z0-9]+/", $ingame_name))
{
$invalidusername = '<font color=red>Oops, invalid username! Username may only contain numbers and letters.</font><br>';
$ingame_name = 'invalid';
}
if (eregi("^[a-zA-Z0-9_]+#[a-zA-Z0-9\-]+\.[a-zA-Z0-9\-\.]+$]", $email))
{
$invalidemail = '<font color=red>Oops, seems that you have an error with your email format.</font></br>';
$email = 'invalid';
}
if ( $ingame_name = 'invalid' || $email = 'invalid')
{
/* do nothin */
}
else
{
header("Location: item.php?username=". $ingame_name ."&email=". $email);
}
}
Nothing seems to work,
Try this:
<?php
$valid_submit = ($_REQUEST && isset($_REQUEST['do']) && $_REQUEST['do'] == 'submit') ? true : false;
if ($valid_submit) {
$ingame_name= ($_POST && isset($_POST['ingame_name'])) ? trim($_POST['ingame_name']) : '';
$email= ($_POST && isset($_POST['email'])) ? trim($_POST['email']) : '';
$invalidusername = '';
$invalidemail = '';
if(!preg_match("/^[A-Za-z0-9]+$/", $ingame_name)) {
$invalidusername = '<font color=red>Oops, invalid username! Username may only contain numbers and letters.</font><br>';
$ingame_name = 'invalid';
}
// This is a much more efficient method to validate email addresses
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$invalidemail = '<font color=red>Oops, seems that you have an error with your email format.</font></br>';
$email = 'invalid';
}
if ( $ingame_name != 'invalid' && $email != 'invalid') {
$location = 'item.php?username=' . $ingame_name . '&email=' . $email;
header("Location: $location");
}
else {
//echo $invalidusername . $invalidemail;
}
}