// New profitability calculation
This commit is contained in:
+30
-45
@@ -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)
|
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))
|
// Filter by groups and no groups => return empty array
|
||||||
die(Tools::displayError());
|
if ($ids_group && (!is_array($ids_group) || !count($ids_group)))
|
||||||
if ($ids_group)
|
return array();
|
||||||
{
|
|
||||||
$ids = '';
|
$sql = '
|
||||||
foreach ($ids_group as $id)
|
SELECT c.*, cl.delay
|
||||||
$ids .= (int)$id.', ';
|
FROM `'._DB_PREFIX_.'carrier` c
|
||||||
$ids = rtrim($ids, ', ');
|
LEFT JOIN `'._DB_PREFIX_.'carrier_lang` cl ON (c.`id_carrier` = cl.`id_carrier` AND cl.`id_lang` = '.(int)$id_lang.Shop::addSqlRestrictionOnLang('cl').')
|
||||||
if ($ids == '')
|
LEFT JOIN `'._DB_PREFIX_.'carrier_zone` cz ON (cz.`id_carrier` = c.`id_carrier`)'.
|
||||||
return array();
|
($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)
|
switch ($modules_filters)
|
||||||
{
|
{
|
||||||
case 1 :
|
case 1 :
|
||||||
$sql .= 'AND c.is_module = 0 ';
|
$sql .= ' AND c.is_module = 0 ';
|
||||||
break;
|
break;
|
||||||
case 2 :
|
case 2 :
|
||||||
$sql .= 'AND c.is_module = 1 ';
|
$sql .= ' AND c.is_module = 1 ';
|
||||||
break;
|
break;
|
||||||
case 3 :
|
case 3 :
|
||||||
$sql .= 'AND c.is_module = 1 AND c.need_range = 1 ';
|
$sql .= ' AND c.is_module = 1 AND c.need_range = 1 ';
|
||||||
break;
|
break;
|
||||||
case 4 :
|
case 4 :
|
||||||
$sql .= 'AND (c.is_module = 0 OR c.need_range = 1) ';
|
$sql .= ' AND (c.is_module = 0 OR c.need_range = 1) ';
|
||||||
break;
|
break;
|
||||||
case 5 :
|
|
||||||
$sql .= '';
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
$sql .= ($ids_group ? ' AND c.id_carrier IN (SELECT id_carrier FROM '._DB_PREFIX_.'carrier_group WHERE id_group IN ('.$ids.')) ' : '').'
|
$sql .= ' GROUP BY c.`id_carrier` ORDER BY c.`position` ASC';
|
||||||
GROUP BY c.`id_carrier`
|
|
||||||
ORDER BY c.`position` ASC';
|
|
||||||
|
|
||||||
$carriers = Db::getInstance()->executeS($sql);
|
$carriers = Db::getInstance()->executeS($sql);
|
||||||
|
foreach ($carriers as $key => $carrier)
|
||||||
if (is_array($carriers) && count($carriers))
|
if ($carrier['name'] == '0')
|
||||||
{
|
$carriers[$key]['name'] = Configuration::get('PS_SHOP_NAME');
|
||||||
foreach ($carriers as $key => $carrier)
|
|
||||||
if ($carrier['name'] == '0')
|
|
||||||
$carriers[$key]['name'] = Configuration::get('PS_SHOP_NAME');
|
|
||||||
}
|
|
||||||
else
|
|
||||||
$carriers = array();
|
|
||||||
|
|
||||||
return $carriers;
|
return $carriers;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,62 +63,103 @@ class AdminDashboardControllerCore extends AdminController
|
|||||||
|
|
||||||
protected function getOptionFields()
|
protected function getOptionFields()
|
||||||
{
|
{
|
||||||
|
$forms = array();
|
||||||
$currency = new Currency(Configuration::get('PS_CURRENCY_DEFAULT'));
|
$currency = new Currency(Configuration::get('PS_CURRENCY_DEFAULT'));
|
||||||
$fields = array();
|
$carriers = Carrier::getCarriers($this->context->language->id, true);
|
||||||
|
|
||||||
$modules = Module::getModulesOnDisk(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)
|
foreach ($modules as $module)
|
||||||
if ($module->tab == 'payments_gateways' && $module->id)
|
if ($module->tab == 'payments_gateways' && $module->id)
|
||||||
{
|
{
|
||||||
$fields['CONF_'.strtoupper($module->name).'_FIXED_FEE'] = array(
|
$forms['payment']['fields']['CONF_'.strtoupper($module->name).'_FIXED'] = array(
|
||||||
'title' => sprintf($this->l('Fixed fee / %s'), $module->displayName),
|
'title' => $module->displayName,
|
||||||
'desc' => sprintf($this->l('Choose a fixed fee for each order placed with %s.'), $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',
|
'validation' => 'isPrice',
|
||||||
'cast' => 'floatval',
|
'cast' => 'floatval',
|
||||||
'type' => 'text',
|
'type' => 'text',
|
||||||
'default' => '0',
|
'default' => '0',
|
||||||
'suffix' => $currency->iso_code
|
'suffix' => $currency->iso_code
|
||||||
);
|
);
|
||||||
$fields['CONF_'.strtoupper($module->name).'_VAR_FEE'] = array(
|
$forms['payment']['fields']['CONF_'.strtoupper($module->name).'_VAR'] = array(
|
||||||
'title' => sprintf($this->l('Variable fee / %s'), $module->displayName),
|
'title' => $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),
|
'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',
|
'validation' => 'isPercentage',
|
||||||
'cast' => 'floatval',
|
'cast' => 'floatval',
|
||||||
'type' => 'text',
|
'type' => 'text',
|
||||||
'default' => '0',
|
'default' => '0',
|
||||||
'suffix' => '%'
|
'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'),
|
foreach ($carriers as $carrier)
|
||||||
'desc' => $this->l('Other fixed fees applied to each order.'),
|
{
|
||||||
'validation' => 'isPrice',
|
$forms['carriers']['fields']['CONF_'.strtoupper($carrier['id_reference']).'_SHIP'] = array(
|
||||||
'cast' => 'floatval',
|
'title' => $carrier['name'],
|
||||||
'type' => 'text',
|
'desc' => sprintf($this->l('%% of what you charged the customer for domestic delivery with %s.'), $carrier['name']),
|
||||||
'default' => '0',
|
'validation' => 'isPercentage',
|
||||||
'suffix' => $currency->iso_code
|
'cast' => 'floatval',
|
||||||
);
|
'type' => 'text',
|
||||||
$fields['CONF_SHIPPING_MARGIN'] = array(
|
'default' => '0',
|
||||||
'title' => $this->l('Shipping Margin'),
|
'suffix' => '%'
|
||||||
'desc' => $this->l('Profit margin on your shipping fees.'),
|
);
|
||||||
|
$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',
|
'validation' => 'isPercentage',
|
||||||
'cast' => 'floatval',
|
'cast' => 'intval',
|
||||||
'type' => 'text',
|
'type' => 'text',
|
||||||
'default' => '0',
|
'default' => '0',
|
||||||
'suffix' => '%'
|
'suffix' => '%'
|
||||||
);
|
);
|
||||||
$fields['CONF_MONTHLY_FEES'] = array(
|
|
||||||
'title' => $this->l('Monthly fees'),
|
$forms['other']['fields']['CONF_ORDER_FIXED'] = array(
|
||||||
'desc' => $this->l('Monthly fees like hosting, adwords, etc.'),
|
'title' => $this->l('Other fee per order'),
|
||||||
'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.'),
|
|
||||||
'validation' => 'isPrice',
|
'validation' => 'isPrice',
|
||||||
'cast' => 'floatval',
|
'cast' => 'floatval',
|
||||||
'type' => 'text',
|
'type' => 'text',
|
||||||
@@ -126,14 +167,26 @@ class AdminDashboardControllerCore extends AdminController
|
|||||||
'suffix' => $currency->iso_code
|
'suffix' => $currency->iso_code
|
||||||
);
|
);
|
||||||
|
|
||||||
return array(
|
$expense_types = array(
|
||||||
'profitability' => array(
|
'hosting' => $this->l('Hosting'),
|
||||||
'title' => $this->l('Profitability Configuration'),
|
'tools' => $this->l('Tools (E-mailing, etc.)'),
|
||||||
'icon' => 'tab-preferences',
|
'acounting' => $this->l('Accounting'),
|
||||||
'fields' => $fields,
|
'development' => $this->l('Development'),
|
||||||
'submit' => array('title' => $this->l('Save'), 'class' => 'button'),
|
'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()
|
public function renderView()
|
||||||
|
|||||||
@@ -324,27 +324,51 @@ class AdminStatsControllerCore extends AdminStatsTabController
|
|||||||
|
|
||||||
public static function getExpenses($date_from, $date_to)
|
public static function getExpenses($date_from, $date_to)
|
||||||
{
|
{
|
||||||
$secs_per_year = 365.25 * 86400;
|
|
||||||
$secs_per_month = 30.4375 * 86400;
|
$secs_per_month = 30.4375 * 86400;
|
||||||
$total_secs = (strtotime($date_to) - min(strtotime($date_from), time())) / 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('
|
$orders = Db::getInstance()->ExecuteS('
|
||||||
SELECT
|
SELECT
|
||||||
total_paid_tax_incl / o.conversion_rate as total_paid_tax_incl,
|
total_paid_tax_incl / o.conversion_rate as total_paid_tax_incl,
|
||||||
total_shipping_tax_excl / o.conversion_rate as total_shipping_tax_excl,
|
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
|
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"
|
WHERE `invoice_date` BETWEEN "'.pSQL($date_from).' 00:00:00" AND "'.pSQL($date_to).' 23:59:59"
|
||||||
'.Shop::addSqlRestriction(false, 'o'));
|
'.Shop::addSqlRestriction(false, 'o'));
|
||||||
foreach ($orders as $order)
|
foreach ($orders as $order)
|
||||||
{
|
{
|
||||||
// Add flat fees for this 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
|
// 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
|
// 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;
|
return $expenses;
|
||||||
}
|
}
|
||||||
@@ -574,13 +598,17 @@ class AdminStatsControllerCore extends AdminStatsTabController
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'netprofit_visitor':
|
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'));
|
$date_to = date('Y-m-d', strtotime('-1 day'));
|
||||||
$total_visitors = AdminStatsController::getUniqueVisitors($date_from, $date_to);
|
$total_visitors = AdminStatsController::getUniqueVisitors($date_from, $date_to);
|
||||||
$total_sales = AdminStatsController::getTotalSales($date_from, $date_to);
|
$total_sales = AdminStatsController::getTotalSales($date_from, $date_to);
|
||||||
$total_expenses = AdminStatsController::getExpenses($date_from, $date_to);
|
$total_expenses = AdminStatsController::getExpenses($date_from, $date_to);
|
||||||
$total_purchases = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue('
|
$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
|
FROM `'._DB_PREFIX_.'orders` o
|
||||||
LEFT JOIN `'._DB_PREFIX_.'order_detail` od ON o.id_order = od.id_order
|
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"
|
WHERE `invoice_date` BETWEEN "'.pSQL($date_from).' 00:00:00" AND "'.pSQL($date_to).' 23:59:59"
|
||||||
|
|||||||
Reference in New Issue
Block a user