Max shipping cost - prestashop

How do I set the maximum shipment amount per 199 in PrestaShop 1.7?
It may be smaller, but it may not exceed 199.
In which file do I look for the variable corresponding to the amount of the shipment?

Override function getPackageShippingCost() from Cart class:
class Cart extends CartCore
{
public function getPackageShippingCost($id_carrier = null, $use_tax = true, Country $default_country = null, $product_list = null, $id_zone = null)
{
$shipping_cost = parent::getPackageShippingCost($id_carrier, $use_tax, $default_country, $product_list, $id_zone);
if ($shipping_cost > 199) {
return 199;
}
}
}
Remember to remove class_index.php and clear cache.

Related

Function to increase price by 20% only if price is less than $20

I'm wondering if someone can help with a function for WP All Import to increase prices only if the price is less than $20. Perhaps my question is how to set up variables? price1(actual price)?
$price1 = "{Cost[1]}";
$price2 = "20"
$price3 = "$price1 + 20%";
function choose_price_to_return ($price1, $price2) {
if ($price1 < $price2) {
return $price3;
} else {
return $price1;
}
}

Prestashop 1.7 check available stock at final order step

I had something working on Prestashop 1.6 to check cart quantities before the customer can buy. Here is my problem on Prestashop 1.7 :
If a customer put an item in his cart today, he comes back in 2 days and he is still logged in. The cart is still available while the product, in reality, became out of stock.
The customer can make the order and the quantity in my stock is -1. Since I upgraded to prestashop 1.7 it's a disaster, I have quantities at -5, -10...because if this non-checked scenario.
abstract class PaymentModule extends PaymentModuleCore
{
public function validateOrder($id_cart, $id_order_state, $amount_paid, $payment_method = 'Unknown',
$message = null, $extra_vars = array(), $currency_special = null, $dont_touch_amount = false,
$secure_key = false, Shop $shop = null)
{
if (!isset($this->context))
$this->context = Context::getContext();
$this->context->cart = new Cart($id_cart);
if (!$this->context->cart->checkQuantities()){
Tools::redirect(__PS_BASE_URI__.'order.php?step=0');
}
return parent::validateOrder($id_cart, $id_order_state, $amount_paid, $payment_method, $message,
$extra_vars, $currency_special, $dont_touch_amount, $secure_key, $shop);
}
}
Actually the best solution is to use this addons : https://addons.prestashop.com/en/stock-supplier-management/21707-temporary-product-reservation-lonely-stock.html
Prestashop handles really bad cart stocks.
Anyway if you want to do it yourself and check stock available it's pretty simple :
<?php
$cart = $this->context->cart;
$cart_products = $cart->getProducts();
if (!empty($cart_products)) {
$db = Db::getInstance();
foreach ($cart_products as $key => $cart_product) {
$real_quantity = StockAvailable::getQuantityAvailableByProduct($cart_product['id_product'], $cart_product['id_product_attribute']);
if ( (int) $real_quantity < (int) $cart_product['quantity'] ) {
// If negative
$real_quantity = (int) $real_quantity < 0 ? 0 : $real_quantity;
$sql = '
UPDATE `'._DB_PREFIX_.'cart_product`
SET quantity = '.(int) $real_quantity.',`date_add` = NOW()
WHERE `id_product` = '.(int) $cart_product['id_product'].
(!empty($cart_product['id_product_attribute']) ? ' AND `id_product_attribute` = '.(int) $cart_product['id_product_attribute'] : '').'
AND `id_cart` = '.(int) $cart->id;
$db->execute($sql);
}
}
// Garbage collector
$db->execute('DELETE FROM '._DB_PREFIX_.'cart_product WHERE quantity < 1 ');
}

What is bloomberg's response when one of a few fields is not found?

