Ejemplo n.º 1
0
 /**
  * Apply sub total discount.
  */
 function apply_sub_total($cart, $sub_total, $discounts)
 {
     foreach ((array) $discounts as $discount) {
         foreach ((array) $discount['rules'] as $rule) {
             if ($rule['enabled'] !== null && !$rule['enabled']) {
                 continue;
             }
             switch ($rule['type']) {
                 case 'product':
                     foreach ((array) $cart['items'] as $item) {
                         if ($item['id'] != $rule['product_id']) {
                             continue;
                         }
                         $d_qty = $discount_qty[$item['id']];
                         // Limit discount quantity?
                         if ($rule['quantity']) {
                             $qty = $rule['quantity'] > $item['quantity'] ? $item['quantity'] : $rule['quantity'];
                             if ($d_qty + $qty >= $rule['quantity']) {
                                 $qty = $qty - ($discout_qty + $qty - $rule['quantity']);
                             }
                         } else {
                             $qty = $item['quantity'];
                         }
                         // Subtract item from total.
                         $sub_total -= $item['price'] * $qty;
                         // Apply discount value to price.
                         $item_price = self::apply_value($item['price'], $rule['value']);
                         // Add new item price back to total.
                         $sub_total += $item_price * $qty;
                         // Track total qty discounted.
                         $discount_qty[$item['id']] += $qty;
                     }
                     break;
                 case 'category':
                     foreach ((array) $cart['items'] as $item) {
                         if (in_array($rule['category_id'], (array) $item['category_ids'])) {
                             $d_qty = $discount_qty[$item['id']];
                             // Limit discount quantity?
                             if ($rule['quantity']) {
                                 $qty = $rule['quantity'] > $item['quantity'] ? $item['quantity'] : $rule['quantity'];
                                 if ($d_qty + $qty > $rule['quantity']) {
                                     $qty = $qty - ($discout_qty + $qty - $rule['quantity']);
                                 }
                             } else {
                                 $qty = $item['quantity'];
                             }
                             // Subtract item from total.
                             $sub_total -= $item['price'] * $qty;
                             // Apply discount value to price.
                             $item_price = self::apply_value($item['price'], $rule['value']);
                             // Add new item price back to total.
                             $sub_total += $item_price * $qty;
                             // Track total qty discounted.
                             $discount_qty[$item['id']] += $qty;
                             $items_discounted++;
                         }
                         // Break if reached category limit.
                         if ($rule['limit'] && $items_discounted >= $rule['limit']) {
                             break;
                         }
                     }
                     break;
                 case '':
                 case 'total':
                     $sub_total = Discounts::apply_value($sub_total, $rule['value']);
                     break;
             }
         }
     }
     return $sub_total;
 }
Ejemplo n.º 2
0
/**
 * Get UPS rate quotes.
 */
