all I found in my search is a programming solution for this.
I know that we can modify /lib/Zend/Locale/Data/en.xml for english stores.
there was in en.xml this part:
<currencyFormats>
<currencyFormatLength>
<currencyFormat>
<pattern>#,##0.00 ¤</pattern>
</currencyFormat>
</currencyFormatLength>
</currencyFormats>
And the price was displaying in this format: 1,321.54
now to remove the decimal part from price I think the only thing I have to do is change en.xml to be like the following:
<currencyFormats>
<currencyFormatLength>
<currencyFormat>
<pattern>#,##0 ¤</pattern>
</currencyFormat>
</currencyFormatLength>
</currencyFormats>
The problem is after this change the prices are show as desired (1,132 Format) but without currency symbol ($).
what I'm missing here??
Thanks in advance.
update
I'm still trying, when pattern node changed to the following
<pattern>¤ #,##0</pattern>
the prices are coming with currency symbol ($ 1,132) but not in desired position O_O, the requirement is to have currency symbol on the right side no left :( SO..
All answers here involve changing the core files. This is NOT what anyone should do. Either you develop a module and make those changes or you leave the core files like that and change the prices with str_replace.
So go into theme/template/catalog/product/price.phtml and (depending on configuration) around line 209 change this:
$_coreHelper->formatPrice($_price, true)
into
$without_decimals = $_coreHelper->formatPrice($_price, true); echo str_replace(".00", "", $without_decimals);
This removes .00 from the price. The good thing is that the prices with other decimals are kept. If you don't want this you can remove everything after the dot and round the number up with round() function.
Depending on configuration other prices might need the change (if you show prices without taxes etc.)
In order to change price precision in magento you would need to overwrite some core files.
In the example below we are changing precision to 0.
1) Overwrite lib/Zend/Currency.php and change precision around line:
69 protected $_options = array(
70 'position' => self::STANDARD,
71 'script' => null,
72 'format' => null,
73 'display' => self::NO_SYMBOL,
74 'precision' => 0, /*CHANGE*/
75 'name' => null,
76 'currency' => null,
77 'symbol' => null,
78 'locale' => null,
79 'value' => 0,
80 'service' => null,
81 'tag' => 'Zend_Locale'
82 );
2) overwrite app/code/core/Mage/Core/Model/Store.php and change roundPrice function:
public function roundPrice($price)
{
return round($price, 4);
}
3) overwrite app/code/core/Mage/Directory/Model/Currency.php and change format function:
public function format($price,
$options=array(),
$includeContainer = true,
$addBrackets = false)
{
return $this->formatPrecision( $price,
4,
$options,
$includeContainer,
$addBrackets);
}
To remove the decimal part from price, you need to modify the file
"code/core/Mage/Directory/Model/Currency.php"
First, instead of the line:
return $this->formatPrecision($price, 2, $options, $includeContainer, $addBrackets);
use:
return $this->formatPrecision($price, 0, $options, $includeContainer, $addBrackets);
To change the position of the currency symbol, modify the file "lib/Zend/Locale/Data/en.xml" with the line:
<pattern>#,##0.00 ¤;(#,##0.00 ¤)</pattern>
When done, don't forget to clear cache.
P.S. To avoid any issues during the upgrade, we strongly recommend you to implement all the above mentioned changes via extensions:
(check the tools here: http://www.magentocommerce.com/magento-connect/catalogsearch/result/?id=&s=7&pl=0&eb=0&hp=0&q=currency|position&t=1&p=1)
To remove the decimal part from price, you need to modify the file:
1) First is to change precision around line
lib/Zend/Currency.php
protected $_options = array(
'position' => self::STANDARD,
'script' => null,
'format' => null,
'display' => self::NO_SYMBOL,
'precision' => 2,
'name' => null,
'currency' => null,
'symbol' => null,
'locale' => null,
'value' => 0,
'service' => null,
'tag' => 'Zend_Locale'
);
Change= 'precision' => 2, to 'precision' => 0,
2) Second file (change roundPrice function:)
app/code/core/Mage/Core/Model/Store.php
public function roundPrice($price)
{
return round($price, 2);
}
To
public function roundPrice($price)
{
return round($price, 0);
}
3) Third and last is to change format function:
app/code/core/Mage/Directory/Model/Currency.php
public function format($price,
$options=array(),
$includeContainer = true,
$addBrackets = false)
{
return $this->formatPrecision( $price,
2,
$options,
$includeContainer,
$addBrackets);
}
TO
public function format($price,
$options=array(),
$includeContainer = true,
$addBrackets = false)
{
return $this->formatPrecision( $price,
0,
$options,
$includeContainer,
$addBrackets);
}
You can do one more change addition to the above all.
Please go to the PriceCurrency.php page
then change the last line to
public function round($price)
{
return round($price, 0);
}
after that in the PriceCurrencyInterface.php page make
const DEFAULT_PRECISION = 0;
at the top.
That's all. Hope it will work.
Related
I want to put a link on an ellipsis in the Paginator. When the pagination has 2 ellipsis's the ellipsis must have different link.
My code is:
echo $this->paginator->numbers(array(
'tag' => 'li',
'separator' => '',
'currentTag' => 'a',
'currentClass' => 'active',
'modulus' => 2,
'first' => 1,
'last' => 1,
'ellipsis' => "<li><a href='#' class='hellip'>...</a></li>"
));
So the result I want to create is:
1 ...(link) 6 7 8 ...(link) 12
In short, the Paginator doesn't support what you want it to do and so your only option is to modify the CakePHP source code. Specifically PaginatorHelper.php
First thing you'll need to do is modify the $defaults variable on line 720, and add leftEllipsis and rightEllipsis fields. This means that we can maintain consistent behavior when we don't set these fields in the $options variable.
$defaults = array('tag' => 'span', 'before' => null, 'after' => null,
'model' => $this->defaultModel(), 'class' => null,'modulus' => '8',
'separator' => ' | ', 'first' => null, 'last' => null, 'ellipsis' => '...',
'currentClass' => 'current', 'currentTag' => null, 'leftEllipsis' => null,
'rightEllipsis' => null);
Probably should unset our two new fields too (lines 735 - 738):
unset($options['tag'], $options['before'], $options['after'], $options['model'],
$options['modulus'], $options['separator'], $options['first'], $options['last'],
$options['ellipsis'], $options['class'], $options['currentClass'], $options['currentTag'],
$options['leftEllipsis'], $options['rightEllipsis']
);
The next bit is a tad tricky because it would be nice to be able to specify one of the ellipsis without the other, and in the absence of either, fallback onto whatever the original ellipsis field was set to. But the developers have used the magical extract and compact functions coupled with the first(...) and last(...) functions depending on certain fields being set in the $options parameter.
After line 756 insert the following code to default the $leftEllipsis to whatever $ellipsis is set to:
if(isempty($leftEllipsis)) {
$leftEllipsis = $ellipsis;
}
Next we need to modify what gets passed as the $options parameter to the first(...) function on lines 758 - 761.
if ($offset < $start - 1) {
$out .= $this->first($offset, compact('tag', 'separator', 'class') + array('ellipsis' => $leftEllipsis));
} else {
$out .= $this->first($offset, compact('tag', 'separator', 'class') + array('after' => $separator, 'ellipsis' => $leftEllipsis));
}
You can use this pattern to attack the right ellipsis too.
The proper way to do this is to fork the project on GitHub, make the changes to your version of the code base and create a pull request so you give the developers a chance to integrate your feature into the mainline. This way everyone can benefit from your work!
Good luck!
I am looking into writing a PHP function that uses a convenient method/formula to calculate the dimensions of i.e. a parcel/pallet loaded with items.
Here is an example of an array with items. Note: Some items are flagged to be sent as separate parcels. Some items may not be tilted.
$items = array(
1 => array(
'quantity' => 1,
'weight' = 1,
'dimensions' => array(80, 50, 50), // Length, Width, Height
'separate' => true, // If the item should be sent as a separate package
'tiltable' => false, // False if the item has a 'this side up' sticker
),
2 => array(
'quantity' => 3,
'weight' = 1,
'dimensions' => array(21, 15, 10),
'separate' => false,
'tiltable' => true,
),
3 => array(
'quantity' => 2,
'weight' = 1,
'dimensions' => array(18, 19, 20),
'separate' => false,
'tiltable' => true,
),
// ... and so on ...
);
Does anyone have the slightest bit of knowledge or experience from doing this? I don't want to reinvent the wheel.
The function I have in mind is something like this:
* (Syntax errors may occur) *
function build_packages($items, $max_weight=0, $max_length=0, $max_width=0, $max_height=0) {
$packages = array();
// Step through each item
foreach ($items as $item) {
// Twist and turn item. Longest side first ([0]=length, [1]=width, [2]=height)
if (!empty($item['tiltable'])) {
rsort($item['dimensions'], SORT_NUMERIC);
} else {
if ($item['dimensions'][0] < $item['dimensions'][1]) {
$item['dimensions'] = array($item['dimensions'][1], $item['dimensions'][0], $item['dimensions'][2]);
}
}
// Validate item
if (!empty($max_weight) && $item['weight'] > $max_weight) return false;
if (!empty($max_length) && $item[0] > $max_length) return false;
if (!empty($max_width) && $item[1] > $max_width) return false;
if (!empty($max_height) && $item[2] > $max_height) return false;
// Step through quantities
for ($i=0; $i<$item['quantity']; $i++) {
// Step through packages
$package_found = false;
foreach (array_keys($packages) as $key) {
// Skip to next package on certain conditions
if ($packages[$key]['separate']) continue;
// ...
// Do some logic
// ...
// Modify package
$package_found = true;
$packages[$key]['num_items']++;
$packages[$key]['weight'] += $item['weight'];
$packages[$key]['dimensions'] = array(0, 0, 0); // <--- Replace with new dimensions
// Twist and turn package. Longest side first ([0]=length, [1]=width, [2]=height)
if (!empty($item['tiltable'])) {
rsort($packages[$key]['dimensions'], SORT_NUMERIC);
} else {
if ($packages[$key]['dimensions'][0] < $packages[$key]['dimensions'][1]) {
$packages[$key]['dimensions'] = array($packages[$key]['dimensions'][1], $packages[$key]['dimensions'][0], $packages[$key]['dimensions'][2]);
}
}
break;
}
if ($package_found) continue;
// Add to a new package
$packages[] = array(
'num_items' => 1,
'weight' => $item['weight'],
'dimensions' => $item['dimensions'],
'separate' => $item['separate'],
'tiltable' => $item['tiltable'],
);
}
}
return $packages;
}
Care to help out with some code?
What you are after is a solution to the Bin Packing problem. The solution is NP Hard so you may want to find a "good enough" solution, rather than the optimal solution. A google search turned up this: One Dimensional Bin Packing class. I did not look at the code, so I am not sure how good it is, but I suggest it as a place to at least start your investigation. If it turns out to be good enough for one dimensional problems, perhaps you can create a solution creating multiple 1 dimensional layouts and keep track of each row's max height, therefor knowing whether you have exceeded the total package height.
Hope this helps.
I found this Package https://github.com/dvdoug/BoxPacker and this service https://3dbinpacking.com/ so far that does this for you.
I have created and successfully created my pdf file in php with fpdf
library support.
But the problem is my footer is showing more space.
I want to reduce the space underneath my text. My output is like
this:
Here my code goes:
<?php
require('fpdf/fpdf.php');
class PDF extends FPDF {
function Header() {
$this->SetY(0.208333);
}
function Footer() {
if ($this->footer <> 1)
{
$this->SetY(-15);
}
else
{
echo "bye";
}
}
}
//class instantiation
$pdf=new PDF("l","in",array(8.5,4.17));
$pdf->SetFont('Arial','',8);
$pdf->footer = -15;
//Array2
$datas = array
(
'Address1' => array
(
'Name' => 'Vijaya',
'Area' => 'Valasaravakkam',
'City' => 'Chennai',
),
'Address2' => array
(
'Companyname' => 'Vy Systems',
'Area' => 'Valasaravakkam',
'City' => 'Chennai',
),
'Address3' => array
(
'Companyname' => 'Vy Systems1',
'Area' => 'Valasaravakkam1',
'City' => 'Chennai1',
),
);
//Array2
$datas1 = array
(
'Address4' => array
(
'Name' => 'Jaya',
'Area' => 'Valasaravakkam',
'City' => 'Chennai',
),
);
foreach($datas1 as $address1 => $details1)
{
//pdf_set_text_pos($pdf, 1240, 490);
//$pdf->ln(1);
foreach($datas as $address => $details)
{
$pdf->SetMargins(0,0,0.3);
$pdf->AddPage();
if((is_array($details)) and (is_array($details1)))
{
foreach($details1 as $rows1 => $value1)
{
$pdf->SetX(0.520833);
$pdf->MultiCell(0, 0.2, $value1, 0, "L");
}
$pdf->ln(1.96);
foreach($details as $rows => $value)
{
$pdf->SetX(5);
$pdf->MultiCell(5, 0.2, $value, 0, "L");
}
}
}//end of sub foreach
}//end of main foreach
$pdf->Output();
?>
I didn't follow the code completely, but it seems you're using the Header and Footer methods to set Y and nothing more, expecting that to be enough to correctly position the MultiCells being output outside of the Header and Footer. Maybe so, but the interaction of positioning inside and outside the Header/Footer isn't well defined.
For example, the process may be something like this: Y is calculated for the MultiCell, that trips the footer, the footer changes Y, the MultiCell is output. Is this the original Y, the revised (by the footer Y), or some other value? Absent a precise definition of what happens, you've set up a complex sequence of things that would be very difficult to sort out.
I would suggest vastly simplifying the code. You may find that the automatic header/footer tripping isn't helpful at all. In that case, turn off the auto page break, get rid of the Footer/Header functions, and totally control each page yourself. That way at least you have a clear, reliable model of what's going on.
I'm editing my invoices file in
/Mage/Sales/Model/Order/Pdf/Items/Invoice/Default.php
And I'm running into a problem with columns running into and overlapping other columns if they have long content. eg Product description running over the next column. I'm trying to figure out how to limit the width / word wrap / create a new line for content.
Code is:
// draw Product name
$lines[0] = array(array(
'text' => Mage::helper('core/string')->str_split($item->getName(), 60, true, true),
'feed' => 35,
));
// draw SKU
// $lines[0][] = array(
// 'text' => Mage::helper('core/string')->str_split($this->getSku($item), 25),
// 'feed' => 255
// );
// draw Brand (Added by James)
$product = Mage::getModel('catalog/product')->loadByAttribute('sku', $this->getSku($item), array('manufacturer'));
if ($product) {
$lines[0][] = array(
'text' => Mage::helper('core/string')->str_split($product->getAttributeText('manufacturer'), 15),
'feed' => 220
);
}
// draw Colour (Added by James)
$product = Mage::getModel('catalog/product')->loadByAttribute('sku', $this->getSku($item), array('pos_short_colour'));
if ($product) {
$lines[0][] = array(
'text' => Mage::helper('core/string')->str_split($product->getAttributeText('pos_short_colour'), 15),
'feed' => 320
);
}
I know that 'feed' is what sets how far in from the left the array starts (pretty much = to a margin-left if all items were 'absolute' in css terms).
But I'm not sure how I can limit their width and word-wrap so that if I have a long manufacturer it won't run into the colour. There isn't enough space on the invoice to just simply give each attribute more room.
The answer was right there:
$lines[0] = array(array(
'text' => Mage::helper('core/string')->str_split($item->getName(), 60, true, true),
'feed' => 35,
));
The 60 here is how many characters will be displayed per line ->getName(), 60, true,
I had the same issue. When I added a new column, Product description column disappeared. I solved this by reducing a number (length) in str_split function of $productDescr.
I have the following values from a database call that I want to apply some logic to. I thought I could originally use PHP's max however this doesn't appear to be the case.
I have three suppliers of a product. They might not all stock the item I am displaying, and they all offer a different margin, on a product by product basis though, so that is why I can't just say generally supplier 1 is better than supplier 2 etc.
$supplier1Live = 1
$supplier2Live = 1
$supplier3Live = 0
$marginSupplier1 = 20
$marginSupplier2 = 40
$martinSupplier3 = 50
In this example I would want to use Supplier 2 as they stock the product supplier2Live = 1 and also have the better margin than the other supplier who stocks the product (supplier1)
My mind however is drawing a complete blank in how to code this?
I thought I could add it to an array giving:
$array = array(
"supplier1" => array(
"live" => 1,
"margin" => 20
),
"supplier2" => array(
"live" => 1,
"margin" => 40
),
"supplier3" => array(
"live" => 0,
"margin" => 50
)
);
And run something on that, but not sure what to.
Filter the array using array_filter (filter by live==1), and then find the maximum out of the resultant array (maximum on the "margin" value)
Like this, if I understand correctly
$array = array(
"supplier1" => array(
"live" => 1,
"margin" => 20
),
"supplier2" => array(
"live" => 1,
"margin" => 40
),
"supplier3" => array(
"live" => 0,
"margin" => 50
)
);
$res = array_filter($array,function($v){return $v["live"];});
$supplier = array_reduce($res, function($a, $b){
return $a["margin"]>$b["margin"]?$a:$b;
});
print_r($supplier);
Try something like this:
$best_supplier = null;
$best_supplier_margin = null;
foreach($array as $name => $supplier) {
if($supplier['live']) {
if($supplier['margin'] > $best_supplier_margin || is_null($best_supplier_margin)) {
$best_supplier = $name;
$best_supplier_margin = $supplier['margin'];
}
}
}
if(is_null($best_supplier)) throw new Exception('No suppliers are live!');
echo $best_supplier;
So you basically want to find the max of supplierXLive * marginSupplierX?
You can also implement a custom compare function and provide it to PHPs usort() function