I have a Java code that uses blpapi to request specific fields of specific securities. My code runs fine now. However, I have thought of a case that is not being handled by my current code.
Say, for example, I am requesting 'CUR_MKT_CAP', 'PX_LAST', and 'EQY_SH_OUT' for a specific security. What if Bloomberg does not have the value for 'PX_LAST'? What will Bloomberg give me then?
(a) Will it give me a field Element where PX_LAST = 0?
(b) Will it give me a field Element where PX_LAST = NULL?
(c) Will it not include PX_LAST to the response that I will receive? Thus, the response will look like this?
HistoricalDataResponse (choice) = {
securityData = {
security = XXXXX Equity
sequenceNumber = 0
fieldData[] = {
fieldData = {
date = YYYY-MM-DD
CUR_MKT_CAP = XX.XXXX
EQY_SH_OUT = XX.XXXX
}
}
} }
Basically, I just want to know how I should handle if one of the fields I need is not given by Bloomberg.
You are correct, if a field returns no data, it will be omitted from the fieldData element. If none of the fields returns data, the fieldData will be empty:
ReferenceDataResponse = {
securityData[] = {
securityData = {
security = "MSFT US Equity"
eidData[] = {
}
fieldExceptions[] = {
}
sequenceNumber = 0
fieldData = {
}
}
}
}
You can easily test this, for example using MSFT US Equity / YAS_BOND_YLD.
I tested it using #assylias's answer. It gave me the following results.
MSFT US Equity
HistoricalDataResponse (choice) = {
securityData = {
security = MSFT US Equity
sequenceNumber = 0
}
}
YAS_BOND_YLD
HistoricalDataResponse (choice) = {
securityData = {
security = YAS_BOND_YLD
sequenceNumber = 0
securityError = {
source = 500::bbdbh5
code = 15
category = BAD_SEC
message = Unknown/Invalid securityInvalid Security [nid:500]
subcategory = INVALID_SECURITY
}
}
}
As per #assylias comment, I used YAS_BOND_YLD as a field. And blpapi returned the following as a response.
My input to the request:
Ticker: XXX XX Equity Start/End Date: 20160818 Fields: CUR_MKT_CAP YAS_BOND_YLD PX_LAST EQY_SH_OUT
BLPAPI's response is,
HistoricalDataResponse (choice) = {
securityData = {
security = XXX XX Equity
sequenceNumber = 0
fieldData[] = {
fieldData = {
date = 2016-08-18
CUR_MKT_CAP = 117.7144
PX_LAST = 1.06
EQY_SH_OUT = 111.051
}
}
}
}
Note: I changed the ticker to XXX XX on purpose. =D

Sku not working in magento product update API

$result = $client->call($session, 'catalog_product.update', array('123', array(
'name' => 'Product333222'
)
)
);
Here '123' is the Sku of product. Sku is not working here in update Api.
If i give Product ID in place of Sku it is working fine.
So what is the Issue behind that.
If anyone Knows please let me know.
Thanks.
Magento is a bit dull here.
Long story short:
If you are using a numeric value without specifying an identification type its assuming you are doing your works on a product id. If you where to insert "abc" as a value (not numeric) it will be treated as if it were a SKU.
Best way to solve this is to use an identification type (in your case "SKU") in your api call.
Please see this for more info on using the identification type. http://www.magentocommerce.com/api/soap/catalog/catalogProduct/catalog_product.update.html
Or see: Magento 1.5, numeric SKUs and productIdentifierType
Short story long:
The following function gets called trough the api
app/code/core/Mage/Catalog/Model/Api/Resource.php
protected function _getProduct($productId, $store = null, $identifierType = null)
{
$product = Mage::helper('catalog/product')->getProduct($productId, $this->_getStoreId($store), $identifierType);
if (is_null($product->getId())) {
$this->_fault('product_not_exists');
}
return $product;
}
As you can see that function is calling the following function in the product helper:
public function getProduct($productId, $store, $identifierType = null) {
$loadByIdOnFalse = false;
if ($identifierType == null) {
if (is_string($productId) && !preg_match("/^[+-]?[1-9][0-9]*$|^0$/", $productId)) {
$identifierType = 'sku';
$loadByIdOnFalse = true;
} else {
$identifierType = 'id';
}
}
/** #var $product Mage_Catalog_Model_Product */
$product = Mage::getModel('catalog/product');
if ($store !== null) {
$product->setStoreId($store);
}
if ($identifierType == 'sku') {
$idBySku = $product->getIdBySku($productId);
if ($idBySku) {
$productId = $idBySku;
}
if ($loadByIdOnFalse) {
$identifierType = 'id';
}
}
if ($identifierType == 'id' && is_numeric($productId)) {
$productId = !is_float($productId) ? (int) $productId : 0;
$product->load($productId);
}
return $product;
}
Without specifying an $identifierType here and using a sku like '123' the thrid line is going to do a preg match with will result in true. Thus using its else function threating it as an ID in stead of sku.
In the end:
So, do your call like:
$result = $client->call($session, 'catalog_product.update', array('123', array(
'name' => 'Product333222'
), null, 'sku'));

When is a groupby query evaluated in RavenDB?

