NEW: Add a new method for margin calculation. Added margin on "cost

price" to margin on WAP price and margin on "best supplier price".
This commit is contained in:
Laurent Destailleur 2016-01-13 12:48:59 +01:00
parent 381eea0dbf
commit d396612a7c
6 changed files with 89 additions and 37 deletions

View File

@ -4191,10 +4191,11 @@ abstract class CommonObject
return true;
}
/**
* define buy price if not defined
/**
* Get buy price to use for margin calculation. This function is called when buy price is unknown.
* set buy price = sell price if ForceBuyingPriceIfNull configured,
* else if calculation MARGIN_TYPE = 'pmp' and pmp is calculated, set pmp as buyprice
* else if calculation MARGIN_TYPE = 'costprice' and costprice is defined, use costprice as buyprice
* else if calculation MARGIN_TYPE = 'pmp' and pmp is calculated, use pmp as buyprice
* else set min buy price as buy price
*
* @param float $unitPrice product unit price
@ -4209,16 +4210,16 @@ abstract class CommonObject
$buyPrice = 0;
if (($unitPrice > 0) && (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1))
if (($unitPrice > 0) && (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1)) // In most cases, test here is false
{
$buyPrice = $unitPrice * (1 - $discountPercent / 100);
}
else
{
// Get PMP
// Get cost price for margin calculation
if (! empty($fk_product))
{
if (isset($conf->global->MARGIN_TYPE) && $conf->global->MARGIN_TYPE == 'pmp')
if (isset($conf->global->MARGIN_TYPE) && $conf->global->MARGIN_TYPE == 'costprice')
{
require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
$product = new Product($this->db);
@ -4228,13 +4229,32 @@ abstract class CommonObject
$this->errors[] = 'ErrorProductIdDoesNotExists';
return -1;
}
if (($product->pmp > 0))
if ($product->cost_price > 0)
{
$buyPrice = $product->cost_price;
}
else if ($product->pmp > 0)
{
$buyPrice = $product->pmp;
}
// TODO add option to set PMP of product
}
else if (isset($conf->global->MARGIN_TYPE) && $conf->global->MARGIN_TYPE == '1')
else if (isset($conf->global->MARGIN_TYPE) && $conf->global->MARGIN_TYPE == 'pmp')
{
require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
$product = new Product($this->db);
$result = $product->fetch($fk_product);
if ($result <= 0)
{
$this->errors[] = 'ErrorProductIdDoesNotExists';
return -1;
}
if ($product->pmp > 0)
{
$buyPrice = $product->pmp;
}
}
if (empty($buyPrice) && isset($conf->global->MARGIN_TYPE) && in_array($conf->global->MARGIN_TYPE, array('1','pmp','costprice')))
{
require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php';
$productFournisseur = new ProductFournisseur($this->db);

View File

@ -521,30 +521,56 @@ jQuery(document).ready(function() {
var defaultkey = '';
var defaultprice = '';
var bestpricefound = 0;
var bestpriceid = 0; var bestpricevalue = 0;
var pmppriceid = 0; var pmppricevalue = 0;
var costpriceid = 0; var costpricevalue = 0;
/* setup of margin calculation */
var defaultbuyprice = '<?php
if (isset($conf->global->MARGIN_TYPE))
{
if ($conf->global->MARGIN_TYPE == '1') print 'bestsupplierprice';
if ($conf->global->MARGIN_TYPE == 'pmp') print 'pmp';
if ($conf->global->MARGIN_TYPE == 'costprice') print 'costprice';
} ?>';
console.log("defaultbuyprice="+defaultbuyprice);
var i = 0;
$(data).each(function() {
if (this.id != 'pmpprice')
if (this.id != 'pmpprice' && this.id != 'costprice')
{
i++;
this.price = parseFloat(this.price);//fix this.price >0
this.price = parseFloat(this.price); // to fix when this.price >0
// If margin is calculated on best supplier price, we set it by defaut (but only if value is not 0)
var defaultbuyprice = '<?php echo ((isset($conf->global->MARGIN_TYPE) && $conf->global->MARGIN_TYPE == '1')?'bestsupplierprice':''); ?>'; // We set here default value to use
console.log(this.id+" "+this.price+" "+defaultbuyprice+" "+(this.price > 0));
if (bestpricefound == 0 && this.price > 0 && 'bestsupplierprice' == defaultbuyprice) { defaultkey = this.id; defaultprice = this.price; bestpricefound=1; } // bestpricefound is used to take the first price > 0
console.log("id="+this.id+"-price="+this.price+"-"+(this.price > 0));
if (bestpricefound == 0 && this.price > 0) { defaultkey = this.id; defaultprice = this.price; bestpriceid = this.id; bestpricevalue = this.price; bestpricefound=1; } // bestpricefound is used to take the first price > 0
}
if (this.id == 'pmpprice')
{
// If margin is calculated on PMP, we set it by defaut (but only if value is not 0)
var defaultbuyprice = '<?php echo ((isset($conf->global->MARGIN_TYPE) && $conf->global->MARGIN_TYPE == 'pmp')?'pmp':''); ?>';
console.log(this.id+" "+this.price+" "+defaultbuyprice);
if (this.price > 0 && 'pmp' == defaultbuyprice) { defaultkey = this.id; defaultprice = this.price; }
console.log("id="+this.id+"-price="+this.price);
if ('pmp' == defaultbuyprice || 'costprice' == defaultbuyprice)
{
if (this.price > 0) { defaultkey = this.id; defaultprice = this.price; pmppriceid = this.id; pmppricevalue = this.price;
console.log("pmppricevalue="+pmppricevalue); }
}
}
if (this.id == 'costprice')
{
// If margin is calculated on Cost price, we set it by defaut (but only if value is not 0)
console.log("id="+this.id+"-price="+this.price+"-pmppricevalue="+pmppricevalue);
if ('costprice' == defaultbuyprice)
{
if (this.price > 0) { defaultkey = this.id; defaultprice = this.price; costpriceid = this.id; costpricevalue = this.price; }
else if (pmppricevalue > 0) { defaultkey = pmppriceid; defaultprice = pmppricevalue; }
}
}
options += '<option value="'+this.id+'" price="'+this.price+'">'+this.label+'</option>';
});
options += '<option value="inputprice" price="'+defaultprice+'"><?php echo $langs->trans("InputPrice"); ?></option>';
console.log("defaultkey="+defaultkey);
console.log("finally selected defaultkey="+defaultkey+" defaultprice="+defaultprice);
$("#fournprice_predef").html(options).show();
if (defaultkey != '')

