// New profitability calculation

This commit is contained in:
Damien Metzger
2013-10-22 11:39:38 +02:00
parent d8d9436f51
commit 16cf10d586
3 changed files with 159 additions and 93 deletions
+30 -45
View File
@@ -404,61 +404,46 @@ class CarrierCore extends ObjectModel
*/
public static function getCarriers($id_lang, $active = false, $delete = false, $id_zone = false, $ids_group = null, $modules_filters = self::PS_CARRIERS_ONLY)
{
if (!Validate::isBool($active))
die(Tools::displayError());
if ($ids_group)
{
$ids = '';
foreach ($ids_group as $id)
$ids .= (int)$id.', ';
$ids = rtrim($ids, ', ');
if ($ids == '')
return array();
}
// Filter by groups and no groups => return empty array
if ($ids_group && (!is_array($ids_group) || !count($ids_group)))
return array();
$sql = '
SELECT c.*, cl.delay
FROM `'._DB_PREFIX_.'carrier` c
LEFT JOIN `'._DB_PREFIX_.'carrier_lang` cl ON (c.`id_carrier` = cl.`id_carrier` AND cl.`id_lang` = '.(int)$id_lang.Shop::addSqlRestrictionOnLang('cl').')
LEFT JOIN `'._DB_PREFIX_.'carrier_zone` cz ON (cz.`id_carrier` = c.`id_carrier`)'.
($id_zone ? 'LEFT JOIN `'._DB_PREFIX_.'zone` z ON (z.`id_zone` = '.(int)$id_zone.')' : '').'
'.Shop::addSqlAssociation('carrier', 'c').'
WHERE c.`deleted` = '.($delete ? '1' : '0');
if ($active)
$sql .= ' AND c.`active` = 1 ';
if ($id_zone)
$sql .= ' AND cz.`id_zone` = '.(int)$id_zone.' AND z.`active` = 1 ';
if ($ids_group)
$sql .= ' AND c.id_carrier IN (SELECT id_carrier FROM '._DB_PREFIX_.'carrier_group WHERE id_group IN ('.implode(',', array_map('intval', $ids_group)).')) ';
$sql = 'SELECT c.*, cl.delay
FROM `'._DB_PREFIX_.'carrier` c
LEFT JOIN `'._DB_PREFIX_.'carrier_lang` cl ON (c.`id_carrier` = cl.`id_carrier` AND cl.`id_lang` = '.(int)$id_lang.Shop::addSqlRestrictionOnLang('cl').')
LEFT JOIN `'._DB_PREFIX_.'carrier_zone` cz ON (cz.`id_carrier` = c.`id_carrier`)'.
($id_zone ? 'LEFT JOIN `'._DB_PREFIX_.'zone` z ON (z.`id_zone` = '.(int)$id_zone.')' : '').'
'.Shop::addSqlAssociation('carrier', 'c').'
WHERE c.`deleted` = '.($delete ? '1' : '0').
($active ? ' AND c.`active` = 1' : '').
($id_zone ? ' AND cz.`id_zone` = '.(int)$id_zone.'
AND z.`active` = 1 ' : ' ');
switch ($modules_filters)
{
case 1 :
$sql .= 'AND c.is_module = 0 ';
break;
$sql .= ' AND c.is_module = 0 ';
break;
case 2 :
$sql .= 'AND c.is_module = 1 ';
break;
$sql .= ' AND c.is_module = 1 ';
break;
case 3 :
$sql .= 'AND c.is_module = 1 AND c.need_range = 1 ';
break;
$sql .= ' AND c.is_module = 1 AND c.need_range = 1 ';
break;
case 4 :
$sql .= 'AND (c.is_module = 0 OR c.need_range = 1) ';
break;
case 5 :
$sql .= '';
break;
$sql .= ' AND (c.is_module = 0 OR c.need_range = 1) ';
break;
}
$sql .= ($ids_group ? ' AND c.id_carrier IN (SELECT id_carrier FROM '._DB_PREFIX_.'carrier_group WHERE id_group IN ('.$ids.')) ' : '').'
GROUP BY c.`id_carrier`
ORDER BY c.`position` ASC';
$sql .= ' GROUP BY c.`id_carrier` ORDER BY c.`position` ASC';
$carriers = Db::getInstance()->executeS($sql);
if (is_array($carriers) && count($carriers))
{
foreach ($carriers as $key => $carrier)
if ($carrier['name'] == '0')
$carriers[$key]['name'] = Configuration::get('PS_SHOP_NAME');
}
else
$carriers = array();
foreach ($carriers as $key => $carrier)
if ($carrier['name'] == '0')
$carriers[$key]['name'] = Configuration::get('PS_SHOP_NAME');
return $carriers;
}
+93 -40
View File
@@ -63,62 +63,103 @@ class AdminDashboardControllerCore extends AdminController
protected function getOptionFields()
{
$forms = array();
$currency = new Currency(Configuration::get('PS_CURRENCY_DEFAULT'));
$fields = array();
$carriers = Carrier::getCarriers($this->context->language->id, true);
$modules = Module::getModulesOnDisk(true);
$forms = array(
'payment' => array('title' => $this->l('Average bank fees per payment method')),
'carriers' => array('title' => $this->l('Average shipping fees per shipping method')),
'other' => array('title' => $this->l('Other settings')),
'expenses' => array('title' => $this->l('Other expenses'))
);
foreach ($forms as &$form)
{
$form['icon'] = 'tab-preferences';
$form['fields'] = array();
$form['submit'] = array('title' => $this->l('Save'), 'class' => 'button');
}
foreach ($modules as $module)
if ($module->tab == 'payments_gateways' && $module->id)
{
$fields['CONF_'.strtoupper($module->name).'_FIXED_FEE'] = array(
'title' => sprintf($this->l('Fixed fee / %s'), $module->displayName),
'desc' => sprintf($this->l('Choose a fixed fee for each order placed with %s.'), $module->displayName),
$forms['payment']['fields']['CONF_'.strtoupper($module->name).'_FIXED'] = array(
'title' => $module->displayName,
'desc' => sprintf($this->l('Choose a fixed fee for each order placed in %s with %s.'), $currency->iso_code, $module->displayName),
'validation' => 'isPrice',
'cast' => 'floatval',
'type' => 'text',
'default' => '0',
'suffix' => $currency->iso_code
);
$fields['CONF_'.strtoupper($module->name).'_VAR_FEE'] = array(
'title' => sprintf($this->l('Variable fee / %s'), $module->displayName),
'desc' => sprintf($this->l('Choose a variable fee for each order placed with %s. It will be applied on the total paid with taxes.'), $module->displayName),
$forms['payment']['fields']['CONF_'.strtoupper($module->name).'_VAR'] = array(
'title' => $module->displayName,
'desc' => sprintf($this->l('Choose a variable fee for each order placed in %s with %s. It will be applied on the total paid with taxes.'), $currency->iso_code, $module->displayName),
'validation' => 'isPercentage',
'cast' => 'floatval',
'type' => 'text',
'default' => '0',
'suffix' => '%'
);
if (Currency::isMultiCurrencyActivated())
{
$forms['payment']['fields']['CONF_'.strtoupper($module->name).'_FIXED_FOREIGN'] = array(
'title' => $module->displayName,
'desc' => sprintf($this->l('Choose a fixed fee for each order placed with a foreign currency with %s.'), $module->displayName),
'validation' => 'isPrice',
'cast' => 'floatval',
'type' => 'text',
'default' => '0',
'suffix' => $currency->iso_code
);
$forms['payment']['fields']['CONF_'.strtoupper($module->name).'_VAR_FOREIGN'] = array(
'title' => $module->displayName,
'desc' => sprintf($this->l('Choose a variable fee for each order placed with a foreign currency with %s. It will be applied on the total paid with taxes.'), $module->displayName),
'validation' => 'isPercentage',
'cast' => 'floatval',
'type' => 'text',
'default' => '0',
'suffix' => '%'
);
}
}
$fields['CONF_ORDER_FIXED_FEES'] = array(
'title' => $this->l('Other fixed fees'),
'desc' => $this->l('Other fixed fees applied to each order.'),
'validation' => 'isPrice',
'cast' => 'floatval',
'type' => 'text',
'default' => '0',
'suffix' => $currency->iso_code
);
$fields['CONF_SHIPPING_MARGIN'] = array(
'title' => $this->l('Shipping Margin'),
'desc' => $this->l('Profit margin on your shipping fees.'),
foreach ($carriers as $carrier)
{
$forms['carriers']['fields']['CONF_'.strtoupper($carrier['id_reference']).'_SHIP'] = array(
'title' => $carrier['name'],
'desc' => sprintf($this->l('%% of what you charged the customer for domestic delivery with %s.'), $carrier['name']),
'validation' => 'isPercentage',
'cast' => 'floatval',
'type' => 'text',
'default' => '0',
'suffix' => '%'
);
$forms['carriers']['fields']['CONF_'.strtoupper($carrier['id_reference']).'_SHIP_OVERSEAS'] = array(
'title' => $carrier['name'],
'desc' => sprintf($this->l('%% of what you charged the customer for overseas delivery with %s.'), $carrier['name']),
'validation' => 'isPercentage',
'cast' => 'floatval',
'type' => 'text',
'default' => '0',
'suffix' => '%'
);
}
$forms['other']['fields']['CONF_AVERAGE_PRODUCT_MARGIN'] = array(
'title' => $this->l('Average gross margin (Selling price / Buying price)'),
'desc' => $this->l('Only used if you do not specify your buying price for each product.'),
'validation' => 'isPercentage',
'cast' => 'floatval',
'cast' => 'intval',
'type' => 'text',
'default' => '0',
'suffix' => '%'
);
$fields['CONF_MONTHLY_FEES'] = array(
'title' => $this->l('Monthly fees'),
'desc' => $this->l('Monthly fees like hosting, adwords, etc.'),
'validation' => 'isPrice',
'cast' => 'floatval',
'type' => 'text',
'default' => '0',
'suffix' => $currency->iso_code
);
$fields['CONF_YEARLY_FEES'] = array(
'title' => $this->l('Yearly fees'),
'desc' => $this->l('Yearly fees like hosting, subscriptions, etc.'),
$forms['other']['fields']['CONF_ORDER_FIXED'] = array(
'title' => $this->l('Other fee per order'),
'validation' => 'isPrice',
'cast' => 'floatval',
'type' => 'text',
@@ -126,14 +167,26 @@ class AdminDashboardControllerCore extends AdminController
'suffix' => $currency->iso_code
);
return array(
'profitability' => array(
'title' => $this->l('Profitability Configuration'),
'icon' => 'tab-preferences',
'fields' => $fields,
'submit' => array('title' => $this->l('Save'), 'class' => 'button'),
),
$expense_types = array(
'hosting' => $this->l('Hosting'),
'tools' => $this->l('Tools (E-mailing, etc.)'),
'acounting' => $this->l('Accounting'),
'development' => $this->l('Development'),
'marketing' => $this->l('Marketing (Adwords, etc.)'),
'others' => $this->l('Others')
);
foreach ($expense_types as $expense_type => $expense_label)
$forms['expenses']['fields']['CONF_MONTHLY_'.strtoupper($expense_type)] = array(
'title' => $expense_label,
'validation' => 'isPrice',
'cast' => 'floatval',
'type' => 'text',
'default' => '0',
'suffix' => $currency->iso_code
);
return $forms;
}
public function renderView()
+36 -8
View File
@@ -324,27 +324,51 @@ class AdminStatsControllerCore extends AdminStatsTabController
public static function getExpenses($date_from, $date_to)
{
$secs_per_year = 365.25 * 86400;
$secs_per_month = 30.4375 * 86400;
$total_secs = (strtotime($date_to) - min(strtotime($date_from), time())) / 86400;
$expenses = Configuration::get('CONF_MONTHLY_FEES') * $total_secs / $secs_per_month + Configuration::get('CONF_YEARLY_FEES') * $total_secs / $secs_per_year;
$expenses =
Configuration::get('CONF_MONTHLY_ACOUNTING')
+ Configuration::get('CONF_MONTHLY_DEVELOPMENT')
+ Configuration::get('CONF_MONTHLY_HOSTING')
+ Configuration::get('CONF_MONTHLY_MARKETING')
+ Configuration::get('CONF_MONTHLY_OTHERS')
+ Configuration::get('CONF_MONTHLY_TOOLS');
$expenses *= $total_secs / $secs_per_month;
$orders = Db::getInstance()->ExecuteS('
SELECT
total_paid_tax_incl / o.conversion_rate as total_paid_tax_incl,
total_shipping_tax_excl / o.conversion_rate as total_shipping_tax_excl,
module
o.module,
a.id_country,
o.id_currency,
c.id_reference as carrier_reference
FROM `'._DB_PREFIX_.'orders` o
LEFT JOIN `'._DB_PREFIX_.'address` a ON o.id_address_delivery = a.id_address
LEFT JOIN `'._DB_PREFIX_.'carrier` c ON o.id_carrier = c.id_carrier
WHERE `invoice_date` BETWEEN "'.pSQL($date_from).' 00:00:00" AND "'.pSQL($date_to).' 23:59:59"
'.Shop::addSqlRestriction(false, 'o'));
foreach ($orders as $order)
{
// Add flat fees for this order
$expenses += Configuration::get('CONF_ORDER_FIXED_FEES') + Configuration::get('CONF_'.strtoupper($order['module']).'_FIXED_FEE');
$expenses += Configuration::get('CONF_ORDER_FIXED') + (
$order['id_currency'] == Configuration::get('PS_DEFAULT_CURRENCY')
? Configuration::get('CONF_'.strtoupper($order['module']).'_FIXED')
: Configuration::get('CONF_'.strtoupper($order['module']).'_FIXED_FOREIGN')
);
// Add variable fees for this order
$expenses += $order['total_paid_tax_incl'] * (Configuration::get('CONF_ORDER_VAR_FEES') + Configuration::get('CONF_'.strtoupper($order['module']).'_VAR_FEE')) / 100;
$expenses += $order['total_paid_tax_incl'] * (
$order['id_currency'] == Configuration::get('PS_DEFAULT_CURRENCY')
? Configuration::get('CONF_'.strtoupper($order['module']).'_VAR')
: Configuration::get('CONF_'.strtoupper($order['module']).'_VAR_FOREIGN')
) / 100;
// Add shipping fees for this order
$expenses += $order['total_shipping_tax_excl'] * (100 - Configuration::get('CONF_SHIPPING_MARGIN')) / 100;
//
$expenses += $order['total_shipping_tax_excl'] * (
$order['id_country'] == Configuration::get('PS_DEFAULT_COUNTRY')
? Configuration::get('CONF_'.strtoupper($order['carrier_reference']).'_SHIP')
: Configuration::get('CONF_'.strtoupper($order['carrier_reference']).'_SHIP_OVERSEAS')
) / 100;
}
return $expenses;
}
@@ -574,13 +598,17 @@ class AdminStatsControllerCore extends AdminStatsTabController
break;
case 'netprofit_visitor':
$date_from = date('Y-m-d', strtotime('-31 day'));
$date_from = date('Y-m-d', strtotime('-131 day'));
$date_to = date('Y-m-d', strtotime('-1 day'));
$total_visitors = AdminStatsController::getUniqueVisitors($date_from, $date_to);
$total_sales = AdminStatsController::getTotalSales($date_from, $date_to);
$total_expenses = AdminStatsController::getExpenses($date_from, $date_to);
$total_purchases = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue('
SELECT SUM(od.`product_quantity` * od.`purchase_supplier_price` / `conversion_rate`) as total_purchase_price
SELECT SUM(od.`product_quantity` * IF(
od.`purchase_supplier_price` > 0,
od.`purchase_supplier_price` / `conversion_rate`,
od.`original_product_price` * '.(int)Configuration::get('CONF_AVERAGE_PRODUCT_MARGIN').' / 100
)) as total_purchase_price
FROM `'._DB_PREFIX_.'orders` o
LEFT JOIN `'._DB_PREFIX_.'order_detail` od ON o.id_order = od.id_order
WHERE `invoice_date` BETWEEN "'.pSQL($date_from).' 00:00:00" AND "'.pSQL($date_to).' 23:59:59"