/**
 * Get shares of the orders distributed between admin and sellers in case the payments go directly to sellers.
 * Shares are returned in absolute amounts, not as percentage
 * 
 * @param array $cart
 * 
 * @return
 * array(
 *  [0] => <admin_share_amount>,
 *  [seller1_id] => <seller_share_amount>,
 *  [seller2_id] => <seller_share_amount>,
 * )
 */
function cw_seller_get_payment_shares($cart)
{
    global $config;
    $shares = array(0 => 0.0);
    foreach ($cart['orders'] as $order) {
        $seller = cw_call('cw_user_get_info', array($order['warehouse_customer_id'], 65535));
        $seller['custom_fields'] = cw_user_get_custom_fields($seller['customer_id'], 0, '', 'field');
        if (empty($seller) || $seller['usertype'] == 'A') {
            $seller['customer_id'] = 0;
        }
        if ($config['seller']['seller_enable_admin_commission_share'] == 'Y') {
            $admin_commision = $seller['custom_fields']['admin_commission_rate'] > 0 ? $seller['custom_fields']['admin_commission_rate'] : $config['seller']['seller_admin_commission_rate'];
        } else {
            $admin_commission = 0.0;
        }
        $shares[$seller['customer_id']] += $_seller_share = (1 - $admin_commision / 100) * $order['info']['total'];
        $shares[0] += $order['info']['total'] - $_seller_share;
    }
    cw_log_add('seller_shares', $shares);
    return $shares;
}
function cw_user_get_info($customer_id, $info_type = 0)
{
    global $tables, $current_language, $default_user_profile_fields, $config;
    global $addons;
    $userinfo = \Customer\get($customer_id);
    if (empty($userinfo)) {
        return null;
    }
    $userinfo = array_merge($userinfo, (array) cw_query_first("SELECT membership, flag FROM {$tables['memberships']} WHERE membership_id = '{$userinfo['membership_id']}'"));
    # kornev, TOFIX
    if ($userinfo['usertype'] == 'B') {
        $userinfo['plan_id'] = cw_query_first_cell("SELECT plan_id FROM {$tables['salesman_commissions']} WHERE salesman_customer_id='{$userinfo['customer_id']}'");
    }
    if ($info_type & 1) {
        $userinfo['addresses'] = cw_user_get_addresses($customer_id);
        $userinfo['main_address'] = cw_user_get_address($customer_id, 'main');
        $userinfo['current_address'] = cw_user_get_address($customer_id, 'current');
        $address = empty($userinfo['main_address']) ? $userinfo['current_address'] : $userinfo['main_address'];
        $userinfo['firstname'] = $address['firstname'];
        $userinfo['lastname'] = $address['lastname'];
        $userinfo['fullname'] = trim($address['firstname'] . ' ' . $address['lastname']);
        unset($address);
    }
    if ($info_type & 2) {
        cw_load('crypt');
        // For security reason password must be left encrypted in userinfo data
        /*
        	$userinfo['password'] = text_decrypt($userinfo['password']);
        	if (is_null($userinfo['password']))
        	    cw_log_flag("log_decrypt_errors", "DECRYPT", "Could not decrypt password for the user ".$userinfo['customer_id'], true);
        	elseif ($userinfo['password'] !== false)
        	    $userinfo['password'] = stripslashes($userinfo['password']);
        */
    }
    if ($info_type & 4) {
        $userinfo['cc_info'] = cw_user_get_current_ccinfo($customer_id);
    }
    if ($info_type & 8) {
        cw_load('profile_fields');
        $userinfo['additional_fields'] = cw_profile_fields_get_additional($customer_id);
    }
    if ($info_type & 16) {
        if ($userinfo['usertype'] == 'B') {
            $userinfo['salesman_info'] = cw_get_salesman_info($customer_id);
        }
    }
    if ($info_type & 32) {
        $userinfo['system_info'] = cw_user_get_system_info($customer_id);
    }
    if ($info_type & 64) {
        $userinfo['additional_info'] = cw_user_get_addition_info($customer_id, $userinfo['usertype']);
        $userinfo['relations'] = cw_user_get_relations($customer_id);
    }
    if ($info_type & 256) {
        $userinfo['addresses'] = cw_user_get_addresses($customer_id);
    }
    if ($info_type & 1024) {
        $userinfo['custom_fields'] = cw_user_get_custom_fields($customer_id);
    }
    return $userinfo;
}
function cw_payment_paypal_adaptive_run_processor($params, $return)
{
    if ($params['payment_data']['processor'] == 'paypal_adaptive') {
        extract($params);
        global $config, $current_location, $top_message;
        $cart =& cw_session_register('cart');
        $skey = cw_call('cw_payment_start');
        $secure_oid =& cw_session_register('secure_oid');
        $memo = implode(',', $params['doc_ids']) . "!" . rand(10, 99);
        $debug = 0;
        $u_phone = preg_replace('![^\\d]+!', '', $params['userinfo']['current_address']['phone']);
        cw_load('http');
        # why so?..
        $pp_url = "https://svcs." . ($config['paypal_adaptive']['test_mode'] == "Y" ? "sandbox." : "") . "paypal.com/AdaptivePayments";
        $post_headers = array("X-PAYPAL-SECURITY-USERID" => $config['paypal_adaptive']['api_access'], "X-PAYPAL-SECURITY-PASSWORD" => $config['paypal_adaptive']['api_password'], "X-PAYPAL-SECURITY-SIGNATURE" => $config['paypal_adaptive']['api_signature'], "X-PAYPAL-DEVICE-IPADDRESS" => $_SERVER["REMOTE_ADDR"], "X-PAYPAL-REQUEST-DATA-FORMAT" => "JSON", "X-PAYPAL-RESPONSE-DATA-FORMAT" => "JSON", "X-PAYPAL-APPLICATION-ID" => "APP-54K5660378319012U");
        $receivers = array();
        $recs = cw_seller_get_payment_shares($cart);
        $amount2admin = $recs[0];
        unset($recs[0]);
        # default amount to admin
        $pp_type = $config['paypal_adaptive']['pp_method'] == "C";
        # true - chain/C; false - parallel/P
        $setdetails = array();
        if ($recs) {
            foreach ($recs as $customer_id => $amount) {
                if ($amount > 0) {
                    $custom = cw_user_get_custom_fields($customer_id, 0, '', 'field');
                    $email = $custom["pp_account"];
                    # // rename??
                    if ($email) {
                        $receivers[] = array("primary" => false, "amount" => $amount, "email" => $email, "invoiceId" => $memo);
                        /*
                                                list($ship,$items,$products) = cw_ppadapt_products($customer_id,$amount,$products);
                                                if(empty($items))
                                                $setdetails[] = array(
                                                        "receiver" => array(
                                                                "email" => $email
                                                        ),
                                                        "invoiceData" => array(
                                                                "totalTax" => 0,
                                                                "totalShipping" => $ship,
                                                                "item" => $items,
                                                        ),
                                                );
                        */
                    }
                    if ($pp_type || !$email) {
                        $amount2admin += $amount;
                    }
                }
            }
        }
        if ($amount2admin > 0) {
            $receivers[] = array("primary" => $pp_type && !empty($receivers), "amount" => $amount2admin, "invoiceId" => $memo, "email" => $config['paypal_adaptive']['email_acc']);
            /*
                            list($ship,$items,$products) = cw_ppadapt_products($customer_id,$amount,$products);
                            if(empty($items))
                            $setdetails[] = array(
                                    "receiver" => array(
                                            "email" => $email
                                    ),
                                    "invoiceData" => array(
                                            "totalTax" => 0,
                                            "totalShipping" => $ship,
                                            "item" => $items,
                                    ),
                            );
            */
        }
        $pp_cancel_url = $current_location . '/index.php?target=cart';
        $post = array("actionType" => $pp_type ? "PAY_PRIMARY" : "PAY", "currencyCode" => $config['paypal_adaptive']['currency'], "feesPayer" => $config['paypal_adaptive']['fee_payer'], "receiverList" => array("receiver" => $receivers), "ipnNotificationUrl" => $current_location . '/index.php?target=paypal_adaptive', "memo" => $memo, "trackingId" => $skey, "returnUrl" => $current_location . '/index.php?target=order-message&doc_ids=' . implode(',', $params['doc_ids']), "cancelUrl" => $pp_cancel_url, "requestEnvelope" => array("errorLanguage" => "en_US", "detailLevel" => "ReturnAll"));
        list($headers, $response) = cw_https_request("POST", $pp_url . "/Pay", array(json_encode($post)), "", "", "application/json", "", "", "", $post_headers);
        if ($debug) {
            print "<pre>";
            print_r(array($recs, $pp_url, $post_headers, $post, json_encode($post), $headers, $response));
        }
        if ($headers == "0") {
            $result = array('success' => false, 'error' => array('ShortMessage' => $response));
        } else {
            $ret = json_decode($response, 1);
            if ($ret["error"]) {
                $err = array();
                foreach ($ret["error"] as $e) {
                    $err[] = $e["severity"] . ": " . $e["message"];
                }
                $result = array('success' => false, 'error' => array('ShortMessage' => join(";", $err)));
            } elseif ($ret["payKey"]) {
                # It's ok. Now let's add options...
                $post = array("payKey" => $ret["payKey"], "requestEnvelope" => array("errorLanguage" => "en_US", "detailLevel" => "ReturnAll"));
                if (!empty($setdetails)) {
                    # should not fire...
                    $post["receiverOptions"] = $setdetails;
                }
                $post["senderOptions"] = array("addressOverride" => true, "shippingAddress" => array());
                foreach (array("addresseeName" => $params['userinfo']['current_address']['firstname'] . " " . $params['userinfo']['current_address']['lastname'], "street1" => $params['userinfo']['current_address']['address'], "street2" => $params['userinfo']['current_address']['address_2'], "city" => $params['userinfo']['current_address']['city'], "state" => $params['userinfo']['current_address']['country'] == 'US' || $params['userinfo']['current_address']['country'] == 'CA' || $params['userinfo']['current_address']['state'] != '' ? $params['userinfo']['current_address']['state'] : 'Other', "zip" => $params['userinfo']['current_address']['zipcode'], "country" => $params['userinfo']['current_address']['country']) as $k => $v) {
                    # filter empty values
                    if ($v) {
                        $post["senderOptions"]["shippingAddress"][$k] = $v;
                    }
                }
                list($headers, $response) = cw_https_request("POST", $pp_url . "/SetPaymentOptions", array(json_encode($post)), "", "", "application/json", "", "", "", $post_headers);
                if ($debug) {
                    print "<hr><hr>";
                    print_r(array($post, json_decode($response, 1), $headers));
                }
                $result = array('success' => true, 'payKey' => $ret["payKey"]);
            }
        }
        $pp_customer_url = "https://www." . ($config['paypal_adaptive']['test_mode'] == "Y" ? "sandbox." : "") . "paypal.com";
        if ($debug) {
            print_r(array($ret, $result));
            if ($result['success'] && !empty($result['payKey'])) {
                die("<h1>" . $pp_customer_url . '/webscr?cmd=_ap-payment&paykey=' . $result['payKey'] . "</h1>");
            }
            die($result['error']['ShortMessage']);
        }
        if ($result['success'] && !empty($result['payKey'])) {
            cw_header_location($pp_customer_url . '/webscr?cmd=_ap-payment&paykey=' . $result['payKey']);
        }
        $top_message = array('type' => 'E', 'content' => $result['error']['ShortMessage']);
        cw_header_location($pp_cancel_url);
    }
    return $return;
}
cw_load('warehouse', 'map', 'cart');
$product_info = cw_func_call('cw_product_get', array('id' => $product_id, 'user_account' => $user_account, 'info_type' => 128 + 8192));
if ($action == 'estimate' && !empty($zipcode)) {
    $userinfo = array();
    $userinfo['current_address']['country'] = $country;
    $userinfo['current_address']['zipcode'] = $zipcode;
    $shippings = array();
    $product_info['amount'] = 1;
    $config['General']['apply_default_country'] = 'Y';
    $config['Shipping']['enable_all_shippings'] = 'N';
    $cart_tmp['products'] = array($product_info);
    $shippings = cw_func_call('cw_shipping_get_list', array('cart' => $cart_tmp, 'products' => array($product_info), 'userinfo' => $userinfo, 'warehouse_customer_id' => $warehouse));
    // Supplier delivery time
    if ($product_info['system']['supplier_customer_id']) {
        $supplier_fields = cw_user_get_custom_fields($product_info['system']['supplier_customer_id'], 0, '', 'field');
        if ($supplier_fields['min_delivery_time'] == $supplier_fields['max_delivery_time']) {
            $product_info['supplier']['delivery_time'] = $supplier_fields['min_delivery_time'];
        } else {
            $product_info['supplier']['delivery_time'] = $supplier_fields['min_delivery_time'] . '-' . $supplier_fields['max_delivery_time'];
        }
    }
    $smarty->assign('shippings', $shippings);
}
$smarty->assign('zipcode', $zipcode);
$smarty->assign('country', $country ? $country : $user_account['country']);
$smarty->assign('product', $product_info);
if (defined('IS_AJAX') && constant('IS_AJAX')) {
    cw_add_ajax_block(array('id' => 'estimate_shipping_container', 'action' => 'replace', 'template' => 'customer/products/estimate-fields.tpl'));
} else {
    $avails = cw_warehouse_get_avails_customer($product_id);
function cw_shipping_get_list($params)
{
    extract($params);
    global $tables, $config, $smarty, $addons;
    global $current_carrier, $cart;
    global $saved_rates;
    if (empty($products)) {
        return;
    }
    $to_address = $userinfo['current_address'];
    $from_address = $config['Company'];
    $current_carrier = $cart['info']['current_carrier'];
    if (isset($saved_rates[$order_hash])) {
        // if used quote
        if ($addons['quote_system'] && isset($cart['info']['quote_doc_id']) && !empty($cart['info']['quote_doc_id']) && isset($cart['info']['shipping_id'])) {
            if (isset($saved_rates[$order_hash][$cart['info']['shipping_id']])) {
                return array($cart['info']['shipping_id'] => $saved_rates[$order_hash][$cart['info']['shipping_id']]);
            } else {
                return array();
            }
        }
        return $saved_rates[$order_hash];
    }
    /*
        if ($warehouse_customer_id != 0) {
            $warehouseinfo = cw_user_get_info($warehouse_customer_id, 1);
            $from_address = $warehouseinfo['main_address'];
        }
    */
    if (empty($userinfo['customer_id']) && $config['General']['apply_default_country'] != "Y" && $config['Shipping']['enable_all_shippings'] == "Y") {
        $enable_all_shippings = true;
        $smarty->assign('force_delivery_dropdown_box', 'Y');
    }
    $what_to_ship_params = cw_call('cw_what_to_ship', array($products));
    cw_load('http');
    $key = md5(serialize($aa = array('to_address' => $to_address, 'from_address' => $from_address, 'what_to_ship' => $what_to_ship_params, 'order_hash' => $order_hash, 'extra_hash' => cw_event('on_collect_shipping_rates_hash', array($products), array()))));
    if (!($rates = cw_cache_get($key, 'shipping_rates'))) {
        $rates = cw_func_call('cw_shipping_get_rates', array('weight' => $what_to_ship_params['apply']['weight'], 'to_address' => $to_address, 'from_address' => $from_address, 'cart' => $cart, 'products' => $products, 'userinfo' => $userinfo, 'what_to_ship_params' => $what_to_ship_params));
        if (!empty($rates)) {
            uasort($rates, 'cw_uasort_by_order');
        }
        cw_cache_save($rates, $key, 'shipping_rates');
    }
    if ($what_to_ship_params['apply']['items'] == 0) {
        foreach ($rates as &$r) {
            $r['original_rate'] = 0;
        }
        unset($r);
    }
    # kornev, it's required for original_rate saving
    $saved_rates[$order_hash] = $rates;
    if ($rates) {
        foreach ($rates as $k => $rate) {
            $tmp_cart = $cart;
            $tmp_cart['info']['shipping_id'] = $rate['shipping_id'];
            # kornev, warehouses fix
            $tmp_cart['info']['shipping_arr'][$warehouse_customer_id] = $rate['shipping_id'];
            $calc_result = cw_func_call('cw_cart_calc', array('cart' => $tmp_cart, 'products' => $products, 'userinfo' => $userinfo));
            $rates[$k]['rate'] = $calc_result['info']['display_shipping_cost'];
            $rates[$k]['tax_cost'] = price_format($calc_result['info']['tax_cost']);
            // TOFIX: Why rate info contains tax for whole cart
            // parse delivery time "3-4 days" to "3" and "4"
            if (preg_match_all('/\\d+/', $rate['shipping_time'], $delivery_time)) {
                $rates[$k]['min_delivery_time'] = $delivery_time[0][0];
                $rates[$k]['max_delivery_time'] = $delivery_time[0][1] ? $delivery_time[0][1] : $rates[$k]['min_delivery_time'];
            }
        }
    }
    # kornev, only available for each products shippings are enabled
    if (is_array($products) && is_array($rates)) {
        $res = null;
        $common_delivery = array('min_delivery_time' => 0, 'max_delivery_time' => 0);
        foreach ($products as $product) {
            // Find longest supplier delivery time among all products
            if ($product['system']['supplier_customer_id']) {
                $product_delivery = cw_user_get_custom_fields($product['system']['supplier_customer_id'], 0, '', 'field');
                if ($product_delivery['min_delivery_time'] > $common_delivery['min_delivery_time']) {
                    $common_delivery['min_delivery_time'] = $product_delivery['min_delivery_time'];
                }
                if ($product_delivery['max_delivery_time'] > $common_delivery['max_delivery_time']) {
                    $common_delivery['max_delivery_time'] = $product_delivery['max_delivery_time'];
                }
            }
            $ps = unserialize($product['shippings']);
            if (is_array($ps) && count($ps)) {
                if (is_null($res)) {
                    $res = array_keys($ps);
                } else {
                    $res = array_intersect($res, array_keys($ps));
                }
            }
        }
        foreach ($rates as $k => $v) {
            if (is_array($res) && !in_array($v['shipping_id'], $res)) {
                unset($rates[$k]);
                continue;
            }
            // Increase delivery time by supplier delivery..
            $rates[$k]['min_delivery_time'] += $common_delivery['min_delivery_time'];
            $rates[$k]['max_delivery_time'] += $common_delivery['max_delivery_time'];
            // ..and re-build shipping time into string
            $rates[$k]['shipping_time_label'] = $rates[$k]['shipping_time'];
            if ($rates[$k]['min_delivery_time'] == $rates[$k]['max_delivery_time']) {
                $rates[$k]['shipping_time'] = $rates[$k]['max_delivery_time'];
            } else {
                $rates[$k]['shipping_time'] = $rates[$k]['min_delivery_time'] . '-' . $rates[$k]['max_delivery_time'];
            }
        }
    } else {
        $rates = array();
    }
    # kornev, final save
    $saved_rates[$order_hash] = $rates;
    // if used quote
    if ($addons['quote_system'] && isset($cart['info']['quote_doc_id']) && !empty($cart['info']['quote_doc_id']) && isset($cart['info']['shipping_id'])) {
        if (isset($rates[$cart['info']['shipping_id']])) {
            return array($cart['info']['shipping_id'] => $rates[$cart['info']['shipping_id']]);
        } else {
            return array();
        }
    }
    return $rates;
}