public function execute() { if (!shopAffiliate::isEnabled()) { throw new waException(_w('Unknown page'), 404); } $scm = new shopCustomerModel(); $customer = $scm->getById(wa()->getUser()->getId()); $atm = new shopAffiliateTransactionModel(); $affiliate_history = $atm->getByContact(wa()->getUser()->getId()); $url_tmpl = wa()->getRouteUrl('/frontend/myOrder', array('id' => '%ID%')); foreach ($affiliate_history as &$row) { if ($row['order_contact_id'] == $row['contact_id']) { $row['order_url'] = str_replace('%ID%', $row['order_id'], $url_tmpl); } } $this->view->assign('customer', $customer); $this->view->assign('affiliate_history', $affiliate_history); // Set up layout and template from theme $this->setThemeTemplate('my.affiliate.html'); $this->view->assign('my_nav_selected', 'affiliate'); if (!waRequest::isXMLHttpRequest()) { $this->setLayout(new shopFrontendLayout()); $this->getResponse()->setTitle(_w('Affiliate program')); $this->view->assign('breadcrumbs', self::getBreadcrumbs()); $this->layout->assign('nofollow', true); } /** * * @event frontend_my_affiliate * @return array[string]string $return[%plugin_id%] html output */ $this->view->assign('frontend_my_affiliate', wa()->event('frontend_my_affiliate')); }
public function execute() { $order_id = waRequest::post('order_id', null, waRequest::TYPE_INT); if ($order_id) { $order_model = new shopOrderModel(); $order = $order_model->getOrder($order_id); $customer_model = new shopCustomerModel(); $customer = $customer_model->getById($order['contact_id']); $customer_model->updateById($order['contact_id'], array('is_spamer' => 1)); $plugin = waSystem::getInstance()->getPlugin('orderantispam'); $action_id = $plugin->getSettings('action_id'); $workflow = new shopWorkflow(); $action = $workflow->getActionById($action_id); $action->run($order_id); // counters $state_counters = $order_model->getStateCounters(); $pending_counters = (!empty($state_counters['new']) ? $state_counters['new'] : 0) + (!empty($state_counters['processing']) ? $state_counters['processing'] : 0) + (!empty($state_counters['paid']) ? $state_counters['paid'] : 0); // update app coutner wa('shop')->getConfig()->setCount($state_counters['new']); $script = "<script>"; $script .= "\$.order_list.updateCounters(" . json_encode(array('state_counters' => $state_counters, 'common_counters' => array('pending_counters' => $pending_counters))) . ");"; $script .= "\$.order.reload();</script>"; $this->response['script'] = $script; } }
public function execute() { $order_id = waRequest::request('order_id', 0, 'int'); $id = waRequest::request('id', 0, 'int'); $to = waRequest::request('to'); $nm = new shopNotificationModel(); $n = $nm->getById($id); if (!$n) { $this->errors = sprintf_wp('%s entry not found', _w('Notification')); return; } $om = new shopOrderModel(); $o = $om->getById($order_id); if (!$o) { $this->errors = _w('Order not found'); return; } shopHelper::workupOrders($o, true); $opm = new shopOrderParamsModel(); $o['params'] = $opm->get($order_id); try { $contact = $o['contact_id'] ? new shopCustomer($o['contact_id']) : wa()->getUser(); $contact->getName(); } catch (Exception $e) { $contact = new shopCustomer(wa()->getUser()->getId()); } $cm = new shopCustomerModel(); $customer = $cm->getById($contact->getId()); if (!$customer) { $customer = $cm->getEmptyRow(); } $workflow = new shopWorkflow(); // send notifications shopNotifications::sendOne($id, array('order' => $o, 'customer' => $contact, 'status' => $workflow->getStateById($o['state_id'])->getName()), $to); }
public function execute() { $form = shopHelper::getCustomerForm(); if ($form->post()) { $customer_validation_disabled = wa()->getSetting('disable_backend_customer_form_validation'); if ($customer_validation_disabled || $form->isValid()) { $c = new waContact(); if ($customer_validation_disabled) { $errors = array(); $c->save($form->post()); } else { $errors = $c->save($form->post(), true); } if (!$errors) { $scm = new shopCustomerModel(); $scm->createFromContact($c->getId()); echo '<script>$.customers.reloadSidebar(); window.location.hash = "#/id/' . $c->getId() . '"</script>'; exit; } // Show errors that waContact returned, e.g. email must be unique. foreach ($errors as $fld => $list) { foreach ($list as $err) { $form->errors($fld, $err); } } } } $this->view->assign('form', $form); $this->view->assign('customer_validation_disabled', wa()->getSetting('disable_backend_customer_form_validation')); }
public static function recalculateTotalSpent($customer_id) { if (!$customer_id) { return; // being paranoid } $m = new shopCustomerModel(); $sql = "SELECT SUM(total*rate)\n FROM shop_order\n WHERE contact_id=:cid\n AND paid_date IS NOT NULL"; $m->updateById($customer_id, array('total_spent' => (double) $m->query($sql, array('cid' => $customer_id))->fetchField())); }
protected function getCustomerData($name = null) { if ($this->customer_data == null) { $customer_model = new shopCustomerModel(); $this->customer_data = $customer_model->getById($this->getId()); } if ($name) { return isset($this->customer_data[$name]) ? $this->customer_data[$name] : null; } return $this->customer_data; }
public function execute() { $customer_id = waRequest::request('customer_id', 0, 'int'); $category_id = waRequest::request('category_id', 0, 'int'); if (!$customer_id || !$category_id) { return; } $ccm = new waContactCategoriesModel(); $ccm->add($customer_id, $category_id); $cm = new shopCustomerModel(); $this->response['count'] = $cm->getCategoryCounts($category_id); }
/** * @param int[] $params Deleted contact_id * @see waEventHandler::execute() * @return void */ public function execute(&$params) { $contact_ids = $params; // We need some info about (not yet) deleted contacts to save into order params. // The idea is to pretend that orders were created by guests with no auth. $c = new waContactsCollection('id/' . implode(',', $contact_ids)); $contacts = $c->getContacts('name,phone,email'); foreach ($contacts as &$contact) { if (is_array($contact['phone'])) { $phone = reset($contact['phone']); if (is_array($phone)) { if (isset($phone['value'])) { $phone = $phone['value']; } else { $phone = ''; } } $contact['phone'] = $phone; } if (is_array($contact['email'])) { $email = reset($contact['email']); $contact['email'] = $email; } } $order_model = new shopOrderModel(); $order_params_model = new shopOrderParamsModel(); $product_reviews_model = new shopProductReviewsModel(); foreach ($contacts as $contact) { // Insert customer info into params of their orders $order_ids = array_keys($order_model->select('id')->where('contact_id=:contact_id', array('contact_id' => $contact['id']))->fetchAll('id')); $order_params_model->set($order_ids, $this->extractContactInfo($contact), false); // Insert contact name into their reviews $product_reviews_model->updateByField('contact_id', $contact['id'], array('contact_id' => 0, 'name' => $contact['name'], 'auth_provider' => null)); } // Update orders as if they were created by guests with no auth $order_model->updateByField('contact_id', $contact_ids, array('contact_id' => null)); // Forget the customer $scm = new shopCustomerModel(); $scm->deleteById($contact_ids); // Forget that this user created coupons $coupm = new shopCouponModel(); $coupm->updateByField('create_contact_id', $contact_ids, array('create_contact_id' => 0)); // !!! TODO: take a look to other models related with contacts }
public function execute(&$params) { $master_id = $params['id']; $merge_ids = $params['contacts']; $all_ids = array_merge($merge_ids, array($master_id)); $m = new waModel(); // // All the simple cases: update contact_id in tables // foreach (array(array('shop_cart_items', 'contact_id'), array('shop_checkout_flow', 'contact_id'), array('shop_order', 'contact_id'), array('shop_order_log', 'contact_id'), array('shop_product', 'contact_id'), array('shop_product_reviews', 'contact_id'), array('shop_affiliate_transaction', 'contact_id')) as $pair) { list($table, $field) = $pair; $sql = "UPDATE {$table} SET {$field} = :master WHERE {$field} in (:ids)"; $m->exec($sql, array('master' => $master_id, 'ids' => $merge_ids)); } // // shop_affiliate_transaction // $balance = 0.0; $sql = "SELECT * FROM shop_affiliate_transaction WHERE contact_id=? ORDER BY id"; foreach ($m->query($sql, $master_id) as $row) { $balance += $row['amount']; if ($row['balance'] != $balance) { $m->exec("UPDATE shop_affiliate_transaction SET balance=? WHERE id=?", $balance, $row['id']); } } $affiliate_bonus = $balance; // // shop_customer // // Make sure it exists $cm = new shopCustomerModel(); $cm->createFromContact($master_id); $sql = "SELECT SUM(number_of_orders) FROM shop_customer WHERE contact_id IN (:ids)"; $number_of_orders = $m->query($sql, array('ids' => $all_ids))->fetchField(); $sql = "SELECT MAX(last_order_id) FROM shop_customer WHERE contact_id IN (:ids)"; $last_order_id = $m->query($sql, array('ids' => $all_ids))->fetchField(); $sql = "UPDATE shop_customer SET number_of_orders=?, last_order_id=?, affiliate_bonus=? WHERE contact_id=?"; $m->exec($sql, ifempty($number_of_orders, 0), ifempty($last_order_id, null), ifempty($affiliate_bonus, 0), $master_id); if ($number_of_orders) { shopCustomers::recalculateTotalSpent($master_id); } wa('shop')->event('customers_merge', $params); return null; }
public function execute() { // Category counts // !!! Probably not the best idea to fetch category counts on the fly... $cm = new shopCustomerModel(); $counts = $cm->getCategoryCounts(); // Categories $ccm = new waContactCategoryModel(); $categories = array(); foreach ($ccm->getAll() as $c) { if ($c['app_id'] == 'shop') { $c['cnt'] = ifset($counts[$c['id']], 0); $categories[$c['id']] = $c; } } $this->view->assign('all_customers_count', $cm->countAll()); $this->view->assign('contacts_url', wa()->getAppUrl('contacts')); $this->view->assign('categories', $categories); }
public function orderActionCreate($params) { if ($this->getSettings('status') && waRequest::cookie('uuid')) { $customer_model = new shopCustomerModel(); $is_spamer = $customer_model->getByField(array('uuid' => waRequest::cookie('uuid'), 'is_spamer' => 1)); $update = array(); if ($is_spamer && $this->getSettings('action_id')) { $update['is_spamer'] = 1; $action_id = $this->getSettings('action_id'); $workflow = new shopWorkflow(); $action = $workflow->getActionById($action_id); $action->run($params['order_id']); } $customer = $customer_model->getById($params['contact_id']); if (!$customer['uuid']) { $update['uuid'] = waRequest::cookie('uuid'); $customer_model->updateById($params['contact_id'], $update); } } }
public function execute() { $order_id = waRequest::request('order_id', 0, 'int'); $followup_id = waRequest::request('followup_id', 0, 'int'); $email = waRequest::request('email'); $fm = new shopFollowupModel(); $f = $fm->getById($followup_id); if (!$f) { $this->errors = sprintf_wp('%s entry not found', _w('Follow-up')); return; } $om = new shopOrderModel(); $o = $om->getById($order_id); if (!$o) { $this->errors = _w('Order not found'); return; } shopHelper::workupOrders($o, true); $opm = new shopOrderParamsModel(); $o['params'] = $opm->get($order_id); try { $contact = $o['contact_id'] ? new shopCustomer($o['contact_id']) : wa()->getUser(); $contact->getName(); } catch (Exception $e) { $contact = new shopCustomer(wa()->getUser()->getId()); } $cm = new shopCustomerModel(); $customer = $cm->getById($contact->getId()); if (!$customer) { $customer = $cm->getEmptyRow(); } $to = array($email => $contact->getName()); if (!shopFollowupCli::sendOne($f, $o, $customer, $contact, $to)) { $this->errors = "Unable to send follow-up #{$f['id']} for order #{$o['id']}: waMessage->send() returned FALSE."; return; } $this->response = 'ok'; }
public function customersAutocomplete($q) { $scm = new shopCustomerModel(); $result = array(); list($list, $total) = $scm->getList(null, $q, 0, $this->limit); $term_safe = htmlspecialchars($q); foreach ($list as $c) { $name = $this->prepare($c['name'], $term_safe); $email = $this->prepare(ifset($c['email'], ''), $term_safe); $phone = $this->prepare(ifset($c['phone'], ''), $term_safe); $phone && ($phone = '<i class="icon16 phone"></i>' . $phone); $email && ($email = '<i class="icon16 email"></i>' . $email); $result[] = array('value' => $c['name'], 'label' => implode(' ', array_filter(array($name, $email, $phone))), 'id' => $c['id']); } foreach ($result as &$c) { $contact = new waContact($c['id']); $c['label'] = "<i class='icon16 userpic20' style='background-image: url(\"" . $contact->getPhoto(20) . "\");'></i>" . $c['label']; } unset($c); return $result; }
public function cart() { $this->getResponse()->addHeader("Cache-Control", "no-store, no-cache, must-revalidate"); $this->getResponse()->addHeader("Expires", date("r")); if (waRequest::method() == 'post') { $data = wa()->getStorage()->get('shop/checkout', array()); if ($coupon_code = waRequest::post('coupon_code')) { $data['coupon_code'] = $coupon_code; } elseif (isset($data['coupon_code'])) { unset($data['coupon_code']); } if (($use = waRequest::post('use_affiliate')) !== null) { if ($use) { $data['use_affiliate'] = 1; } elseif (isset($data['use_affiliate'])) { unset($data['use_affiliate']); } } if ($coupon_code || $use) { wa()->getStorage()->set('shop/checkout', $data); wa()->getStorage()->remove('shop/cart'); } } $cart_model = new shopCartItemsModel(); $cart = new shopCart(); $code = $cart->getCode(); $errors = array(); if (waRequest::post('checkout')) { $saved_quantity = $cart_model->select('id,quantity')->where("type='product' AND code = s:code", array('code' => $code))->fetchAll('id'); $quantity = waRequest::post('quantity'); foreach ($quantity as $id => $q) { if ($q != $saved_quantity[$id]) { $cart->setQuantity($id, $q); } } $not_available_items = $cart_model->getNotAvailableProducts($code, !wa()->getSetting('ignore_stock_count')); foreach ($not_available_items as $row) { if ($row['sku_name']) { $row['name'] .= ' (' . $row['sku_name'] . ')'; } if ($row['available']) { $errors[$row['id']] = sprintf(_w('Only %d pcs of %s are available, and you already have all of them in your shopping cart.'), $row['count'], $row['name']); } else { $errors[$row['id']] = _w('Oops! %s is not available for purchase at the moment. Please remove this product from your shopping cart to proceed.'); } } if (!$errors) { $this->redirect(wa()->getRouteUrl('/frontend/checkout')); } } $items = $cart_model->where('code= ?', $code)->order('parent_id')->fetchAll('id'); $product_ids = $sku_ids = $service_ids = $type_ids = array(); foreach ($items as $item) { $product_ids[] = $item['product_id']; $sku_ids[] = $item['sku_id']; } $product_ids = array_unique($product_ids); $sku_ids = array_unique($sku_ids); $product_model = new shopProductModel(); if (waRequest::param('url_type') == 2) { $products = $product_model->getWithCategoryUrl($product_ids); } else { $products = $product_model->getById($product_ids); } $sku_model = new shopProductSkusModel(); $skus = $sku_model->getByField('id', $sku_ids, 'id'); $image_model = new shopProductImagesModel(); $delete_items = array(); foreach ($items as $item_id => &$item) { if (!isset($skus[$item['sku_id']])) { unset($items[$item_id]); $delete_items[] = $item_id; continue; } if ($item['type'] == 'product') { $item['product'] = $products[$item['product_id']]; $sku = $skus[$item['sku_id']]; if ($sku['image_id'] && $sku['image_id'] != $item['product']['image_id']) { $img = $image_model->getById($sku['image_id']); if ($img) { $item['product']['image_id'] = $sku['image_id']; $item['product']['ext'] = $img['ext']; } } $item['sku_name'] = $sku['name']; $item['sku_code'] = $sku['sku']; $item['price'] = $sku['price']; $item['compare_price'] = $sku['compare_price']; $item['currency'] = $item['product']['currency']; $type_ids[] = $item['product']['type_id']; if (isset($errors[$item_id])) { $item['error'] = $errors[$item_id]; if (strpos($item['error'], '%s') !== false) { $item['error'] = sprintf($item['error'], $item['product']['name'] . ($item['sku_name'] ? ' (' . $item['sku_name'] . ')' : '')); } } } } unset($item); if ($delete_items) { $cart_model->deleteByField(array('code' => $code, 'id' => $delete_items)); } $type_ids = array_unique($type_ids); // get available services for all types of products $type_services_model = new shopTypeServicesModel(); $rows = $type_services_model->getByField('type_id', $type_ids, true); $type_services = array(); foreach ($rows as $row) { $service_ids[] = $row['service_id']; $type_services[$row['type_id']][$row['service_id']] = true; } // get services for all products $product_services_model = new shopProductServicesModel(); $rows = $product_services_model->getByProducts($product_ids); $product_services = $sku_services = array(); foreach ($rows as $row) { if ($row['sku_id'] && !in_array($row['sku_id'], $sku_ids)) { continue; } $service_ids[] = $row['service_id']; if (!$row['sku_id']) { $product_services[$row['product_id']][$row['service_id']]['variants'][$row['service_variant_id']] = $row; } if ($row['sku_id']) { $sku_services[$row['sku_id']][$row['service_id']]['variants'][$row['service_variant_id']] = $row; } } $service_ids = array_unique($service_ids); $service_model = new shopServiceModel(); $variant_model = new shopServiceVariantsModel(); $services = $service_model->getByField('id', $service_ids, 'id'); foreach ($services as &$s) { unset($s['id']); } unset($s); $rows = $variant_model->getByField('service_id', $service_ids, true); foreach ($rows as $row) { $services[$row['service_id']]['variants'][$row['id']] = $row; unset($services[$row['service_id']]['variants'][$row['id']]['id']); } foreach ($items as $item_id => $item) { if ($item['type'] == 'product') { $p = $item['product']; $item_services = array(); // services from type settings if (isset($type_services[$p['type_id']])) { foreach ($type_services[$p['type_id']] as $service_id => &$s) { $item_services[$service_id] = $services[$service_id]; } } // services from product settings if (isset($product_services[$item['product_id']])) { foreach ($product_services[$item['product_id']] as $service_id => $s) { if (!isset($s['status']) || $s['status']) { if (!isset($item_services[$service_id])) { $item_services[$service_id] = $services[$service_id]; } // update variants foreach ($s['variants'] as $variant_id => $v) { if ($v['status']) { if ($v['price'] !== null) { $item_services[$service_id]['variants'][$variant_id]['price'] = $v['price']; } } else { unset($item_services[$service_id]['variants'][$variant_id]); } } } elseif (isset($item_services[$service_id])) { // remove disabled service unset($item_services[$service_id]); } } } // services from sku settings if (isset($sku_services[$item['sku_id']])) { foreach ($sku_services[$item['sku_id']] as $service_id => $s) { if (!isset($s['status']) || $s['status']) { // update variants foreach ($s['variants'] as $variant_id => $v) { if ($v['status']) { if ($v['price'] !== null) { $item_services[$service_id]['variants'][$variant_id]['price'] = $v['price']; } } else { unset($item_services[$service_id]['variants'][$variant_id]); } } } elseif (isset($item_services[$service_id])) { // remove disabled service unset($item_services[$service_id]); } } } foreach ($item_services as $s_id => &$s) { if (!$s['variants']) { unset($item_services[$s_id]); continue; } if ($s['currency'] == '%') { foreach ($s['variants'] as $v_id => $v) { $s['variants'][$v_id]['price'] = $v['price'] * $item['price'] / 100; } $s['currency'] = $item['currency']; } if (count($s['variants']) == 1) { $v = reset($s['variants']); $s['price'] = $v['price']; unset($s['variants']); } } unset($s); uasort($item_services, array('shopServiceModel', 'sortServices')); $items[$item_id]['services'] = $item_services; } else { $items[$item['parent_id']]['services'][$item['service_id']]['id'] = $item['id']; if (isset($item['service_variant_id'])) { $items[$item['parent_id']]['services'][$item['service_id']]['variant_id'] = $item['service_variant_id']; } unset($items[$item_id]); } } foreach ($items as $item_id => $item) { $price = shop_currency($item['price'] * $item['quantity'], $item['currency'], null, false); if (isset($item['services'])) { foreach ($item['services'] as $s) { if (!empty($s['id'])) { if (isset($s['variants'])) { $price += shop_currency($s['variants'][$s['variant_id']]['price'] * $item['quantity'], $s['currency'], null, false); } else { $price += shop_currency($s['price'] * $item['quantity'], $s['currency'], null, false); } } } } $items[$item_id]['full_price'] = $price; } $total = $cart->total(false); $order = array('total' => $total, 'items' => $items); $order['discount'] = $discount = shopDiscounts::calculate($order); $order['total'] = $total = $total - $order['discount']; $data = wa()->getStorage()->get('shop/checkout'); $this->view->assign('cart', array('items' => $items, 'total' => $total, 'count' => $cart->count())); $this->view->assign('coupon_code', isset($data['coupon_code']) ? $data['coupon_code'] : ''); if (shopAffiliate::isEnabled()) { $affiliate_bonus = 0; if ($this->getUser()->isAuth()) { $customer_model = new shopCustomerModel(); $customer = $customer_model->getById($this->getUser()->getId()); $affiliate_bonus = $customer ? round($customer['affiliate_bonus'], 2) : 0; } $this->view->assign('affiliate_bonus', $affiliate_bonus); $use = !empty($data['use_affiliate']); $this->view->assign('use_affiliate', $use); if ($use) { $discount -= shop_currency(shopAffiliate::convertBonus($order['params']['affiliate_bonus']), $this->getConfig()->getCurrency(true), null, false); $this->view->assign('used_affiliate_bonus', $order['params']['affiliate_bonus']); } $order['currency'] = $this->getConfig()->getCurrency(false); $add_affiliate_bonus = shopAffiliate::calculateBonus($order); $this->view->assign('add_affiliate_bonus', round($add_affiliate_bonus, 2)); } $this->view->assign('discount', $discount); /** * @event frontend_cart * @return array[string]string $return[%plugin_id%] html output */ $this->view->assign('frontend_cart', wa()->event('frontend_cart')); $checkout_flow = new shopCheckoutFlowModel(); $checkout_flow->add(array('code' => $code, 'step' => 0, 'description' => null)); }
public function execute() { $order = $this->getOrder(); if (!$order) { $this->view->assign('order', $order); return; } $workflow = new shopWorkflow(); $actions = $workflow->getStateById($order['state_id'])->getActions(); $bottom_buttons = $top_buttons = $buttons = array(); foreach ($actions as $action) { /** * @var shopWorkflowAction $action */ if ($action->getOption('top') || $action->getOption('position') == 'top') { $top_buttons[] = $action->getButton(); } elseif ($action->getOption('position') == 'bottom') { $bottom_buttons[] = $action->getButton(); } else { $buttons[] = $action->getButton(); } } $config = $this->getConfig(); $last_action_datetime = null; $log_model = new shopOrderLogModel(); $log = $log_model->getLog($order['id']); foreach ($log as &$l) { if ($l['action_id']) { $l['action'] = $workflow->getActionById($l['action_id']); } if ($order['state_id'] == $l['after_state_id']) { $last_action_datetime = $l['datetime']; } } $params = $order['params']; $tracking = ''; if (!empty($params['shipping_id'])) { try { $plugin = shopShipping::getPlugin(null, $params['shipping_id']); if (!empty($params['tracking_number'])) { $tracking = $plugin->tracking($params['tracking_number']); } if ($custom_fields = $plugin->customFields(new waOrder())) { foreach ($custom_fields as $k => $v) { if (!empty($params['shipping_params_' . $k])) { $custom_fields[$k]['value'] = $params['shipping_params_' . $k]; } else { unset($custom_fields[$k]); } } $this->view->assign('custom_fields', $custom_fields); } } catch (waException $ex) { $tracking = $ex->getMessage(); } } $this->view->assign('tracking', $tracking); $settings = wa('shop')->getConfig()->getCheckoutSettings(); $form_fields = ifset($settings['contactinfo']['fields'], array()); $formatter = new waContactAddressSeveralLinesFormatter(); $shipping_address = shopHelper::getOrderAddress($params, 'shipping'); $this->view->assign('shipping_address_text', shopHelper::getShippingAddressText($params)); $shipping_address = $formatter->format(array('data' => $shipping_address)); $shipping_address = $shipping_address['value']; if (isset($form_fields['address.billing'])) { $billing_address = shopHelper::getOrderAddress($params, 'billing'); $billing_address = $formatter->format(array('data' => $billing_address)); $billing_address = $billing_address['value']; if ($billing_address === $shipping_address) { $billing_address = null; } } else { $billing_address = null; } $customer_model = new shopCustomerModel(); $customer = $customer_model->getById($order['contact_id']); $customer_contact = new waContact($order['contact_id']); // Customer info $main_contact_info = array(); foreach (array('email', 'phone', 'im') as $f) { if ($v = $customer_contact->get($f, 'top,html')) { $main_contact_info[] = array('id' => $f, 'name' => waContactFields::get($f)->getName(), 'value' => is_array($v) ? implode(', ', $v) : $v); } } $this->view->assign(array('customer' => $customer, 'customer_contact' => $customer_contact, 'main_contact_info' => $main_contact_info, 'currency' => $config->getCurrency(), 'order' => $order, 'params' => $params, 'log' => $log, 'last_action_datetime' => $last_action_datetime, 'bottom_buttons' => $bottom_buttons, 'top_buttons' => $top_buttons, 'buttons' => $buttons, 'filter_params' => $this->getParams(), 'filter_params_str' => $this->getParams(true), 'count_new' => $this->getModel()->getStateCounters('new'), 'timeout' => $config->getOption('orders_update_list'), 'printable_docs' => shopHelper::getPrintForms(array_merge($order, array('params' => $params))), 'billing_address' => $billing_address, 'shipping_address' => $shipping_address, 'shipping_id' => ifset($params['shipping_id'], '') . '.' . ifset($params['shipping_rate_id'], ''), 'offset' => $this->getModel()->getOffset($order['id'], $this->getParams(), true))); /** * Backend order profile page * UI hook allow extends order profile page * @event backend_order * @param array $order * @return array[string][string]string $return[%plugin_id%]['title_suffix'] html output * @return array[string][string]string $return[%plugin_id%]['action_button'] html output * @return array[string][string]string $return[%plugin_id%]['action_link'] html output * @return array[string][string]string $return[%plugin_id%]['info_section'] html output */ $this->view->assign('backend_order', wa()->event('backend_order', $order, array('title_suffix', 'action_button', 'action_link', 'info_section'))); }
public function execute() { $fm = new shopFollowupModel(); $opm = new shopOrderParamsModel(); $asm = new waAppSettingsModel(); $olm = new shopOrderLogModel(); $cm = new shopCustomerModel(); $om = new shopOrderModel(); $asm->set('shop', 'last_followup_cli', time()); $view = wa()->getView(); $empty_customer = $cm->getEmptyRow(); $general = wa('shop')->getConfig()->getGeneralSettings(); foreach ($fm->getAllEnabled() as $f) { $between_from = date('Y-m-d', strtotime($f['last_cron_time']) - 24 * 3600); $between_to = date('Y-m-d 23:59:59', time() - $f['delay'] - 10 * 3600); $orders = $om->where('paid_date >= ? AND paid_date < ?', $between_from, $between_to)->fetchAll('id'); if ($orders) { $f_param_key = 'followup_' . $f['id']; // Params for all orders with one query $params = $opm->get(array_keys($orders)); // Customer data for all orders with one query $cids = array(); foreach ($orders as $o) { $cids[] = $o['contact_id']; } $customers = $cm->getById($cids); $sent_count = 0; foreach ($orders as $o) { try { // Is there a recipient in the first place? if (empty($o['contact_id'])) { if (waSystemConfig::isDebug()) { waLog::log("Unable to send follow-up #{$f['id']} for order #{$o['id']}: no contact_id"); } continue; } // Check that this is the first order of this customer if ($f['first_order_only']) { $first_order_id = $om->select('MIN(id)')->where('contact_id=? AND paid_date IS NOT NULL', $o['contact_id'])->fetchField(); if ($first_order_id != $o['id']) { if (waSystemConfig::isDebug()) { waLog::log("Skipping follow-up #{$f['id']} for order #{$o['id']}: not the first order of a customer."); } continue; } } $o['params'] = ifset($params[$o['id']], array()); $source = 'backend'; if (!empty($o['params']['storefront'])) { $source = rtrim($o['params']['storefront'], '/') . '/*'; } if ($f['source'] && $f['source'] != $source) { continue; } // Make sure we have not send follow-up for this order yet if (isset($o['params'][$f_param_key])) { if (waSystemConfig::isDebug()) { waLog::log("Skipping follow-up #{$f['id']} for order #{$o['id']}: already sent before."); } continue; } shopHelper::workupOrders($o, true); // Recipient info $customer = ifset($customers[$o['contact_id']], $empty_customer); $contact = new shopCustomer($o['contact_id']); $email = $contact->get('email', 'default'); // this with throw exception if contact does not exist; that's ok if (!$email) { if (waSystemConfig::isDebug()) { waLog::log("Unable to send follow-up #{$f['id']} for order #{$o['id']}: contact has no email"); } continue; } $to = array($email => $contact->getName()); if (self::sendOne($f, $o, $customer, $contact, $to, $view, $general)) { $sent_count++; // Write to order log $olm->add(array('order_id' => $o['id'], 'contact_id' => null, 'action_id' => '', 'text' => sprintf_wp("Follow-up <strong>%s</strong> (%s) sent to customer.", htmlspecialchars($f['name']), $f['id']), 'before_state_id' => $o['state_id'], 'after_state_id' => $o['state_id'])); // Write to order params $opm->insert(array('order_id' => $o['id'], 'name' => $f_param_key, 'value' => date('Y-m-d H:i:s'))); } else { waLog::log("Unable to send follow-up #{$f['id']} for order #{$o['id']}: waMessage->send() returned FALSE."); } } catch (Exception $e) { waLog::log("Unable to send follow-up #{$f['id']} for order #{$o['id']}:\n" . $e); } } /** * Notify plugins about sending followup * @event followup_send * @param array[string]int $params['sent_count'] number of emails successfully sent * @param array[string]int $params['id'] followup_id * @return void */ $event_params = $f; $event_params['sent_count'] = $sent_count; wa()->event('followup_send', $event_params); } $fm->updateById($f['id'], array('last_cron_time' => $between_to)); } }
public function execute() { $category_id = waRequest::request('category', 0, 'int'); $search = waRequest::request('search'); $start = waRequest::request('start', 0, 'int'); $limit = 50; $order = waRequest::request('order', '!last_order'); $config = $this->getConfig(); $use_gravatar = $config->getGeneralSettings('use_gravatar'); $gravatar_default = $config->getGeneralSettings('gravatar_default'); // Get customers $scm = new shopCustomerModel(); list($customers, $total) = $scm->getList($category_id, $search, $start, $limit, $order); $has_more = $start + count($customers) < $total; $countries = array(); foreach ($customers as &$c) { $c['affiliate_bonus'] = (double) $c['affiliate_bonus']; if (!$c['photo'] && $use_gravatar) { $c['photo'] = shopHelper::getGravatar(!empty($c['email']) ? $c['email'] : '', 50, $gravatar_default); } else { $c['photo'] = waContact::getPhotoUrl($c['id'], $c['photo'], 50, 50); } $c['categories'] = array(); if (!empty($c['address']['region']) && !empty($c['address']['country'])) { $countries[$c['address']['country']] = array(); } } unset($c); // Add region names to addresses if ($countries) { $rm = new waRegionModel(); foreach ($rm->where('country_iso3 IN (?)', array_keys($countries))->query() as $row) { $countries[$row['country_iso3']][$row['code']] = $row['name']; } foreach ($customers as &$c) { if (!empty($c['address']['region']) && !empty($c['address']['country'])) { $country = $c['address']['country']; $region = $c['address']['region']; if (!empty($countries[$country]) && !empty($countries[$country][$region])) { $c['address']['region_formatted'] = $countries[$country][$region]; } } } unset($c); } // Contact categories $ccm = new waContactCategoryModel(); $categories = $ccm->getAll('id'); if ($customers) { $ccsm = new waContactCategoriesModel(); foreach ($ccsm->getContactsCategories(array_keys($customers)) as $c_id => $list) { foreach ($list as $cat_id) { if (!empty($categories[$cat_id])) { $customers[$c_id]['categories'][$cat_id] = $categories[$cat_id]; } } } } // Set up lazy loading if (!$has_more) { // Do not trigger lazy loading, show total count at end of list $total_customers_number = $start + count($customers); } else { $total_customers_number = null; // trigger lazy loading } // List title and other params depending on list type if ($search) { $title = _w('Search results'); $hash_start = '#/search/0/' . urlencode($search) . '/'; $discount = null; } else { if ($category_id) { if (!empty($categories[$category_id])) { $title = $categories[$category_id]['name']; } else { $title = _w('Unknown category') . ' ' . $category_id; } $hash_start = '#/category/' . $category_id . '/'; if (wa()->getSetting('discount_category')) { $ccdm = new shopContactCategoryDiscountModel(); $discount = sprintf_wp('%s%% discount', $ccdm->getDiscount($category_id)); } else { $discount = null; } } else { $title = _w('All customers'); $hash_start = '#/all/0/'; $discount = null; } } $lazy_loading_params = array('limit=' . $limit, 'start=' . ($start + $limit), 'order=' . $order); if ($search) { $lazy_loading_params[] = 'search=' . $search; } else { if ($category_id) { $lazy_loading_params[] = 'category=' . $category_id; } } $lazy_loading_params = implode('&', $lazy_loading_params); $this->view->assign('cols', self::getCols()); $this->view->assign('title', $title); $this->view->assign('order', $order); $this->view->assign('total', $total); $this->view->assign('discount', $discount); $this->view->assign('customers', $customers); $this->view->assign('hash_start', $hash_start); $this->view->assign('category_id', $category_id); $this->view->assign('lazy_loading_params', $lazy_loading_params); $this->view->assign('total_customers_number', $total_customers_number); }
public static function discount(&$order, $contact, $apply, $other_discounts) { if (!$contact || !$contact->getId()) { return 0; } $checkout_data = wa()->getStorage()->read('shop/checkout'); if (empty($checkout_data['use_affiliate'])) { return 0; // !!! Will this fail when recalculating existing order? } $usage_rate = (double) wa()->getSetting('affiliate_usage_rate', 0, 'shop'); if ($usage_rate <= 0) { return 0; } $cm = new shopCustomerModel(); $customer = $cm->getById($contact->getId()); if (!$customer || $customer['affiliate_bonus'] <= 0) { return 0; } $order_total = $order['total'] - $other_discounts; $max_bonus = $customer['affiliate_bonus']; if (!empty($order['params']['affiliate_bonus'])) { // Recalculating existing order: take old discount into account $max_bonus += $order['params']['affiliate_bonus']; } $crm = new shopCurrencyModel(); $discount = (double) $crm->convert($max_bonus * $usage_rate, wa()->getConfig()->getCurrency(true), wa()->getConfig()->getCurrency(false)); if ($discount > $order_total) { $discount = $order_total; } if ($discount < $order_total) { $bonus_used = $max_bonus; } else { $bonus_used = (double) $crm->convert($discount, wa()->getConfig()->getCurrency(false), wa()->getConfig()->getCurrency(true)) / $usage_rate; } if (empty($order['params'])) { $order['params'] = array(); } $order['params']['affiliate_bonus'] = $bonus_used; if ($apply) { $balance_change = $max_bonus - $bonus_used - $customer['affiliate_bonus']; if (abs($balance_change) > 0.0001) { if (!empty($order['params']['affiliate_bonus'])) { $message = sprintf_wp('Recalculation of order total, new discount: %s', waCurrency::format('%{s}', $discount, wa()->getConfig()->getCurrency())); } else { $message = sprintf_wp('Discount of %s', waCurrency::format('%{s}', $discount, wa()->getConfig()->getCurrency())); } $atm = new shopAffiliateTransactionModel(); $atm->applyBonus($contact->getId(), $balance_change, ifset($order['id']), $message); } } return $discount; }
public function execute($data = null) { if (wa()->getEnv() == 'frontend') { // Now we are in frontend, so fill stock_id for items. Stock_id get from storefront-settings // But: // - some skus may have not any stock // - stock_id from storefront isn't setted (empty) $sku_ids = array(); foreach ($data['items'] as $item) { if ($item['type'] == 'product') { $sku_ids[] = (int) $item['sku_id']; } } $product_stocks_model = new shopProductStocksModel(); $sku_ids = $product_stocks_model->filterSkusByNoStocks($sku_ids); $sku_ids_map = array_fill_keys($sku_ids, true); // storefront stock-id $stock_id = waRequest::param('stock_id'); $stock_model = new shopStockModel(); if (!$stock_id || !$stock_model->stockExists($stock_id)) { $stock_id = $stock_model->select('id')->order('sort')->limit(1)->fetchField(); } foreach ($data['items'] as &$item) { if ($item['type'] == 'product') { if (!isset($sku_ids_map[$item['sku_id']])) { // have stocks $item['stock_id'] = $stock_id; } } } } $currency = wa()->getConfig()->getCurrency(false); $rate_model = new shopCurrencyModel(); $row = $rate_model->getById($currency); $rate = $row['rate']; // Save contact if (isset($data['contact'])) { if (is_numeric($data['contact'])) { $contact = new waContact($data['contact']); } else { /** * @var waContact $contact */ $contact = $data['contact']; if (!$contact->getId()) { $contact->save(); // if user has been created if ($contact['password']) { $signup_action = new shopSignupAction(); $signup_action->send($contact); } } } } else { $data['contact'] = $contact = wa()->getUser(); } $subtotal = 0; foreach ($data['items'] as &$item) { if ($currency != $item['currency']) { $item['price'] = shop_currency($item['price'], $item['currency'], null, false); if (!empty($item['purchase_price'])) { $item['purchase_price'] = shop_currency($item['purchase_price'], $item['currency'], null, false); } $item['currency'] = $currency; } $subtotal += $item['price'] * $item['quantity']; } unset($item); if ($data['discount'] === '') { $data['total'] = $subtotal; $data['discount'] = shopDiscounts::apply($data); } $shipping_address = $contact->getFirst('address.shipping'); if (!$shipping_address) { $shipping_address = $contact->getFirst('address'); } $billing_address = $contact->getFirst('address.billing'); if (!$billing_address) { $billing_address = $contact->getFirst('address'); } $discount_rate = $subtotal ? $data['discount'] / $subtotal : 0; $taxes = shopTaxes::apply($data['items'], array('shipping' => isset($shipping_address['data']) ? $shipping_address['data'] : array(), 'billing' => isset($billing_address['data']) ? $billing_address['data'] : array(), 'discount_rate' => $discount_rate)); $tax = $tax_included = 0; foreach ($taxes as $t) { if (isset($t['sum'])) { $tax += $t['sum']; } if (isset($t['sum_included'])) { $tax_included += $t['sum_included']; } } $order = array('state_id' => 'new', 'total' => $subtotal - $data['discount'] + $data['shipping'] + $tax, 'currency' => $currency, 'rate' => $rate, 'tax' => $tax_included + $tax, 'discount' => $data['discount'], 'shipping' => $data['shipping'], 'comment' => isset($data['comment']) ? $data['comment'] : ''); $order['contact_id'] = $contact->getId(); // Add contact to 'shop' category $contact->addToCategory('shop'); // Save order $order_model = new shopOrderModel(); $order_id = $order_model->insert($order); // Create record in shop_customer, or update existing record $scm = new shopCustomerModel(); $scm->updateFromNewOrder($order['contact_id'], $order_id); // save items $items_model = new shopOrderItemsModel(); $parent_id = null; foreach ($data['items'] as $item) { $item['order_id'] = $order_id; if ($item['type'] == 'product') { $parent_id = $items_model->insert($item); } elseif ($item['type'] == 'service') { $item['parent_id'] = $parent_id; $items_model->insert($item); } } // Order params if (empty($data['params'])) { $data['params'] = array(); } $data['params']['auth_code'] = self::generateAuthCode($order_id); $data['params']['auth_pin'] = self::generateAuthPin(); // Save params $params_model = new shopOrderParamsModel(); $params_model->set($order_id, $data['params']); $log_model = new waLogModel(); $log_model->add('order_create', $order_id, null, $order['contact_id']); return array('order_id' => $order_id, 'contact_id' => wa()->getEnv() == 'frontend' ? $contact->getId() : wa()->getUser()->getId()); }
/** Discounts by amount of money previously spent by this customer. */ protected static function byCustomerTotal($order, $contact, $apply) { if (!$contact || !$contact->getId()) { return 0; } $cm = new shopCustomerModel(); $customer = $cm->getById($contact->getId()); if ($customer && $customer['total_spent'] > 0) { $dbsm = new shopDiscountBySumModel(); return max(0.0, min(100.0, (double) $dbsm->getDiscount('customer_total', $customer['total_spent']))) * $order['total'] / 100.0; } return 0.0; }
public function execute() { $id = waRequest::request('id', null, waRequest::TYPE_INT); $scm = new shopCustomerModel(); $customer = $scm->getById($id); try { $contact = new waContact($id); $contact->getName(); } catch (waException $e) { // !!! What to do when shop_customer exists, but no wa_contact found? throw $e; } $ccsm = new waContactCategoriesModel(); $contact_categories = $ccsm->getContactCategories($id); $contacts_url = wa()->getAppUrl('contacts'); // Info above tabs $top = array(); foreach (array('email', 'phone', 'im') as $f) { if ($v = $contact->get($f, 'top,html')) { $top[] = array('id' => $f, 'name' => waContactFields::get($f)->getName(), 'value' => is_array($v) ? implode(', ', $v) : $v); } } // Get photo $photo = $contact->get('photo'); $config = $this->getConfig(); $use_gravatar = $config->getGeneralSettings('use_gravatar'); $gravatar_default = $config->getGeneralSettings('gravatar_default'); if (!$photo && $use_gravatar) { $photo = shopHelper::getGravatar($contact->get('email', 'default'), 96, $gravatar_default); } else { $photo = $contact->getPhoto(96); } $contact['photo'] = $photo; // Customer orders $im = new shopOrderItemsModel(); $orders_collection = new shopOrdersCollection('search/contact_id=' . $id); $total_count = $orders_collection->count(); $orders = $orders_collection->getOrders('*,items,params', 0, $total_count); shopHelper::workupOrders($orders); foreach ($orders as &$o) { $o['total_formatted'] = waCurrency::format('%{s}', $o['total'], $o['currency']); $o['shipping_name'] = ifset($o['params']['shipping_name'], ''); $o['payment_name'] = ifset($o['params']['payment_name'], ''); // !!! TODO: shipping and payment icons } // Customer reviews $prm = new shopProductReviewsModel(); $reviews = $prm->getList('*,is_new,product', array('escape' => false, 'where' => array('contact_id' => $id), 'limit' => false)); // Customer affiliate transactions history $atm = new shopAffiliateTransactionModel(); $affiliate_history = $atm->getByContact($id); $this->view->assign('top', $top); $this->view->assign('orders', $orders); $this->view->assign('reviews', $reviews); $this->view->assign('contact', $contact); $this->view->assign('customer', $customer); $this->view->assign('contacts_url', $contacts_url); $this->view->assign('affiliate_history', $affiliate_history); $this->view->assign('contact_categories', $contact_categories); $this->view->assign('def_cur_tmpl', str_replace('0', '%s', waCurrency::format('%{s}', 0, wa()->getConfig()->getCurrency()))); $this->view->assign('point_rate', str_replace(',', '.', (double) str_replace(',', '.', wa()->getSetting('affiliate_usage_rate')))); $fields = waContactFields::getAll('person'); if (isset($fields['name'])) { unset($fields['name']); } $this->view->assign('fields', $fields); $this->view->assign('orders_default_view', $config->getOption('orders_default_view')); /* * @event backend_customer * @return array[string]array $return[%plugin_id%] array of html output * @return array[string][string]string $return[%plugin_id%]['info_section'] html output * @return array[string][string]string $return[%plugin_id%]['name_suffix'] html output * @return array[string][string]string $return[%plugin_id%]['header'] html output * @return array[string][string]string $return[%plugin_id%]['action_link'] html output */ $this->view->assign('backend_customer', wa()->event('backend_customer', $customer)); }