pitneybowes_gsp - Version 0.9.0

Version Notes

Initial Stable GSP release for Magento Connect.

Download this release

Release Info

Developer Raymond Lai
Extension pitneybowes_gsp
Version 0.9.0
Comparing to
See all releases


Version 0.9.0

Files changed (39) hide show
  1. app/code/local/Pb/Pbgsp/Block/Adminhtml/Sales/Order/Invoice/Totals.php +17 -0
  2. app/code/local/Pb/Pbgsp/Block/Adminhtml/Sales/Order/Totals.php +17 -0
  3. app/code/local/Pb/Pbgsp/Block/Checkout/Shipping/Method/Available.php +67 -0
  4. app/code/local/Pb/Pbgsp/Block/Form.php +77 -0
  5. app/code/local/Pb/Pbgsp/Block/Sales/Order/Invoice/Totals.php +14 -0
  6. app/code/local/Pb/Pbgsp/Block/Sales/Order/Totals.php +35 -0
  7. app/code/local/Pb/Pbgsp/Model/Api.php +443 -0
  8. app/code/local/Pb/Pbgsp/Model/Carrier/ShippingMethod.php +298 -0
  9. app/code/local/Pb/Pbgsp/Model/Catalog/Category.php +128 -0
  10. app/code/local/Pb/Pbgsp/Model/Catalog/Cron.php +95 -0
  11. app/code/local/Pb/Pbgsp/Model/Catalog/File.php +673 -0
  12. app/code/local/Pb/Pbgsp/Model/Catalog/Product.php +198 -0
  13. app/code/local/Pb/Pbgsp/Model/Credentials.php +114 -0
  14. app/code/local/Pb/Pbgsp/Model/Creditmemo/Duty.php +31 -0
  15. app/code/local/Pb/Pbgsp/Model/Handlingoptions.php +18 -0
  16. app/code/local/Pb/Pbgsp/Model/Helper.php +11 -0
  17. app/code/local/Pb/Pbgsp/Model/Inboundparcel.php +11 -0
  18. app/code/local/Pb/Pbgsp/Model/Invoice/Duty.php +32 -0
  19. app/code/local/Pb/Pbgsp/Model/Messages.php +121 -0
  20. app/code/local/Pb/Pbgsp/Model/Mysql4/Inboundparcel.php +9 -0
  21. app/code/local/Pb/Pbgsp/Model/Mysql4/Inboundparcel/Collection.php +8 -0
  22. app/code/local/Pb/Pbgsp/Model/Mysql4/Ordernumber.php +9 -0
  23. app/code/local/Pb/Pbgsp/Model/Mysql4/Ordernumber/Collection.php +8 -0
  24. app/code/local/Pb/Pbgsp/Model/Mysql4/Variable.php +9 -0
  25. app/code/local/Pb/Pbgsp/Model/Mysql4/Variable/Collection.php +8 -0
  26. app/code/local/Pb/Pbgsp/Model/Observer.php +318 -0
  27. app/code/local/Pb/Pbgsp/Model/Ordernumber.php +11 -0
  28. app/code/local/Pb/Pbgsp/Model/Pdf/Tax.php +14 -0
  29. app/code/local/Pb/Pbgsp/Model/Quote/Duty.php +76 -0
  30. app/code/local/Pb/Pbgsp/Model/Resource/Mysql4/Setup.php +11 -0
  31. app/code/local/Pb/Pbgsp/Model/Sales/Order/Shipment.php +137 -0
  32. app/code/local/Pb/Pbgsp/Model/Util.php +23 -0
  33. app/code/local/Pb/Pbgsp/Model/Variable.php +11 -0
  34. app/code/local/Pb/Pbgsp/README +2 -0
  35. app/code/local/Pb/Pbgsp/etc/config.xml +491 -0
  36. app/code/local/Pb/Pbgsp/etc/system.xml +361 -0
  37. app/code/local/Pb/Pbgsp/sql/pbgsp_setup/mysql4-install-1.0.0.php +60 -0
  38. app/etc/modules/Pb_Pbgsp.xml +12 -0
  39. package.xml +32 -0
