finish invoice per product per line
This commit is contained in:
parent
c951e681c2
commit
902301659b
@ -3500,6 +3500,7 @@ class Facture extends CommonInvoice
|
||||
return -2;
|
||||
}
|
||||
} else {
|
||||
$this->errors[]='status of invoice must be Draft to allow use of ->addline()';
|
||||
dol_syslog(get_class($this)."::addline status of invoice must be Draft to allow use of ->addline()", LOG_ERR);
|
||||
return -3;
|
||||
}
|
||||
|
||||
@ -259,7 +259,7 @@ TimeSpentInvoiced=Time spent billed
|
||||
TimeSpentForIntervention=Time spent
|
||||
TimeSpentForInvoice=Time spent
|
||||
OneLinePerUser=One line per user
|
||||
ServiceToUseOnLines=Service to use on lines
|
||||
ServiceToUseOnLines=Service to use on lines by default
|
||||
InvoiceGeneratedFromTimeSpent=Invoice %s has been generated from time spent on project
|
||||
InterventionGeneratedFromTimeSpent=Intervention %s has been generated from time spent on project
|
||||
ProjectBillTimeDescription=Check if you enter timesheet on tasks of project AND you plan to generate invoice(s) from the timesheet to bill the customer of the project (do not check if you plan to create invoice that is not based on entered timesheets). Note: To generate invoice, go on tab 'Time spent' of the project and select lines to include.
|
||||
@ -276,6 +276,7 @@ NewInter=New intervention
|
||||
OneLinePerTask=One line per task
|
||||
OneLinePerPeriod=One line per period
|
||||
OneLinePerTimeSpentLine=One line for each time spent declaration
|
||||
OneLinePerTimeSpentLineProduct=One line for each time spent declaration with product defined
|
||||
AddDetailDateAndDuration=With date and duration into line description
|
||||
RefTaskParent=Ref. Parent Task
|
||||
ProfitIsCalculatedWith=Profit is calculated using
|
||||
|
||||
@ -6058,6 +6058,43 @@ class Product extends CommonObject
|
||||
dol_print_error($this->db);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the duration in Hours of a service base on duration fields
|
||||
* @return int -1 KO, >= 0 is the duration in hours
|
||||
*/
|
||||
public function getProductDurationHours()
|
||||
{
|
||||
global $langs;
|
||||
|
||||
if (empty($this->duration_value)) {
|
||||
$this->errors[]='ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice';
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ($this->duration_unit == 'i') {
|
||||
$prodDurationHours = 1. / 60;
|
||||
}
|
||||
if ($this->duration_unit == 'h') {
|
||||
$prodDurationHours = 1.;
|
||||
}
|
||||
if ($this->duration_unit == 'd') {
|
||||
$prodDurationHours = 24.;
|
||||
}
|
||||
if ($this->duration_unit == 'w') {
|
||||
$prodDurationHours = 24. * 7;
|
||||
}
|
||||
if ($this->duration_unit == 'm') {
|
||||
$prodDurationHours = 24. * 30;
|
||||
}
|
||||
if ($this->duration_unit == 'y') {
|
||||
$prodDurationHours = 24. * 365;
|
||||
}
|
||||
$prodDurationHours *= $this->duration_value;
|
||||
|
||||
return $prodDurationHours;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -392,36 +392,21 @@ if ($action == 'confirm_generateinvoice') {
|
||||
$generateinvoicemode = GETPOST('generateinvoicemode', 'string');
|
||||
$invoiceToUse = GETPOST('invoiceid', 'int');
|
||||
|
||||
$prodDurationHours = 1.0;
|
||||
$prodDurationHoursBase = 1.0;
|
||||
if ($idprod > 0) {
|
||||
$tmpproduct->fetch($idprod);
|
||||
if ($result<0) {
|
||||
$error++;
|
||||
setEventMessages($tmpproduct->error, $tmpproduct->errors, 'errors');
|
||||
}
|
||||
|
||||
if (empty($tmpproduct->duration_value)) {
|
||||
$prodDurationHoursBase=$tmpproduct->getProductDurationHours();
|
||||
if ($prodDurationHoursBase<0) {
|
||||
$error++;
|
||||
$langs->load("errors");
|
||||
setEventMessages($langs->trans("ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice"), null, 'errors');
|
||||
setEventMessages(null, $tmpproduct->errors, 'errors');
|
||||
}
|
||||
|
||||
if ($tmpproduct->duration_unit == 'i') {
|
||||
$prodDurationHours = 1. / 60;
|
||||
}
|
||||
if ($tmpproduct->duration_unit == 'h') {
|
||||
$prodDurationHours = 1.;
|
||||
}
|
||||
if ($tmpproduct->duration_unit == 'd') {
|
||||
$prodDurationHours = 24.;
|
||||
}
|
||||
if ($tmpproduct->duration_unit == 'w') {
|
||||
$prodDurationHours = 24. * 7;
|
||||
}
|
||||
if ($tmpproduct->duration_unit == 'm') {
|
||||
$prodDurationHours = 24. * 30;
|
||||
}
|
||||
if ($tmpproduct->duration_unit == 'y') {
|
||||
$prodDurationHours = 24. * 365;
|
||||
}
|
||||
$prodDurationHours *= $tmpproduct->duration_value;
|
||||
|
||||
$dataforprice = $tmpproduct->getSellPrice($mysoc, $projectstatic->thirdparty, 0);
|
||||
|
||||
$pu_ht = empty($dataforprice['pu_ht']) ? 0 : $dataforprice['pu_ht'];
|
||||
@ -429,7 +414,7 @@ if ($action == 'confirm_generateinvoice') {
|
||||
$localtax1 = $dataforprice['localtax1'];
|
||||
$localtax2 = $dataforprice['localtax2'];
|
||||
} else {
|
||||
$prodDurationHours = 1;
|
||||
$prodDurationHoursBase = 1;
|
||||
|
||||
$pu_ht = 0;
|
||||
$txtva = get_default_tva($mysoc, $projectstatic->thirdparty);
|
||||
@ -476,7 +461,7 @@ if ($action == 'confirm_generateinvoice') {
|
||||
}
|
||||
|
||||
// Add lines
|
||||
$lineid = $tmpinvoice->addline($langs->trans("TimeSpentForInvoice", $username).' : '.$qtyhourtext, $pu_ht, round($qtyhour / $prodDurationHours, 2), $txtva, $localtax1, $localtax2, ($idprod > 0 ? $idprod : 0));
|
||||
$lineid = $tmpinvoice->addline($langs->trans("TimeSpentForInvoice", $username).' : '.$qtyhourtext, $pu_ht, round($qtyhour / $prodDurationHoursBase, 2), $txtva, $localtax1, $localtax2, ($idprod > 0 ? $idprod : 0));
|
||||
|
||||
// Update lineid into line of timespent
|
||||
$sql = 'UPDATE '.MAIN_DB_PREFIX.'projet_task_time SET invoice_line_id = '.((int) $lineid).', invoice_id = '.((int) $tmpinvoice->id);
|
||||
@ -488,8 +473,9 @@ if ($action == 'confirm_generateinvoice') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} elseif ($generateinvoicemode == 'onelineperperiod') { // One line for each time spent line
|
||||
} elseif ($generateinvoicemode == 'onelineperperiod' || $generateinvoicemode == 'onelineperperiodproduct') { // One line for each time spent line
|
||||
$arrayoftasks = array();
|
||||
$product_data_cache = array();
|
||||
$withdetail=GETPOST('detail_time_duration', 'alpha');
|
||||
foreach ($toselect as $key => $value) {
|
||||
// Get userid, timepent
|
||||
@ -519,6 +505,7 @@ if ($action == 'confirm_generateinvoice') {
|
||||
$arrayoftasks[$object->timespent_id]['note'] .= ' - '.$langs->trans("Duration").': '.convertSecondToTime($object->timespent_duration, 'all', $conf->global->MAIN_DURATION_OF_WORKDAY);
|
||||
}
|
||||
$arrayoftasks[$object->timespent_id]['user'] = $object->timespent_fk_user;
|
||||
$arrayoftasks[$object->timespent_id]['fk_product'] = $object->timespent_fk_product;
|
||||
}
|
||||
|
||||
foreach ($arrayoftasks as $timespent_id => $value) {
|
||||
@ -534,7 +521,50 @@ if ($action == 'confirm_generateinvoice') {
|
||||
}
|
||||
|
||||
// Add lines
|
||||
$lineid = $tmpinvoice->addline($value['note'], $pu_ht, round($qtyhour / $prodDurationHours, 2), $txtva, $localtax1, $localtax2, ($idprod > 0 ? $idprod : 0));
|
||||
$prodDurationHours = $prodDurationHoursBase;
|
||||
$idprodline=$idprod;
|
||||
$pu_htline = $pu_ht;
|
||||
$txtvaline = $txtva;
|
||||
$localtax1line = $localtax1;
|
||||
$localtax2line = $localtax2;
|
||||
|
||||
|
||||
if ($generateinvoicemode == 'onelineperperiodproduct' && !empty($value['fk_product']) && $value['fk_product']!==$idprod) {
|
||||
if (!array_key_exists($value['fk_product'], $product_data_cache)) {
|
||||
$result = $tmpproduct->fetch($value['fk_product']);
|
||||
if ($result < 0) {
|
||||
$error++;
|
||||
setEventMessages($tmpproduct->error, $tmpproduct->errors, 'errors');
|
||||
}
|
||||
$prodDurationHours = $tmpproduct->getProductDurationHours();
|
||||
if ($prodDurationHours < 0) {
|
||||
$error++;
|
||||
$langs->load("errors");
|
||||
setEventMessages(null, $tmpproduct->errors, 'errors');
|
||||
}
|
||||
|
||||
$dataforprice = $tmpproduct->getSellPrice($mysoc, $projectstatic->thirdparty, 0);
|
||||
|
||||
$pu_htline = empty($dataforprice['pu_ht']) ? 0 : $dataforprice['pu_ht'];
|
||||
$txtvaline = $dataforprice['tva_tx'];
|
||||
$localtax1line = $dataforprice['localtax1'];
|
||||
$localtax2line = $dataforprice['localtax2'];
|
||||
|
||||
$product_data_cache[$value['fk_product']] = array('duration'=>$prodDurationHours,'dataforprice'=>$dataforprice);
|
||||
} else {
|
||||
$prodDurationHours = $product_data_cache[$value['fk_product']]['duration'];
|
||||
$pu_htline = empty($product_data_cache[$value['fk_product']]['dataforprice']['pu_ht']) ? 0 : $product_data_cache[$value['fk_product']]['dataforprice']['pu_ht'];
|
||||
$txtvaline = $product_data_cache[$value['fk_product']]['dataforprice']['tva_tx'];
|
||||
$localtax1line = $product_data_cache[$value['fk_product']]['dataforprice']['localtax1'];
|
||||
$localtax2line = $product_data_cache[$value['fk_product']]['dataforprice']['localtax2'];
|
||||
}
|
||||
$idprodline=$value['fk_product'];
|
||||
}
|
||||
$lineid = $tmpinvoice->addline($value['note'], $pu_htline, round($qtyhour / $prodDurationHours, 2), $txtvaline, $localtax1line, $localtax2line, ($idprodline > 0 ? $idprodline : 0));
|
||||
if ($lineid<0) {
|
||||
$error++;
|
||||
setEventMessages(null, $tmpinvoice->errors, 'errors');
|
||||
}
|
||||
//var_dump($lineid);exit;
|
||||
|
||||
// Update lineid into line of timespent
|
||||
@ -1178,6 +1208,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser
|
||||
'onelineperuser'=>'OneLinePerUser',
|
||||
'onelinepertask'=>'OneLinePerTask',
|
||||
'onelineperperiod'=>'OneLinePerTimeSpentLine',
|
||||
'onelineperperiodproduct'=>'OneLinePerTimeSpentLineProduct',
|
||||
);
|
||||
print $form->selectarray('generateinvoicemode', $tmparray, 'onelineperuser', 0, 0, 0, '', 1);
|
||||
print "\n".'<script type="text/javascript">';
|
||||
@ -1834,7 +1865,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser
|
||||
|
||||
//Product
|
||||
if (!empty($arrayfields['t.fk_product']['checked'])) {
|
||||
print '<td class="nowraponall right">';
|
||||
print '<td class="nowraponall">';
|
||||
if ($action == 'editline' && $_GET['lineid'] == $task_time->rowid) {
|
||||
$form->select_produits($task_time->fk_product, 'fk_product', '1', 0, $projectstatic->thirdparty->price_level, 1, 2, '', 0, array(), $projectstatic->thirdparty->id, 'None', 0, 'maxwidth500');
|
||||
} elseif (!empty($task_time->fk_product)) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user