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:
parent
381eea0dbf
commit
d396612a7c
@ -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);
|
||||
|
||||
@ -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 != '')
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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">';
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user