function fwd_ups_rates($params, $settings)
{
    // Configurable UPS service methods.
    $service_list = array('01' => 'UPS Next Day Air', '02' => 'UPS Second Day Air', '03' => 'UPS Ground', '11' => 'UPS Standard', '12' => 'UPS Three-Day Select', '13' => 'UPS Next Day Air Saver', '65' => 'UPS Worldwide Saver', '07' => 'UPS Worldwide Express', '08' => 'UPS Worldwide Expedited', '14' => 'UPS Next Day Air Early A.M.', '54' => 'UPS Worldwide Express Plus', '59' => 'UPS Second Day Air A.M.');
    // If params are empty, return available methods only.
    if (empty($params)) {
        $methods = array();
        foreach ((array) $settings['methods'] as $key => $method) {
            if ($method) {
                $method = is_array($method) ? $method : array();
                $methods[] = array('id' => $key, 'name' => $method['name'] ?: $service_list[$key]);
            }
        }
        return $methods;
    }
    // Get shipper, default or specific settings.
    $shipper = array_merge(array('package_weight' => 100), (array) $settings['shippers'][0], (array) $settings['shippers'][$params['shipper']]);
    // Split package by weight limit?
    if ($shipper['package_weight'] && $params['weight'] > $shipper['package_weight']) {
        $num_packages = ceil($params['weight'] / $shipper['package_weight']);
        for ($i = 0; $i < $num_packages; $i++) {
            if ($i >= 200) {
                break;
            }
            $params['packages'][$i] = array('weight' => $params['weight'] / $num_packages, 'units' => $params['units']);
        }
    } else {
        $params['packages'][1] = array('weight' => $params['weight'] ?: 1, 'units' => $params['units']);
    }
    // Add package(s) to request.
    foreach ($params['packages'] as $package) {
        // Dimensions?
        if ($package['dimensions']) {
            $package_dimensions = "\n\t\t\t\t<Dimensions>\n\t\t\t\t\t<Length>{$package['dimensions']['length']}</Length>\n\t\t\t\t\t<Width>{$package['dimensions']['width']}</Width>\n\t\t\t\t\t<Height>{$package['dimensions']['height']}</Height>\n\t\t\t\t\t<UnitOfMeasurement>\n\t\t\t\t\t\t<Code>" . ($package['dimensions']['units'] ?: 'IN') . "</Code>\n\t\t\t\t\t</UnitOfMeasurement>\n\t\t\t\t</Dimensions>\n\t\t\t";
        } else {
            $package_dimensions = null;
        }
        $request_packages .= "\n\t\t\t<Package>\n\t\t\t\t<PackagingType>\n\t\t\t\t\t<Code>02</Code>\n\t\t\t\t</PackagingType>\n\t\t\t\t<PackageWeight>\n\t\t\t\t\t<UnitOfMeasurement>\n\t\t\t\t\t\t<Code>" . ($package['units'] ? "{$package['units']}S" : 'LBS') . "</Code>\n\t\t\t\t\t</UnitOfMeasurement>\n\t\t\t\t\t<Weight>{$package['weight']}</Weight>\n\t\t\t\t</PackageWeight>\n\t\t\t\t{$package_dimensions}\n\t\t\t</Package>\n\t\t";
    }
    // XML API call.
    $request = "\n\t\t<?xml version=\"1.0\" ?>\n\t\t<AccessRequest xml:lang='en-US'>\n\t\t\t<AccessLicenseNumber>{$settings['license']}</AccessLicenseNumber>\n\t\t\t<UserId>{$settings['login']}</UserId>\n\t\t\t<Password>{$settings['password']}</Password>\n\t\t</AccessRequest>\n\t\t<?xml version=\"1.0\" ?>\n\t\t<RatingServiceSelectionRequest>\n\t\t\t<Request>\n\t\t\t\t<RequestAction>Rate</RequestAction>\n\t\t\t\t<RequestOption>Shop</RequestOption>\n\t\t\t</Request>\n\t\t\t<PickupType>\n\t\t\t\t<Code>01</Code>\n\t\t\t</PickupType>\n\n\t\t\t<Shipment>\n\t\t\t\t<Shipper>\n\t\t\t\t\t<ShipperNumber>" . ($shipper['account'] ?: $settings['account']) . "</ShipperNumber>\n\t\t\t\t\t<Address>\n\t\t\t\t\t\t<City>{$shipper['city']}</City>\n\t\t\t\t\t\t<PostalCode>{$shipper['zip']}</PostalCode>\n\t\t\t\t\t\t<CountryCode>" . ($shipper['country'] ?: 'US') . "</CountryCode>\n\t\t\t\t\t</Address>\n\t\t\t\t</Shipper>\n\n\t\t\t\t<ShipTo>\n\t\t\t\t\t<Address>\n\t\t\t\t\t\t<City>{$params['city']}</City>\n\t\t\t\t\t\t<StateProvinceCode>{$params['state']}</StateProvinceCode>\n\t\t\t\t\t\t<PostalCode>{$params['zip']}</PostalCode>\n\t\t\t\t\t\t<CountryCode>" . ($params['country'] ?: 'US') . "</CountryCode>\n\t\t\t\t\t\t<ResidentialAddressIndicator/>\n\t\t\t\t\t</Address>\n\t\t\t\t</ShipTo>\n\n\t\t\t\t{$request_packages}\n\n\t\t\t</Shipment>\n\n\t\t</RatingServiceSelectionRequest>\n\t";
    // Initialize connection with UPS service.
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $settings['host'] ?: "https://wwwcie.ups.com/ups.app/xml/Rate");
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $response = curl_exec($ch);
    curl_close($ch);
    if ($response) {
        $doc = new SimpleXMLElement($response);
        $response_code = (string) $doc->Response[0]->ResponseStatusCode;
    }
    switch ($response_code) {
        // Good response.
        case 1:
            foreach ($doc->RatedShipment as $shipment) {
                if ($service_type = (string) $shipment->Service[0]->Code) {
                    $price = (double) $shipment->TotalCharges[0]->MonetaryValue;
                    // Markup?
                    if ($settings['markup']) {
                        $price = Discounts::apply_value($price, '+' . $settings['markup']);
                    }
                    // Discount?
                    if ($settings['discount']) {
                        $price = Discounts::apply_value($price, $settings['markup']);
                    }
                    // Rated method configured/available?
                    if ($method = $settings['methods'][$service_type]) {
                        $method = is_array($method) ? $method : array();
                        $service_name = $method['name'] ?: $service_list[$service_type];
                        $service_price = round($price, 2);
                        $shipment_rates[] = array('id' => $service_type, 'name' => $service_name, 'price' => $service_price);
                    }
                }
            }
            break;
            // Bad response.
        // Bad response.
        case 0:
            throw new Exception((string) $doc->Response[0]->Error[0]->ErrorDescription[0]);
            break;
            // No response?
        // No response?
        default:
            throw new Exception("Unknown response from UPS Rating Service");
    }
    return $shipment_rates;
}
Ejemplo n.º 3
0
/**
 * Get FedEx rate quotes.
 */