View File

@ -1,6 +1,7 @@
<?php
/* Copyright (C) 2012 Christophe Battarel <christophe.battarel@altairis.fr>
* Copyright (C) 2015 Francis Appels <francis.appels@z-application.com>
* Copyright (C) 2015 Francis Appels <francis.appels@z-application.com>
* Copyright (C) 2016 Laurent Destailleur <eldy@users.sourceforge.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -18,7 +19,7 @@
/**
* \file /htdocs/fourn/ajax/getSupplierPrices.php
* \brief File to return an Ajax response to get a supplier prices
* \brief File to return an Ajax response to get list of possible prices for margin calculation
*/
if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Disables token renewal
@ -36,6 +37,8 @@ $idprod=GETPOST('idprod','int');
$prices = array();
$langs->load('stocks');
$langs->load('margins');
/*
* View
@ -92,6 +95,10 @@ if ($idprod > 0)
// Add price for pmp
$price=$producttmp->pmp;
$prices[] = array("id" => 'pmpprice', "price" => price2num($price), "label" => $langs->trans("PMPValueShort").': '.price($price,0,$langs,0,0,-1,$conf->currency), "title" => $langs->trans("PMPValueShort").': '.price($price,0,$langs,0,0,-1,$conf->currency)); // For price field, we must use price2num(), for label or title, price()
// Add price for costprice
$price=$producttmp->cost_price;
$prices[] = array("id" => 'costprice', "price" => price2num($price), "label" => $langs->trans("CostPrice").': '.price($price,0,$langs,0,0,-1,$conf->currency), "title" => $langs->trans("PMPValueShort").': '.price($price,0,$langs,0,0,-1,$conf->currency)); // For price field, we must use price2num(), for label or title, price()
}
echo json_encode($prices);

View File

@ -35,8 +35,9 @@ MargeBrute=Raw margin
MargeNette=Net margin
MargeType1=Margin on Best supplier price
MargeType2=Margin on Weighted Average Price (WAP)
MARGIN_TYPE_DETAILS=Raw margin : Selling price - Buying price<br/>Net margin : Selling price - Cost price
MarginTypeDesc=Margin on best buying price : Selling price - Best supplier price defined on product card<br/>Margin on Weighted Average Price (WAP) : Selling price - Product Weighted Average Price (WAP) or best supplier price if WAP not yet defined
MargeType3=Margin on Cost Price
MARGIN_TYPE_DETAILS=Raw margin : Selling price - Buying price<br>Net margin : Selling price - Cost price
MarginTypeDesc=* Margin on best buying price = Selling price - Best supplier price defined on product card<br>* Margin on Weighted Average Price (WAP) = Selling price - Product Weighted Average Price (WAP) or best supplier price if WAP not yet defined<br>* Margin on Cost price = Selling price - Cost price defined on product card or WAP if cost price not defined, or best supplier price if WAP not yet defined
CostPrice=Cost price
BuyingCost=Cost price
UnitCharges=Unit charges

View File

@ -1,5 +1,6 @@
<?php
/* Copyright (C) 2012 Christophe Battarel <christophe.battarel@altairis.fr>
* Copyright (C) 2016 Laurent Destailleur <eldy@users.sourceforge.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -145,20 +146,15 @@ if (isset($conf->global->MARGIN_TYPE) && $conf->global->MARGIN_TYPE == '1')
print '/> ';
print $langs->trans('MargeType1');
print '<br>';
/*print $langs->trans('MargeNette');
print ' <input type="radio" name="MARGIN_TYPE" value="2" ';
if (isset($conf->global->MARGIN_TYPE) && $conf->global->MARGIN_TYPE == '2')
print 'checked ';
print '/>';*/
// TODO Check that PMP is available when stock module is not enabled. If not, make this choice greyed when stock module disabled.
//if (! empty($conf->stock->enabled))
//{
print ' <input type="radio" name="MARGIN_TYPE" value="pmp" ';
if (isset($conf->global->MARGIN_TYPE) && $conf->global->MARGIN_TYPE == 'pmp')
print 'checked ';
print '/> ';
print $langs->trans('MargeType2');
//}
print ' <input type="radio" name="MARGIN_TYPE" value="pmp" ';
if (isset($conf->global->MARGIN_TYPE) && $conf->global->MARGIN_TYPE == 'pmp') print 'checked ';
print '/> ';
print $langs->trans('MargeType2');
print '<br>';
print ' <input type="radio" name="MARGIN_TYPE" value="costprice" ';
if (isset($conf->global->MARGIN_TYPE) && $conf->global->MARGIN_TYPE == 'costprice') print 'checked ';
print '/> ';
print $langs->trans('MargeType3');
print '</td>';
print '<td>';
print '<input type="submit" class="button" value="'.$langs->trans("Modify").'" class="button">';

View File

@ -106,6 +106,8 @@ class Product extends CommonObject
//! Stock
var $stock_reel;
//! Cost price
var $cost_price;
//! Average price value for product entry into stock (PMP)
var $pmp;
//! Stock alert