app/code/local/Pb/Pbgsp/Block/Adminhtml/Sales/Order/Invoice/Totals.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Pb_Pbgsp_Block_Adminhtml_Sales_Order_Invoice_Totals extends Mage_Adminhtml_Block_Sales_Order_Totals {
3
+
4
+
5
+
6
+ public function addTotal(Varien_Object $total, $after=null) {
7
+
8
+ $shipMethod = $this->getOrder()->getShippingMethod();
9
+ $taxAmount = $this->getOrder()->getTaxAmount();
10
+ $total = Pb_Pbgsp_Block_Sales_Order_Totals::addDuties($total,$after,$shipMethod,$taxAmount);
11
+ return parent::addTotal($total,$after);
12
+
13
+ }
14
+
15
+ }
16
+
17
+ ?>
app/code/local/Pb/Pbgsp/Block/Adminhtml/Sales/Order/Totals.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Pb_Pbgsp_Block_Adminhtml_Sales_Order_Totals extends Mage_Adminhtml_Block_Sales_Order_Totals {
3
+
4
+
5
+
6
+ public function addTotal(Varien_Object $total, $after=null) {
7
+
8
+ $shipMethod = $this->getOrder()->getShippingMethod();
9
+ $taxAmount = $this->getOrder()->getTaxAmount();
10
+ $total = Pb_Pbgsp_Block_Sales_Order_Totals::addDuties($total,$after,$shipMethod,$taxAmount);
11
+ return parent::addTotal($total,$after);
12
+
13
+ }
14
+
15
+ }
16
+
17
+ ?>
app/code/local/Pb/Pbgsp/Block/Checkout/Shipping/Method/Available.php ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Pb_Pbgsp_Block_Checkout_Shipping_Method_Available extends Mage_Checkout_Block_Onepage_Shipping_Method_Available {
3
+
4
+ protected $errors;
5
+ protected $restrictions;
6
+
7
+ /**
8
+ * Internal constructor, that is called from real constructor
9
+ *
10
+ */
11
+ protected function _construct()
12
+ {
13
+ parent::_construct();
14
+ $this->errors = Mage::getSingleton("customer/session")->getPbRestrictions();
15
+ $cart = Mage::getModel('checkout/cart');
16
+ $items = array();
17
+ foreach($cart->getItems() as $item) {
18
+ $items[$item->getProductId()] = array("name" => $item->getName(), "url" => $item->getProduct()->getProductUrl());
19
+ }
20
+
21
+ $this->restrictions = array();
22
+ if(count($this->errors) > 0){
23
+ foreach ($this->errors as $sku => $value) {
24
+ $processor = new Pb_Pbgsp_Model_Messages();
25
+ $message = $processor->getDisplayMessage($value["code"],$value["message"]);
26
+
27
+ $product_sku = $this->getSku($value['index']);
28
+ if($product_sku!=''):
29
+ $i_sku = Mage::getModel('catalog/product')->loadByAttribute('sku', $product_sku)->getName();
30
+ $i_msg = "$i_sku needs to be removed or modified to continue.";
31
+ $message = str_replace("{IDENTIFY SKU}", $i_msg, $message);
32
+ else:
33
+ $message = str_replace("{IDENTIFY SKU}", $product_sku, $message);
34
+ endif;
35
+ array_push($this->restrictions,array("name" => $items[$sku]["name"],
36
+ "message" => $message,
37
+ "sku" => $sku,
38
+ "url" => $items[$sku]["url"]));
39
+ }
40
+ }
41
+
42
+ }
43
+
44
+ private function getSku($index){
45
+ if($index == null) return '';
46
+ $items = Mage::getSingleton('checkout/cart')->getItems();
47
+ $i = 0;
48
+ foreach ($items as $item):
49
+ if($i++==$index):
50
+ return $item->getSku();
51
+ endif;
52
+ endforeach;
53
+ return '';
54
+ }
55
+ public function displayRestrictions() {
56
+ if(isset($this->errors)) {
57
+ return true;
58
+ } else {
59
+ return false;
60
+ }
61
+ }
62
+
63
+ public function getRestrictions() {
64
+ return $this->restrictions;
65
+ }
66
+ }
67
+ ?>
app/code/local/Pb/Pbgsp/Block/Form.php ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category Mage
22
+ * @package Mage_Paypal
23
+ * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * PayPal Standard payment "form"
29
+ */
30
+ class Pb_Pbgsp_Block_Form extends Mage_Payment_Block_Form
31
+ {
32
+ /**
33
+ * Payment method code
34
+ * @var string
35
+ */
36
+ protected $_methodCode = Mage_Paypal_Model_Config::METHOD_WPS;
37
+
38
+ /**
39
+ * Config model instance
40
+ *
41
+ * @var Mage_Paypal_Model_Config
42
+ */
43
+ protected $_config;
44
+
45
+ /**
46
+ * Set template and redirect message
47
+ */
48
+ protected function _construct()
49
+ {
50
+ Pb_Pbgsp_Model_Util::log("PBGSP form construct");
51
+ $this->_config = Mage::getModel('paypal/config')->setMethod($this->getMethodCode());
52
+ $locale = Mage::app()->getLocale();
53
+ $mark = Mage::getConfig()->getBlockClassName('core/template');
54
+ $mark = new $mark;
55
+ $mark->setTemplate('paypal/payment/mark.phtml')
56
+ ->setPaymentAcceptanceMarkHref($this->_config->getPaymentMarkWhatIsPaypalUrl($locale))
57
+ ->setPaymentAcceptanceMarkSrc($this->_config->getPaymentMarkImageUrl($locale->getLocaleCode()))
58
+ ; // known issue: code above will render only static mark image
59
+ $this->setTemplate('paypal/payment/redirect.phtml')
60
+ ->setRedirectMessage(
61
+ Mage::helper('paypal')->__('You will be redirected to PayPal website when you place an order.')
62
+ )
63
+ ->setMethodTitle('') // Output PayPal mark, omit title
64
+ ->setMethodLabelAfterHtml($mark->toHtml())
65
+ ;
66
+ return parent::_construct();
67
+ }
68
+
69
+ /**
70
+ * Payment method code getter
71
+ * @return string
72
+ */
73
+ public function getMethodCode()
74
+ {
75
+ return $this->_methodCode;
76
+ }
77
+ }
app/code/local/Pb/Pbgsp/Block/Sales/Order/Invoice/Totals.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Pb_Pbgsp_Block_Sales_Order_Invoice_Totals extends Mage_Sales_Block_Order_Invoice_Totals {
3
+
4
+ public function addTotal(Varien_Object $total, $after=null) {
5
+
6
+ $shipMethod = $this->getOrder()->getShippingMethod();
7
+ $taxAmount = $this->getOrder()->getTaxAmount();
8
+ $total = Pb_Pbgsp_Block_Sales_Order_Totals::addDuties($total,$after,$shipMethod,$taxAmount);
9
+ return parent::addTotal($total,$after);
10
+
11
+ }
12
+
13
+ }
14
+ ?>
app/code/local/Pb/Pbgsp/Block/Sales/Order/Totals.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Pb_Pbgsp_Block_Sales_Order_Totals extends Mage_Sales_Block_Order_Totals {
3
+
4
+ public static function addDuties(Varien_Object $total, $after, $shipMethod, $taxAmount) {
5
+
6
+ // TODO: This is kind of ugly. I am replacing the tax template with a tax entry...
7
+ // By default this sets the block_name without parameters which loads the appropriate
8
+ // template. Need to see if this breaks anything.
9
+
10
+ $len = strlen("pbgsp_");
11
+ if (strlen($shipMethod) > $len && substr($shipMethod,0,$len) == "pbgsp_") {
12
+ if ($total->getCode() == "tax") {
13
+ $total = new Varien_Object(array(
14
+ 'code' => 'tax',
15
+ 'value' => $taxAmount,
16
+ 'label' => 'Duty & Taxes'
17
+ ));
18
+ }
19
+ }
20
+
21
+ return $total;
22
+ }
23
+
24
+ public function addTotal(Varien_Object $total, $after=null) {
25
+
26
+ $shipMethod = $this->getOrder()->getShippingMethod();
27
+ $taxAmount = $this->getOrder()->getTaxAmount();
28
+ Pb_Pbgsp_Model_Util::log("Add Duty & Taxes at Order");
29
+ $total = self::addDuties($total,$after,$shipMethod,$taxAmount);
30
+ return parent::addTotal($total,$after);
31
+
32
+ }
33
+
34
+ }
35
+ ?>
app/code/local/Pb/Pbgsp/Model/Api.php ADDED
@@ -0,0 +1,443 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Pb_Pbgsp_Model_Api
3
+ {
4
+
5
+
6
+ public static function CallAPI($method, $url, $data = false,$isSecondCall=false)
7
+ {
8
+ $curl = curl_init();
9
+ $headers = array();
10
+ $dataString = '';
11
+ switch ($method)
12
+ {
13
+ case "POST":
14
+ curl_setopt($curl, CURLOPT_POST, 1);
15
+
16
+ if ($data) {
17
+ $dataString = json_encode($data);
18
+ Pb_Pbgsp_Model_Util::log("Data to pass to get quote $dataString");
19
+ $headers[] = 'Content-Type: application/json';
20
+ $headers[] = 'Content-Length: ' . strlen($dataString);
21
+ curl_setopt($curl, CURLOPT_POSTFIELDS, $dataString);
22
+ }
23
+
24
+ break;
25
+ case "PUT":
26
+ curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT');
27
+ if ($data) {
28
+ $dataString = json_encode($data);
29
+ Pb_Pbgsp_Model_Util::log("Data to pass to PUT $dataString");
30
+ $headers[] = 'Content-Type: application/json';
31
+ $headers[] = 'Content-Length: ' . strlen($dataString);
32
+ curl_setopt($curl, CURLOPT_POSTFIELDS, $dataString);
33
+ }
34
+ break;
35
+ default:
36
+ if ($data)
37
+ $url = sprintf("%s?%s", $url, http_build_query($data));
38
+ }
39
+ if($dataString != '')
40
+ Pb_Pbgsp_Model_Util::log("Passing $dataString to $url");
41
+ curl_setopt($curl, CURLOPT_URL, $url);
42
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
43
+ $token = self::getToken();
44
+ if(!$token)
45
+ throw new Exception("Could not get authentication token");
46
+ $headers[] = 'Cookie: '. $token['cookie'][0];
47
+ $headers[] = 'Authorization: '.$token['token_type'].' '.$token['access_token'];
48
+ curl_setopt($curl, CURLOPT_HTTPHEADER, $headers );
49
+ curl_setopt($curl, CURLOPT_VERBOSE, 1); // turn verbose on
50
+ curl_setopt($curl, CURLINFO_HEADER_OUT, true);
51
+ $result = curl_exec($curl);
52
+ $info = curl_getinfo($curl);
53
+ //Pb_Pbgsp_Model_Util::log($info);
54
+ $status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
55
+ if($status != 200 && $status != 201 && $status != 400)
56
+ {
57
+ Pb_Pbgsp_Model_Util::log("Http Status: $status");
58
+ Pb_Pbgsp_Model_Util::log("body : $result");
59
+ if($status == 401 && !$isSecondCall) {
60
+ //token expired regenerat it
61
+ Pb_Pbgsp_Model_Util::log("Regenerating token");
62
+ Mage::getSingleton("customer/session")->setPbToken(false);
63
+ self::CallAPI($method,$url,$data,true);
64
+ }
65
+ else {
66
+ throw new Exception($result,$status);
67
+ }
68
+ }
69
+ curl_close($curl);
70
+ return $result;
71
+ }
72
+
73
+ public static function getToken() {
74
+ $token = Mage::getSingleton("customer/session")->getPbToken();
75
+ if(!$token) {
76
+ $curl = curl_init();
77
+ curl_setopt($curl, CURLOPT_POST, 1);
78
+ $username = trim(Pb_Pbgsp_Model_Credentials::getUsername());
79
+ $password = trim(Pb_Pbgsp_Model_Credentials::getPassword());
80
+ curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
81
+ curl_setopt($curl, CURLOPT_USERPWD, "$username:$password");
82
+ curl_setopt($curl, CURLINFO_HEADER_OUT, 1); // capture the header info
83
+ curl_setopt($curl, CURLOPT_VERBOSE, 1); // turn verbose on
84
+ // get headers too with this line
85
+ curl_setopt($curl, CURLOPT_HEADER, 1);
86
+ curl_setopt($curl, CURLOPT_POSTFIELDS, 'grant_type=client_credentials');
87
+ // Will return the response, if false it print the response
88
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
89
+ $url = Pb_Pbgsp_Model_Credentials::getApiUrl().'/auth/token';
90
+ curl_setopt($curl, CURLOPT_URL, $url);
91
+ $response = curl_exec($curl);
92
+ $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
93
+ $header = substr($response, 0, $header_size);
94
+ // get cookies
95
+ $cookies = array();
96
+ preg_match_all('/Set-Cookie:(?<cookie>\s{0,}.*)$/im', $header, $cookies);
97
+ $body = substr($response, $header_size);
98
+ $status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
99
+ $info = curl_getinfo($curl);
100
+ if($status != 200) {
101
+ throw new Exception("Could not get authentication token",$status);
102
+ }
103
+ curl_close($curl);
104
+ $token = json_decode($body,true);
105
+ $token['cookie'] = $cookies['cookie'];
106
+ Mage::getSingleton("customer/session")->setPbToken($token);
107
+ }
108
+ return $token;
109
+ }
110
+
111
+ protected static function getClientIP() {
112
+ $ipaddress = '';
113
+ if (array_key_exists('HTTP_CLIENT_IP',$_SERVER))
114
+ $ipaddress = $_SERVER['HTTP_CLIENT_IP'];
115
+ else if (array_key_exists('HTTP_X_FORWARDED_FOR',$_SERVER))
116
+ $ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
117
+ else if (array_key_exists('HTTP_X_FORWARDED',$_SERVER))
118
+ $ipaddress = $_SERVER['HTTP_X_FORWARDED'];
119
+ else if (array_key_exists('HTTP_FORWARDED_FOR',$_SERVER))
120
+ $ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
121
+ else if (array_key_exists('HTTP_FORWARDED',$_SERVER))
122
+ $ipaddress = $_SERVER['HTTP_FORWARDED'];
123
+ else if (array_key_exists('REMOTE_ADDR',$_SERVER))
124
+ $ipaddress = $_SERVER['REMOTE_ADDR'];
125
+ else
126
+ $ipaddress = '0.0.0.0';
127
+ return $ipaddress;
128
+ }
129
+ protected static function makeBasket($products, $address,$method='STANDARD')
130
+ {
131
+ $basketLines = array();
132
+ $totalProducts = 0;
133
+ /* BigPixel code for adding handling fee, 6/6/2012*/
134
+
135
+
136
+ $handlingFee = Pb_Pbgsp_Model_Credentials::getHandlingFee();
137
+
138
+ $handlingoption = Pb_Pbgsp_Model_Credentials::getHandlingOption();
139
+ $domesticShippingFee = Pb_Pbgsp_Model_Credentials::getDomesticShippingFee();
140
+ $domesticShippingOption = Pb_Pbgsp_Model_Credentials::getDomesticShippingOption();
141
+
142
+ $deliveryAdjMinDays = Pb_Pbgsp_Model_Credentials::getDeliveryAdjustmentMinDays();
143
+ $deliveryAdjMixDays = Pb_Pbgsp_Model_Credentials::getDeliveryAdjustmentMaxDays();
144
+
145
+ foreach ($products as $product) {
146
+ if ((!$product->getParentItem() && $product->getRealProductType()
147
+ != Mage_Catalog_Model_Product_Type::TYPE_BUNDLE) ||
148
+ ($product->getParentItem() && $product->isChildrenCalculated())) {
149
+ /* @var Mage_Sales_Model_Order_Item $product */
150
+
151
+ $totalProducts += $product->getQty();
152
+ //$value = $product->getPrice() - ($product->getDiscountAmount() / $product->getQty());
153
+ /* @var Mage_Catalog_Model_Product $realProd*/
154
+ //$realProd = $product->getProduct();
155
+ //Pb_Pbgsp_Model_Util::log('discount amount'. $product->getDiscountAmount());
156
+ //$price = $realProd->getPrice();
157
+ $price = $product->getPrice();//$price - ($product->getDiscountAmount() * $product->getQty());
158
+ array_push($basketLines, array(
159
+ "lineId" => $product->getSku(),
160
+ "commodity" => array('merchantComRefId' => $product->getSku()),
161
+ "unitPrice" => array('price' => array('value' => $price)),
162
+ "quantity" => intval($product->getQty())
163
+
164
+ )
165
+ );
166
+ }
167
+
168
+ }
169
+
170
+ if(isset($handlingoption) && $handlingoption == "2") { //apply as per item
171
+ $handlingFee = $handlingFee * $totalProducts;
172
+ }
173
+ if(isset($domesticShippingOption) && $domesticShippingOption == "2") { //apply as per item
174
+ $domesticShippingFee = $domesticShippingFee * $totalProducts;
175
+ }
176
+ $toHubTransportations = array(
177
+ array(
178
+ 'merchantShippingIdentifier' => 'PB',
179
+ 'speed' => $method,
180
+ 'shipping' => array('value' => $handlingFee),
181
+ 'handling' => array('value' => $domesticShippingFee),
182
+ 'total' => array('value' => $handlingFee + $domesticShippingFee),
183
+ 'minDays' => $deliveryAdjMinDays,
184
+ 'maxDays' => $deliveryAdjMixDays
185
+ )
186
+ );
187
+
188
+ if (strlen($address->getEmail()) > 0) {
189
+ $email = $address->getEmail();
190
+ }
191
+ elseif (strlen(Mage::getSingleton('checkout/cart')->getQuote()->getBillingAddress()->getEmail()) > 0) {
192
+ $email = Mage::getSingleton('checkout/cart')->getQuote()->getBillingAddress()->getEmail();
193
+ }
194
+ else {
195
+ $email = Mage::getSingleton('customer/session')->getCustomer()->getEmail();
196
+ }
197
+ if(!$email)
198
+ $email = "kamranattari@gmail.com";
199
+
200
+ $consignee = array(
201
+ 'familyName' => $address->getLastname(),
202
+ 'givenName' => $address->getFirstname(),
203
+ 'email' => $email,
204
+ 'phoneNumbers' => array(
205
+ array(
206
+ 'number' => $address->getTelephone(),
207
+ 'type' => 'other'
208
+ )
209
+ )
210
+ );
211
+ $shippingAddress = array(
212
+ 'street1' => $address->getStreet1(),
213
+ 'street2' => $address->getStreet2(),
214
+
215
+ 'city' => $address->getCity(),
216
+ 'countyOrRegion' => '',
217
+ 'provinceOrState' => $address->getRegionCode(),
218
+ 'country' => $address->getCountryId(),
219
+ 'postalOrZipCode' => $address->getPostcode()
220
+ );
221
+ $currency = Mage::app()->getStore()->getCurrentCurrencyCode();
222
+ $basket = array(
223
+ 'merchantId' => Pb_Pbgsp_Model_Credentials::getMerchantCode(),
224
+ 'purchaserIPAddress' => self::getClientIP(),
225
+ 'transactionId' => mt_rand(100000, 999999),
226
+ 'quoteCurrency' => $currency,
227
+ 'basketLines' => $basketLines
228
+ ,
229
+ 'toHubTransportations' => $toHubTransportations,
230
+ 'consignee' => $consignee
231
+ ,
232
+ 'shippingAddress' => $shippingAddress
233
+
234
+ );
235
+
236
+
237
+ return $basket;
238
+
239
+ }
240
+
241
+ public static function generateInboundParcelNumber($shipment,$items,$mageOrderNumber,$cpOrderNumber) {
242
+ $inboundParcelCommodities = array();
243
+ /* @var Mage_Sales_Model_Order_Shipment $shipment*/
244
+ $totalWeight = 0;
245
+ foreach($shipment->getItemsCollection() as $item) {
246
+ $product = Mage::getModel('catalog/product')->loadByAttribute('sku',$item->getSku());
247
+ $commodity = array(
248
+ 'merchantComRefId' => $item->getSku(),
249
+
250
+ 'quantity' => intval($item->getQty()),
251
+ 'coo' => $product->getCountryOfManufacture(),
252
+ 'size' => array(
253
+ 'weight' => $product->getWeight(),
254
+ 'weightUnit' => 'lb'
255
+ )
256
+
257
+ );
258
+ array_push($inboundParcelCommodities,$commodity);
259
+ $totalWeight += $product->getWeight();
260
+ }
261
+ $tracks = array();
262
+
263
+ foreach($shipment->getTracksCollection() as $track) {
264
+ $tracks[] = $track;
265
+ }
266
+ $requestBody = array(
267
+ 'merchantOrderNumber' => $cpOrderNumber,
268
+ 'parcelIdentificationNumber' => $tracks[0]->getNumber(),
269
+ 'inboundParcelCommodities' => $inboundParcelCommodities,
270
+ 'shipper' => $tracks[0]->getTitle(),
271
+ 'shipperService' => 'EXPRESS',
272
+ 'shipperTrackingNumber'=> $tracks[0]->getNumber(),
273
+ 'dcId' => '211113442',
274
+ 'dcAddress' => array(
275
+ 'street1' => '200 Main Street',
276
+ 'city' => 'PHOENIX',
277
+ 'provinceOrState' => 'AZ',
278
+ 'country' => 'US',
279
+ 'postalOrZipCode' => '85123'
280
+ ),
281
+ 'returnDetails' => array(
282
+ 'returnAddress' => array(
283
+ 'street1' => '200 Main Street',
284
+ 'city' => 'PHOENIX',
285
+ 'provinceOrState' => 'AZ',
286
+ 'country' => 'US',
287
+ 'postalOrZipCode' => '85123'
288
+ ),
289
+ 'contactInformation' => array(
290
+ 'familyName' => 'Smith',
291
+ 'givenName' => 'Mary',
292
+ 'email' => 'retailer_email@test.com',
293
+ 'phoneNumbers' => array(
294
+ array(
295
+ 'number' => '12123232',
296
+ 'type' => 'home'
297
+ )
298
+ )
299
+ )
300
+ ),
301
+ 'size' => array(
302
+ 'weight' => $totalWeight,
303
+ 'weightUnit' => 'LB'
304
+ )
305
+ );
306
+ $url = Pb_Pbgsp_Model_Credentials::getOrderMgmtAPIUrl().'/orders/'.
307
+ $cpOrderNumber.'/inbound-parcels';
308
+ $response = self::CallAPI('POST',$url,$requestBody);
309
+ $parcelResponse = json_decode($response,true);
310
+ Pb_Pbgsp_Model_Util::log('Response of inbound-parcels');
311
+ Pb_Pbgsp_Model_Util::log($parcelResponse);
312
+ return $parcelResponse;
313
+
314
+ }
315
+ public static function getCheckoutUrl($method) {
316
+ return Pb_Pbgsp_Model_Credentials::getApiUrl().'/checkout/services/v1/'.$method;
317
+ }
318
+ public static function getQuote($products,$address)
319
+ {
320
+
321
+ Pb_Pbgsp_Model_Util::log('Getting quote from clearpath');
322
+ $basket = Pb_Pbgsp_Model_Api::makeBasket($products, $address);
323
+
324
+ $url = self::getCheckoutUrl('quotes');
325
+ $response = self::CallAPI('POST',$url,$basket);
326
+
327
+
328
+ $quoteSet = json_decode($response,true);
329
+ Pb_Pbgsp_Model_Util::log('response of quotes ');
330
+ Pb_Pbgsp_Model_Util::log($quoteSet);
331
+ return $quoteSet;
332
+
333
+
334
+ }
335
+
336
+
337
+ public static function createOrder($products,$method,$address) {
338
+
339
+
340
+ try {
341
+ Pb_Pbgsp_Model_Util::log('Creating order in clearpath');
342
+ $basket = Pb_Pbgsp_Model_Api::makeBasket($products, $address,$method);
343
+
344
+ $url = self::getCheckoutUrl('orders');
345
+ $response = self::CallAPI('POST',$url,$basket);
346
+
347
+
348
+ $orderSet = json_decode($response,true);
349
+ Pb_Pbgsp_Model_Util::log('response of orders ');
350
+ Pb_Pbgsp_Model_Util::log($orderSet);
351
+ foreach($orderSet['order'] as $order) {
352
+ $tax = 0;
353
+ if(!self::logIfError($order,'createOrder')) {
354
+ // if(array_key_exists('order',$order)) {
355
+ // $quote = $order['order'];
356
+ // $tax = $quote['totalImportation']['total']['value'];
357
+ // }
358
+
359
+ return $order;//array("orderNumber" => $order['orderId'], "tax" => $tax);
360
+ }
361
+ else {
362
+ return false;
363
+ }
364
+
365
+ }
366
+ return $orderSet;
367
+ }
368
+ catch(Exception $e) {
369
+ Pb_Pbgsp_Model_Util::log("Received unexpected exception from Pb while calling createOrder.");
370
+ Pb_Pbgsp_Model_Util::logException($e);
371
+
372
+
373
+ }
374
+
375
+ }
376
+
377
+ private static function logIfError($object,$action=null) {
378
+ if(array_key_exists('errors',$object) && count($object['errors']) > 0) {
379
+ $processor = new Pb_Pbgsp_Model_Messages();
380
+ foreach($object['errors'] as $error) {
381
+ $message = '';
382
+ if(array_key_exists('message',$error))
383
+ $message = $error['message'];
384
+ $message = $processor->getDisplayMessage($error["error"],$message);//.$sku;
385
+ if($action)
386
+ Pb_Pbgsp_Model_Util::log("Error received in action $action");
387
+ Pb_Pbgsp_Model_Util::log($message);
388
+ }
389
+ return true;
390
+ }
391
+ return false;
392
+ }
393
+ public static function confirmOrder($orderNumber,$order) {
394
+ /* @var Mage_Sales_Model_Order $order */
395
+
396
+
397
+
398
+ $billingAddress = $order->getBillingAddress();
399
+ $confirm = array(
400
+ 'transactionId' => $order->getRealOrderId(),
401
+ 'merchantOrderNumber' => $order->getRealOrderId(),
402
+ 'purchaser' => array(
403
+ 'familyName' => $order->getCustomerLastname(),
404
+ 'givenName' => $order->getCustomerFirstname(),
405
+ 'email' => $order->getCustomerEmail(),
406
+ 'phoneNumbers' => array(
407
+ array(
408
+ 'number' => $billingAddress->getTelephone(),
409
+ 'type' => 'other'
410
+ )
411
+ )),
412
+ 'purchaserBillingAddress' => array(
413
+ 'street1' => $billingAddress->getStreet1(),
414
+ 'street2' => '',
415
+ 'city' => $billingAddress->getCity(),
416
+ 'countyOrRegion' => '',
417
+ 'provinceOrState' => $billingAddress->getRegionCode(),
418
+ 'country' => $billingAddress->getCountryId(),
419
+ 'postalOrZipCode' => $billingAddress->getPostcode(),
420
+ )
421
+
422
+ );
423
+ try {
424
+ $url = self::getCheckoutUrl("orders/$orderNumber/confirm");
425
+ $response = self::CallAPI('PUT',$url,$confirm);
426
+ Pb_Pbgsp_Model_Util::log("Passing $url ");
427
+ Pb_Pbgsp_Model_Util::log($confirm);
428
+ $confirmResponse = json_decode($response,true);
429
+ if(self::logIfError($confirmResponse,'confirmOrder'))//there is an error
430
+ return false;
431
+ return true;
432
+ }
433
+ catch(Exception $e) {
434
+ Pb_Pbgsp_Model_Util::log("Received unexpected exception from Pb while calling confirming order.");
435
+ Pb_Pbgsp_Model_Util::log($e->getMessage(). ' '. $e->getTraceAsString());
436
+ return false;
437
+ }
438
+ return true;
439
+ }
440
+
441
+ }
442
+
443
+ ?>
app/code/local/Pb/Pbgsp/Model/Carrier/ShippingMethod.php ADDED
@@ -0,0 +1,298 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class Pb_Pbgsp_Model_Carrier_ShippingMethod
5
+ */
6
+ class Pb_Pbgsp_Model_Carrier_ShippingMethod extends Mage_Shipping_Model_Carrier_Abstract
7
+ {
8
+ /**
9
+ * unique internal shipping method identifier
10
+ *
11
+ * @var string [a-z0-9_]
12
+ */
13
+ protected $_code = 'pbgsp';
14
+
15
+ public function getConfigData($field) {
16
+ /* BigPixel 3/25/2012. hide errors for not applicable countries */
17
+ /*if ($field == "showmethod") {
18
+ // Make sure all errors are displayed.
19
+ return 1;
20
+ } else {
21
+ return parent::getConfigData($field);
22
+ }*/
23
+ /*if ($field == "showmethod") {
24
+ Pb_Pbgsp_Model_Util::log($field .':'. parent::getConfigData($field));
25
+ Pb_Pbgsp_Model_Util::log($this->get_callstack());
26
+ }*/
27
+ return parent::getConfigData($field);
28
+ }
29
+
30
+ /**
31
+ * @param $result
32
+ * @param $errors
33
+ * Adds custom error messages to $result
34
+ */
35
+ public function displayErrors($result,$quote) {
36
+ $processor = new Pb_Pbgsp_Model_Messages();
37
+ $isUnitErrorAdded = false;
38
+
39
+ foreach($quote['quoteLines'] as $quoteLine) {
40
+ if(array_key_exists('unitErrors',$quoteLine)) {
41
+ foreach($quoteLine['unitErrors'] as $error) {
42
+ $message = '';
43
+ if(array_key_exists('message',$error))
44
+ $message = $error['message'];
45
+ $message = $processor->getDisplayMessage($error["error"],$message);//.$sku;
46
+ $sku = $quoteLine['merchantComRefId'];
47
+ $product = Mage::getModel('catalog/product')->loadByAttribute('sku',$sku);
48
+ $message = $message . " Please remove ". $product->getName() . " from cart.";
49
+ $this->_addError($result,$message);
50
+ $isUnitErrorAdded = true;
51
+ }
52
+
53
+ }
54
+
55
+ }
56
+ if(!$isUnitErrorAdded) {
57
+ foreach($quote['errors'] as $error) {
58
+ $message = '';
59
+ if(array_key_exists('message',$error))
60
+ $message = $error['message'];
61
+ $message = $processor->getDisplayMessage($error["error"],$message);//.$sku;
62
+ $this->_addError($result,$message);
63
+ }
64
+ }
65
+
66
+ }
67
+
68
+ private function _addError($result,$message) {
69
+ $error = Mage::getModel('shipping/rate_result_error');
70
+ $error->setCarrier('pbgsp');
71
+ $error->setCarrierTitle("Pitney Bowes");
72
+ $error->setErrorMessage($message);
73
+ $result->append($error);
74
+ Pb_Pbgsp_Model_Util::log("Added error $message");
75
+ }
76
+
77
+ /**
78
+ * @param $index
79
+ * @return string
80
+ */
81
+ private function getSku($index){
82
+ $items = Mage::getSingleton('checkout/cart')->getItems();
83
+ $i = 0;
84
+ foreach ($items as $item):
85
+ if($i++==$index):
86
+ return $item->getSku();
87
+ endif;
88
+ endforeach;
89
+ return '';
90
+ }
91
+
92
+ /**
93
+ * @param $index
94
+ * @return mixed
95
+ */
96
+ public function getRestrictId($index){
97
+ $sku = $this->getSku($index);
98
+ $id = Mage::getModel('catalog/product')->getIdBySku($sku);
99
+ return $id;
100
+ }
101
+
102
+ private function _getShipMethodFromQuote($quote,$items) {
103
+ $handlingFee = Pb_Pbgsp_Model_Credentials::getHandlingFee();
104
+
105
+ $handlingoption = Pb_Pbgsp_Model_Credentials::getHandlingOption();
106
+ $domesticShippingFee = Pb_Pbgsp_Model_Credentials::getDomesticShippingFee();
107
+ $domesticShippingOption = Pb_Pbgsp_Model_Credentials::getDomesticShippingOption();
108
+
109
+ $deliveryAdjMinDays = Pb_Pbgsp_Model_Credentials::getDeliveryAdjustmentMinDays();
110
+ $deliveryAdjMixDays = Pb_Pbgsp_Model_Credentials::getDeliveryAdjustmentMaxDays();
111
+ $totalQty = 0;
112
+ foreach($items as $item) {
113
+ $totalQty += $item->getQty();
114
+ }
115
+ if(isset($handlingoption) && $handlingoption == "2") { //apply as per item
116
+ $handlingFee = $handlingFee * $totalQty;
117
+ }
118
+ if(isset($domesticShippingOption) && $domesticShippingOption == "2") { //apply as per item
119
+ $domesticShippingFee = $domesticShippingFee * $totalQty;
120
+ }
121
+ $transportation = $quote['totalTransportation'];
122
+ // create new instance of method rate
123
+ $method = Mage::getModel('shipping/rate_result_method');
124
+
125
+ // record carrier information
126
+ $method->setCarrier($this->_code);
127
+
128
+ // get config info
129
+ $vv = Mage::getStoreConfig('carriers/pbgsp/title');
130
+ $method->setCarrierTitle($vv);
131
+
132
+ // record method information
133
+ $title = $transportation['speed']." - ".(intval($transportation['minDays']) + $deliveryAdjMinDays)."-".(intval($transportation['maxDays']) + $deliveryAdjMixDays )." days";
134
+ $method->setMethod($transportation['speed']);
135
+ $method->setMethodTitle($title);
136
+
137
+ // rate cost is optional property to record how much it costs to vendor to ship
138
+ $method->setCost($transportation['shipping']['value']);
139
+ $method->setPrice((floatval($transportation['total']['value']) + $handlingFee + $domesticShippingFee));
140
+ $method->setTax($quote['totalImportation']['total']['value']);
141
+ return $method;
142
+ }
143
+ private function _getCheapestShipMethod($quoteSet,$items)
144
+ {
145
+ $minPrice = -1;
146
+ $minQuote = null;
147
+ foreach ($quoteSet['quote'] as $quote) {
148
+
149
+ if (array_key_exists('totalTransportation', $quote)) {
150
+ $transportation = $quote['totalTransportation'];
151
+ $cost = floatval($transportation['total']['value']);
152
+ if($minPrice == -1 || $minPrice > $cost) {
153
+ $minPrice = $cost;
154
+ $minQuote = $quote;
155
+
156
+ }
157
+ }
158
+
159
+ }
160
+ return $this->_getShipMethodFromQuote($minQuote,$items);
161
+ }
162
+ /**
163
+ * Collect rates for this shipping method based on information in $request
164
+ *
165
+ * @param Mage_Shipping_Model_Rate_Request $data
166
+ * @return Mage_Shipping_Model_Rate_Result
167
+ */
168
+ public function collectRates(Mage_Shipping_Model_Rate_Request $request)
169
+ {
170
+ Pb_Pbgsp_Model_Util::log('Pb_Pbgsp_Model_Carrier_ShippingMethod.collectRates ' . Mage::getStoreConfig('carriers/'.$this->_code.'/active'));
171
+ // skip if not enabled
172
+ if (!Mage::getStoreConfig('carriers/'.$this->_code.'/active')) {
173
+ return false;
174
+ }
175
+
176
+ // skip if the store is not located in the US
177
+ Pb_Pbgsp_Model_Util::log($request->country_id);
178
+ if ($request->country_id != "US") {
179
+ return false;
180
+ }
181
+
182
+ // get necessary configuration values
183
+
184
+
185
+ // this object will be returned as result of this method
186
+ // containing all the shipping rates of this method
187
+ $result = Mage::getModel('shipping/rate_result');
188
+
189
+ $items = Mage::getSingleton('checkout/cart')->getItems();
190
+ $address = Mage::getSingleton('checkout/cart')->getQuote()->getShippingAddress();
191
+
192
+ if(!$items || count($items) == 0)
193
+ $items = $request->getAllItems();
194
+ if(!$address->getCountryId()) {
195
+ $address->setCountryId($request->getDestCountryId());
196
+ $address->setCity($request->getDestCity());
197
+ $address->setStreet($request->getDestStreet());
198
+ $address->setRegion($request->getDestRegionCode());
199
+ $address->setPostcode($request->getDestPostcode());
200
+ $address->setEmail('test@bigpixelstudio.com');
201
+ $address->setFirstname('firstname');
202
+ $address->setLastname('lastname');
203
+ $address->setTelephone('1231231234');
204
+
205
+ }
206
+
207
+ // Clear all restrictions from previous calls
208
+ Mage::getSingleton("customer/session")->setPbRestrictions(null);
209
+ $allowSpecific = Mage::getStoreConfig('carriers/'.$this->_code .'/sallowspecific');
210
+ if($allowSpecific) {
211
+ $activeCountries = Mage::getStoreConfig('carriers/'.$this->_code .'/specificcountry');
212
+
213
+ if(!(strpos($activeCountries,$address->getCountryId()) !== false)) {
214
+ Pb_Pbgsp_Model_Util::log($address->getCountryId().' not found');
215
+ return false;
216
+ }
217
+ }
218
+
219
+
220
+ // NOTE: Insert calls to Magento Domestic Shipping costs here. Pass the newly calculated
221
+ // domestic shipping costs to the API calls to get a proper full quote.
222
+
223
+
224
+ if (!$address->getStreet1() || !$address->getCity()) {
225
+ $address->setFirstname('firstname');
226
+ $address->setLastname('lastname');
227
+ $address->setCity('city');
228
+ $address->setTelephone('phone');
229
+ $address->setEmail('email@email.com');
230
+ $address->setStreet(array('street'));
231
+ }
232
+
233
+ try {
234
+
235
+ $shipMethodAvailable = false;
236
+ $quoteSet = Pb_Pbgsp_Model_Api::getQuote($items, $address);
237
+ $freeShippingEnabled = Mage::getStoreConfig('carriers/pbgsp/free_shipping_enable');
238
+ $freeShippingSubTotal = Mage::getStoreConfig('carriers/pbgsp/free_shipping_subtotal');
239
+
240
+ $totalOrderPrice = $this->getTotalOrderPrice($items);
241
+ $shipMethods = array();
242
+ foreach($quoteSet['quote'] as $quote) {
243
+ if(array_key_exists('errors',$quote) && count($quote['errors']) > 0) {
244
+ $this->displayErrors($result,$quote);
245
+ }
246
+ else if(array_key_exists('totalTransportation',$quote)) {
247
+ if($freeShippingEnabled && $totalOrderPrice >= $freeShippingSubTotal) {
248
+ //get cheapest shipping method from quoteSet
249
+ $method = $this->_getCheapestShipMethod($quoteSet,$items);
250
+ $method->setCost(0);
251
+ $method->setPrice(0);
252
+ $method->setTax(0);
253
+ $result->append($method);
254
+ array_push($shipMethods,$method);
255
+ break;
256
+ }
257
+ else {
258
+ $method = $this->_getShipMethodFromQuote($quote,$items);
259
+ // add this rate to the result
260
+ $result->append($method);
261
+ array_push($shipMethods,$method);
262
+ }
263
+
264
+
265
+ $shipMethodAvailable = true;
266
+ }
267
+ }
268
+ if($shipMethodAvailable) {
269
+ Mage::getSingleton('checkout/session')->setPbMethods($shipMethods);
270
+ }
271
+ }
272
+ catch(Exception $e) {
273
+ Pb_Pbgsp_Model_Util::log("Error getting quotes");
274
+ Pb_Pbgsp_Model_Util::logException($e);
275
+ $message = $e->getMessage();
276
+ if($e->getMessage() == '')
277
+ $message = "Received unexpected error in getting quotes from Pbgsp. Please contact with administrator.";
278
+ $this->_addError($result,$message);
279
+
280
+ }
281
+ return $result;
282
+
283
+
284
+ }
285
+
286
+ private function getTotalOrderPrice($products)
287
+ {
288
+ $totalOrderPrice = 0;
289
+ foreach ($products as $product) {
290
+ if ((!$product->getParentItem() && $product->getRealProductType() != Mage_Catalog_Model_Product_Type::TYPE_BUNDLE) || ($product->getParentItem() && $product->isChildrenCalculated())) {
291
+ $totalOrderPrice += $product->getPrice() * $product->getQty();
292
+
293
+ }
294
+ }
295
+ return $totalOrderPrice;
296
+ }
297
+ }
298
+ ?>
app/code/local/Pb/Pbgsp/Model/Catalog/Category.php ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Pb_Pbgsp_Model_Catalog_Category {
3
+ protected $category;
4
+ private static $roots;
5
+ protected $url;
6
+ public function __construct($id,$url=null) {
7
+ if (gettype($id) == "object" && get_class($id) == "Mage_Catalog_Model_Category") {
8
+ $this->category = $id;
9
+ } else {
10
+ $this->category = Mage::getModel('catalog/category')->load($id);
11
+ }
12
+ $this->url = $url;
13
+ }
14
+ public function getCategory() {
15
+ return $this->category;
16
+ }
17
+ public function getName() {
18
+ return $this->category->getName();
19
+ }
20
+
21
+ public function getCode() {
22
+ return $this->category->getId();
23
+ }
24
+
25
+ public function getUrl() {
26
+ //Pb_Pbgsp_Model_Util::log($this->category->getUrl());
27
+ if($this->url)
28
+ return $this->url;
29
+ return $this->category->getUrl();
30
+ //return Mage::app()->getStore($this->category->getStoreId())->getBaseUrl();
31
+ }
32
+
33
+ public function isRoot() {
34
+ if (!$this->category->getParentId()) {
35
+ return true;
36
+ }
37
+ if (!self::$roots) {
38
+ $categoryOp = new Mage_Adminhtml_Block_Catalog_Category_Abstract();
39
+ self::$roots = $categoryOp->getRootIds();
40
+ }
41
+ foreach (self::$roots as $rootId) {
42
+ if ($this->getCode() == $rootId) {
43
+ return true;
44
+ }
45
+ }
46
+ return false;
47
+ }
48
+
49
+ public function getParentCode() {
50
+ return $this->category->getParentId();
51
+ }
52
+
53
+ public function writeToFile($file) {
54
+ $name = Pb_Pbgsp_Model_Catalog_File::stripHtml($this->getName());
55
+ $name = preg_replace("/[^A-Za-z0-9 ,.\-\+=;:\\(){}\[\]@?%$#]/", '', $name);
56
+ // $string = "<Category>\n";
57
+ // $string .= "<CategoryCode>".htmlentities($this->getCode())."</CategoryCode>\n";
58
+ // $string .= "<Name>".htmlentities($name)."</Name>\n";
59
+ // //$string .= "<URL><![CDATA[".htmlentities($this->getUrl())."]]></URL>\n";
60
+ // $string .= "<URL><![CDATA[".htmlentities($this->getUrl())."]]></URL>\n";
61
+ // if($this->getParentCode() != 1 && !$this->isRoot()){
62
+ // $string .= "<ParentCategoryCode>".htmlentities($this->getParentCode())."</ParentCategoryCode>\n";
63
+ // }
64
+ // $string .= "</Category>\n";
65
+ //fputcsv($this->file,array('CATEGORY_ID','PARENT_CATEGORY_ID','NAME','ID_PATH','URL'));
66
+ $parentCateID = '';
67
+ if($this->getParentCode() != 1 && !$this->isRoot()){
68
+ $parentCateID = $this->getParentCode();
69
+ }
70
+ fputcsv($file,array($this->getCode(),$parentCateID,$name,'',$this->getUrl()));
71
+ //fwrite($file,$string);
72
+ }
73
+
74
+ // This is done via API
75
+ public function upload() {
76
+ echo "Uploading category: ".$this->category->getName()."... ";
77
+ if (Pb_Pbgsp_Model_Api::addCategory($this)) {
78
+ echo "ok";
79
+ } else {
80
+ echo "failed!";
81
+ }
82
+ echo "<br/>";
83
+
84
+ $products = $this->category->getProductCollection();
85
+ // TODO: Products that are part of multiple categories will be uploaded
86
+ // multiple times.
87
+ foreach ($products as $product) {
88
+ $clearPathProduct = new Pb_Pbgsp_Model_Catalog_Product($product);
89
+ echo "Uploading product: ".$clearPathProduct->getName()."... ";
90
+ if (Pb_Pbgsp_Model_Api::addCommodity($clearPathProduct)) {
91
+ echo "ok";
92
+ } else {
93
+ echo "failed!";
94
+ }
95
+ echo "<br/>";
96
+ }
97
+
98
+
99
+ $children = $this->category->getChildrenCategories();
100
+
101
+ // TODO: this code will run out of memory if there are a lot of categories....
102
+ // Need to convert the recursive call to a loop at some point.
103
+ foreach ($children as $child) {
104
+ $childCategory = new Pb_Pbgsp_Model_Catalog_Category($child);
105
+ $childCategory->upload();
106
+ }
107
+ }
108
+
109
+ // This fuction starts at the Magento root and its not very efficient... see isRoot for proper implementation.
110
+ // This function is only used by the API upload.
111
+ public static function getAllRootCategories() {
112
+ $roots = array();
113
+
114
+ $categories = Mage::getModel('catalog/category')->getCollection();//->getSelect()->order(array('IF(`id`>0, `id`, 9999) ASC'));
115
+ $categories = $categories->getIterator();
116
+
117
+ foreach ($categories as $category) {
118
+ $parents = $category->getParentId();
119
+ if (!$parents) {
120
+ $rootCategory = new Pb_Pbgsp_Model_Catalog_Category($category->getId());
121
+ array_push($roots,$rootCategory);
122
+ }
123
+ }
124
+ return $roots;
125
+ }
126
+
127
+ }
128
+ ?>
app/code/local/Pb/Pbgsp/Model/Catalog/Cron.php ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Pb_Pbgsp_Model_Catalog_Cron {
3
+
4
+ private $lastDiff;
5
+ private $lastFull;
6
+
7
+
8
+
9
+ public function catalogSync() {
10
+ Pb_Pbgsp_Model_Util::log("Start Sync...");
11
+ $diffPeriod = Mage::getStoreConfig('carriers/pbgsp/catalog_diff');
12
+ $fullPeriod = Mage::getStoreConfig('carriers/pbgsp/catalog_full');
13
+
14
+ $collection = Mage::getModel("pb_pbgsp/variable")->getCollection();
15
+ foreach ($collection as $variable) {
16
+ Pb_Pbgsp_Model_Util::log($variable->getName()." -> ".$variable->getValue());
17
+ if ($variable->getName() == "lastFull") {
18
+ $this->lastFull = $variable;
19
+ }
20
+ if ($variable->getName() == "lastDiff") {
21
+ $this->lastDiff = $variable;
22
+ }
23
+ }
24
+
25
+
26
+ $appRoot = Mage::getRoot();
27
+ $mageRoot = dirname($appRoot);
28
+ $configOptions = Mage::getModel('core/config_options');
29
+ $configOptions->createDirIfNotExists($mageRoot.'/var/pbgsp');
30
+ chmod($mageRoot . '/var/pbgsp/', 0777);
31
+
32
+ if (!isset($this->lastFull) || $this->lastFull->getValue() < time() - $fullPeriod*24*3600) {
33
+ // Full catalog upload needed
34
+ $this->uploadCatalog();
35
+ } else if (!isset($this->lastDiff) && $this->lastFull->getValue() < time() - $diffPeriod*3600) {
36
+ // First catalog diff upload
37
+ $this->uploadCatalog($this->lastFull);
38
+ } else if (isset($this->lastDiff) && ($this->lastDiff->getValue() < time() - $diffPeriod*3600 &&
39
+ $this->lastFull->getValue() < time() - $diffPeriod*3600)) {
40
+ // Catalog diff upload
41
+ $this->uploadCatalog($this->lastDiff);
42
+ }
43
+ else {
44
+ Pb_Pbgsp_Model_Util::log('PB Export cron. Do not export catalog');
45
+
46
+ }
47
+
48
+ }
49
+
50
+ public function uploadCatalog($lastDiff = false) {
51
+ if (!$lastDiff) {
52
+ Pb_Pbgsp_Model_Util::log("Full catalog upload");
53
+ $file = new Pb_Pbgsp_Model_Catalog_File();
54
+ if (isset($this->lastFull)) {
55
+ $this->lastFull->setValue(time());
56
+ } else {
57
+ $this->lastFull = Mage::getModel("pb_pbgsp/variable");
58
+ $this->lastFull->setName("lastFull");
59
+ $this->lastFull->setValue(time());
60
+ }
61
+ $this->lastFull->save();
62
+ } else {
63
+ Pb_Pbgsp_Model_Util::log("catalog diff");
64
+ $file = new Pb_Pbgsp_Model_Catalog_File($lastDiff->getValue());
65
+ if (isset($this->lastDiff)) {
66
+ $this->lastDiff->setValue(time());
67
+ } else {
68
+ $this->lastDiff = Mage::getModel("pb_pbgsp/variable");
69
+ $this->lastDiff->setName("lastDiff");
70
+ $this->lastDiff->setValue(time());
71
+ }
72
+ $this->lastDiff->save();
73
+ }
74
+
75
+ Pb_Pbgsp_Model_Util::log("RAY:Create Function Started");
76
+
77
+ $file->createNew();
78
+
79
+ Pb_Pbgsp_Model_Util::log("RAY:Create Function Complete");
80
+
81
+ Pb_Pbgsp_Model_Util::log("RAY:upload Started");
82
+ $file->upload();
83
+ $file->logProdWithoutCategories();
84
+ Pb_Pbgsp_Model_Util::log("RAY:upload Complete");
85
+ }
86
+
87
+ public function processStatusNotifications() {
88
+ $file = new Pb_Pbgsp_Model_Catalog_File();
89
+ $file->processStatusNotifications();
90
+ }
91
+
92
+ }
93
+
94
+
95
+ ?>
app/code/local/Pb/Pbgsp/Model/Catalog/File.php ADDED
@@ -0,0 +1,673 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /* Creates a temporary file containing a Pb catalog xml file. Because of possible PHP timeouts the creation of the
4
+ * xml file is done in concrete steps that can be resumed in case of a timeout.
5
+ */
6
+
7
+ class Pb_Pbgsp_Model_Catalog_File {
8
+
9
+
10
+ private $file;
11
+ private $filename;
12
+ private $lastDiff;
13
+ private $productIds;
14
+ private $lastFileName;
15
+
16
+ public function __construct($lastDiff = false) {
17
+ $this->lastDiff = $lastDiff;
18
+ $this->productIds = array();
19
+ }
20
+
21
+ private function _getTempDir() {
22
+ $appRoot = Mage::getRoot();
23
+ $mageRoot = dirname($appRoot);
24
+ $configOptions = Mage::getModel('core/config_options');
25
+ $tmpDir = $mageRoot . '/var/pbgsp/tmp/';
26
+ $configOptions->createDirIfNotExists( $tmpDir);
27
+ chmod($tmpDir, 0777);
28
+ return $tmpDir;
29
+ }
30
+
31
+
32
+ private function _getDataFileName($dataFeedName,$part=null) {
33
+ $partName = '';
34
+ if($part)
35
+ $partName = '_part'.$part;
36
+ $fileName = Pb_Pbgsp_Model_Credentials::getCatalogSenderID() . "_".$dataFeedName."_update_". Pb_Pbgsp_Model_Credentials::getPBID().'_'.date('Ymd_His').'_'.mt_rand(100000, 999999);
37
+ if($part == 1)
38
+ $this->lastFileName = $fileName;
39
+ else
40
+ $fileName = $this->lastFileName;
41
+ return $fileName.$partName.'.csv';
42
+ }
43
+ private function _createNewCommoditiyFile($part=null) {
44
+ $fileName = $this->_getDataFileName('catalog',$part);
45
+
46
+
47
+ $this->filename = $this->_getTempDir().$fileName;
48
+ $this->file = fopen($this->filename,"w+");
49
+ chmod($this->filename, 0777);
50
+ //add header row
51
+ fputcsv($this->file,array('MERCHANT_COMMODITY_REF_ID','COMMODITY_NAME_TITLE','SHORT_DESCRIPTION',
52
+ 'LONG_DESCRIPTION','RETAILER_ID','COMMODITY_URL','RETAILER_UNIQUE_ID','PCH_CATEGORY_ID',
53
+ 'RH_CATEGORY_ID','STANDARD_PRICE','WEIGHT_UNIT','DISTANCE_UNIT','COO','IMAGE_URL','PARENT_SKU',
54
+ 'CHILD_SKU','PARCELS_PER_SKU','UPC','UPC_CHECK_DIGIT','GTIN','MPN','ISBN','BRAND','MANUFACTURER',
55
+ 'MODEL_NUMBER','MANUFACTURER_STOCK_NUMBER','COMMODITY_CONDITION','COMMODITY_HEIGHT',
56
+ 'COMMODITY_WIDTH','COMMODITY_LENGTH','PACKAGE_WEIGHT','PACKAGE_HEIGHT','PACKAGE_WIDTH',
57
+ 'PACKAGE_LENGTH','HAZMAT','ORMD','CHEMICAL_INDICATOR','PESTICIDE_INDICATOR','AEROSOL_INDICATOR',
58
+ 'RPPC_INDICATOR','BATTERY_TYPE','NON_SPILLABLE_BATTERY','FUEL_RESTRICTION','SHIP_ALONE',
59
+ 'RH_CATEGORY_ID_PATH','RH_CATEGORY_NAME_PATH'));//,'RH_CATEGORY_URL_PATH','GPC','COMMODITY_WEIGHT','HS_CODE','CURRENCY'
60
+
61
+ fflush($this->file);
62
+ }
63
+ private function _createNewCategoryFile($part=null) {
64
+ $fileName = $this->_getDataFileName('category-tree',$part);
65
+
66
+
67
+ $this->filename = $this->_getTempDir().$fileName;
68
+ $this->file = fopen($this->filename,"w+");
69
+ chmod($this->filename, 0777);
70
+ //add header row
71
+ fputcsv($this->file,array('CATEGORY_ID','PARENT_CATEGORY_ID','NAME',
72
+ 'ID_PATH','URL'));
73
+
74
+ fflush($this->file);
75
+ }
76
+
77
+
78
+
79
+
80
+ private function _getSelectedCategory($categories,$catId) {
81
+ foreach($categories as $cat) {
82
+ if($cat->getId() == $catId)
83
+ return $cat;
84
+ }
85
+ return false;
86
+ }
87
+ /**
88
+ * Extracts the categories and products and exports them into xml file.
89
+ */
90
+ public function createNew() {
91
+
92
+ $maxRecordsCount = Pb_Pbgsp_Model_Credentials::getMaxRecordsCount();
93
+ if(!$maxRecordsCount)
94
+ $maxRecordsCount = 10000;
95
+
96
+ $prodCount = 0;
97
+ $catCount = 0;
98
+ $fileRecordCount = 0;
99
+ //get stores which has disabled clearpath
100
+ $stores = Mage::app()->getStores();
101
+ $defaultStoreUrl = Mage::getBaseUrl();
102
+ $secDefaultStoreUrl = str_replace("http","https",$defaultStoreUrl);
103
+ $disabledStores = array();
104
+ $addedCategories = array();
105
+ $part=1;
106
+ foreach($stores as $store) {
107
+
108
+ $isActive = Mage::getStoreConfig('carriers/pbgsp/active',$store);
109
+ $baseURL = $store->getBaseUrl();
110
+
111
+ if(!$isActive) {
112
+ $disabledStores[] = $store;
113
+ Pb_Pbgsp_Model_Util::log("Disabled store". $store->getId(). ' '. $store->getCode());
114
+ }
115
+ else {
116
+ $rootId = Mage::app()->getStore($store->getId())->getRootCategoryId();
117
+ $rootCat = Mage::getModel('catalog/category')->load($rootId);
118
+ /* @var $rootCat Mage_Catalog_Model_Category */
119
+ $rootCat->setData('store',$store);
120
+ Pb_Pbgsp_Model_Util::log("Default store url $defaultStoreUrl store ".$store->getCode()." store base url".
121
+ $baseURL." root cat url". $rootCat->getUrl(). " cat name". $rootCat->getName());
122
+ $catUrl = str_replace($defaultStoreUrl,$baseURL,$rootCat->getUrl());
123
+ if($catUrl == $rootCat->getUrl())
124
+ $catUrl = str_replace($secDefaultStoreUrl,$baseURL,$rootCat->getUrl());
125
+ $cat = new Pb_Pbgsp_Model_Catalog_Category($rootCat,$catUrl);
126
+ if(!$this->file || $fileRecordCount > $maxRecordsCount)
127
+ {
128
+ $this->_createNewCategoryFile($part);
129
+ $fileRecordCount=0;
130
+ $part++;
131
+ }
132
+ $cat->writeToFile($this->file);
133
+ fflush($this->file);
134
+ $catCount++;
135
+ $fileRecordCount++;
136
+ $categories = Mage::getModel('catalog/category')
137
+ ->getCollection()
138
+ ->addUrlRewriteToResult()
139
+ ->addAttributeToSelect('name')
140
+ ->addFieldToFilter('path', array('like'=> "1/$rootId/%"));
141
+ $addedCategories[] = $rootCat;
142
+
143
+ foreach($categories as $category) {
144
+ if(!$this->file || $fileRecordCount > $maxRecordsCount)
145
+ {
146
+ $this->_createNewCategoryFile($part);
147
+ $fileRecordCount=0;
148
+ $part++;
149
+ }
150
+ /* @var $category Mage_Catalog_Model_Category */
151
+ $category->setStoreId($store->getId());
152
+ $category->setData('store',$store);
153
+ $addedCategories[] = $category;
154
+
155
+
156
+
157
+
158
+ $catUrl = str_replace($defaultStoreUrl,$baseURL,$category->getUrl());
159
+ if($catUrl == $category->getUrl())
160
+ $catUrl = str_replace($secDefaultStoreUrl,$baseURL,$category->getUrl());
161
+ $cat = new Pb_Pbgsp_Model_Catalog_Category($category,$catUrl);
162
+ $cat->writeToFile($this->file);
163
+ fflush($this->file);
164
+ $catCount++;
165
+ $fileRecordCount++;
166
+ }
167
+ }
168
+ }
169
+
170
+ fclose($this->file);
171
+ $this->_stripPartFromFileName($part);
172
+ //fwrite($this->file,"</CategoryList>\n<CommodityList>\n");
173
+ $fileRecordCount=0;
174
+ $part=1;
175
+ $this->_createNewCommoditiyFile($part);
176
+ $part++;
177
+ $addedProducts = array();
178
+ foreach($addedCategories as $category) {
179
+ //Mage::app()->setCurrentStore($category->getStoreId());
180
+
181
+ $count = Mage::getModel('catalog/product')->getCollection()
182
+ ->addCategoryFilter($category)
183
+ ->count();
184
+ $pageSize = 400;
185
+ $currIndex = 0;
186
+ while($currIndex < $count) {
187
+ $productCollection = Mage::getModel('catalog/product')->getCollection()
188
+
189
+ ->addCategoryFilter($category)
190
+
191
+ ->addAttributeToSelect('name')
192
+ ->addAttributeToSelect('sku')
193
+ ->addAttributeToSelect('country_of_manufacture')
194
+ ->addAttributeToSelect('description')
195
+ ->addAttributeToSelect('product_url')
196
+ ->addAttributeToSelect('type_id')
197
+ ->addAttributeToSelect('pb_pbgsp_upload')
198
+ // ->addUrlRewrite($category->getId()) //this will add the url rewrite.
199
+ ->addAttributeToSelect('price')
200
+ ->addAttributeToSelect('weight');
201
+
202
+ $baseURL = Mage::app()->getStore($category->getStoreId())->getBaseUrl();
203
+ $productUrlFormat = $baseURL ."catalog/product/view/id/%d/";
204
+ foreach($productCollection as $product) {
205
+ /* @var $product Mage_Catalog_Model_Product */
206
+ if($product->getTypeId() == 'virtual')
207
+ continue;
208
+ $cateIds = $product->getCategoryIds();
209
+ $cateId = 0;
210
+ foreach($cateIds as $cId) {
211
+ $cateId = $cId;//get lower level of category
212
+ }
213
+ $prodCat = $this->_getSelectedCategory($addedCategories,$cateId);
214
+ if(!$prodCat)
215
+ $prodCat = $category;
216
+ $cIds = explode('/',$prodCat->getPath());
217
+ $cIds = array_slice($cIds,1);//remove root category
218
+ $prodCat->setData('id_path',implode(':',$cIds));
219
+ $prodCat->setData('name_path',$this->_getCatNamePath($addedCategories,$cIds));
220
+ if($product->getTypeId() == 'configurable' ) {
221
+ $productType = $product->getTypeInstance(true);
222
+ $allowedProducts = $productType->getUsedProducts(null, $product);
223
+ /** @var $childProduct Mage_Catalog_Model_Product */
224
+
225
+ foreach($allowedProducts as $childProduct) {
226
+ if(!array_key_exists($childProduct->getSku(),$addedProducts)) {
227
+ if( $fileRecordCount > $maxRecordsCount)
228
+ {
229
+ $this->_createNewCommoditiyFile($part);
230
+ $fileRecordCount=0;
231
+ $part++;
232
+ }
233
+ $pbChildProduct = new Pb_Pbgsp_Model_Catalog_Product($childProduct->getId(),sprintf($productUrlFormat,$product->getId()));
234
+ $this->writeProduct($pbChildProduct,$cateId,$product->getSku(),$prodCat);
235
+ $addedProducts[$childProduct->getSku()] = "added";
236
+ $prodCount++;
237
+ $fileRecordCount++;
238
+ }
239
+ }
240
+ }
241
+ else {
242
+ if(!array_key_exists($product->getSku(),$addedProducts)) {
243
+ $pbProduct = new Pb_Pbgsp_Model_Catalog_Product($product,sprintf($productUrlFormat,$product->getId()));
244
+ if( $fileRecordCount > $maxRecordsCount)
245
+ {
246
+ $this->_createNewCommoditiyFile();
247
+ $fileRecordCount=0;
248
+ $part++;
249
+ }
250
+ $this->writeProduct($pbProduct,$cateId,null,$prodCat);
251
+ $prodCount++;
252
+ $fileRecordCount++;
253
+ $addedProducts[$product->getSku()] = "added";
254
+
255
+ }
256
+
257
+
258
+ }
259
+
260
+
261
+ }
262
+ $currIndex += $pageSize;
263
+
264
+ }
265
+ }
266
+
267
+
268
+
269
+ // fwrite($this->file,"</CommodityList>\n</Catalog>\n");
270
+ fflush($this->file);
271
+
272
+ $this->_stripPartFromFileName($part);
273
+ }
274
+
275
+ private function _getCatNamePath($categories,$cateIds) {
276
+
277
+ $names = array();
278
+ foreach($cateIds as $id) {
279
+ foreach($categories as $cat) {
280
+ if($cat->getId() == $id) {
281
+ array_push($names, $cat->getName());
282
+ break;
283
+ }
284
+ }
285
+ }
286
+ // Pb_Pbgsp_Model_Util::log($names);
287
+ return implode('|',$names);
288
+ }
289
+
290
+ /**
291
+ * Updates the pb_pbgsp_upload time in all uploaded products
292
+ */
293
+ public function updateLastProductUpload() {
294
+
295
+ $attribute = Mage::getModel('eav/config')->getAttribute('catalog_product', 'pb_pbgsp_upload');
296
+ if(!$attribute->getAttributeId()) {
297
+ $setup = new Mage_Eav_Model_Entity_Setup('core_setup');
298
+ $setup->addAttribute('catalog_product', 'pb_pbgsp_upload', array(
299
+ 'label' => 'Last Pb upload timestampt',
300
+ 'type' => 'varchar',
301
+ 'input' => 'text',
302
+ 'visible' => false,
303
+ 'required' => false,
304
+ 'position' => 1,
305
+ ));
306
+ }
307
+
308
+ $productIds = array_unique($this->productIds);
309
+ Pb_Pbgsp_Model_Util::log('Uploaded products' . count($productIds));
310
+ $updated = 0;
311
+ foreach ($productIds as $prodId) {
312
+ $product = Mage::getModel("catalog/product")->load($prodId);
313
+ //Pb_Pbgsp_Model_Util::log('Updating product '. $product->getSKU());
314
+ $product->setPbPbgspUpload(time());
315
+ try{
316
+ $product->save();
317
+ $updated++;
318
+ }catch(Exception $e){
319
+ Pb_Pbgsp_Model_Util::log("There was a problem saving the product with sku ". $product->getSku() ." Error Message \n" . $e->getMessage());
320
+ }
321
+
322
+ //Pb_Pbgsp_Model_Util::log($product->getId()." ".$product->getName()." ".$product->getPbPbgspUpload());
323
+ }
324
+ Pb_Pbgsp_Model_Util::log("$updated products' pb_pbgsp_upload updated");
325
+ }
326
+
327
+ /**
328
+ * Uploads the xml file to clearpath SFTP server
329
+ */
330
+
331
+ private function _getNotificationDir() {
332
+ $tmpDir = $this->_getTempDir();
333
+ $configOptions = Mage::getModel('core/config_options');
334
+ $notificationDir = $tmpDir . 'notifications';
335
+ $configOptions->createDirIfNotExists( $notificationDir);
336
+ chmod($notificationDir, 0777);
337
+ return $notificationDir;
338
+ }
339
+
340
+ public function processStatusNotifications() {
341
+ try {
342
+
343
+ $adminEmail = Pb_Pbgsp_Model_Credentials::getAdminEmail();
344
+ if(!isset($adminEmail) || $adminEmail=='')
345
+ return;
346
+ $notificationDir = $this->_getNotificationDir();
347
+ $this->_downloadStatusNotifications($notificationDir);
348
+ $notificationFiles = array_diff(scandir($notificationDir), array('..', '.'));
349
+ if(count($notificationFiles) > 0) {
350
+ $mail = new Zend_Mail();
351
+ $mail->setFrom('no-reply@pb.com','Pitney Bowes');
352
+ $mail->addTo($adminEmail)
353
+ ->setSubject('Catalog Export Error')
354
+ ->setBodyText('Catalog Export Error. Please see attached files.');
355
+ $fileCount = 0;
356
+ foreach($notificationFiles as $notificationFile) {
357
+ if($this->_endsWith($notificationFile,'.err') || $this->_endsWith($notificationFile,'.log') ) {
358
+ $file = $notificationDir.'/'. $notificationFile;
359
+ $at = new Zend_Mime_Part(file_get_contents($file));
360
+ $at->filename = basename($file);
361
+ $at->disposition = Zend_Mime::DISPOSITION_ATTACHMENT;
362
+ $at->encoding = Zend_Mime::ENCODING_8BIT;
363
+
364
+ $mail->addAttachment($at);
365
+ $fileCount++;
366
+ }
367
+
368
+ }
369
+ if($fileCount > 0) {
370
+ $mail->send();
371
+ Pb_Pbgsp_Model_Util::log("Email sent with error files.");
372
+ }
373
+
374
+ else {
375
+ Pb_Pbgsp_Model_Util::log(" No error files found.");
376
+ }
377
+ //keep these files until next upload and delete files from old upload
378
+ $this->_cleanNotificationFiles();
379
+ }
380
+ }
381
+ catch (Exception $e) {
382
+ Pb_Pbgsp_Model_Util::log("Error in processStatusNotifications:". $e->getMessage());
383
+ Pb_Pbgsp_Model_Util::log($e->getTraceAsString());
384
+
385
+ }
386
+
387
+ }
388
+ private function _cleanNotificationFiles() {
389
+ //keep resent files until next upload and delete files from old upload
390
+ $lastExportedFiles = $this->_getLastExportedFileNames();
391
+ if(!$lastExportedFiles)
392
+ return;
393
+ $notificationDir = $this->_getNotificationDir();
394
+ $notificationFiles = array_diff(scandir($notificationDir), array('..', '.'));
395
+
396
+ foreach($notificationFiles as $notificationFile) {
397
+ $path_parts = pathinfo($notificationFile);
398
+ $localFileNameWithoutExt = $path_parts['filename'];
399
+ $isOldFile = true;
400
+ foreach($lastExportedFiles as $lastExportedFile) {
401
+ $lastExportedFileNameWithoutExt = str_replace('.gpg','',str_replace('.csv','',$lastExportedFile));
402
+ if($lastExportedFileNameWithoutExt == $localFileNameWithoutExt) {
403
+ $isOldFile = false;
404
+ break;
405
+ }
406
+ }
407
+ if($isOldFile) {
408
+ //this is from 2nd last upload, remove it from disk
409
+ unlink($notificationDir.'/'.$notificationFile);
410
+ }
411
+ }
412
+
413
+ }
414
+ private function _downloadStatusNotifications($notificationDir) {
415
+
416
+ $credentials = $this->_getSftpCredentials();
417
+ try {
418
+ $sftpDumpFile = new Varien_Io_Sftp();
419
+ $sftpDumpFile->open(
420
+ $credentials
421
+ );
422
+ $rootDir = Pb_Pbgsp_Model_Credentials::getSftpCatalogDirectory();
423
+ if(!$this->_endsWith($rootDir,'/'))
424
+ $rootDir = $rootDir.'/';
425
+ $processedDir = $rootDir.'outbound';
426
+ $sftpDumpFile->cd($processedDir);
427
+ $files = $sftpDumpFile->ls();
428
+
429
+ //Pb_Pbgsp_Model_Util::log($files);
430
+
431
+ $exportedFiles = $this->_getLastExportedFileNames();
432
+ if(!$exportedFiles)
433
+ return;
434
+ foreach($files as $file) {
435
+ foreach($exportedFiles as $exportedFile) {
436
+ $fileNameWithoutExtension = str_replace(".gpg","",str_replace(".csv","",$exportedFile));
437
+ if($this->_startsWith($file['text'],$fileNameWithoutExtension)) {
438
+ $dest = $notificationDir.'/'.$file['text'];
439
+ $sftpDumpFile->read($file['text'],$dest);
440
+ }
441
+ }
442
+
443
+ }
444
+ $sftpDumpFile->close();
445
+ }
446
+ catch (Exception $e) {
447
+ Pb_Pbgsp_Model_Util::log($e->getTraceAsString());
448
+ Pb_Pbgsp_Model_Util::log("Pb Module could not connect to sftp server: ".$credentials['host']." Wrong username/password. Postponing catalog upload.");
449
+ return;
450
+ }
451
+
452
+ }
453
+
454
+ private function _encryptExportedFiles($exportedFiles) {
455
+ $encryptedFiles = array();
456
+ $publicKey = Pb_Pbgsp_Model_Credentials::getPublicKey();
457
+ if(!isset($publicKey) || $publicKey=='') {
458
+ Pb_Pbgsp_Model_Util::log('Public key is not set cannot encrypt catalog files.');
459
+ return $exportedFiles;
460
+ }
461
+ try {
462
+ $gnupg = new gnupg();
463
+ $keyInfo = $gnupg->import($publicKey);
464
+ $gnupg->addencryptkey($keyInfo['fingerprint']);
465
+ $tmpDir = $this->_getTempDir();
466
+ Pb_Pbgsp_Model_Util::log('Encrypting the files.');
467
+ foreach($exportedFiles as $exportedFile) {
468
+ $fileName = $tmpDir . $exportedFile;
469
+ if(is_dir($fileName))
470
+ continue;
471
+ $encryptedFileName = $exportedFile.'.gpg';
472
+ Pb_Pbgsp_Model_Util::log("Encrypted file $encryptedFileName");
473
+ file_put_contents($tmpDir.$encryptedFileName,$gnupg->encrypt(file_get_contents($fileName)));
474
+ $encryptedFiles[] = $encryptedFileName;
475
+ }
476
+ return $encryptedFiles;
477
+ }
478
+ catch (Exception $e) {
479
+ Pb_Pbgsp_Model_Util::log($e->getTraceAsString());
480
+ Pb_Pbgsp_Model_Util::log("Error in encryption.");
481
+ return $encryptedFiles;
482
+ }
483
+
484
+
485
+ }
486
+ public function upload() {
487
+
488
+ $tmpDir = $this->_getTempDir();
489
+ $exportedFiles = array_diff(scandir($tmpDir), array('..', '.'));
490
+ if (count($this->productIds) == 0) {
491
+ // No new products to send, don't send anything.
492
+ $this->_removeExportedFiles($exportedFiles);
493
+
494
+ return;
495
+ }
496
+
497
+ Pb_Pbgsp_Model_Util::log("Pb catalog file upload started");
498
+ try {
499
+
500
+ if(Pb_Pbgsp_Model_Credentials::isEncryptionEnabled()) {
501
+ $exportedFiles = $this->_encryptExportedFiles($exportedFiles);
502
+ }
503
+ else {
504
+ Pb_Pbgsp_Model_Util::log('Encryption is not enabled.'.Pb_Pbgsp_Model_Credentials::isEncryptionEnabled());
505
+ }
506
+ $sftpDumpFile = new Varien_Io_Sftp();
507
+ $credentials = $this->_getSftpCredentials();
508
+
509
+ Pb_Pbgsp_Model_Util::log($credentials);
510
+
511
+ $sftpDumpFile->open(
512
+ $credentials
513
+ );
514
+ //Upload to SFTP
515
+ $rootDir = Pb_Pbgsp_Model_Credentials::getSftpCatalogDirectory();
516
+ if(!$this->_endsWith($rootDir,'/'))
517
+ $rootDir = $rootDir.'/';
518
+ $tmpSFTPDir = $rootDir.'tmp';
519
+ $inboundDir = $rootDir.'inbound';
520
+ $uploadedFiles = array();
521
+ foreach($exportedFiles as $exportedFile) {
522
+ $fileName = $tmpDir . $exportedFile;
523
+ if(is_dir($fileName))
524
+ continue;
525
+
526
+ Pb_Pbgsp_Model_Util::log("CD to $tmpSFTPDir");
527
+ $sftpDumpFile->cd($tmpSFTPDir);
528
+ Pb_Pbgsp_Model_Util::log("Uploading $fileName");
529
+ $sftpDumpFile->write($exportedFile, file_get_contents($fileName));
530
+ Pb_Pbgsp_Model_Util::log("Moving ".$tmpSFTPDir."/$exportedFile"." to ".$inboundDir."/$exportedFile");
531
+ $sftpDumpFile->mv($tmpSFTPDir."/$exportedFile",$inboundDir."/$exportedFile");
532
+ $uploadedFiles[] = $exportedFile;
533
+ }
534
+ $sftpDumpFile->close();
535
+
536
+ } catch (Exception $e) {
537
+ Pb_Pbgsp_Model_Util::log($e->getTraceAsString());
538
+ Pb_Pbgsp_Model_Util::log("Pb Module could not connect to sftp server: ".$credentials['host']." Wrong username/password. Postponing catalog upload.");
539
+ return;
540
+ }
541
+
542
+ Pb_Pbgsp_Model_Util::log("Pb catalog file upload ended");
543
+
544
+ $this->_removeExportedFiles($exportedFiles);
545
+ $this->updateLastProductUpload();
546
+ $this->_logExportedFileInDB($uploadedFiles);
547
+ }
548
+
549
+ private function _getExportedFilesVariable() {
550
+ $collection = Mage::getModel("pb_pbgsp/variable")->getCollection();
551
+ $exportedFilesVariable = null;
552
+ foreach ($collection as $variable) {
553
+
554
+ if ($variable->getName() == "exportedFiles") {
555
+ $exportedFilesVariable = $variable;
556
+ break;
557
+ }
558
+
559
+ }
560
+ return $exportedFilesVariable;
561
+ }
562
+ private function _getLastExportedFileNames() {
563
+ $exportedFilesVariable = $this->_getExportedFilesVariable();
564
+ if(!isset($exportedFilesVariable))
565
+ return false;
566
+ $exportedFiles = explode('|',$exportedFilesVariable->getValue());
567
+ return $exportedFiles;
568
+ }
569
+ private function _logExportedFileInDB($exportedFiles) {
570
+ $strExportedFiles = implode('|',$exportedFiles);
571
+ $exportedFilesVariable = $this->_getExportedFilesVariable();
572
+ if(!isset($exportedFilesVariable))
573
+ {
574
+ $exportedFilesVariable = Mage::getModel("pb_pbgsp/variable");
575
+ $exportedFilesVariable->setName("exportedFiles");
576
+ }
577
+
578
+ $exportedFilesVariable->setValue($strExportedFiles);
579
+ $exportedFilesVariable->save();
580
+ }
581
+ private function _startsWith($haystack, $needle) {
582
+ // search backwards starting from haystack length characters from the end
583
+ return $needle === "" || strrpos($haystack, $needle, -strlen($haystack)) !== FALSE;
584
+ }
585
+ private function _endsWith($haystack, $needle) {
586
+ // search forward starting from end minus needle length characters
587
+ return $needle === "" || (($temp = strlen($haystack) - strlen($needle)) >= 0 && strpos($haystack, $needle, $temp) !== FALSE);
588
+ }
589
+ private function _removeExportedFiles($exportedFiles) {
590
+ $tmpDir = $this->_getTempDir();
591
+ foreach($exportedFiles as $exportedFile) {
592
+ $fileName = $tmpDir . $exportedFile;
593
+ if(is_dir($fileName))
594
+ continue;
595
+ unlink($fileName);
596
+ $fileName = str_replace(".gpg","",$fileName);//remove unencrypted file
597
+ if(is_file($fileName))
598
+ unlink($fileName);
599
+ }
600
+ }
601
+
602
+
603
+
604
+
605
+
606
+
607
+ /**
608
+ * @param Pb_Pbgsp_Model_Catalog_Product $product
609
+ * @param string $categoryCode
610
+ */
611
+ private function writeProduct($product,$categoryCode,$parentSku,$category)
612
+ {
613
+ if ($product->shouldUpload($this->lastDiff)) {
614
+ array_push($this->productIds,$product->getMageProduct()->getId());
615
+ // Pb_Pbgsp_Model_Util::log("Product SKU:" . $product->getSKU());
616
+ $product->writeToFile($this->file,$categoryCode,$parentSku,$category);
617
+ fflush($this->file);
618
+ }
619
+ }
620
+
621
+ public static function stripHtml($text) {
622
+ return preg_replace("/<\s*\/\s*\w\s*.*?>|<\s*br\s*>/",'',preg_replace("/<\s*\w.*?>/", '', $text));
623
+ }
624
+
625
+ /**
626
+ * Loads products without categories and logs them in log file
627
+ */
628
+ public function logProdWithoutCategories() {
629
+ $productCollection = Mage::getResourceModel('catalog/product_collection')
630
+ ->setStoreId(0)
631
+ ->joinField('category_id', 'catalog/category_product', 'category_id', 'product_id=entity_id', null, 'left')
632
+ ->addAttributeToFilter('category_id', array('null' => true))
633
+ ->addAttributeToSelect('*');
634
+
635
+
636
+ $productCollection->getSelect()->group('product_id')->distinct(true);
637
+
638
+ $productCollection->load();
639
+ $skus = '';
640
+ foreach($productCollection as $product) {
641
+ $skus = $skus . $product->getSku() . ",";
642
+
643
+ }
644
+ Pb_Pbgsp_Model_Util::log("Products without categories:" . $skus);
645
+ }
646
+
647
+ /**
648
+ * @return array
649
+ */
650
+ private function _getSftpCredentials()
651
+ {
652
+ $credentials = array(
653
+ 'host' => Pb_Pbgsp_Model_Credentials::getSftpHostname(),
654
+ "port" => Pb_Pbgsp_Model_Credentials::getSftpPort(),
655
+ 'username' => Pb_Pbgsp_Model_Credentials::getSftpUsername(),
656
+ 'password' => Pb_Pbgsp_Model_Credentials::getSftpPassword(),
657
+ 'timeout' => '10'
658
+ );
659
+ return $credentials;
660
+ }
661
+
662
+ /**
663
+ * @param $part
664
+ */
665
+ private function _stripPartFromFileName($part)
666
+ {
667
+ if ($part == 2) {
668
+ //there is only one part remove part1 from filename
669
+ rename($this->filename, str_replace('_part1', '', $this->filename));
670
+ }
671
+ }
672
+ }
673
+ ?>
app/code/local/Pb/Pbgsp/Model/Catalog/Product.php ADDED
@@ -0,0 +1,198 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class Pb_Pbgsp_Model_Catalog_Product
5
+ *
6
+ */
7
+ class Pb_Pbgsp_Model_Catalog_Product {
8
+ /*@var $product Mage_Catalog_Model_Product */
9
+ protected $product;
10
+ protected $_productUrl;
11
+
12
+
13
+ public function __construct($product,$url=null) {
14
+ $id = $product;
15
+ if (gettype($product) == "object" && get_class($id) == "Mage_Catalog_Model_Product") {
16
+ $this -> product = $product;
17
+ }
18
+ else
19
+ $this -> product = Mage::getModel('catalog/product') -> load($id);
20
+ $this->_productUrl = $url;
21
+ }
22
+
23
+ /**
24
+ * Created by BigPixel 6/15/2012
25
+ * @return Mage_Catalog_Model_Product
26
+ */
27
+ public function getMageProduct() {
28
+ return $this->product;
29
+ }
30
+
31
+ /**
32
+ * @return string
33
+ */
34
+ public function getSKU() {
35
+ return $this -> product -> getSku();
36
+ }
37
+
38
+ public function getPrice() {
39
+ return $this->product->getPrice();
40
+ }
41
+
42
+ public function getUPC() {
43
+ }
44
+
45
+ /**
46
+ * @return string
47
+ */
48
+ public function getURL() {
49
+ if($this->_productUrl)
50
+ return $this->_productUrl;
51
+ return $this -> product -> getProductUrl();
52
+ }
53
+
54
+ /**
55
+ * @return int
56
+ * Gets the id of the category that is direct parent of the product
57
+ */
58
+ public function getCategoryCode() {
59
+ $categories = $this -> product -> getCategoryCollection();
60
+
61
+ $maxDepth = -1;
62
+ $finalCategory = null;
63
+ foreach ($categories as $category) {
64
+ $pathComponents = explode("/",$category->getPath());
65
+ if (count($pathComponents) > $maxDepth) {
66
+ $finalCategory = $category;
67
+ $maxDepth = count($pathComponents);
68
+ }
69
+ }
70
+ return $finalCategory->getId();
71
+ }
72
+
73
+ /**
74
+ * @return string
75
+ *
76
+ */
77
+ public function getCountryOfOrigin() {
78
+ return $this->product->getCountryOfManufacture(); //added by kamran,1/14/2012
79
+ }
80
+
81
+ /**
82
+ * @return string
83
+ */
84
+ public function getDescription() {
85
+ return utf8_encode($this -> product -> getDescription());
86
+ }
87
+ public function getShortDescription() {
88
+ return utf8_encode($this -> product -> getShortDescription());
89
+ }
90
+ /**
91
+ * @return string
92
+ */
93
+ public function getName() {
94
+ return utf8_encode($this -> product -> getName());
95
+ }
96
+
97
+ /**
98
+ * @return flaot
99
+ */
100
+ public function getWeight() {
101
+ return $this -> product -> getWeight();
102
+ }
103
+
104
+ public function getSize() {
105
+ }
106
+
107
+ /**
108
+ * @param $file
109
+ * @param $categoryCode
110
+ * Write this product into the xml file
111
+ */
112
+ public function writeToFile($file,$categoryCode,$parentSku,$category) {
113
+ /** $categoryCode is passed in method because we don't have categoryCode for child products. BigPixel 6/11/2012 */
114
+ $name = Pb_Pbgsp_Model_Catalog_File::stripHtml($this -> getName());
115
+ $name = preg_replace("/[^A-Za-z0-9 ,.\-\+=;:\\(){}\[\]@?%$#]/", '', $name);
116
+ $string = "<Commodity>\n";
117
+ $string .= "<CategoryCode><![CDATA[" . htmlentities($categoryCode) . "]]></CategoryCode>\n";
118
+ $string .= "<SKU><![CDATA[" . htmlentities($this -> getSKU()) . "]]></SKU>\n";
119
+ $string .= "<Name><![CDATA[" . htmlentities($name) . "]]></Name>\n";
120
+ $string .= "<CountryOfOrigin><![CDATA[" . htmlentities(preg_replace("/[^A-Za-z0-9]/",'',$this -> getCountryOfOrigin())) . "]]></CountryOfOrigin>\n"; //added by kamran,1/14/2012
121
+ $description = Pb_Pbgsp_Model_Catalog_File::stripHtml($this -> getDescription());
122
+ $description = preg_replace("/[^A-Za-z0-9 ,.\-\+=;:\\(){}\[\]@?%$#]/", '', $description);
123
+ if (strlen($description) >= 2000) {
124
+
125
+ $description = $this -> chopString($description, 1999);
126
+ }
127
+
128
+ $shortDescription = Pb_Pbgsp_Model_Catalog_File::stripHtml($this -> getShortDescription());
129
+ $shortDescription = preg_replace("/[^A-Za-z0-9 ,.\-\+=;:\\(){}\[\]@?%$#]/", '', $shortDescription);
130
+ if (strlen($shortDescription) >= 2000) {
131
+
132
+ $shortDescription = $this -> chopString($shortDescription, 1999);
133
+ }
134
+ $string .= "<Description><![CDATA[" . $description . "]]></Description>\n";
135
+ $string .= "<URL><![CDATA[" . htmlentities($this -> getURL()) . "]]></URL>\n";
136
+
137
+ if ($this->getWeight() != null) {
138
+ $string .= "<Size><Weight><![CDATA[" . $this -> getWeight() . "]]></Weight><Source><![CDATA[" . Pb_Pbgsp_Model_Credentials::getMerchantCode() . "]]></Source></Size>\n";
139
+ }
140
+ $string .= "</Commodity>\n";
141
+ // fputcsv($this->file,array('MERCHANT_COMMODITY_REF_ID','COMMODITY_NAME_TITLE','SHORT_DESCRIPTION',
142
+ // 'LONG_DESCRIPTION','RETAILER_ID','COMMODITY_URL','RETAILER_UNIQUE_ID','PCH_CATEGORY_ID',
143
+ // 'RH_CATEGORY_ID','STANDARD_PRICE','WEIGHT_UNIT','DISTANCE_UNIT','COO','IMAGE_URL','PARENT_SKU',
144
+ // 'CHILD_SKU','PARCELS_PER_SKU','UPC','UPC_CHECK_DIGIT','GTIN','MPN','ISBN','BRAND','MANUFACTURER',
145
+ // 'MODEL_NUMBER','MANUFACTURER_STOCK_NUMBER','COMMODITY_CONDITION','COMMODITY_HEIGHT',
146
+ // 'COMMODITY_WIDTH','COMMODITY_LENGTH','PACKAGE_WEIGHT','PACKAGE_HEIGHT','PACKAGE_WIDTH',
147
+ // 'PACKAGE_LENGTH','HAZMAT','ORMD','CHEMICAL_INDICATOR','PESTICIDE_INDICATOR','AEROSOL_INDICATOR',
148
+ // 'RPPC_INDICATOR','BATTERY_TYPE','NON_SPILLABLE_BATTERY','FUEL_RESTRICTION','SHIP_ALONE',
149
+ // 'RH_CATEGORY_ID_PATH','RH_CATEGORY_NAME_PATH','RH_CATEGORY_URL_PATH','GPC','COMMODITY_WEIGHT',
150
+ // 'HS_CODE','CURRENCY'));
151
+ $merchantCode = Pb_Pbgsp_Model_Credentials::getMerchantCode();
152
+ fputcsv($file,array($this -> getSKU(),$name,$shortDescription,
153
+ $description,$merchantCode,$this -> getURL(),$merchantCode,'',
154
+ $categoryCode,$this->getPrice(),'lb','',$this->getCountryOfOrigin(),'','',
155
+ '','','','','','','','','',
156
+ '','','','',
157
+ '','',$this -> getWeight(),'','',
158
+ '','','','','','',
159
+ '','','','','',
160
+ strval($category->getData('id_path')),$category->getData('name_path')
161
+ //,'','','','',$category->getData('store')->getCurrentCurrencyCode()
162
+ ));
163
+ //fwrite($file, $string);
164
+ }
165
+
166
+ /**
167
+ * @param $lastDiff
168
+ * @return bool
169
+ * Checks whether we need to upload this product or not
170
+ */
171
+ public function shouldUpload($lastDiff) {
172
+
173
+ $lastUpload = $this -> product -> getPbPbgspUpload();
174
+ //Pb_Pbgsp_Model_Util::log('Product '. $this -> getSKU() . ' lastUpload='. $lastUpload . ' '. date('m-d-Y H:i:s',$lastUpload));
175
+ if (!$lastUpload) {
176
+ // First upload.
177
+ return true;
178
+ } else if ($lastDiff <= $lastUpload - (30 * 60)) {
179
+ // Added after the last diff
180
+ return true;
181
+ } else {
182
+ return false;
183
+ }
184
+ }
185
+
186
+ public function chopString($str, $len) {
187
+ $end = $len;
188
+ $lastFour = substr($str,$end - strlen("&amp"),strlen("&amp"));
189
+ $pos = strpos($lastFour,"&");
190
+ if (!($pos === FALSE)) {
191
+ $end = $end - strlen("&amp") + $pos;
192
+ }
193
+ $ret = substr($str,0,$end);
194
+ return $ret;
195
+ }
196
+
197
+ }
198
+ ?>
app/code/local/Pb/Pbgsp/Model/Credentials.php ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Pb_Pbgsp_Model_Credentials {
3
+
4
+ public static function decrypt($string) {
5
+ if (!empty($string)) {
6
+ return Mage::helper('core')->decrypt($string);
7
+ }
8
+ return "";
9
+ }
10
+
11
+ public static function getApiUrl() {
12
+ return Mage::getStoreConfig('carriers/pbgsp/apiurl');
13
+ }
14
+ public static function getMaxRecordsCount() {
15
+ return Mage::getStoreConfig('carriers/pbgsp/catalog_size');
16
+ }
17
+ public static function getAdminEmail() {
18
+ return Mage::getStoreConfig('carriers/pbgsp/admin_email');
19
+ }
20
+ public static function getCatalogSenderID() {
21
+ return Mage::getStoreConfig('carriers/pbgsp/catalog_sender_id');
22
+ }
23
+ public static function getDeliveryAdjustmentMinDays() {
24
+ return self::_getIntValue(Mage::getStoreConfig('carriers/pbgsp/delivery_adjustment_min_days'));
25
+ }
26
+ public static function getDeliveryAdjustmentMaxDays() {
27
+ return self::_getIntValue(Mage::getStoreConfig('carriers/pbgsp/delivery_adjustment_max_days'));
28
+ }
29
+ public static function getDomesticShippingFee() {
30
+ return self::_getFloatValue(Mage::getStoreConfig('carriers/pbgsp/domestic_shipping_fee'));
31
+ }
32
+ public static function getDomesticShippingOption() {
33
+ return Mage::getStoreConfig('carriers/pbgsp/domestic_shipping_option');
34
+ }
35
+ public static function isASNGenerationEnabled() {
36
+ return Mage::getStoreConfig('carriers/pbgsp/asn_generation_enabled');
37
+ }
38
+ public static function getHandlingFee() {
39
+
40
+ return self::_getFloatValue(Mage::getStoreConfig('carriers/pbgsp/handlingfee'));
41
+ }
42
+ private static function _getIntValue($value) {
43
+ $number = 0;
44
+
45
+ if(isset($value)) {
46
+ if(is_numeric($value)) {
47
+ $number = intval($value);
48
+ }
49
+ }
50
+ return $number;
51
+ }
52
+ private static function _getFloatValue($value) {
53
+ $number = 0;
54
+
55
+ if(isset($value)) {
56
+ if(is_numeric($value)) {
57
+ $number = floatval($value);
58
+ }
59
+ }
60
+ return $number;
61
+ }
62
+ public static function getHandlingOption() {
63
+ return Mage::getStoreConfig('carriers/pbgsp/handlingoption');
64
+ }
65
+ /* public static function getWSDL() {
66
+ if(Mage::getStoreConfig('carriers/pbgsp/environment') == 1) {
67
+ // Production
68
+ } else {
69
+ // Staging
70
+ return "./app/code/local/Pb/Pbgsp/etc/cpAPI.wsdl.xml";
71
+ }
72
+ }*/
73
+
74
+ public static function getUsername() {
75
+ return self::decrypt(Mage::getStoreConfig('carriers/pbgsp/apiuser'));
76
+ }
77
+
78
+ public static function getPassword() {
79
+ return self::decrypt(Mage::getStoreConfig('carriers/pbgsp/apipass'));
80
+ }
81
+
82
+ public static function getMerchantCode() {
83
+ return self::decrypt(Mage::getStoreConfig('carriers/pbgsp/merchantcode'));
84
+ }
85
+
86
+ public static function getSftpUsername() {
87
+ return self::decrypt(Mage::getStoreConfig('carriers/pbgsp/ftpuser'));
88
+ }
89
+ public static function getSftpPassword() {
90
+ return self::decrypt(Mage::getStoreConfig('carriers/pbgsp/ftppass'));
91
+ }
92
+ public static function getSftpHostname() {
93
+ return Mage::getStoreConfig('carriers/pbgsp/ftphost');
94
+ }
95
+ public static function getSftpPort() {
96
+ return Mage::getStoreConfig('carriers/pbgsp/ftpport');
97
+ }
98
+ public static function getSftpCatalogDirectory() {
99
+ return self::decrypt(Mage::getStoreConfig('carriers/pbgsp/ftpdir'));
100
+ }
101
+ public static function isEncryptionEnabled() {
102
+ return Mage::getStoreConfig('carriers/pbgsp/catalog_encryption_enabled');
103
+ }
104
+ public static function getPublicKey() {
105
+ return Mage::getStoreConfig('carriers/pbgsp/encryption_public_key');
106
+ }
107
+ public static function getOrderMgmtAPIUrl() {
108
+ return Mage::getStoreConfig('carriers/pbgsp/order_mgmt_api');
109
+ }
110
+ public static function getPBID() {
111
+ return "16061";
112
+ }
113
+ }
114
+ ?>
app/code/local/Pb/Pbgsp/Model/Creditmemo/Duty.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Pb_Pbgsp_Model_Creditmemo_Duty extends Mage_Sales_Model_Order_Creditmemo_Total_Tax
3
+ {
4
+ public function collect(Mage_Sales_Model_Order_Creditmemo $creditmemo)
5
+ {
6
+ Pb_Pbgsp_Model_Util::log('Pb_Pbgsp_Model_Creditmemo_Duty.collect');
7
+ $len = strlen("pbgsp_");
8
+ $order = $creditmemo->getOrder();
9
+ $shipMethod = $order->getShippingMethod();
10
+ if (strlen($shipMethod) > $len && substr($shipMethod, 0, $len) == "pbgsp_") {
11
+ $totalTax = 0;
12
+ $baseTotalTax = 0;
13
+ $totalHiddenTax = 0;
14
+ $baseTotalHiddenTax = 0;
15
+ if ($order->getTaxAmount()) {
16
+ $totalTax = $order->getTaxAmount();
17
+ $baseTotalTax = $totalTax;
18
+ }
19
+ $creditmemo->setTaxAmount($totalTax);
20
+ $creditmemo->setBaseTaxAmount($baseTotalTax);
21
+ $creditmemo->setHiddenTaxAmount($totalHiddenTax);
22
+ $creditmemo->setBaseHiddenTaxAmount($baseTotalHiddenTax);
23
+ $creditmemo->setGrandTotal($creditmemo->getGrandTotal() + $totalTax + $totalHiddenTax);
24
+ $creditmemo->setBaseGrandTotal($creditmemo->getBaseGrandTotal() + $baseTotalTax + $baseTotalHiddenTax);
25
+ } else {
26
+ parent::collect($creditmemo);
27
+ }
28
+
29
+ return $this;
30
+ }
31
+ }
app/code/local/Pb/Pbgsp/Model/Handlingoptions.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Created by JetBrains PhpStorm.
4
+ * User: muhammad.kamran
5
+ * Date: 6/6/12
6
+ * Time: 11:36 PM
7
+ * To change this template use File | Settings | File Templates.
8
+ */
9
+ class Pb_Pbgsp_Model_Handlingoptions {
10
+ public function toOptionArray()
11
+ {
12
+ return array(
13
+ array('value'=>1, 'label'=>'Per Order'),
14
+ array('value'=>2, 'label'=>'Per Item'),
15
+
16
+ );
17
+ }
18
+ }
app/code/local/Pb/Pbgsp/Model/Helper.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Pb_Pbgsp_Model_Helper {
3
+ public static function displayInfo($var) {
4
+ echo "<hr/>Class type: ".get_class($var)."<br/>Methods:<br/>";
5
+ $methods = get_class_methods($var);
6
+ foreach ($methods as $method) {
7
+ echo $method."<br/>";
8
+ }
9
+ }
10
+ }
11
+ ?>
app/code/local/Pb/Pbgsp/Model/Inboundparcel.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Pb_Pbgsp_Model_Inboundparcel extends Mage_Core_Model_Abstract {
4
+ public function _construct()
5
+ {
6
+ parent::_construct();
7
+ $this->_init('pb_pbgsp/inboundparcel');
8
+ }
9
+ }
10
+
11
+ ?>
app/code/local/Pb/Pbgsp/Model/Invoice/Duty.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Pb_Pbgsp_Model_Invoice_Duty extends Mage_Sales_Model_Order_Invoice_Total_Tax
3
+ {
4
+ public function collect(Mage_Sales_Model_Order_Invoice $invoice)
5
+ {
6
+ Pb_Pbgsp_Model_Util::log('Pb_Pbgsp_Model_Invoice_Duty.collect');
7
+ $len = strlen("pbgsp_");
8
+ $order = $invoice->getOrder();
9
+ $shipMethod = $order->getShippingMethod();
10
+ if (strlen($shipMethod) > $len && substr($shipMethod, 0, $len) == "pbgsp_") {
11
+ $totalTax = 0;
12
+ $baseTotalTax = 0;
13
+ $totalHiddenTax = 0;
14
+ $baseTotalHiddenTax = 0;
15
+ if ($order->getTaxAmount()) {
16
+ $totalTax = $order->getTaxAmount();
17
+ $baseTotalTax = $totalTax;
18
+ }
19
+ $invoice->setTaxAmount($totalTax);
20
+ $invoice->setBaseTaxAmount($baseTotalTax);
21
+ $invoice->setHiddenTaxAmount($totalHiddenTax);
22
+ $invoice->setBaseHiddenTaxAmount($baseTotalHiddenTax);
23
+
24
+ $invoice->setGrandTotal($invoice->getGrandTotal() + $totalTax + $totalHiddenTax);
25
+ $invoice->setBaseGrandTotal($invoice->getBaseGrandTotal() + $baseTotalTax + $baseTotalHiddenTax);
26
+ } else {
27
+ parent::collect($invoice);
28
+ }
29
+
30
+ return $this;
31
+ }
32
+ }
app/code/local/Pb/Pbgsp/Model/Messages.php ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Pb_Pbgsp_Model_Messages {
4
+ // protected $messages = array(
5
+ // 101 => array(
6
+ // "code" => "INTERNAL_ERROR",
7
+ // "original" => "Internal Error.",
8
+ // "display" => "Error 101: An error has occurred. Please contact the merchant for assistance."),
9
+ // 102 => array(
10
+ // "code" => "NULL_VALUE",
11
+ // "original" => "Null value.",
12
+ // "display" => "A required field is missing, please select a Province."),
13
+ // 103 => array(
14
+ // "code" => "INVALID_VALUE",
15
+ // "original" => "Invalid value.",
16
+ // "display" => "Error 103: An invalid value for a required non-null field has been submitted"),
17
+ // 105 => array(
18
+ // "code" => "MISSING_RECORD",
19
+ // "original" => "Missing record.",
20
+ // "display" => "Error 105: One or more items have not yet been prepared for international sale. Please remove the item(s) from your basket and try again. <IDENTIFY SKU>"),
21
+ // 108 => array(
22
+ // "code" => "CLASSIFICATION_NOT_AVAILABLE",
23
+ // "original" => "Item cannot be classified.",
24
+ // "display" => "Error 108: One or more items have not yet been prepared for international sale. Please remove the item(s) from your basket and try again. <IDENTIFY SKU>"),
25
+ // 109 => array(
26
+ // "code" => "QUANTITY_EXCEEDED",
27
+ // "original" => "Quantity exceeded.",
28
+ // "display" => "Error 109: The quantity of one or more selected items exceeds international shipping regulations. <IDENTIFY SKU>"),
29
+ // 131 => array(
30
+ // "code" => "SHIPPING_METHODS_NOT_AVAILABLE ",
31
+ // "original" => "No shipping methods available. ",
32
+ // "display" => "Error 131: No international shipping methods are available for the selected items."),
33
+ // 139 => array(
34
+ // "code" => "DUTY_NOT_AVAILABLE",
35
+ // "original" => "Duties are not available.",
36
+ // "display" => "Error 139: International duty items are not available for one or more items. Please remove the item(s) from your basket and try again. <IDENTIFY SKU>"),
37
+ // 141 => array(
38
+ // "code" => "MISSING_DUTIABLE_PRICE",
39
+ // "original" => "Missing dutiable price.",
40
+ // "display" => "Error 141: One or more selected items do not have a valid dutiable price for international sale. Please remove the item(s) from your basket and try again. <IDENTIFY SKU>"),
41
+ // 142 => array(
42
+ // "code" => "INVALID_DUTIABLE_PRICE",
43
+ // "original" => "Invalid dutiable price.",
44
+ // "display" => "Error 142: One or more selected items do not have a valid dutiable price for international sale. Please remove the item(s) from your basket and try again. <IDENTIFY SKU>"),
45
+ // 144 => array(
46
+ // "code" => "INVALID_SALE_PRICE",
47
+ // "original" => "Invalid sale price.",
48
+ // "display" => "Error 144: One or more items do not have a valid sale price for international sale. Please remove the item(s) from your basket and try again. <IDENTIFY SKU>"),
49
+ // 145 => array(
50
+ // "code" => "TAX_NOT_AVAILABLE",
51
+ // "original" => "Fail to retrieve taxes.",
52
+ // "display" => "Error 145: One or more items does not have tax information for international sale. Please remove the item(s) from your basket and try again. <IDENTIFY SKU>"),
53
+ // 154 => array(
54
+ // "code" => "SHIPPING_CANNOT_BE_CALCULATED",
55
+ // "original" => "Shipping cannot be calculated.",
56
+ // "display" => "Error 154: The selected address is not valid for international delivery. Please note that FedEx cannot deliver to PO Boxes."),
57
+ // 155 => array(
58
+ // "code" => "SHIPPING_TARIFF_NOT_FOUND",
59
+ // "original" => "Shipping tariff not found.",
60
+ // "display" => "Error 155: The current basket of items exceeds international shipping guidelines. Please remove some items and try again."),
61
+ // 161 => array(
62
+ // "code" => "QUANTITY_SHIPPING_RESTRICTION",
63
+ // "original" => "HS quantity shipping restriction.",
64
+ // "display" => "Error 161: One or more items is restricted from international sale to the selected destination. Please remove the item(s) from your basket and try again. <IDENTIFY SKU>"),
65
+ // 162 => array(
66
+ // "code" => "QUANTITY_SHIPPING_RESTRICTION",
67
+ // "original" => "HS quantity shipping restriction.",
68
+ // "display" => "Error 161: One or more items exceed maximum value guidelines for international sale to the selected destination. Please remove the item(s) from your basket and try again. <IDENTIFY SKU>"),
69
+ // 168 => array(
70
+ // "code" => "SHIPPING_TARIFF_NOT_AVAILABLE",
71
+ // "original" => "The weight of the item is exceeding the maximum accepted by tariffs.",
72
+ // "display" => "Error 168: The weight of the basket exceeds international shipping guidelines. Please remove one or more items and try again."),
73
+ // 174 => array(
74
+ // "code" => "SHIPPING_SIZE_RESTRICTIONS",
75
+ // "original" => "Item (commodity or merchant box) didn’t pass shipping size restrictions",
76
+ // "display" => "Error 174: One or more selected items exceed dimensional limits for international sale. Please remove the item(s) from your basket and try again. <IDENTIFY SKU>"),
77
+ // 175 => array(
78
+ // "code" => "INVALID_PROVINCE_POSTALCODE_PAIR",
79
+ // "original" => "Canada address validation failed (postal code does not match the province).",
80
+ // "display" => "Error 175: The postal code and province entered do not match. Please check the postal code and province to ensure that they are entered correctly and try again."),
81
+ // 176 => array(
82
+ // "code" => "INVALID_POSTALCODE_FORMAT",
83
+ // "original" => "Invalid Canadian Postal Code format (should be ldldld, where l=letter and d=digit).",
84
+ // "display" => "Error 176: The postal code entered is invalid. Please check the postal code and try again."),
85
+ // 177 => array(
86
+ // "code" => "SHIPPING_VALUE_RESTRICTIONS",
87
+ // "original" => "The order value exceeds Shipping Value Restrictions.",
88
+ // "display" => "Error 177: The basket total exceeds maximum order value guidelines for international sale. Please remove items from the basket and try again."),
89
+ // 1001 => array(
90
+ // "code" => "LICENSE",
91
+ // "original" => "Item is restricted for shipping due to license requirements.",
92
+ // "display" => "Error 1001: One or more items is license restricted for international sale. Please remove the item(s) and try again. <IDENTIFY SKU>"),
93
+ // 1002 => array(
94
+ // "code" => "SIZE",
95
+ // "original" => "Item is restricted for shipping due to its size.",
96
+ // "display" => "Error 1002: One or more items exceed size limits for international sale. Please remove the item(s) and try again. <IDENTIFY SKU>"),
97
+ // 1003 => array(
98
+ // "code" => "PROHIBITED",
99
+ // "original" => "Item is restricted for shipping.",
100
+ // "display" => "Error 1003: One or more items is restricted for international sale. Please remove the item(s) and try again. <IDENTIFY SKU>"),
101
+ // 1004 => array(
102
+ // "code" => "CARRIER",
103
+ // "original" => "Item is restricted for shipping due to a carrier restriction. The logistics carrier will not ship this product ",
104
+ // "display" => "Error 1004: One or more items is restricted for international sale. Please remove the item(s) and try again. <IDENTIFY SKU>"),
105
+ // );
106
+ //
107
+ public function getDisplayMessage($code,$message) {
108
+ // if (array_key_exists($code,$this->messages)) {
109
+ // return $this->messages[$code]["display"];
110
+ // }
111
+
112
+ // moved to config
113
+
114
+ $config_data = Mage::getStoreConfig('carriers/pbgsp/error_messages');
115
+
116
+ if(isset($config_data["_$code"]['display']))
117
+ return $config_data["_$code"]['display'];
118
+
119
+ return $message;
120
+ }
121
+ }
app/code/local/Pb/Pbgsp/Model/Mysql4/Inboundparcel.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Pb_Pbgsp_Model_Mysql4_Inboundparcel extends Mage_Core_Model_Mysql4_Abstract {
3
+ public function _construct()
4
+ {
5
+ $this->_init('pb_pbgsp/inboundparcel', 'inbound_parcel_id');
6
+ }
7
+ }
8
+
9
+ ?>
app/code/local/Pb/Pbgsp/Model/Mysql4/Inboundparcel/Collection.php ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Pb_Pbgsp_Model_Mysql4_Inboundparcel_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract {
3
+ public function _construct()
4
+ {
5
+ $this->_init('pb_pbgsp/inboundparcel');
6
+ }
7
+ }
8
+ ?>
app/code/local/Pb/Pbgsp/Model/Mysql4/Ordernumber.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Pb_Pbgsp_Model_Mysql4_Ordernumber extends Mage_Core_Model_Mysql4_Abstract {
3
+ public function _construct()
4
+ {
5
+ $this->_init('pb_pbgsp/ordernumber', 'ordernumber_id');
6
+ }
7
+ }
8
+
9
+ ?>
app/code/local/Pb/Pbgsp/Model/Mysql4/Ordernumber/Collection.php ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Pb_Pbgsp_Model_Mysql4_Ordernumber_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract {
3
+ public function _construct()
4
+ {
5
+ $this->_init('pb_pbgsp/ordernumber');
6
+ }
7
+ }
8
+ ?>
app/code/local/Pb/Pbgsp/Model/Mysql4/Variable.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Pb_Pbgsp_Model_Mysql4_Variable extends Mage_Core_Model_Mysql4_Abstract {
3
+ public function _construct()
4
+ {
5
+ $this->_init('pb_pbgsp/variable', 'variable_id');
6
+ }
7
+ }
8
+
9
+ ?>
app/code/local/Pb/Pbgsp/Model/Mysql4/Variable/Collection.php ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Pb_Pbgsp_Model_Mysql4_Variable_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract {
3
+ public function _construct()
4
+ {
5
+ $this->_init('pb_pbgsp/variable');
6
+ }
7
+ }
8
+ ?>
app/code/local/Pb/Pbgsp/Model/Observer.php ADDED
@@ -0,0 +1,318 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Pb_Pbgsp_Model_Observer {
3
+ const MODULE_NAME = 'Pb_Pbgsp';
4
+ public function __construct() {
5
+ }
6
+
7
+ public function isPbOrder($address) {
8
+ $shipMethod = $address->getShippingMethod();
9
+ $len = strlen("pbgsp_");
10
+ if (strlen($shipMethod) > $len && substr($shipMethod,0,$len) == "pbgsp_") {
11
+ return true;
12
+ }
13
+ Pb_Pbgsp_Model_Util::log("Shipping method". $shipMethod);
14
+ return false;
15
+
16
+ }
17
+
18
+
19
+ public function getShipMethod($observer) {
20
+ Pb_Pbgsp_Model_Util::log('Pb_Pbgsp_Model_Observer.getShipMethod');
21
+ $shipMethod = $observer->getQuote()->getShippingAddress()->getShippingMethod();
22
+
23
+ return substr($shipMethod,strlen("pbgsp_"));
24
+ }
25
+
26
+ public function generateInboundParcelPreAdvice($observer) {
27
+
28
+ if(Pb_Pbgsp_Model_Credentials::isASNGenerationEnabled() == '1') {
29
+ try {
30
+ $shipment = $observer->getEvent()->getShipment();
31
+ $order = $shipment->getOrder();
32
+ /* @var $order Mage_Sales_Model_Order */
33
+
34
+ if(!$this->isPbOrder($order))
35
+ return;
36
+ //check if ASN already generated or not
37
+ $parcel = Mage::getModel("pb_pbgsp/inboundparcel")-> getCollection();
38
+ $parcel -> addFieldToFilter('mage_order_number', $order -> getRealOrderId());
39
+ if(count($parcel) > 0)
40
+ return;
41
+ Pb_Pbgsp_Model_Util::log("Generting ASN.");
42
+ $clearPathOrders = Mage::getModel("pb_pbgsp/ordernumber")-> getCollection();
43
+ $clearPathOrders -> addFieldToFilter('mage_order_number', $order -> getRealOrderId());
44
+ foreach ($clearPathOrders as $cpOrder) {
45
+ $cpOrderNumber = $cpOrder -> getCpOrderNumber();
46
+ $tracks = array();
47
+ $items = array();
48
+ foreach($shipment->getTracksCollection() as $track) {
49
+ $tracks[] = $track;
50
+ }
51
+ foreach($shipment->getItemsCollection() as $item) {
52
+
53
+ $items[] = $item;
54
+
55
+ }
56
+
57
+ $parcelResponse = Pb_Pbgsp_Model_Api::generateInboundParcelNumber($shipment,$items,$order -> getRealOrderId(),$cpOrderNumber);
58
+ if(array_key_exists('errors',$parcelResponse)) {
59
+ Pb_Pbgsp_Model_Util::log("Error generating inbound parcel");
60
+ Pb_Pbgsp_Model_Util::log($parcelResponse);
61
+ }
62
+ else {
63
+ $cpParcel = Mage::getModel('pb_pbgsp/inboundparcel');
64
+ $cpParcel->setInboundParcel($parcelResponse['parcelIdentifier']);
65
+ $cpParcel->setMageOrderNumber( $order->getRealOrderId());
66
+ $cpParcel->setPbOrderNumber( $cpOrderNumber);
67
+ $cpParcel->save();
68
+ Pb_Pbgsp_Model_Util::log('Inbound Parcel Number Saved');
69
+ }
70
+
71
+ }
72
+
73
+
74
+ }
75
+ catch(Exception $e) {
76
+ Pb_Pbgsp_Model_Util::log("Error creating inbound parcel. ");
77
+ Pb_Pbgsp_Model_Util::logException($e);
78
+ }
79
+ }
80
+
81
+ }
82
+ public function createPbOrder($observer) {
83
+ // Pb_Pbgsp_Model_Util::log('Pb_Pbgsp_Model_Observer.createPbOrder');
84
+ Mage::getSingleton("customer/session")->setPbDutyAndTax(0);
85
+ $mageOrderNumber = Mage::getSingleton('checkout/session')->getLastRealOrderId();
86
+ $order = Mage::getModel('sales/order')->loadByIncrementId($mageOrderNumber);
87
+ Pb_Pbgsp_Model_Util::log(" createPbOrder");
88
+ if ($this->isPbOrder($order)) {
89
+ $orderNumber = Mage::getSingleton("customer/session")->getPbOrderNumber();
90
+
91
+ // Save in DB
92
+
93
+ $orderNumber->setMageOrderNumber($mageOrderNumber);
94
+ //$orderNumber->setCpOrderNumber($cpOrderNumber);
95
+ Pb_Pbgsp_Model_Util::log($orderNumber->getHubId());
96
+ Pb_Pbgsp_Model_Util::log($orderNumber->getHubCountry());
97
+ $orderNumber->setConfirmed(false);
98
+ $orderNumber->setReferenced(false);
99
+ $orderNumber->save();
100
+ Pb_Pbgsp_Model_Util::log("calling PB confirm order for $mageOrderNumber");
101
+ if (Pb_Pbgsp_Model_Api::confirmOrder($orderNumber->getCpOrderNumber(),$order)) {
102
+ $orderNumber->setConfirmed(true);
103
+ $orderNumber->setReferenced(true);
104
+ $orderNumber->save();
105
+ Pb_Pbgsp_Model_Util::log(" $mageOrderNumber order is confirmed in PB");
106
+ }
107
+ // if (Pb_Pbgsp_Model_Api::setOrderReference($cpOrderNumber,$mageOrderNumber)) {
108
+ // $orderNumber->setReferenced(true);
109
+ // $orderNumber->save();
110
+ // }
111
+ }
112
+ else {
113
+ Pb_Pbgsp_Model_Util::log("$mageOrderNumber not PB order");
114
+ }
115
+
116
+ }
117
+
118
+ public function saveShippingMethod($observer) {
119
+ // Pb_Pbgsp_Model_Util::log('Pb_Pbgsp_Model_Observer.saveShippingMethod');
120
+ //TODO: If anything fails here I need to fail the checkout process.
121
+ $address = $observer->getQuote()->getShippingAddress();
122
+ if ($this->isPbOrder($address)) {
123
+ Pb_Pbgsp_Model_Util::log(" PB order");
124
+ $items = Mage::getSingleton('checkout/cart')->getItems();
125
+ $shipMethod = $this->getShipMethod($observer);
126
+ $order = Pb_Pbgsp_Model_Api::createOrder($items,$shipMethod,$address);
127
+ if (!$order) {
128
+ Mage::throwException("Unable to create Pb order.");
129
+ }
130
+
131
+ Mage::getSingleton("customer/session")->setPbDutyAndTax($order['order']['totalImportation']['total']['value']);
132
+
133
+ $orderNumber = Mage::getModel("pb_pbgsp/ordernumber");
134
+
135
+ $orderNumber->setCpOrderNumber($order["orderId"]);
136
+ $orderNumber->setHubId($order["shipToHub"]['hubId']);
137
+ $orderNumber->setHubStreet1($order["shipToHub"]['hubAddress']['street1']);
138
+ $orderNumber->setHubStreet2($order["shipToHub"]['hubAddress']['street2']);
139
+ $orderNumber->setHubProvinceOrState($order["shipToHub"]['hubAddress']['provinceOrState']);
140
+ $orderNumber->setHubCountry($order["shipToHub"]['hubAddress']['country']);
141
+
142
+ Mage::getSingleton("customer/session")->setPbOrderNumber($orderNumber);
143
+ } else {
144
+ Pb_Pbgsp_Model_Util::log(" not clearpath order");
145
+ Mage::getSingleton("customer/session")->setPbDutyAndTax(false);
146
+ Mage::getSingleton("customer/session")->setPbOrderNumber(false);
147
+ }
148
+ }
149
+
150
+ public function addDutiesOnEstimation($observer){
151
+ //Pb_Pbgsp_Model_Util::log('Pb_Pbgsp_Model_Observer.addDutiesOnEstimation');
152
+ Mage::getSingleton("customer/session")->setPbDutyAndTax(false);//Added by BigPixel to clear previous values, 10/20/2013
153
+ $clearPathMethods = Mage::getSingleton('checkout/session')->getPbMethods();
154
+ $quote = Mage::getSingleton('checkout/session')->getQuote();
155
+ $selectedMethod = null;
156
+ if($quote->getShippingAddress()){
157
+ $selectedMethod = $quote->getShippingAddress()->getShippingMethod();
158
+ }
159
+
160
+ if($selectedMethod){
161
+ $selectedMethod = preg_replace('/pbgsp_/', '',$selectedMethod);
162
+ foreach($clearPathMethods as $clearPathMethod){
163
+ Pb_Pbgsp_Model_Util::log('addDutiesOnEstimation method'.$clearPathMethod->getMethod().' and tax'.$clearPathMethod->getTax());
164
+ if($clearPathMethod->getMethod() == $selectedMethod){
165
+ Mage::getSingleton("customer/session")->setPbDutyAndTax($clearPathMethod->getTax());
166
+ }
167
+ }
168
+ }
169
+ }
170
+
171
+ public function modifyOrderView($observer = NULL) {
172
+
173
+ //return;
174
+ if (!$observer) {
175
+ return;
176
+ }
177
+ if (Mage::getStoreConfig('advanced/modules_disable_output/'.self::MODULE_NAME))
178
+ return;
179
+ $transport = $observer->getEvent()->getTransport();
180
+ $layoutName = $observer->getEvent()->getBlock()->getNameInLayout();
181
+ if ('order_info' == $layoutName) {
182
+
183
+ if (!Mage::getStoreConfig('advanced/modules_disable_output/'.self::MODULE_NAME)) {
184
+
185
+
186
+ $cpOrderNumber = $this->_getCpOrderNumber($observer->getEvent()->getBlock()->getOrder());
187
+ if($cpOrderNumber) {
188
+ $html = "<div class='entry-edit'>
189
+ <div class='entry-edit-head'>
190
+ <h4 class='icon-head '>Pitney Bowes Shipments</h4>
191
+ </div>
192
+ <fieldset>
193
+ <strong>PB Order Number</strong>
194
+ <span>".$cpOrderNumber->getCpOrderNumber()."</span><br/>
195
+ <strong>Hub ID</strong>
196
+ <span>".$cpOrderNumber->getHubId()."</span><br/>
197
+ <strong>Hub Street 1</strong>
198
+ <span>".$cpOrderNumber->getHubStreet1()."</span><br/>
199
+ <strong>Hub Street 2</strong>
200
+ <span>".$cpOrderNumber->getHubStreet2()."</span><br/>
201
+ <strong>Hub Province/State</strong>
202
+ <span>".$cpOrderNumber->getHubProvinceOrState()."</span><br/>
203
+ <strong>Hub Zip</strong>
204
+ <span>".$cpOrderNumber->getHubPostCode()."</span><br/>
205
+ <strong>Hub Country</strong>
206
+ <span>".$cpOrderNumber->getHubCountry()."</span><br/>
207
+ </fieldset>
208
+ </div>";
209
+ $transport['html'] = $transport['html'] . $html;
210
+ }
211
+
212
+
213
+ }
214
+ }
215
+ else if('email/order/shipment/track.phtml' == $observer->getEvent()->getBlock()->getTemplate()) {
216
+ if(!Mage::getStoreConfig('carriers/pbgsp/trackinglink'))
217
+ return;
218
+
219
+ $cpord = $this->_getCPORD($observer->getEvent()->getBlock()->getOrder());
220
+ if($cpord) {
221
+ $staging = 0;
222
+ if(strpos(Pb_Pbgsp_Model_Credentials::getApiUrl(),'cpsandbox') >=0)
223
+ $staging = 1;
224
+ $transport['html'] = "<a href='http://tracking.ecommerce.pb.com/track/$cpord?staging=$staging'>Track your order</a>";
225
+ }
226
+
227
+ }
228
+ else if('shipping.tracking.popup' == $layoutName) {
229
+ if(!Mage::getStoreConfig('carriers/pbgsp/trackinglink'))
230
+ return;
231
+
232
+ $helper = Mage::helper('shipping');
233
+ $data = $helper->decodeTrackingHash($observer->getEvent()->getBlock()->getRequest()->getParam('hash'));
234
+
235
+ $orderId = null;
236
+ if($data['key'] == 'order_id')
237
+ $orderId = $data['id'];
238
+ else if($data['key'] == 'ship_id') {
239
+ /* @var $model Mage_Sales_Model_Order_Shipment */
240
+ $model = Mage::getModel('sales/order_shipment');
241
+ $ship = $model->load($data['id']);
242
+ $orderId = $model->getOrderId();
243
+ }
244
+ else if($data['key'] == 'track_id') {
245
+ $track = Mage::getModel('sales/order_shipment_track')->load($data['id']);
246
+ $orderId = $track->getOrderId();
247
+ }
248
+ if(!$orderId)
249
+ return;
250
+ $cpord = $this->_getCPORD(Mage::getModel('sales/order')->load($orderId));
251
+ if($cpord) {
252
+ $staging = 0;
253
+ if(strpos(Pb_Pbgsp_Model_Credentials::getApiUrl(),'cpsandbox') >=0)
254
+ $staging = 1;
255
+ $script = "<script lang='javascript'>
256
+ window.location = 'http://tracking.ecommerce.pb.com/track/$cpord?staging=$staging';
257
+ </script>
258
+ ";
259
+ $transport['html'] = $script;
260
+ }
261
+
262
+ }
263
+ else
264
+ // if( 'checkout.onepage.review' == $layoutName
265
+ // || 'checkout.onepage.review.info.totals' == $layoutName
266
+ // || 'checkout.cart.totals' == $layoutName)
267
+ {
268
+ //replace "Shipping & Handling" to "Transportation Charges" and "Duty & Taxes" to "Importation Charges"
269
+ $html = $transport['html'];
270
+ $pbTitle = Mage::getStoreConfig('carriers/pbgsp/title');
271
+ if(strpos($html,$pbTitle) !== false) {
272
+ $html = str_replace("Shipping &amp; Handling","Transportation Charges",$html);
273
+ $html = str_replace("Shipping & Handling","Transportation Charges",$html);
274
+ $html = str_replace("Duty & Taxes","Importation Charges",$html);
275
+ $html = str_replace("Duty &amp; Taxes","Importation Charges",$html);
276
+ $transport['html'] = $html;
277
+ }
278
+
279
+ }
280
+ // else {
281
+ //
282
+ // }
283
+ // else {
284
+ // $html = $transport['html'];
285
+ // if(strpos('Shipping & Handling',$html) >= 0)
286
+ // Pb_Pbgsp_Model_Util::log("Found in $layoutName");
287
+ // }
288
+
289
+ return $this;
290
+ }
291
+ private function _getCPORD($order)
292
+ {
293
+ if($order) {
294
+ $cpOrder = $this->_getCpOrderNumber($order);
295
+ if($cpOrder) {
296
+ return $cpOrder -> getCpOrderNumber();
297
+ }
298
+
299
+ }
300
+
301
+ return false;
302
+ }
303
+ private function _getCpOrderNumber($order)
304
+ {
305
+ if($order) {
306
+ $clearPathOrders = Mage::getModel("pb_pbgsp/ordernumber")-> getCollection();
307
+
308
+ $clearPathOrders -> addFieldToFilter('mage_order_number', $order -> getRealOrderId());
309
+ foreach ($clearPathOrders as $cpOrder) {
310
+ return $cpOrder ;
311
+
312
+ }
313
+ }
314
+
315
+ return false;
316
+ }
317
+ }
318
+ ?>
app/code/local/Pb/Pbgsp/Model/Ordernumber.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Pb_Pbgsp_Model_Ordernumber extends Mage_Core_Model_Abstract {
4
+ public function _construct()
5
+ {
6
+ parent::_construct();
7
+ $this->_init('pb_pbgsp/ordernumber');
8
+ }
9
+ }
10
+
11
+ ?>
app/code/local/Pb/Pbgsp/Model/Pdf/Tax.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Pb_Pbgsp_Model_Pdf_Tax extends Mage_Tax_Model_Sales_Pdf_Tax {
4
+ public function getTitle() {
5
+ $shipMethod = $this->getOrder()->getShippingMethod();
6
+ $len = strlen("pbgsp_");
7
+ if (strlen($shipMethod) > $len && substr($shipMethod,0,$len) == "pbgsp_") {
8
+ return "Importation Charges";
9
+ }
10
+ return parent::getTitle();
11
+ }
12
+ }
13
+
14
+ ?>
app/code/local/Pb/Pbgsp/Model/Quote/Duty.php ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Pb_Pbgsp_Model_Quote_Duty extends Mage_Tax_Model_Sales_Total_Quote_Tax
4
+ {
5
+ /**
6
+ * Discount calculation object
7
+ *
8
+ * @var Mage_SalesRule_Model_Validator
9
+ */
10
+ protected $dutyCalculated = false;
11
+ protected $dutyDisplayed = false;
12
+
13
+ public function __construct()
14
+ {
15
+ parent::__construct();
16
+ }
17
+
18
+ public function getDutyAndTax() {
19
+ //Pb_Pbgsp_Model_Util::log('Pb_Pbgsp_Model_Quote_Duty.getDutyAndTax');
20
+ return Mage::getSingleton("customer/session")->getPbDutyAndTax();
21
+ }
22
+
23
+ /**
24
+ * Collect address discount amount
25
+ *
26
+ * @param Mage_Sales_Model_Quote_Address $address
27
+ * @return Mage_SalesRule_Model_Quote_Discount
28
+ */
29
+ public function collect(Mage_Sales_Model_Quote_Address $address)
30
+ {
31
+ //Pb_Pbgsp_Model_Util::log('Pb_Pbgsp_Model_Quote_Duty.collect');
32
+ parent::collect($address);
33
+
34
+ if ($this->getDutyAndTax()) {
35
+ $items = $this->_getAddressItems($address);
36
+ if (!count($items)) {
37
+ return $this;
38
+ }
39
+
40
+ $this->_addAmount($this->getDutyAndTax());
41
+ $this->_addBaseAmount($this->getDutyAndTax());
42
+ }
43
+ return $this;
44
+ }
45
+
46
+
47
+ /**
48
+ * Add discount total information to address
49
+ *
50
+ * @param Mage_Sales_Model_Quote_Address $address
51
+ * @return Mage_SalesRule_Model_Quote_Discount
52
+ */
53
+ public function fetch(Mage_Sales_Model_Quote_Address $address)
54
+ {
55
+ //Pb_Pbgsp_Model_Util::log('Pb_Pbgsp_Model_Quote_Duty.fetch');
56
+
57
+ if ($this->getDutyAndTax()) {
58
+ if($this->dutyDisplayed) {
59
+ return $this;
60
+ }
61
+ $this->dutyDisplayed = true;
62
+
63
+ $amount = $address->getTaxAmount();
64
+ $title = "Duty & Taxes";
65
+ Pb_Pbgsp_Model_Util::log("Add Duty & Taxes at Duty");
66
+ $address->addTotal(array(
67
+ 'code' => $this->getCode(),
68
+ 'title' => $title,
69
+ 'value' => $amount
70
+ ));
71
+ } else {
72
+ return parent::fetch($address);
73
+ }
74
+ return $this;
75
+ }
76
+ }
app/code/local/Pb/Pbgsp/Model/Resource/Mysql4/Setup.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Created by PhpStorm.
4
+ * User: Muhammad
5
+ * Date: 3/31/2015
6
+ * Time: 11:48 PM
7
+ */
8
+
9
+ class Pb_Pbgsp_Model_Resource_Mysql4_Setup extends Mage_Core_Model_Resource_Setup {
10
+
11
+ }
app/code/local/Pb/Pbgsp/Model/Sales/Order/Shipment.php ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Created by PhpStorm.
4
+ * User: Muhammad
5
+ * Date: 3/27/2015
6
+ * Time: 12:51 AM
7
+ */
8
+
9
+ class Pb_Pbgsp_Model_Sales_Order_Shipment extends Mage_Sales_Model_Order_Shipment {
10
+
11
+ public function sendEmail($notifyCustomer = true, $comment = '')
12
+ {
13
+ if(Mage::getStoreConfig('carriers/pbgsp/suppress_domestic_tracking') != '1')
14
+ return parent::sendEmail($notifyCustomer,$comment);
15
+ $order = $this->getOrder();
16
+ $storeId = $order->getStore()->getId();
17
+
18
+ if (!Mage::helper('sales')->canSendNewShipmentEmail($storeId)) {
19
+ return $this;
20
+ }
21
+ // Get the destination email addresses to send copies to
22
+ $copyTo = $this->_getEmails(self::XML_PATH_EMAIL_COPY_TO);
23
+ $copyMethod = Mage::getStoreConfig(self::XML_PATH_EMAIL_COPY_METHOD, $storeId);
24
+ // Check if at least one recepient is found
25
+ if (!$notifyCustomer && !$copyTo) {
26
+ return $this;
27
+ }
28
+
29
+ // Start store emulation process
30
+ $appEmulation = Mage::getSingleton('core/app_emulation');
31
+ $initialEnvironmentInfo = $appEmulation->startEnvironmentEmulation($storeId);
32
+
33
+ try {
34
+ // Retrieve specified view block from appropriate design package (depends on emulated store)
35
+ $paymentBlock = Mage::helper('payment')->getInfoBlock($order->getPayment())
36
+ ->setIsSecureMode(true);
37
+ $paymentBlock->getMethod()->setStore($storeId);
38
+ $paymentBlockHtml = $paymentBlock->toHtml();
39
+ } catch (Exception $exception) {
40
+ // Stop store emulation process
41
+ $appEmulation->stopEnvironmentEmulation($initialEnvironmentInfo);
42
+ throw $exception;
43
+ }
44
+
45
+ // Stop store emulation process
46
+ $appEmulation->stopEnvironmentEmulation($initialEnvironmentInfo);
47
+
48
+ // Retrieve corresponding email template id and customer name
49
+ if ($order->getCustomerIsGuest()) {
50
+ //$templateId = Mage::getStoreConfig(self::XML_PATH_EMAIL_GUEST_TEMPLATE, $storeId);
51
+ $customerName = $order->getBillingAddress()->getName();
52
+ } else {
53
+ //$templateId = Mage::getStoreConfig(self::XML_PATH_EMAIL_TEMPLATE, $storeId);
54
+ $customerName = $order->getCustomerName();
55
+ }
56
+
57
+
58
+
59
+ $emailTemplateVariables = array(
60
+ 'order' => $order,
61
+ 'shipment' => $this,
62
+ 'comment' => $comment,
63
+ 'billing' => $order->getBillingAddress(),
64
+ 'store' => Mage::app()->getStore($storeId),
65
+ 'payment_html' => $paymentBlockHtml
66
+
67
+
68
+ );
69
+ $emailTemplate = Mage::getModel('core/email_template');
70
+ // ->loadDefault('pbgsp_shipment_new');
71
+ $emailTemplate = $this->_setTemplateBodyAndSubject($emailTemplate,
72
+ Mage::getStoreConfig('carriers/pbgsp/custom_shipment_email_template'),
73
+ Mage::getStoreConfig('carriers/pbgsp/custom_shipment_email_subject'));
74
+ $emailTemplate->setSenderEmail(Mage::getStoreConfig(self::XML_PATH_EMAIL_IDENTITY, $storeId));
75
+ $processedTemplate = $emailTemplate->getProcessedTemplate($emailTemplateVariables);
76
+ //Pb_Pbgsp_Model_Util::log($processedTemplate);
77
+ //$emailTemplate->send($order->getCustomerEmail(), $customerName,$emailTemplateVariables);
78
+ //Pb_Pbgsp_Model_Util::log('Email subject'. $emailTemplate->getTemplateSubject());
79
+ //Pb_Pbgsp_Model_Util::log('Processed Email Subject is'. $emailTemplate->getProcessedTemplateSubject($emailTemplateVariables));
80
+ $fromName = Mage::getStoreConfig('trans_email/ident_' . Mage::getStoreConfig(self::XML_PATH_EMAIL_IDENTITY, $storeId) . '/name', $storeId);
81
+ $fromEmail = Mage::getStoreConfig('trans_email/ident_' . Mage::getStoreConfig(self::XML_PATH_EMAIL_IDENTITY, $storeId) . '/email', $storeId);
82
+ $mail = Mage::getModel('core/email')
83
+ ->setToName($customerName)
84
+ ->setToEmail($order->getCustomerEmail())
85
+ ->setBody($processedTemplate)
86
+ ->setSubject($emailTemplate->getProcessedTemplateSubject($emailTemplateVariables))
87
+ ->setFromEmail($fromEmail)
88
+ ->setFromName($fromName)
89
+ ->setType('html');
90
+ try{
91
+
92
+ Pb_Pbgsp_Model_Util::log("Form email $fromEmail from name $fromName");
93
+ $mail->send();
94
+ //Pb_Pbgsp_Model_Util::log("Email sent to");
95
+ //Pb_Pbgsp_Model_Util::log($order->getCustomerEmail());
96
+ }
97
+ catch(Exception $error)
98
+ {
99
+ Pb_Pbgsp_Model_Util::log("Error sending shipment email". $error->getMessage());
100
+ Pb_Pbgsp_Model_Util::log($error->getTraceAsString());
101
+
102
+ }
103
+
104
+ return $this;
105
+ }
106
+ private function _setTemplateBodyAndSubject($template,$body,$subject)
107
+ {
108
+
109
+ $template->setTemplateType( Mage_Core_Model_Template::TYPE_HTML);
110
+
111
+ $templateText = $body;
112
+ $template->setTemplateSubject($subject);
113
+
114
+
115
+ if (preg_match('/<!--@vars\s*((?:.)*?)\s*@-->/us', $templateText, $matches)) {
116
+ $template->setData('orig_template_variables', str_replace("\n", '', $matches[1]));
117
+ $templateText = str_replace($matches[0], '', $templateText);
118
+ }
119
+
120
+ if (preg_match('/<!--@styles\s*(.*?)\s*@-->/s', $templateText, $matches)) {
121
+ $this->setTemplateStyles($matches[1]);
122
+ $templateText = str_replace($matches[0], '', $templateText);
123
+ }
124
+
125
+ /**
126
+ * Remove comment lines
127
+ */
128
+ $templateText = preg_replace('#\{\*.*\*\}#suU', '', $templateText);
129
+
130
+ $template->setTemplateText($templateText);
131
+ // $this->setId($templateId);
132
+
133
+ return $template;
134
+ }
135
+
136
+
137
+ }
app/code/local/Pb/Pbgsp/Model/Util.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Pb_Pbgsp_Model_Util {
4
+
5
+ const FILE_NAME = 'pbgsp.log';
6
+ public static function log($message) {
7
+ if( Mage::getStoreConfig('carriers/pbgsp/separate_log_file'))
8
+ Mage::log($message,null,self::FILE_NAME);
9
+ else
10
+ Mage::log($message);
11
+ }
12
+ public static function logException($e) {
13
+ /* @var Exception $e */
14
+ if( Mage::getStoreConfig('carriers/pbgsp/separate_log_file')) {
15
+ Mage::log($e->getMessage(),null,self::FILE_NAME);
16
+ Mage::log($e->getTraceAsString(),null,self::FILE_NAME);
17
+ }
18
+ else
19
+ Mage::logException($e);
20
+ }
21
+ }
22
+
23
+ ?>
app/code/local/Pb/Pbgsp/Model/Variable.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Pb_Pbgsp_Model_Variable extends Mage_Core_Model_Abstract {
4
+ public function _construct()
5
+ {
6
+ parent::_construct();
7
+ $this->_init('pb_pbgsp/variable');
8
+ }
9
+ }
10
+
11
+ ?>
app/code/local/Pb/Pbgsp/README ADDED
@@ -0,0 +1,2 @@
 
 
1
+ Dependencies:
2
+ gnupg
app/code/local/Pb/Pbgsp/etc/config.xml ADDED
@@ -0,0 +1,491 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Pb_Pbgsp>
5
+ <version>1.0.0</version>
6
+ </Pb_Pbgsp>
7
+ </modules>
8
+ <global>
9
+ <!--<template>-->
10
+ <!--<email>-->
11
+ <!--<sales_email_pb_shipment_template>-->
12
+ <!--<label>Pitney Bowes Custom Shipment Email</label>-->
13
+ <!--<file>pbgsp_shipment_new.html</file>-->
14
+ <!--<type>html</type>-->
15
+ <!--</sales_email_pb_shipment_template>-->
16
+ <!--</email>-->
17
+ <!--</template>-->
18
+ <blocks>
19
+ <PB_Pbgsp>
20
+ <class>Pb_Pbgsp_Block</class>
21
+ </PB_Pbgsp>
22
+ <sales>
23
+ <rewrite>
24
+ <order_totals>Pb_Pbgsp_Block_Sales_Order_Totals</order_totals>
25
+ <order_invoice_totals>Pb_Pbgsp_Block_Sales_Order_Invoice_Totals</order_invoice_totals>
26
+
27
+ </rewrite>
28
+ </sales>
29
+ <adminhtml>
30
+ <rewrite>
31
+ <sales_order_totals>Pb_Pbgsp_Block_Adminhtml_Sales_Order_Totals</sales_order_totals>
32
+ <sales_order_invoice_totals>Pb_Pbgsp_Block_Adminhtml_Sales_Order_Invoice_Totals</sales_order_invoice_totals>
33
+
34
+ </rewrite>
35
+ </adminhtml>
36
+ <checkout>
37
+ <rewrite>
38
+ <onepage_shipping_method_available>Pb_Pbgsp_Block_Checkout_Shipping_Method_Available</onepage_shipping_method_available>
39
+ </rewrite>
40
+ </checkout>
41
+ </blocks>
42
+ <models>
43
+ <pb_pbgsp>
44
+ <class>Pb_Pbgsp_Model</class>
45
+ <resourceModel>pb_pbgsp_mysql4</resourceModel>
46
+ </pb_pbgsp>
47
+ <pb_pbgsp_mysql4>
48
+ <class>Pb_Pbgsp_Model_Mysql4</class>
49
+ <entities>
50
+ <variable>
51
+ <table>pbgsp_variable</table>
52
+ </variable>
53
+ <ordernumber>
54
+ <table>pbgsp_ordernumber</table>
55
+ </ordernumber>
56
+ <inboundparcel>
57
+ <table>pbgsp_inbound_parcel</table>
58
+ </inboundparcel>
59
+ </entities>
60
+ </pb_pbgsp_mysql4>
61
+ <sales>
62
+ <rewrite>
63
+ <order_invoice_total_tax>Pb_Pbgsp_Model_Invoice_Duty</order_invoice_total_tax>
64
+ <order_creditmemo_total_tax>Pb_Pbgsp_Model_Creditmemo_Duty</order_creditmemo_total_tax>
65
+ <order_shipment>Pb_Pbgsp_Model_Sales_Order_Shipment</order_shipment>
66
+ </rewrite>
67
+ </sales>
68
+ </models>
69
+ <resources>
70
+ <pbgsp_setup>
71
+ <setup>
72
+ <module>Pb_Pbgsp</module>
73
+ <class>Pb_Pbgsp_Model_Resource_Mysql4_Setup</class>
74
+ </setup>
75
+ <connection>
76
+ <use>core_setup</use>
77
+ </connection>
78
+ </pbgsp_setup>
79
+ <pb_pbgsp_write>
80
+ <connection>
81
+ <use>core_write</use>
82
+ </connection>
83
+ </pb_pbgsp_write>
84
+ <pb_pbgsp_read>
85
+ <connection>
86
+ <use>core_read</use>
87
+ </connection>
88
+ </pb_pbgsp_read>
89
+ </resources>
90
+ <events>
91
+ <!--<checkout_submit_all_after>&lt;!&ndash; added by Kamran 7/2/2014 &ndash;&gt;-->
92
+ <!--<observers>-->
93
+ <!--<Pb_Pbgsp_Model_CheckoutSubmitAllAfter>-->
94
+ <!--<type>model</type>-->
95
+ <!--<class>pb_pbgsp/observer</class>-->
96
+ <!--<method>createOrderAdminAfter</method>-->
97
+ <!--</Pb_Pbgsp_Model_CheckoutSubmitAllAfter>-->
98
+ <!--</observers>-->
99
+ <!--</checkout_submit_all_after>-->
100
+ <core_block_abstract_to_html_after>
101
+ <observers>
102
+ <Pb_Pbgsp_Model_OrderView>
103
+ <type>model</type>
104
+ <class>pb_pbgsp/observer</class>
105
+ <method>modifyOrderView</method>
106
+ </Pb_Pbgsp_Model_OrderView>
107
+ </observers>
108
+ </core_block_abstract_to_html_after>
109
+ <checkout_controller_onepage_save_shipping_method>
110
+ <observers>
111
+ <Pb_Pbgsp_Model_SaveShippingOne>
112
+ <type>model</type>
113
+ <class>pb_pbgsp/observer</class>
114
+ <method>saveShippingMethod</method>
115
+ </Pb_Pbgsp_Model_SaveShippingOne>
116
+ </observers>
117
+ </checkout_controller_onepage_save_shipping_method>
118
+ <checkout_onepage_controller_success_action>
119
+ <observers>
120
+ <Pb_Pbgsp_Model_CheckoutCompleteOne>
121
+ <type>model</type>
122
+ <class>pb_pbgsp/observer</class>
123
+ <method>createPbOrder</method>
124
+ </Pb_Pbgsp_Model_CheckoutCompleteOne>
125
+ </observers>
126
+ </checkout_onepage_controller_success_action>
127
+ <controller_action_postdispatch_checkout_cart_estimateUpdatePost>
128
+ <observers>
129
+ <Pb_Pbgsp_Estimated_Shipping>
130
+ <type>model</type>
131
+ <class>pb_pbgsp/observer</class>
132
+ <method>addDutiesOnEstimation</method>
133
+ </Pb_Pbgsp_Estimated_Shipping>
134
+ </observers>
135
+ </controller_action_postdispatch_checkout_cart_estimateUpdatePost>
136
+ </events>
137
+ <sales>
138
+ <quote>
139
+ <totals>
140
+ <tax>
141
+ <class>Pb_Pbgsp_Model_Quote_Duty</class>
142
+ <before>grand_total</before>
143
+ <after>shipping</after>
144
+ </tax>
145
+ </totals>
146
+ </quote>
147
+ </sales>
148
+ <pdf>
149
+ <totals>
150
+ <tax translate="title">
151
+ <title>Tax</title>
152
+ <source_field>tax_amount</source_field>
153
+ <model>pb_pbgsp/pdf_tax</model>
154
+ <font_size>7</font_size>
155
+ <display_zero>0</display_zero>
156
+ <sort_order>300</sort_order>
157
+ </tax>
158
+ </totals>
159
+ </pdf>
160
+
161
+ </global>
162
+ <resources>
163
+ <sales_setup>
164
+ <setup>
165
+ <module>Pb_Pbgsp</module>
166
+ <class>Pb_Pbgsp_Model_Entity_Setup</class>
167
+ </setup>
168
+ </sales_setup>
169
+ </resources>
170
+
171
+ <!--<frontend>-->
172
+ <!--<layout>-->
173
+ <!--<updates>-->
174
+ <!--<pbcheckout>-->
175
+ <!--<file>pbcheckout.xml</file>-->
176
+ <!--</pbcheckout>-->
177
+ <!--</updates>-->
178
+ <!--</layout>-->
179
+ <!--<routers>-->
180
+ <!--<Pb_Pbgsp>-->
181
+ <!--<use>standard</use>-->
182
+ <!--<args>-->
183
+ <!--<module>Pb_Pbgsp</module>-->
184
+ <!--<frontName>pbgsp</frontName>-->
185
+ <!--&lt;!&ndash; loads ../controller/IndexController in http://..../magento/index.php/testController &ndash;&gt;-->
186
+ <!--</args>-->
187
+ <!--</Pb_Pbgsp>-->
188
+ <!--</routers>-->
189
+ <!--<translate>-->
190
+ <!--<modules>-->
191
+ <!--<translations>-->
192
+ <!--<files>-->
193
+ <!--<default>Pb_Pbgsp.csv</default>-->
194
+ <!--</files>-->
195
+ <!--</translations>-->
196
+ <!--</modules>-->
197
+ <!--</translate>-->
198
+ <!--</frontend>-->
199
+
200
+ <default>
201
+ <carriers>
202
+ <pbgsp>
203
+ <active>1</active>
204
+ <sallowspecific>0</sallowspecific>
205
+ <model>Pb_Pbgsp_Model_Carrier_ShippingMethod</model>
206
+ <specificerrmsg>
207
+ This shipping method is currently unavailable.
208
+ If you would like to ship using this shipping
209
+ method, please contact us.
210
+ </specificerrmsg>
211
+ <handling_type>F</handling_type>
212
+ <catalog_diff>1</catalog_diff>
213
+ <catalog_full>1</catalog_full>
214
+ <catalog_size>10000</catalog_size>
215
+ <catalog_encryption_enabled>0</catalog_encryption_enabled>
216
+ <asn_generation_enabled>1</asn_generation_enabled>
217
+ <suppress_domestic_tracking>1</suppress_domestic_tracking>
218
+ <custom_shipment_email_subject><![CDATA[{{var store.getFrontendName()}}: Shipment confirmation for Order # {{var order.increment_id}}]]>
219
+ </custom_shipment_email_subject>
220
+ <custom_shipment_email_template><![CDATA[<h1 style="font-size:22px; font-weight:normal; line-height:22px; margin:0 0 11px 0;"">Hello, {{htmlescape var=$order.getCustomerName()}}</h1>
221
+ <p style="font-size:12px; line-height:16px; margin:0;">
222
+ Thank you for your order from {{var store.getFrontendName()}}.
223
+ You can check the status of your order by <a href="{{store url="customer/account/"}}" style="color:#1E7EC8;">logging into your account</a>.
224
+
225
+ </p>
226
+ <p style="font-size:12px; line-height:16px; margin:0;">
227
+ Your shipping confirmation is below. Thank you again for your business.
228
+ </p>
229
+
230
+ <h2 style="font-size:18px; font-weight:normal; margin:0;">Your Order #{{var order.increment_id}} has been shipped from local warehouse to international shipment hub from where it will be shipped to your country.</h2>
231
+
232
+ ]]>
233
+ </custom_shipment_email_template>
234
+ <separate_log_file>0</separate_log_file>
235
+
236
+ <shipping_services>
237
+ <POSTAL_PRIORITY>
238
+ <title>Standard</title>
239
+ <enabled>0</enabled>
240
+ </POSTAL_PRIORITY>
241
+ <FEDEX_ECONOMY>
242
+ <title>Express</title>
243
+ <enabled>1</enabled>
244
+ </FEDEX_ECONOMY>
245
+ <FEDEX_PRIORITY>
246
+ <title>Express Plus</title>
247
+ <enabled>1</enabled>
248
+ </FEDEX_PRIORITY>
249
+ <AE_STANDARD>
250
+ <title>Premier</title>
251
+ <enabled>1</enabled>
252
+ </AE_STANDARD>
253
+ <AU_STANDARD>
254
+ <title>Premier</title>
255
+ <enabled>1</enabled>
256
+ </AU_STANDARD>
257
+ <CN_STANDARD>
258
+ <title>Premier</title>
259
+ <enabled>1</enabled>
260
+ </CN_STANDARD>
261
+ <CPC_EXPRESS>
262
+ <title>Premier Plus</title>
263
+ <enabled>1</enabled>
264
+ </CPC_EXPRESS>
265
+ <CPC_STANDARD>
266
+ <title>Premier</title>
267
+ <enabled>1</enabled>
268
+ </CPC_STANDARD>
269
+ <EU_STANDARD>
270
+ <title>Premier</title>
271
+ <enabled>1</enabled>
272
+ </EU_STANDARD>
273
+ <HK_STANDARD>
274
+ <title>Premier</title>
275
+ <enabled>1</enabled>
276
+ </HK_STANDARD>
277
+ <KR_STANDARD>
278
+ <title>Premier</title>
279
+ <enabled>1</enabled>
280
+ </KR_STANDARD>
281
+ <NZ_STANDARD>
282
+ <title>Premier</title>
283
+ <enabled>1</enabled>
284
+ </NZ_STANDARD>
285
+ <PH_STANDARD>
286
+ <title>Premier</title>
287
+ <enabled>1</enabled>
288
+ </PH_STANDARD>
289
+ <SG_STANDARD>
290
+ <title>Premier</title>
291
+ <enabled>1</enabled>
292
+ </SG_STANDARD>
293
+ <TH_STANDARD>
294
+ <title>Premier</title>
295
+ <enabled>1</enabled>
296
+ </TH_STANDARD>
297
+ <TW_STANDARD>
298
+ <title>Premier</title>
299
+ <enabled>1</enabled>
300
+ </TW_STANDARD>
301
+ </shipping_services>
302
+ <error_messages>
303
+ <_1005001>
304
+ <display>The shipping address is invalid.</display>
305
+ </_1005001>
306
+ <_1005002>
307
+ <display>The consignee information is invalid.</display>
308
+ </_1005002>
309
+ <_1005003>
310
+ <display>The COP transportation information is invalid.</display>
311
+ </_1005003>
312
+ <_1005004>
313
+ <display>The requested return currency is invalid.</display>
314
+ </_1005004>
315
+ <_1005005>
316
+ <display>The request currency is not supported for the target country.</display>
317
+ </_1005005>
318
+ <_1005006>
319
+ <display>The order cannot be shipped by the method selected.</display>
320
+ </_1005006>
321
+ <_1005007>
322
+ <display>The order value has exceeded the allowed value.</display>
323
+ </_1005007>
324
+ <_1005008>
325
+ <display>Invalid fields in parcels.</display>
326
+ </_1005008>
327
+ <_1005009>
328
+ <display>Invalid fields in commoditySources.</display>
329
+ </_1005009>
330
+ <_1005010>
331
+ <display>There are errors at the Quote Line Level.</display>
332
+ </_1005010>
333
+ <_1005011>
334
+ <display>There are errors at the Quote Item Level.</display>
335
+ </_1005011>
336
+ <_1005012>
337
+ <display>The order exceeded the weight limit.</display>
338
+ </_1005012>
339
+ <_1005013>
340
+ <display>The shipping address has missing fields.</display>
341
+ </_1005013>
342
+ <_1005014>
343
+ <display>Missing fields in basket.</display>
344
+ </_1005014>
345
+ <_1005015>
346
+ <display>Invalid fields in basket.</display>
347
+ </_1005015>
348
+ <_1005016>
349
+ <display>The consignee information is missing.</display>
350
+ </_1005016>
351
+ <_1005017>
352
+ <display>The COP transportation information is missing.</display>
353
+ </_1005017>
354
+ <_1005018>
355
+ <display>Shipping Speed unavailable.</display>
356
+ </_1005018>
357
+ <_1005018>
358
+ <display>Shipping Speed unavailable.</display>
359
+ </_1005018>
360
+ <_1005019>
361
+ <display>Missing Basket.</display>
362
+ </_1005019>
363
+ <_1005020>
364
+ <display>Missing Parcel Fields.</display>
365
+ </_1005020>
366
+ <_1005021>
367
+ <display>Missing fields in the basket commodity source.</display>
368
+ </_1005021>
369
+ <_1005022>
370
+ <display>Invalid Parcel Fields.</display>
371
+ </_1005022>
372
+ <_1006001>
373
+ <display>The commodity was invalid.</display>
374
+ </_1006001>
375
+ <_1006002>
376
+ <display>The commodity is too large to ship (length, width or height).</display>
377
+ </_1006002>
378
+ <_1006003>
379
+ <display>The commodity cannot be shipped to the COD.</display>
380
+ </_1006003>
381
+ <_1006004>
382
+ <display>The commodity has a negative price.</display>
383
+ </_1006004>
384
+ <_1006005>
385
+ <display>The commodity’s price was too low and did not have a dutiable value.</display>
386
+ </_1006005>
387
+ <_1006006>
388
+ <display>The item price exceeds maximum.</display>
389
+ </_1006006>
390
+ <_1006007>
391
+ <display>Item weight exceeds maximum.</display>
392
+ </_1006007>
393
+ <_1006008>
394
+ <display>Invalid commodity rated data. Commodity cannot be shipped at this time. This is an internal error and should be raised to PB immediately. .</display>
395
+ </_1006008>
396
+ <_1006009>
397
+ <display>The Commodity is restricted for this Country of Destination.</display>
398
+ </_1006009>
399
+ <_10060010>
400
+ <display>Commodity cannot be quoted.</display>
401
+ </_10060010>
402
+ <_10060011>
403
+ <display>Commodity cannot shipped to the address specified.</display>
404
+ </_10060011>
405
+ <_1007001>
406
+ <display>Order value exceeded on this line.</display>
407
+ </_1007001>
408
+ <_1007002>
409
+ <display>Line too large to ship (length, width or height of the shipping box).</display>
410
+ </_1007002>
411
+ <_1007003>
412
+ <display>The quantity is invalid or missing.</display>
413
+ </_1007003>
414
+ <_1007004>
415
+ <display>Weight Value exceeded on this line.</display>
416
+ </_1007004>
417
+ <_1007005>
418
+ <display>Errors in the kitContents.</display>
419
+ </_1007005>
420
+ <_1007006>
421
+ <display>Missing fields in basket line.</display>
422
+ </_1007006>
423
+ <_1007007>
424
+ <display>Invalid fields in basket line.</display>
425
+ </_1007007>
426
+ <_1007008>
427
+ <display>Quantity exceeded for Country of Destination.</display>
428
+ </_1007008>
429
+ </error_messages>
430
+ </pbgsp>
431
+ </carriers>
432
+ </default>
433
+
434
+ <!-- Please modify this part for CRON JOB
435
+ For more information on Magento Cron Job, please visit the following url:
436
+ http://www.magentocommerce.com/wiki/1_-_installation_and_configuration/how_to_setup_a_cron_job#built-in_cron_jobs
437
+ -->
438
+ <crontab>
439
+ <jobs>
440
+ <pb_pbgsp>
441
+ <schedule>
442
+ <cron_expr>30 * * * *</cron_expr>
443
+ </schedule>
444
+ <run>
445
+ <model>pb_pbgsp/catalog_cron::catalogSync</model>
446
+ </run>
447
+ </pb_pbgsp>
448
+ <pb_notifications>
449
+ <schedule>
450
+ <cron_expr>20 * * * *</cron_expr>
451
+ </schedule>
452
+ <run>
453
+ <model>pb_pbgsp/catalog_cron::processStatusNotifications</model>
454
+ </run>
455
+ </pb_notifications>
456
+ </jobs>
457
+ </crontab>
458
+ <adminhtml>
459
+ <events>
460
+ <!--<sales_order_save_commit_after>-->
461
+ <!--<observers>-->
462
+ <!--<Pb_Pbgsp_CreateParcel>-->
463
+ <!--<type>model</type>-->
464
+ <!--<class>pb_pbgsp/observer</class>-->
465
+ <!--<method>generateInboundParcelPreAdvice</method>-->
466
+ <!--</Pb_Pbgsp_CreateParcel>-->
467
+ <!--</observers>-->
468
+ <!--</sales_order_save_commit_after>-->
469
+ <sales_order_shipment_save_after>
470
+ <observers>
471
+ <Pb_Pbgsp_CreateParcel>
472
+ <type>model</type>
473
+ <class>pb_pbgsp/observer</class>
474
+ <method>generateInboundParcelPreAdvice</method>
475
+ </Pb_Pbgsp_CreateParcel>
476
+ </observers>
477
+ </sales_order_shipment_save_after>
478
+ </events>
479
+ <!--<translate>-->
480
+ <!--<modules>-->
481
+ <!--<translations>-->
482
+ <!--<files>-->
483
+ <!--<default>Pb_Pbgsp.csv</default>-->
484
+ <!--</files>-->
485
+ <!--</translations>-->
486
+ <!--</modules>-->
487
+ <!--</translate>-->
488
+ </adminhtml>
489
+
490
+ </config>
491
+
app/code/local/Pb/Pbgsp/etc/system.xml ADDED
@@ -0,0 +1,361 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <sections>
4
+ <carriers>
5
+ <groups>
6
+ <pbgsp translate="label" module="shipping">
7
+ <label>Pitney Bowes PBGSP</label>
8
+ <frontend_type>text</frontend_type>
9
+ <sort_order>13</sort_order>
10
+ <show_in_default>1</show_in_default>
11
+ <show_in_website>1</show_in_website>
12
+ <show_in_store>1</show_in_store>
13
+ <fields>
14
+ <active translate="label">
15
+ <label>Enabled</label>
16
+ <frontend_type>select</frontend_type>
17
+ <source_model>adminhtml/system_config_source_yesno</source_model>
18
+ <sort_order>1</sort_order>
19
+ <show_in_default>1</show_in_default>
20
+ <show_in_website>1</show_in_website>
21
+ <show_in_store>1</show_in_store>
22
+ </active>
23
+ <merchantcode translate="label">
24
+ <label>Merchant Code</label>
25
+ <frontend_type>text</frontend_type>
26
+ <backend_model>adminhtml/system_config_backend_encrypted</backend_model>
27
+ <sort_order>10</sort_order>
28
+ <show_in_default>1</show_in_default>
29
+ <show_in_website>1</show_in_website>
30
+ <show_in_store>1</show_in_store>
31
+ </merchantcode>
32
+ <apiurl translate="label">
33
+ <label>API Endpoint</label>
34
+ <frontend_type>text</frontend_type>
35
+ <sort_order>18</sort_order>
36
+ <show_in_default>1</show_in_default>
37
+ <show_in_website>1</show_in_website>
38
+ <show_in_store>1</show_in_store>
39
+ </apiurl>
40
+ <order_mgmt_api translate="label">
41
+ <label>Order Management API Endpoint</label>
42
+ <frontend_type>text</frontend_type>
43
+
44
+ <sort_order>19</sort_order>
45
+ <show_in_default>1</show_in_default>
46
+ <show_in_website>1</show_in_website>
47
+ <show_in_store>1</show_in_store>
48
+ </order_mgmt_api>
49
+ <apiuser translate="label">
50
+ <label>API username</label>
51
+ <frontend_type>text</frontend_type>
52
+ <backend_model>adminhtml/system_config_backend_encrypted</backend_model>
53
+ <sort_order>20</sort_order>
54
+ <show_in_default>1</show_in_default>
55
+ <show_in_website>1</show_in_website>
56
+ <show_in_store>1</show_in_store>
57
+ </apiuser>
58
+ <apipass translate="label">
59
+ <label>API password</label>
60
+ <frontend_type>password</frontend_type>
61
+ <backend_model>adminhtml/system_config_backend_encrypted</backend_model>
62
+ <sort_order>30</sort_order>
63
+ <show_in_default>1</show_in_default>
64
+ <show_in_website>1</show_in_website>
65
+ <show_in_store>1</show_in_store>
66
+ </apipass>
67
+ <ftpuser translate="label">
68
+ <label>SFTP username</label>
69
+ <frontend_type>text</frontend_type>
70
+ <backend_model>adminhtml/system_config_backend_encrypted</backend_model>
71
+ <sort_order>40</sort_order>
72
+ <show_in_default>1</show_in_default>
73
+ <show_in_website>1</show_in_website>
74
+ <show_in_store>1</show_in_store>
75
+ </ftpuser>
76
+ <ftppass translate="label">
77
+ <label>SFTP password</label>
78
+ <frontend_type>password</frontend_type>
79
+ <backend_model>adminhtml/system_config_backend_encrypted</backend_model>
80
+ <sort_order>50</sort_order>
81
+ <show_in_default>1</show_in_default>
82
+ <show_in_website>1</show_in_website>
83
+ <show_in_store>1</show_in_store>
84
+ </ftppass>
85
+ <ftphost translate="label">
86
+ <label>SFTP hostname</label>
87
+ <frontend_type>text</frontend_type>
88
+ <sort_order>60</sort_order>
89
+ <show_in_default>1</show_in_default>
90
+ <show_in_website>1</show_in_website>
91
+ <show_in_store>1</show_in_store>
92
+ </ftphost>
93
+ <ftpport translate="label">
94
+ <label>SFTP port</label>
95
+ <frontend_type>text</frontend_type>
96
+ <sort_order>70</sort_order>
97
+ <show_in_default>1</show_in_default>
98
+ <show_in_website>1</show_in_website>
99
+ <show_in_store>1</show_in_store>
100
+ </ftpport>
101
+ <ftpdir translate="label">
102
+ <label>SFTP catalog directory</label>
103
+ <frontend_type>text</frontend_type>
104
+ <backend_model>adminhtml/system_config_backend_encrypted</backend_model>
105
+ <sort_order>80</sort_order>
106
+ <show_in_default>1</show_in_default>
107
+ <show_in_website>1</show_in_website>
108
+ <show_in_store>1</show_in_store>
109
+ </ftpdir>
110
+ <catalog_diff translate="label">
111
+ <label>Catalog update period (hours, min 1 hour)</label>
112
+ <frontend_type>text</frontend_type>
113
+ <sort_order>90</sort_order>
114
+ <show_in_default>1</show_in_default>
115
+ <show_in_website>1</show_in_website>
116
+ <show_in_store>1</show_in_store>
117
+ </catalog_diff>
118
+ <catalog_full translate="label">
119
+ <label>Full catalog upload period (days)</label>
120
+ <frontend_type>text</frontend_type>
121
+ <sort_order>100</sort_order>
122
+ <show_in_default>1</show_in_default>
123
+ <show_in_website>1</show_in_website>
124
+ <show_in_store>1</show_in_store>
125
+ </catalog_full>
126
+ <catalog_size translate="label">
127
+ <label>Maximum Records Per File</label>
128
+ <frontend_type>text</frontend_type>
129
+ <validate>validate-number</validate>
130
+ <sort_order>105</sort_order>
131
+ <show_in_default>1</show_in_default>
132
+ <show_in_website>1</show_in_website>
133
+ <show_in_store>1</show_in_store>
134
+ </catalog_size>
135
+ <catalog_sender_id translate="label">
136
+ <label>Catalog Sender ID</label>
137
+ <frontend_type>text</frontend_type>
138
+
139
+ <sort_order>106</sort_order>
140
+ <show_in_default>1</show_in_default>
141
+ <show_in_website>1</show_in_website>
142
+ <show_in_store>1</show_in_store>
143
+ </catalog_sender_id>
144
+ <admin_email translate="label">
145
+ <label>Admin Email</label>
146
+ <frontend_type>text</frontend_type>
147
+ <validate>validate-email</validate>
148
+ <sort_order>110</sort_order>
149
+ <show_in_default>1</show_in_default>
150
+ <show_in_website>1</show_in_website>
151
+ <show_in_store>1</show_in_store>
152
+ </admin_email>
153
+ <catalog_encryption_enabled translate="label">
154
+ <label>Catalog Encryption Enabled</label>
155
+ <frontend_type>select</frontend_type>
156
+ <source_model>adminhtml/system_config_source_yesno</source_model>
157
+ <sort_order>115</sort_order>
158
+ <show_in_default>1</show_in_default>
159
+ <show_in_website>1</show_in_website>
160
+ <show_in_store>1</show_in_store>
161
+ </catalog_encryption_enabled>
162
+ <encryption_public_key translate="label">
163
+ <label>Catalog Encryption Public Key</label>
164
+ <frontend_type>textarea</frontend_type>
165
+ <sort_order>120</sort_order>
166
+ <show_in_default>1</show_in_default>
167
+ <show_in_website>1</show_in_website>
168
+ <show_in_store>1</show_in_store>
169
+ </encryption_public_key>
170
+ <asn_generation_enabled translate="label">
171
+ <label>Generate ASN</label>
172
+ <frontend_type>select</frontend_type>
173
+ <source_model>adminhtml/system_config_source_yesno</source_model>
174
+ <sort_order>121</sort_order>
175
+ <show_in_default>1</show_in_default>
176
+ <show_in_website>1</show_in_website>
177
+ <show_in_store>1</show_in_store>
178
+ </asn_generation_enabled>
179
+
180
+ <!--
181
+ If the free_shipping_enable flag enable, the system will check free_shipping_subtotal to give free shipping
182
+ otherwise will use shopping cart price rule behaviour
183
+ -->
184
+ <free_shipping_enable translate="label">
185
+ <label>Free shipping with minimum order amount</label>
186
+ <frontend_type>select</frontend_type>
187
+ <source_model>adminhtml/system_config_source_enabledisable</source_model>
188
+ <sort_order>160</sort_order>
189
+ <show_in_default>1</show_in_default>
190
+ <show_in_website>1</show_in_website>
191
+ <show_in_store>1</show_in_store>
192
+ </free_shipping_enable>
193
+ <free_shipping_subtotal translate="label">
194
+ <label>Minimum order amount for free shipping</label>
195
+ <frontend_type>text</frontend_type>
196
+ <sort_order>170</sort_order>
197
+ <show_in_default>1</show_in_default>
198
+ <show_in_website>1</show_in_website>
199
+ <show_in_store>1</show_in_store>
200
+ </free_shipping_subtotal>
201
+ <sort_order translate="label">
202
+ <label>Sort order</label>
203
+ <frontend_type>text</frontend_type>
204
+ <sort_order>230</sort_order>
205
+ <show_in_default>1</show_in_default>
206
+ <show_in_website>1</show_in_website>
207
+ <show_in_store>1</show_in_store>
208
+ </sort_order>
209
+ <title translate="label">
210
+ <label>Title</label>
211
+ <frontend_type>text</frontend_type>
212
+ <sort_order>240</sort_order>
213
+ <show_in_default>1</show_in_default>
214
+ <show_in_website>1</show_in_website>
215
+ <show_in_store>1</show_in_store>
216
+ </title>
217
+ <!-- added by BigPixel 6/5/2012 -->
218
+ <handlingfee translate="label">
219
+ <label>Handling Fee</label>
220
+ <frontend_type>text</frontend_type>
221
+ <sort_order>241</sort_order>
222
+ <show_in_default>1</show_in_default>
223
+ <show_in_website>1</show_in_website>
224
+ <show_in_store>1</show_in_store>
225
+ </handlingfee>
226
+ <handlingoption translate="label">
227
+ <label>Handling Fee Apply As</label>
228
+ <frontend_type>select</frontend_type>
229
+ <source_model>pb_pbgsp/handlingoptions</source_model>
230
+ <sort_order>242</sort_order>
231
+ <show_in_default>1</show_in_default>
232
+ <show_in_website>1</show_in_website>
233
+ <show_in_store>1</show_in_store>
234
+ </handlingoption>
235
+ <domestic_shipping_fee translate="label">
236
+ <label>Domestic Shipping Fee</label>
237
+ <frontend_type>text</frontend_type>
238
+ <sort_order>243</sort_order>
239
+ <show_in_default>1</show_in_default>
240
+ <show_in_website>1</show_in_website>
241
+ <show_in_store>1</show_in_store>
242
+ </domestic_shipping_fee>
243
+ <domestic_shipping_option translate="label">
244
+ <label>Apply Domestic shipping fee as</label>
245
+ <frontend_type>select</frontend_type>
246
+ <source_model>pb_pbgsp/handlingoptions</source_model>
247
+ <sort_order>244</sort_order>
248
+ <show_in_default>1</show_in_default>
249
+ <show_in_website>1</show_in_website>
250
+ <show_in_store>1</show_in_store>
251
+ </domestic_shipping_option>
252
+ <delivery_adjustment_min_days translate="label">
253
+ <label>Minimum Delivery Days to PB Hub</label>
254
+ <frontend_type>text</frontend_type>
255
+ <validate>validate-number</validate>
256
+ <sort_order>245</sort_order>
257
+ <show_in_default>1</show_in_default>
258
+ <show_in_website>1</show_in_website>
259
+ <show_in_store>1</show_in_store>
260
+ </delivery_adjustment_min_days>
261
+ <delivery_adjustment_max_days translate="label">
262
+ <label>Maximum Delivery Days to PB Hub</label>
263
+ <frontend_type>text</frontend_type>
264
+ <validate>validate-number</validate>
265
+ <sort_order>246</sort_order>
266
+ <show_in_default>1</show_in_default>
267
+ <show_in_website>1</show_in_website>
268
+ <show_in_store>1</show_in_store>
269
+ </delivery_adjustment_max_days>
270
+ <!-- added by BigPixel 6/5/2012 -->
271
+ <sallowspecific translate="label">
272
+ <label>Ship to applicable countries</label>
273
+ <frontend_type>select</frontend_type>
274
+ <sort_order>250</sort_order>
275
+ <frontend_class>shipping-applicable-country</frontend_class>
276
+ <source_model>adminhtml/system_config_source_shipping_allspecificcountries</source_model>
277
+ <show_in_default>1</show_in_default>
278
+ <show_in_website>1</show_in_website>
279
+ <show_in_store>1</show_in_store>
280
+ </sallowspecific>
281
+ <specificcountry translate="label">
282
+ <label>Ship to Specific countries</label>
283
+ <frontend_type>multiselect</frontend_type>
284
+ <sort_order>251</sort_order>
285
+ <source_model>adminhtml/system_config_source_country</source_model>
286
+ <show_in_default>1</show_in_default>
287
+ <show_in_website>1</show_in_website>
288
+ <show_in_store>1</show_in_store>
289
+ </specificcountry>
290
+ <showmethod translate="label">
291
+ <label>Show Method if Not Applicable</label>
292
+ <frontend_type>select</frontend_type>
293
+ <sort_order>260</sort_order>
294
+ <frontend_class>shipping-skip-hide</frontend_class>
295
+ <source_model>adminhtml/system_config_source_yesno</source_model>
296
+ <show_in_default>1</show_in_default>
297
+ <show_in_website>1</show_in_website>
298
+ <show_in_store>0</show_in_store>
299
+ </showmethod>
300
+ <specificerrmsg translate="label">
301
+ <label>Displayed Error Message</label>
302
+ <frontend_type>textarea</frontend_type>
303
+ <sort_order>270</sort_order>
304
+ <show_in_default>1</show_in_default>
305
+ <show_in_website>1</show_in_website>
306
+ <show_in_store>1</show_in_store>
307
+ </specificerrmsg>
308
+ <!-- test comments -->
309
+ <trackinglink translate="label">
310
+ <label>Enable Tracking Links</label>
311
+ <frontend_type>select</frontend_type>
312
+ <source_model>adminhtml/system_config_source_yesno</source_model>
313
+ <sort_order>271</sort_order>
314
+ <show_in_default>1</show_in_default>
315
+ <show_in_website>1</show_in_website>
316
+ <show_in_store>1</show_in_store>
317
+ </trackinglink>
318
+ <suppress_domestic_tracking translate="label">
319
+ <label>Suppress Domestic Leg Tracking</label>
320
+ <frontend_type>select</frontend_type>
321
+ <sort_order>280</sort_order>
322
+ <frontend_class>shipping-skip-hide</frontend_class>
323
+ <source_model>adminhtml/system_config_source_yesno</source_model>
324
+ <show_in_default>1</show_in_default>
325
+ <show_in_website>1</show_in_website>
326
+ <show_in_store>1</show_in_store>
327
+ </suppress_domestic_tracking>
328
+ <custom_shipment_email_subject translate="label">
329
+ <label>Custom Shipment Email Subject</label>
330
+ <frontend_type>text</frontend_type>
331
+
332
+ <sort_order>281</sort_order>
333
+ <show_in_default>1</show_in_default>
334
+ <show_in_website>1</show_in_website>
335
+ <show_in_store>1</show_in_store>
336
+ </custom_shipment_email_subject>
337
+ <custom_shipment_email_template>
338
+ <label>Custom Shipment Email</label>
339
+ <frontend_type>textarea</frontend_type>
340
+ <sort_order>282</sort_order>
341
+ <show_in_default>1</show_in_default>
342
+ <show_in_website>1</show_in_website>
343
+ <show_in_store>1</show_in_store>
344
+ </custom_shipment_email_template>
345
+ <separate_log_file translate="label">
346
+ <label>Log in separate file</label>
347
+ <frontend_type>select</frontend_type>
348
+ <sort_order>283</sort_order>
349
+ <frontend_class>shipping-skip-hide</frontend_class>
350
+ <source_model>adminhtml/system_config_source_yesno</source_model>
351
+ <show_in_default>1</show_in_default>
352
+ <show_in_website>1</show_in_website>
353
+ <show_in_store>1</show_in_store>
354
+ </separate_log_file>
355
+ </fields>
356
+ </pbgsp>
357
+ </groups>
358
+ </carriers>
359
+
360
+ </sections>
361
+ </config>
app/code/local/Pb/Pbgsp/sql/pbgsp_setup/mysql4-install-1.0.0.php ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+
5
+ $installer = $this;
6
+
7
+ $installer->startSetup();
8
+
9
+ $installer->run("
10
+
11
+ DROP TABLE IF EXISTS {$this->getTable('pb_pbgsp/variable')};
12
+ CREATE TABLE {$this->getTable('pb_pbgsp/variable')} (
13
+ `variable_id` int(11) unsigned NOT NULL auto_increment,
14
+ `name` varchar(255) NOT NULL default '',
15
+ `value` varchar(255) NOT NULL default '',
16
+ PRIMARY KEY (`variable_id`)
17
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
18
+
19
+ DROP TABLE IF EXISTS {$this->getTable('pb_pbgsp/ordernumber')};
20
+ CREATE TABLE {$this->getTable('pb_pbgsp/ordernumber')} (
21
+ `ordernumber_id` int(11) unsigned NOT NULL auto_increment,
22
+ `cp_order_number` varchar(255) NOT NULL default '',
23
+ `mage_order_number` varchar(255) NOT NULL default '',
24
+ `confirmed` tinyint NOT NULL default 0,
25
+ `referenced` tinyint NOT NULL default 0,
26
+ `hub_id` varchar(50) null,
27
+ `hub_street1` varchar(50) null,
28
+ `hub_street2` varchar(50) null,
29
+ `hub_province_or_state` varchar(50) null,
30
+ `hub_country` varchar(50) null,
31
+ PRIMARY KEY (`ordernumber_id`)
32
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
33
+
34
+ DROP TABLE IF EXISTS {$this->getTable('pb_pbgsp/inboundparcel')};
35
+ CREATE TABLE {$this->getTable('pb_pbgsp/inboundparcel')} (
36
+ `inbound_parcel_id` int(11) unsigned NOT NULL auto_increment,
37
+ `inbound_parcel` varchar(255) NOT NULL default '',
38
+ `mage_order_number` varchar(255) NOT NULL default '',
39
+ `pb_order_number` varchar(255) NOT NULL default '',
40
+ PRIMARY KEY (`inbound_parcel_id`)
41
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
42
+
43
+ ");
44
+
45
+ $eav = Mage::getResourceModel('catalog/setup', 'catalog_setup');//new Mage_Eav_Model_Entity_Setup('catalog_setup');
46
+ //$eav->removeAttribute('catalog_product','pb_pbgsp_upload');
47
+ $eav->addAttribute('catalog_product', 'pb_pbgsp_upload', array(
48
+ 'type' => 'int',
49
+ 'input' => 'text',
50
+ 'label' => 'Last PBGSP upload timestampt',
51
+ 'global' => 2,
52
+ 'user_defined' => 0,
53
+ 'required' => 0,
54
+ 'visible' => 1,
55
+ 'default' => 0
56
+
57
+ ));
58
+
59
+ $installer->endSetup();
60
+ ?>
app/etc/modules/Pb_Pbgsp.xml ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Pb_Pbgsp>
5
+ <active>true</active>
6
+ <codePool>local</codePool>
7
+ <depends>
8
+ </depends>
9
+ </Pb_Pbgsp>
10
+ </modules>
11
+ </config>
12
+
package.xml ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>pitneybowes_gsp</name>
4
+ <version>0.9.0</version>
5
+ <stability>beta</stability>
6
+ <license uri="http://opensource.org/licenses/osl-3.0.php">Open Software License (OSL)</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>Pitney Bowes Global Shipping Platform (GSP) simplifies cross-border transactions and enables global ecommerce!</summary>
10
+ <description>Pitney Bowes does more cross-border transactions than any other company in the world, and with the Global Shipping Platform for Magento extension, you can start selling and shipping your products to 70+ countries around the world!&#xD;
11
+ &#xD;
12
+ Pitney Bowes eliminates cross-border friction and simplifies global transactions by:&#xD;
13
+ &lt;ul&gt;&#xD;
14
+ &lt;li&gt;Providing &lt;b&gt;fully-landed cost quotes&lt;/b&gt; to 70+ countries worldwide directly in your shopping basket and one-page checkout. All fully-landed cost quotes include &lt;b&gt;duty, tax, brokerage fee, international shipping, and international handling.&lt;/b&gt;&#xD;
15
+ &lt;/li&gt;&#xD;
16
+ &lt;li&gt;Automatically transmitting your catalog to Pitney Bowes for internationalization and shipping preparation.&lt;/li&gt;&#xD;
17
+ &lt;li&gt;Clearly displaying errors for shipping restrictions to international locales due to import and trade rules.&#xD;
18
+ &lt;/li&gt;&#xD;
19
+ &lt;li&gt;&#xD;
20
+ Providing full international tracking linked from your admin page&#xD;
21
+ &lt;/li&gt;&#xD;
22
+ &lt;/ul&gt;&#xD;
23
+ To learn more, go to &lt;a href="http://www.pb.com/ecom"&gt;http://www.pb.com/ecom&lt;/a&gt;&#xD;
24
+ </description>
25
+ <notes>Initial Stable GSP release for Magento Connect.</notes>
26
+ <authors><author><name>Raymond Lai</name><user>r3lai</user><email>raymond.lai@pb.com</email></author></authors>
27
+ <date>2015-04-14</date>
28
+ <time>11:41:56</time>
29
+ <contents><target name="magelocal"><dir name="Pb"><dir name="Pbgsp"><dir name="Block"><dir name="Adminhtml"><dir name="Sales"><dir name="Order"><dir name="Invoice"><file name="Totals.php" hash="691656a14608642b25fc9efab2a0c155"/></dir><file name="Totals.php" hash="dbf77cfd835102e99539f062af3b9c55"/></dir></dir></dir><dir name="Checkout"><dir name="Shipping"><dir name="Method"><file name="Available.php" hash="bd20945fe9da40d382898dc013f860ea"/></dir></dir></dir><file name="Form.php" hash="ae0844bdb3c596cb48191a94850423fa"/><dir name="Sales"><dir name="Order"><dir name="Invoice"><file name="Totals.php" hash="c0d69d334712951c59400ed0911f5ef7"/></dir><file name="Totals.php" hash="ad7708efb7550991df82e4cb8c387270"/></dir></dir></dir><dir name="Model"><file name="Api.php" hash="a0c3d5adbb470590ef4adde3d659addc"/><dir name="Carrier"><file name="ShippingMethod.php" hash="dd79e517a6b17c0e9b7175a6383c5f2d"/></dir><dir name="Catalog"><file name="Category.php" hash="83e2c6c7374d0917eba8fc66d33379c2"/><file name="Cron.php" hash="4c20db78b5e9b0e00f542d922c2a5077"/><file name="File.php" hash="bb9c2f8e88ab97c75cec51eca254219f"/><file name="Product.php" hash="0b9c77ce88c98bb6c4c27f5f0bdbc82e"/></dir><file name="Credentials.php" hash="c8bff1c913d7f0200020af3b04348b1c"/><dir name="Creditmemo"><file name="Duty.php" hash="7aeeaf0203624a0beec9c87c4176b120"/></dir><file name="Handlingoptions.php" hash="1e8b845d2a595e54bab55dc44e55a1be"/><file name="Helper.php" hash="b68156a8556a00a379ef121ece805d06"/><file name="Inboundparcel.php" hash="3b149c32bf1c49eb255c16811806327f"/><dir name="Invoice"><file name="Duty.php" hash="783ece295715095c41041d7bd636d989"/></dir><file name="Messages.php" hash="073a95d2033acadf0e66156b25e073f6"/><dir name="Mysql4"><dir name="Inboundparcel"><file name="Collection.php" hash="9e22c4602437006a588288c7bb4ebe00"/></dir><file name="Inboundparcel.php" hash="1375e23587f63783e2c28328bfa6a7e4"/><dir name="Ordernumber"><file name="Collection.php" hash="952c035d9a62093a5f57b2e1b94315c6"/></dir><file name="Ordernumber.php" hash="a798162bba3d6385fde9a617913d05c1"/><dir name="Variable"><file name="Collection.php" hash="758c590a398acca4a5825bbd49de18fe"/></dir><file name="Variable.php" hash="bedf862cc7934157b892c9dd8efc5b86"/></dir><file name="Observer.php" hash="71449974b3b49766405faa0a1ca3fb0b"/><file name="Ordernumber.php" hash="79180b9acee40a15d02238d303ef2b78"/><dir name="Pdf"><file name="Tax.php" hash="0e787b3f319d4c13c2c929288f38b8f9"/></dir><dir name="Quote"><file name="Duty.php" hash="931e21fae6443d99a094b3ee409eae25"/></dir><dir name="Resource"><dir name="Mysql4"><file name="Setup.php" hash="af6d513cce9b9f59eab82cec0f2156a1"/></dir></dir><dir name="Sales"><dir name="Order"><file name="Shipment.php" hash="8caca8e1a7fc7437b6c865656b88ecf8"/></dir></dir><file name="Util.php" hash="86bf7854c9466e98464aac409e6e3604"/><file name="Variable.php" hash="384e9eb6d24b92596bc259fbc6a55756"/></dir><file name="README" hash="5baea7c4c231d8cda23465a1abd5427e"/><dir name="etc"><file name="config.xml" hash="6af31f94bb2b26b9cd87cb7c0da86ac3"/><file name="system.xml" hash="e34d51c16e5068d4f76ceff5b00781e1"/></dir><dir name="sql"><dir name="pbgsp_setup"><file name="mysql4-install-1.0.0.php" hash="0c22ce6149ffd831eddb9299ffd8eaab"/></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Pb_Pbgsp.xml" hash="dc3ea1c2b33fc8e526486c17a24965a4"/></dir></target></contents>
30
+ <compatible/>
31
+ <dependencies><required><php><min>5.1.0</min><max>5.3.3</max></php><extension><name>gnupg</name><min>1.3.5</min><max>1.3.6</max></extension></required></dependencies>
32
+ </package>