I'm struggling with the behaviour of grouping using RavenDB and LuceneQuery.
I was always under the impression that IEnumerable was only evaluated when calling ToArray(), etc.
The following query was split into two parts for the sake of clarity.
I would not expect the query to be evaluated until after ToArray() is called on totalledBalanceList, my expectation being that the grouping is done on the server across all of the data. However, the actual result depends on the number of items stipulated in .Take(). Without the Take(1024), the results come back for the default 128 items.
I need to be able to perform the grouping across the entire dataset.
using (var session = MvcApplication.RavenSession)
{
var computedBalanceList =
from c in session.Advanced.LuceneQuery<Journal, Ledger_ByDateAndDebitIdAndCreditIdAndValues>()
.Where(parameters)
.OrderBy(c => c.DateAsString).Take(1024)
select new LedgerBalanceDto
{
Account = account,
Name = queryName,
Debits = c.DebitId == account.Id
? c.DebitValue
: 0,
Credits = (c.CreditId == account.Id)
? c.CreditValue
: 0,
Currency = (c.DebitId == account.Id) ? c.DebitCurrency : c.CreditCurrency,
CurrencySymbol = (c.DebitId == account.Id) ? c.DebitCurrencySymbol : c.CreditCurrencySymbol,
};
var totalledBalanceList =
from balance in computedBalanceList
group new {balance.Debits, balance.Credits} by new {balance.Currency, balance.CurrencySymbol}
into grouping
select new LedgerBalanceDto
{
Account = account,
Currency = grouping.Key.Currency,
CurrencySymbol = grouping.Key.CurrencySymbol,
Debits = grouping.Sum(c => c.Debits),
Credits = grouping.Sum(c => c.Credits),
Name = queryName
};
return totalledBalanceList;
And the index:
public class Ledger_ByDateAndDebitIdAndCreditIdAndValues:AbstractIndexCreationTask<Journal>
{
public Ledger_ByDateAndDebitIdAndCreditIdAndValues()
{
Map = journals => from c in journals
select new {c.Date,c.DateAsString, c.DebitId, c.CreditId,c.DebitValue,c.CreditValue};
Index(x=>x.Date,FieldIndexing.Analyzed);
Index(x=>x.DateAsString,FieldIndexing.Analyzed);
Index(x=>x.DebitId,FieldIndexing.Analyzed);
Index(x=>x.CreditId,FieldIndexing.Analyzed);
Index(x=>x.DebitValue,FieldIndexing.Analyzed);
Index(x=>x.CreditValue,FieldIndexing.Analyzed);
Sort(x=>x.DateAsString,SortOptions.String);
}
}
I've also rewritten the query so that the grouping happens "outside" the filter, but I get exactly the same results, namely the result depends on the Take().
var totalledBalanceList = from balance in
from c in query
.Where(parameters)
.OrderBy(c => c.DateAsString)
select new LedgerBalanceDto
{
Account = account,
Name = queryName,
Debits = c.DebitId == account.Id
? c.DebitValue
: 0,
Credits = (c.CreditId == account.Id)
? c.CreditValue
: 0,
Currency = (c.DebitId == account.Id) ? c.DebitCurrency : c.CreditCurrency,
CurrencySymbol = (c.DebitId == account.Id) ? c.DebitCurrencySymbol : c.CreditCurrencySymbol,
}
group new {balance.Debits, balance.Credits} by new {balance.Currency, balance.CurrencySymbol}
into grouping
select new LedgerBalanceDto
{
Account = account,
Currency = grouping.Key.Currency,
CurrencySymbol = grouping.Key.CurrencySymbol,
Debits = grouping.Sum(c => c.Debits),
Credits = grouping.Sum(c => c.Credits),
Name = queryName
};
return totalledBalanceList;
Any thoughts on this would be much appreciated.
Part of the Journal class:
public class Journal
{
public string Id { get; set; }
public string DebitId{get;set;}
public string CreditId{get;set;}
public decimal? ExchangeRate { get; set; }
public decimal CreditValue {get;set;}
public decimal DebitValue {get;set;}
public string DebitCurrency {get;set;}
public string CreditCurrency {get;set;}
public decimal Nett
{
get { return _nett; }
set
{
_nett = value;
CreditValue = Math.Round(Nett, 2);
DebitValue = Math.Round(Nett * (ExchangeRate ?? 1), 2);
}
}
etc ...
}
Example data IEnumerable<Journal>:
Id DebitId CreditId Nett ExchangeRate DbCurr CrCurr DbVal CrVal
1 Expense1 Bank 100 2.03 BRL USD 203.00 100.00
2 Expense2 Bank 50 null USD USD 50.00 50.00
3 Bank Client1 300 null USD USD 300.00 300.00
4 Stock Bank 300 null USD USD 300.00 300.00
For example, when I query for the Bank, I want to be able to sum the DbVal and CrVal and calculate the balance, but in order to do so, I have to zero either one or the other (as per the query).
You are mixing LINQ and Lucene query here, and that means they will be evaluated on the client.
You need to move a lot of this into an index and query that using session.Query, not session.Advanced.LuceneQuery.