function fwd_fedex_rates($params, $settings)
{
    // Configurable FedEx service methods.
    $service_list = array('FEDEX_GROUND' => 'Fedex Ground', 'FEDEX_EXPRESS_SAVER' => 'Fedex Express Saver', 'FEDEX_2_DAY' => 'Fedex 2-Day Air', 'FEDEX_2_DAY_AM' => 'Fedex 2-Day Air A.M.', 'STANDARD_OVERNIGHT' => 'Fedex Standard Overnight', 'PRIORITY_OVERNIGHT' => 'Fedex Priority Overnight', 'FIRST_OVERNIGHT' => 'Fedex First Overnight', 'INTERNATIONAL_PRIORITY' => 'Fedex Priority International');
    // If params are empty, return available methods only.
    if (empty($params)) {
        $methods = array();
        foreach ((array) $settings['methods'] as $key => $method) {
            if ($method) {
                $method = is_array($method) ? $method : array();
                $methods[] = array('id' => $key, 'name' => $method['name'] ?: $service_list[$key]);
            }
        }
        return $methods;
    }
    // Get shipper, default or specific.
    $shipper = array_merge(array('package_weight' => 100), (array) $settings['shippers'][0], (array) $settings['shippers'][$params['shipper']]);
    // Disable WSDL caching.
    ini_set('soap.wsdl_cache_enabled', '0');
    // Create SOAP client with Fedex RateService WSDL.
    $client = new SoapClient(dirname(__FILE__) . '/wsdl/RateService_v10.wsdl', array('trace' => 1));
    // Set endpoint host?
    if ($settings['host']) {
        $client->__setLocation($settings['host']);
    }
    // Split package by weight limit?
    if ($shipper['package_weight'] && $params['weight'] > $shipper['package_weight']) {
        $num_packages = ceil($params['weight'] / $shipper['package_weight']);
        for ($i = 0; $i < $num_packages; $i++) {
            if ($i >= 200) {
                break;
            }
            $params['packages'][$i] = array('insurance_amount' => $params['insurance_amount'] / $num_packages, 'insurance_currency' => $params['insurance_currency'], 'weight' => $params['weight'] / $num_packages, 'units' => $params['units']);
        }
    }
    // Setup request.
    $request = array('WebAuthenticationDetail' => array('UserCredential' => array('Key' => $settings['key'], 'Password' => $settings['password'])), 'ClientDetail' => array('AccountNumber' => $settings['account'], 'MeterNumber' => $settings['meter']), 'TransactionDetail' => array('CustomerTransactionId' => '*** Rate Request v10 using PHP ***'), 'Version' => array('ServiceId' => 'crs', 'Major' => '10', 'Intermediate' => '0', 'Minor' => '0'), 'ReturnTransitAndCommit' => true, 'RequestedShipment' => array('DropoffType' => 'REGULAR_PICKUP', 'ShipTimestamp' => date('c'), 'PackagingType' => 'YOUR_PACKAGING', 'Shipper' => array('Address' => array('StreetLines' => array($shipper['address']), 'City' => $shipper['city'], 'StateOrProvinceCode' => $shipper['state'], 'PostalCode' => $shipper['zip'], 'CountryCode' => $shipper['country'] ?: 'US')), 'Recipient' => array('Address' => array('StreetLines' => array($params['address']), 'City' => $params['city'], 'StateOrProvinceCode' => $params['state'], 'PostalCode' => $params['zip'], 'CountryCode' => $params['country'] ?: 'US')), 'ShippingChargesPayment' => array('PaymentType' => 'SENDER', 'Payor' => array('AccountNumber' => $shipper['account'] ?: $settings['account'], 'CountryCode' => $shipper['country'] ?: 'US')), 'RateRequestTypes' => 'ACCOUNT', 'RateRequestTypes' => 'LIST', 'PackageCount' => $params['packages'] ? count($params['packages']) : '1', 'RequestedPackages' => array()));
    // Default single package?
    if (count($params['packages']) == 0) {
        $params['packages'][0] = array('insurance_amount' => $params['insurance_amount'], 'insurance_currency' => $params['insurance_currency'], 'weight' => $params['weight'] ?: 1, 'units' => $params['units']);
        if ($params['dimensions']) {
            $params['packages'][0]['dimensions'] = array('length' => $params['dimensions']['length'], 'width' => $params['dimensions']['width'], 'height' => $params['dimensions']['height'], 'units' => $params['dimensions']['units']);
        }
    }
    // Add package(s) to request.
    foreach ($params['packages'] as $seq => $package) {
        $request['RequestedShipment']['RequestedPackageLineItems'][$seq] = array('SequenceNumber' => $seq + 1, 'GroupPackageCount' => 1, 'InsuredValue' => array('Amount' => $package['insurance_amount'] ?: 0, 'Currency' => $package['insurance_currency'] ?: 'USD'), 'Weight' => array('Value' => $package['weight'], 'Units' => $package['units'] ?: 'LB'));
        // Dimensions?
        if ($package['dimensions']) {
            $request['RequestedShipment']['RequestedPackageLineItems'][$seq]['Dimensions'] = array('Length' => $package['dimensions']['length'], 'Width' => $package['dimensions']['width'], 'Height' => $package['dimensions']['height'], 'Units' => $package['dimensions']['units'] ?: 'IN');
        }
    }
    // Try the request.
    try {
        $response = $client->getRates($request);
        if ($response->HighestSeverity != 'FAILURE' && $response->HighestSeverity != 'ERROR') {
            if (!is_array($response->RateReplyDetails)) {
                $response->RateReplyDetails = array($response->RateReplyDetails);
            }
            foreach ($response->RateReplyDetails as $RateReplyDetail) {
                $service_type = $RateReplyDetail->ServiceType;
                if ($service_list[$service_type]) {
                    $rsd = end($RateReplyDetail->RatedShipmentDetails);
                    $tnc = $rsd->ShipmentRateDetail->TotalNetCharge;
                    $price = (double) preg_replace('/[^\\d\\.]/i', '', $tnc->Amount);
                    // Markup?
                    if ($settings['markup']) {
                        $price = Discounts::apply_value($price, '+' . $settings['markup']);
                    }
                    // Discount?
                    if ($settings['discount']) {
                        $price = Discounts::apply_value($price, $settings['markup']);
                    }
                    // Rated method configured/available?
                    if ($method = $settings['methods'][$service_type]) {
                        $method = is_array($method) ? $method : array();
                        $service_name = $method['name'] ?: $service_list[$service_type];
                        $service_price = round($price, 2);
                        $shipment_rates[] = array('id' => $service_type, 'name' => $service_name, 'price' => $service_price);
                    }
                }
            }
        } elseif ($response->HighestSeverity == 'FAILURE' || $response->HighestSeverity == 'ERROR') {
            throw new Exception($response->Notifications->LocalizedMessage ?: $response->Notifications->Message);
        }
    } catch (SoapFault $e) {
        throw new Exception($e->getMessage());
    }
    return $shipment_rates;
}