1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10:
11:
12: 13: 14:
15: class IllApps_Shipsync_Model_Shipping_Package
16: {
17:
18:
19: protected $_packageError;
20: protected $_packageCollection;
21:
22:
23:
24: 25: 26: 27: 28: 29:
30: public function getDefaultPackages($carriers = null)
31: {
32:
33: $mergedPackages = array_merge($this->getSpecialPackage(),
34: $this->getShipsyncPackages(),
35: $this->getCarrierPackages($carriers)
36: );
37:
38: $sortedPackages = Mage::getModel('shipsync/shipping_package_sort')->sortByKey('max_weight', $mergedPackages);
39:
40: foreach ($sortedPackages as $key => $package) {
41: $package['value'] = $key;
42: $package['items'] = null;
43: $defaultPackages[] = $package;
44: }
45:
46: return $defaultPackages;
47: }
48:
49:
50:
51: 52: 53: 54: 55: 56:
57: public function getCarrierPackages($carriers)
58: {
59: $carrierPackages = array();
60:
61:
62: if (is_array($carriers)) {
63:
64:
65: foreach ($carriers as $carrier) {
66: if ($carrier == 'fedex') {
67: if ($fedexPackages = Mage::getModel('usa/shipping_carrier_fedex')->getPackages()) {
68: $carrierPackages = array_merge($fedexPackages, $carrierPackages);
69: }
70: }
71: }
72: }
73:
74: return $carrierPackages;
75: }
76:
77:
78:
79:
80: 81: 82: 83: 84:
85: public function getSpecialPackage()
86: {
87:
88: return array(
89: 'SPECIAL_PACKAGE' => array(
90: 'label' => Mage::helper('usa')->__('Special Packaging'),
91: 'length' => null,
92: 'width' => null,
93: 'height' => null,
94: 'max_weight' => null,
95: 'max_volume' => null,
96: 'baseline' => null
97: )
98: );
99: }
100:
101:
102:
103: 104: 105: 106: 107:
108: public function getShipsyncPackages()
109: {
110:
111: $shipsyncPackages = array();
112:
113:
114: for ($i = 1; $i <= 20; $i++) {
115:
116: if (Mage::getStoreConfig('shipping/packages/pkg' . $i . 'enabled')) {
117: $label = Mage::getStoreConfig('shipping/packages/pkg' . $i . 'title');
118: $length = Mage::getStoreConfig('shipping/packages/pkg' . $i . 'length');
119: $width = Mage::getStoreConfig('shipping/packages/pkg' . $i . 'width');
120: $height = Mage::getStoreConfig('shipping/packages/pkg' . $i . 'height');
121: $base = Mage::getStoreConfig('shipping/packages/pkg' . $i . 'base');
122: $max_weight = Mage::getStoreConfig('shipping/packages/pkg' . $i . 'weight');
123:
124: $max_volume = ($length * $width * $height);
125:
126:
127: $shipsyncPackages["SHIPSYNC_PKG_$i"] = array(
128: 'label' => $label,
129: 'length' => $length,
130: 'width' => $width,
131: 'height' => $height,
132: 'max_weight' => $max_weight,
133: 'max_volume' => $max_volume,
134: 'baseline' => $base
135: );
136: }
137: }
138:
139:
140: return $shipsyncPackages;
141: }
142:
143:
144:
145: 146: 147: 148: 149: 150: 151:
152: public function getParsedItems($items, $toShip = false)
153: {
154: return Mage::getModel('shipsync/shipping_package_item')->getParsedItems($items, $toShip);
155: }
156:
157:
158:
159: 160: 161: 162: 163: 164: 165:
166: public function estimatePackages($itemsToShip, $defaultPackages)
167: {
168: $i = 0;
169: $s = 0;
170:
171:
172: unset($defaultPackages['SPECIAL_PACKAGE']);
173:
174: $_items = $this->collectPackages($itemsToShip, $specialPackages, $s);
175:
176: if (!empty($_items)) {
177: foreach ($_items as $alt => $items) {
178:
179: foreach ($items as $key => $item) {
180:
181: if (!isset($item['dimensions']) || $item['dimensions'] == null) {
182:
183: $item['volume'] = 0;
184: }
185:
186:
187: if (!isset($packages[$i]['weight'])) {
188:
189: $packages[$i]['volume'] = 0;
190:
191:
192: $this->initPackage($defaultPackages, $packages, $item, $i, true);
193: }
194:
195:
196: else {
197: $key = Mage::getModel('shipsync/shipping_package_sort')->findBestFit($packages, $item);
198:
199: if (isset($key)) {
200: $packages[$key]['items'][] = $item;
201: $packages[$key]['weight'] += $item['weight'];
202: $packages[$key]['volume'] += $item['volume'];
203: $packages[$key]['free_weight'] = $packages[$key]['free_weight'] - $item['weight'];
204: $packages[$key]['free_volume'] = $packages[$key]['free_volume'] - $item['volume'];
205: } else {
206: $i++;
207:
208: $this->initPackage($defaultPackages, $packages, $item, $i);
209: }
210: }
211: }
212:
213: $count = (isset($_packages)) ? count($_packages) : 0;
214:
215: foreach ($packages as $key => $package) {
216: $package['alt_origin'] = $alt;
217: $_packages[$key + $count] = $package;
218: }
219: unset($packages);
220: }
221: }
222:
223: if (isset($_packages)) {
224: $this->optimizePackages($defaultPackages, $_packages);
225: }
226:
227: if (isset($specialPackages) && is_array($specialPackages)) {
228: foreach ($specialPackages as $specialPackage) {
229: $_packages[] = $specialPackage;
230: }
231: }
232:
233: $this->setPackageOrigin($_packages);
234:
235: return $_packages;
236: }
237:
238:
239:
240: 241: 242: 243: 244: 245:
246: public function optimizePackages($defaultPackages, &$packages)
247: {
248: $sort = Mage::getModel('shipsync/shipping_package_sort');
249:
250: foreach ($defaultPackages as $key => $defaultPackage)
251: {
252: if ($defaultPackage['value'] == 'SPECIAL_PACKAGE') { unset($defaultPackages[$key]); break;}
253: $free_weights[] = $defaultPackage['max_weight'];
254: $free_volumes[] = $defaultPackage['max_volume'];
255: $longest_side[] = $sort->getPackageLongestSide($defaultPackage);
256: }
257:
258: foreach ($packages as $key => &$package)
259: {
260: $i = 0;
261:
262: $package['max_dim'] = $sort->getItemLongestSide($package['items']);
263:
264: while ($i < count($free_weights))
265: {
266: if (isset($package['weight']) && isset($package['volume'])
267: && $package['weight'] < $free_weights[$i]
268: && $package['volume'] < $free_volumes[$i]
269: && $sort->dimensionCheck($longest_side[$i], $package['max_dim'])
270: || isset($package['weight'])
271: && !isset($package['volume'])
272: && $package['weight'] < $free_weights[$i])
273: {
274: $j = $i;
275:
276: $packages[$key]['value'] = $defaultPackages[$j]['value'];
277: $packages[$key]['label'] = $defaultPackages[$j]['label'];
278: $packages[$key]['max_weight'] = $defaultPackages[$j]['max_weight'];
279: $packages[$key]['max_volume'] = $defaultPackages[$j]['max_volume'];
280: $packages[$key]['length'] = $defaultPackages[$j]['length'];
281: $packages[$key]['width'] = $defaultPackages[$j]['width'];
282: $packages[$key]['height'] = $defaultPackages[$j]['height'];
283: $packages[$key]['free_weight'] = $defaultPackages[$j]['max_weight'] - $package['weight'];
284: $packages[$key]['free_volume'] = $defaultPackages[$j]['max_volume'] - $package['volume'];
285: $packages[$key]['baseline'] = $defaultPackages[$j]['baseline'];
286: }
287:
288: $i++;
289: }
290: if(isset($package['weight']) && isset($package['baseline'])) { $package['weight'] = $package['weight'] + $package['baseline']; }
291: }
292: }
293:
294:
295: 296: 297: 298: 299: 300: 301: 302: 303: 304: 305:
306: public function initPackage(&$defaultPackages, &$packages, $item, $i, $init = false)
307: {
308: $packageFit = false;
309:
310: foreach ($defaultPackages as $key => &$defaultPackage) {
311: if ($init) {
312: $defaultPackage['free_weight'] = $defaultPackage['max_weight'] - $defaultPackage['baseline'];
313: $defaultPackage['free_volume'] = $defaultPackage['max_volume'];
314: }
315:
316: if (Mage::getModel('shipsync/shipping_package_sort')->findFit($defaultPackage, $item)) {
317: $packages[$i]['free_weight'] = $defaultPackage['free_weight'];
318: $packages[$i]['free_volume'] = $defaultPackage['free_volume'];
319:
320: $this->setPackage($defaultPackage, $packages, $item, $i);
321: $packageFit = true;
322: break;
323: }
324: }
325: if (!$packageFit) {
326: $this->_packageError = 'There are no configured packages large enough to ship this item.
327: Please contact the store administrator.';
328: }
329: }
330:
331:
332:
333: 334: 335: 336: 337: 338: 339: 340: 341:
342: public function setSpecial(&$specialPackages, &$item, &$s)
343: {
344: $specialPackages[$s]['value'] = 'SPECIAL_PACKAGE';
345: $specialPackages[$s]['label'] = Mage::Helper('usa')->__('Special Packaging');
346:
347: $specialPackages[$s]['items'][0] = $item;
348: $specialPackages[$s]['weight'] = $item['weight'];
349: $specialPackages[$s]['alt_origin'] = $item['alt_origin'];
350:
351:
352: if ($item['dimensions']) {
353: $specialPackages[$s]['length'] = $item['length'];
354: $specialPackages[$s]['width'] = $item['width'];
355: $specialPackages[$s]['height'] = $item['height'];
356: $specialPackages[$s]['volume'] = $item['volume'];
357: } else {
358: $specialPackages[$s]['length'] = null;
359: $specialPackages[$s]['width'] = null;
360: $specialPackages[$s]['height'] = null;
361: $specialPackages[$s]['volume'] = null;
362: }
363:
364:
365: $s++;
366: }
367:
368: 369: 370: 371: 372: 373: 374: 375: 376: 377:
378: public function setPackage($defaultPackage, &$packages, $item, $i)
379: {
380: $packages[$i]['value'] = $defaultPackage['value'];
381: $packages[$i]['label'] = $defaultPackage['label'];
382: $packages[$i]['max_weight'] = $defaultPackage['max_weight'];
383: $packages[$i]['max_volume'] = $defaultPackage['max_volume'];
384: $packages[$i]['items'][] = $item;
385: $packages[$i]['weight'] = $item['weight'] + $defaultPackage['baseline'];
386: $packages[$i]['length'] = $defaultPackage['length'];
387: $packages[$i]['width'] = $defaultPackage['width'];
388: $packages[$i]['height'] = $defaultPackage['height'];
389: $packages[$i]['free_weight'] = $packages[$i]['free_weight'] - $item['weight'];
390: $packages[$i]['free_volume'] = $packages[$i]['free_volume'] - $item['volume'];
391:
392: if (isset($item['dimensions'])) {
393: $packages[$i]['volume'] = +$item['volume'];
394: } else {
395: $packages[$i]['volume'] = 0;
396: }
397: }
398:
399:
400:
401: 402: 403: 404: 405: 406: 407:
408: public function asRange($items, $field)
409: {
410: $previous = $items[0][$field];
411:
412: $ret = '';
413:
414: $new = true;
415:
416: foreach ($items as $key => $item) {
417: if ($new) {
418: $ret = $ret . $previous;
419: $previous = $item[$field];
420: $new = false;
421: } elseif ($key + 1 == count($items)) {
422: if ($item[$field] != $previous + 1) {
423: $ret = $ret . ',' . $item[$field];
424: } else {
425: $ret = $ret . $item[$field];
426: $previous = $item[$field];
427: }
428: } elseif ($item[$field] == $previous + 1) {
429: $ret = $ret . '-';
430:
431: $previous = $item[$field];
432: } elseif ($item[$field] != $previous + 1) {
433: $ret = $ret . $previous . ',';
434: $previous = $item[$field];
435: $new = true;
436: }
437: }
438: return preg_replace('/[\-]+/u', '-', $ret);
439: }
440:
441: public function setPackageOrigin(&$packages)
442: {
443:
444: $origCountry = Mage::getStoreConfig('shipping/origin/country_id');
445: $origRegionCode = Mage::getModel('directory/region')->load(Mage::getStoreConfig('shipping/origin/region_id'))->getCode();
446:
447: $package['country'] = $origCountry;
448: $package['region'] = (strlen($origRegionCode) > 2) ? '' : $origRegionCode;
449: $package['postcode'] = Mage::getStoreConfig('shipping/origin/postcode');
450: $package['city'] = Mage::getStoreConfig('shipping/origin/city');
451: $package['address1'] = Mage::getStoreConfig('shipping/origin/address1');
452: if (Mage::getStoreConfig('shipping/origin/address2') != '') {
453: $package['address2'] = Mage::getStoreConfig('shipping/origin/address2');
454: }
455: if (Mage::getStoreConfig('shipping/origin/address3') != '') {
456: $package['address3'] = Mage::getStoreConfig('shipping/origin/address3');
457: }
458:
459: }
460:
461:
462:
463: 464: 465: 466: 467:
468: public function getPackageError()
469: {
470: if ($this->_packageError != '') {
471: return $this->_packageError;
472: }
473: return false;
474: }
475:
476: public function getFreeMethodWeight($items)
477: {
478: $weight = 0;
479:
480: foreach ($items as $item) {
481: if ($item['free_shipping']) {
482: $weight += $item['weight'];
483: }
484: }
485: return $weight;
486: }
487:
488: public function getPackageWeight($items)
489: {
490: $weight = 0;
491:
492: if (Mage::getModel('shipsync/shipping_carrier_fedex')->getWeightUnits() == 'G') {
493: $weightCoef = 0.001;
494: }
495: else {
496: $weightCoef = 1.0;
497: }
498:
499: foreach ($items as $item) {
500: $weight += $item['weight'] * $weightCoef;
501: }
502:
503: return $weight;
504: }
505:
506: public function getPackageValue($items)
507: {
508: $value = 0.0;
509:
510: foreach ($items as $item) {
511: if (isset($item['value'])) {
512: $value += $item['value'];
513: }
514: }
515: return $value;
516: }
517:
518: public function getPackageDiscount($items, $order)
519: {
520: $discount = 0.0;
521: foreach ($items as $item) {
522: $discount += $order->getItemById($item['id'])->getDiscountAmount();
523: }
524: return $discount;
525: }
526:
527: public function collectPackages($itemsToShip, &$specialPackages, &$s)
528: {
529: if (empty($itemsToShip)) {
530: return false;
531: }
532:
533:
534: foreach ($itemsToShip as $key => &$item) {
535:
536: $item['item_number'] = $key + 1;
537:
538:
539: if ($item['special']) {
540:
541: $this->setSpecial($specialPackages, $item, $s);
542: }
543: 544: 545: 546:
547: else {
548: $_items[$item['alt_origin']][] = $item;
549: }
550:
551: }
552: return isset($_items) ? $_items : false;
553: }
554: }
555: