Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop
This commit is contained in:
commit
aec4d6016c
@ -65,6 +65,7 @@ $search_filter = GETPOST("search_filter", 'alpha');
|
||||
$search_status = GETPOST("search_status", 'intcomma');
|
||||
$catid = GETPOST("catid", 'int');
|
||||
$optioncss = GETPOST('optioncss', 'alpha');
|
||||
$socid = GETPOST('socid', 'int');
|
||||
|
||||
$filter = GETPOST("filter", 'alpha');
|
||||
if ($filter) {
|
||||
|
||||
@ -57,10 +57,11 @@ class FormIntervention
|
||||
* @param int $selected Id intervention preselected
|
||||
* @param string $htmlname Nom de la zone html
|
||||
* @param int $maxlength Maximum length of label
|
||||
* @param int $showempty Show empty line
|
||||
* @param int $showempty Show empty line ('1' or string to show for empty line)
|
||||
* @param int $draftonly Show only drafts intervention
|
||||
* @return int Nbre of project if OK, <0 if KO
|
||||
*/
|
||||
public function select_interventions($socid = -1, $selected = '', $htmlname = 'interventionid', $maxlength = 16, $showempty = 1)
|
||||
public function select_interventions($socid = -1, $selected = '', $htmlname = 'interventionid', $maxlength = 16, $showempty = 1, $draftonly = false)
|
||||
{
|
||||
// phpcs:enable
|
||||
global $db, $user, $conf, $langs;
|
||||
@ -80,13 +81,17 @@ class FormIntervention
|
||||
$sql .= " AND f.fk_soc = ".((int) $socid);
|
||||
}
|
||||
}
|
||||
if ($draftonly) $sql .= " AND f.fk_statut = 0";
|
||||
|
||||
dol_syslog(get_class($this)."::select_intervention", LOG_DEBUG);
|
||||
$resql = $this->db->query($sql);
|
||||
if ($resql) {
|
||||
$out .= '<select id="interventionid" class="flat" name="'.dol_escape_htmltag($htmlname).'">';
|
||||
if ($showempty) {
|
||||
$out .= '<option value="0"> </option>';
|
||||
$out .= '<option value="0">';
|
||||
if (!is_numeric($showempty)) $out .= $showempty;
|
||||
else $out .= ' ';
|
||||
$out .= '</option>';
|
||||
}
|
||||
$num = $this->db->num_rows($resql);
|
||||
$i = 0;
|
||||
@ -102,7 +107,7 @@ class FormIntervention
|
||||
$out .= '<option value="'.$obj->rowid.'" selected>'.$labeltoshow.'</option>';
|
||||
} else {
|
||||
$disabled = 0;
|
||||
if (!$obj->fk_statut > 0) {
|
||||
if (!$obj->fk_statut > 0 && ! $draftonly) {
|
||||
$disabled = 1;
|
||||
$labeltoshow .= ' ('.$langs->trans("Draft").')';
|
||||
}
|
||||
|
||||
@ -202,7 +202,7 @@ $now = dol_now();
|
||||
|
||||
//$help_url="EN:Module_KnowledgeRecord|FR:Module_KnowledgeRecord_FR|ES:Módulo_KnowledgeRecord";
|
||||
$help_url = '';
|
||||
$title = $langs->trans('ListOfArticles');
|
||||
$title = $langs->trans('ListKnowledgeRecord');
|
||||
$morejs = array();
|
||||
$morecss = array();
|
||||
|
||||
|
||||
@ -66,3 +66,4 @@ RepeatableIntervention=Template of intervention
|
||||
ToCreateAPredefinedIntervention=To create a predefined or recurring intervention, create a common intervention and convert it into intervention template
|
||||
Reopen=Reopen
|
||||
ConfirmReopenIntervention=Are you sure you want to open back the intervention <b>%s</b>?
|
||||
GenerateInter=Generate intervention
|
||||
|
||||
@ -242,6 +242,7 @@ LatestModifiedProjects=Latest %s modified projects
|
||||
OtherFilteredTasks=Other filtered tasks
|
||||
NoAssignedTasks=No assigned tasks found (assign project/tasks to the current user from the top select box to enter time on it)
|
||||
ThirdPartyRequiredToGenerateInvoice=A third party must be defined on project to be able to invoice it.
|
||||
ThirdPartyRequiredToGenerateInvoice=A third party must be defined on project to be able to create intervention.
|
||||
ChooseANotYetAssignedTask=Choose a task not yet assigned to you
|
||||
# Comments trans
|
||||
AllowCommentOnTask=Allow user comments on tasks
|
||||
@ -253,10 +254,12 @@ SendProjectRef=Information project %s
|
||||
ModuleSalaryToDefineHourlyRateMustBeEnabled=Module 'Salaries' must be enabled to define employee hourly rate to have time spent valorized
|
||||
NewTaskRefSuggested=Task ref already used, a new task ref is required
|
||||
TimeSpentInvoiced=Time spent billed
|
||||
TimeSpentForIntervention=Time spent
|
||||
TimeSpentForInvoice=Time spent
|
||||
OneLinePerUser=One line per user
|
||||
ServiceToUseOnLines=Service to use on lines
|
||||
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.
|
||||
ProjectFollowOpportunity=Follow opportunity
|
||||
ProjectFollowTasks=Follow tasks or time spent
|
||||
@ -265,7 +268,9 @@ UsageOpportunity=Usage: Opportunity
|
||||
UsageTasks=Usage: Tasks
|
||||
UsageBillTimeShort=Usage: Bill time
|
||||
InvoiceToUse=Draft invoice to use
|
||||
InterToUse=Draft intervention to use
|
||||
NewInvoice=New invoice
|
||||
NewInter=New intervention
|
||||
OneLinePerTask=One line per task
|
||||
OneLinePerPeriod=One line per period
|
||||
OneLinePerTimeSpentLine=One line for each time spent declaration
|
||||
@ -275,4 +280,4 @@ AddPersonToTask=Add also to tasks
|
||||
UsageOrganizeEvent=Usage: Event Organization
|
||||
PROJECT_CLASSIFY_CLOSED_WHEN_ALL_TASKS_DONE=Classify project as closed when all its tasks are completed (100%% progress)
|
||||
PROJECT_CLASSIFY_CLOSED_WHEN_ALL_TASKS_DONE_help=Note: existing projects with all tasks at 100 %% progress won't be affected: you will have to close them manually. This option only affects open projects.
|
||||
SelectLinesOfTimeSpentToInvoice=Select lines of time spent that are unbilled, then bulk action "Generate Invoice" to bill them
|
||||
SelectLinesOfTimeSpentToInvoice=Select lines of time spent that are unbilled, then bulk action "Generate Invoice" to bill them
|
||||
|
||||
@ -64,3 +64,4 @@ InterLineDuration=Durée ligne intervention
|
||||
InterLineDesc=Description ligne intervention
|
||||
RepeatableIntervention=Modèle d'intervention
|
||||
ToCreateAPredefinedIntervention=Pour créer une intervention prédéfinie ou récurrente, créez une intervention standard et convertissez-la en modèle d'intervention
|
||||
GenerateInter=Générer une fiche d'intervention
|
||||
|
||||
@ -241,6 +241,7 @@ LatestModifiedProjects=Les %s derniers projets modifiés
|
||||
OtherFilteredTasks=Autres tâches filtrées
|
||||
NoAssignedTasks=Aucune tâche assignée (assignez un projet/tâche à l'utilisateur depuis la liste déroulante utilisateur en haut pour pouvoir saisir du temps dessus)
|
||||
ThirdPartyRequiredToGenerateInvoice=Un tiers doit être défini sur le projet pour pouvoir le facturer.
|
||||
ThirdPartyRequiredToGenerateIntervention=Un tiers doit être défini sur le projet pour pouvoir créer une intervention.
|
||||
ChooseANotYetAssignedTask=Choisissez une tâche qui ne vous est pas encore assignée
|
||||
# Comments trans
|
||||
AllowCommentOnTask=Autoriser les utilisateurs à ajouter des commentaires sur les tâches
|
||||
@ -253,18 +254,22 @@ ModuleSalaryToDefineHourlyRateMustBeEnabled=Le module 'Paiement des salaires des
|
||||
NewTaskRefSuggested=Réf de tâche déjà utilisée, une nouvelle référence de tâche est requise
|
||||
TimeSpentInvoiced=Temps passé facturé
|
||||
TimeSpentForInvoice=Temps consommés
|
||||
TimeSpentForIntervention=Temps consommés
|
||||
OneLinePerUser=Une ligne par utilisateur
|
||||
ServiceToUseOnLines=Service à utiliser sur les lignes
|
||||
InvoiceGeneratedFromTimeSpent=La facture %s a été générée à partir du temps passé sur le projet
|
||||
InterventionGeneratedFromTimeSpent=L'intervention %s a été générée à partir du temps passé sur le projet
|
||||
ProjectBillTimeDescription=Cochez si vous saisissez du temps sur les tâches du projet ET prévoyez de générer des factures à partir des temps pour facturer le client du projet (ne cochez pas si vous comptez créer une facture qui n'est pas basée sur la saisie des temps). Note: Pour générer une facture, aller sur l'onglet 'Temps consommé' du project et sélectionnez les lignes à inclure.
|
||||
ProjectFollowOpportunity=Suivre une opportunité
|
||||
ProjectFollowOpportunity=Suivre une opportunité
|
||||
ProjectFollowTasks=Suivre des tâches ou du temps passé
|
||||
Usage=Usage
|
||||
UsageOpportunity=Utilisation: Opportunité
|
||||
UsageTasks=Utilisation: Tâches
|
||||
UsageBillTimeShort=Utilisation: Facturation du temps
|
||||
InvoiceToUse=Facture brouillon à utiliser
|
||||
InterToUse=Intervention brouillon à utiliser
|
||||
NewInvoice=Nouvelle facture
|
||||
NewInter=Nouvelle intervention
|
||||
OneLinePerTask=Une ligne par tâche
|
||||
OneLinePerPeriod=Une ligne par période
|
||||
OneLinePerTimeSpentLine=One line for each time spent declaration
|
||||
|
||||
@ -354,10 +354,10 @@ if ((!empty($conf->product->enabled) || !empty($conf->service->enabled)) && ($us
|
||||
|
||||
|
||||
print '<tr class="oddeven">';
|
||||
print '<td class="nowrap">';
|
||||
print '<td class="nowraponall tdoverflowmax100">';
|
||||
print $product_static->getNomUrl(1, '', 16);
|
||||
print "</td>\n";
|
||||
print '<td>'.dol_trunc($objp->label, 32).'</td>';
|
||||
print '<td class="tdoverflowmax200" title="'.dol_escape_htmltag($objp->label).'">'.dol_escape_htmltag($objp->label).'</td>';
|
||||
print "<td>";
|
||||
print dol_print_date($db->jdate($objp->datem), 'day');
|
||||
print "</td>";
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
* Copyright (C) 2011 Juanjo Menent <jmenent@2byte.es>
|
||||
* Copyright (C) 2018 Ferran Marcet <fmarcet@2byte.es>
|
||||
* Copyright (C) 2018 Frédéric France <frederic.france@netlogic.fr>
|
||||
* Copyright (C) 2019 Christophe Battarel <christophe@altairis.fr>
|
||||
* Copyright (C) 2019-2021 Christophe Battarel <christophe@altairis.fr>
|
||||
*
|
||||
* 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
|
||||
@ -35,6 +35,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formintervention.class.php';
|
||||
|
||||
// Load translation files required by the page
|
||||
$langsLoad=array('projects', 'bills', 'orders');
|
||||
@ -115,7 +116,7 @@ $extrafields->fetch_name_optionals_label($object->table_element);
|
||||
if (GETPOST('cancel', 'alpha')) {
|
||||
$action = '';
|
||||
}
|
||||
if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend' && $massaction != 'confirm_generateinvoice') {
|
||||
if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend' && $massaction != 'confirm_generateinvoice' && $massaction != 'confirm_generateinter') {
|
||||
$massaction = '';
|
||||
}
|
||||
|
||||
@ -536,6 +537,81 @@ if ($action == 'confirm_generateinvoice') {
|
||||
}
|
||||
}
|
||||
|
||||
if ($action == 'confirm_generateinter') {
|
||||
$langs->load('interventions');
|
||||
|
||||
if (!empty($projectstatic->socid)) $projectstatic->fetch_thirdparty();
|
||||
|
||||
if (!($projectstatic->thirdparty->id > 0)) {
|
||||
setEventMessages($langs->trans("ThirdPartyRequiredToGenerateIntervention"), null, 'errors');
|
||||
} else {
|
||||
include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
|
||||
include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
|
||||
include_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
|
||||
|
||||
|
||||
require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php';
|
||||
$tmpinter = new Fichinter($db);
|
||||
$tmptimespent = new Task($db);
|
||||
$fuser = new User($db);
|
||||
|
||||
$db->begin();
|
||||
$interToUse = GETPOST('interid', 'int');
|
||||
|
||||
|
||||
$tmpinter->socid = $projectstatic->thirdparty->id;
|
||||
$tmpinter->date = dol_mktime(GETPOST('rehour', 'int'), GETPOST('remin', 'int'), GETPOST('resec', 'int'), GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int'));
|
||||
$tmpinter->fk_project = $projectstatic->id;
|
||||
$tmpinter->description = $projectstatic->title . ( ! empty($projectstatic->description) ? '-' . $projectstatic->label : '' );
|
||||
|
||||
if ($interToUse) {
|
||||
$tmpinter->fetch($interToUse);
|
||||
} else {
|
||||
$result = $tmpinter->create($user);
|
||||
if ($result <= 0) {
|
||||
$error++;
|
||||
setEventMessages($tmpinter->error, $tmpinter->errors, 'errors');
|
||||
}
|
||||
}
|
||||
|
||||
if (!$error) {
|
||||
$arrayoftasks = array();
|
||||
foreach ($toselect as $key => $value) {
|
||||
// Get userid, timepent
|
||||
$object->fetchTimeSpent($value);
|
||||
// $object->id is the task id
|
||||
$arrayoftasks[$object->timespent_id]['timespent'] = $object->timespent_duration;
|
||||
$arrayoftasks[$object->timespent_id]['totalvaluetodivideby3600'] = $object->timespent_duration * $object->timespent_thm;
|
||||
$arrayoftasks[$object->timespent_id]['note'] = $object->timespent_note;
|
||||
$arrayoftasks[$object->timespent_id]['date'] = date('Y-m-d H:i:s', $object->timespent_datehour);
|
||||
}
|
||||
|
||||
foreach ($arrayoftasks as $timespent_id => $value) {
|
||||
$ftask = new Task($db);
|
||||
$ftask->fetch($object->id);
|
||||
// Define qty per hour
|
||||
$qtyhour = $value['timespent'] / 3600;
|
||||
$qtyhourtext = convertSecondToTime($value['timespent'], 'all', $conf->global->MAIN_DURATION_OF_WORKDAY);
|
||||
|
||||
// Add lines
|
||||
$lineid = $tmpinter->addline($user, $tmpinter->id, $ftask->label . ( ! empty($value['note']) ? ' - ' . $value['note'] : '' ), $value['date'], $value['timespent']);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$error) {
|
||||
$urltointer = $tmpinter->getNomUrl(0);
|
||||
$mesg = $langs->trans("InterventionGeneratedFromTimeSpent", '{s1}');
|
||||
$mesg = str_replace('{s1}', $urltointer, $mesg);
|
||||
setEventMessages($mesg, null, 'mesgs');
|
||||
|
||||
//var_dump($tmpinvoice);
|
||||
|
||||
$db->commit();
|
||||
} else {
|
||||
$db->rollback();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* View
|
||||
@ -749,12 +825,16 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0) {
|
||||
'generateinvoice'=>$langs->trans("GenerateBill"),
|
||||
//'builddoc'=>$langs->trans("PDFMerge"),
|
||||
);
|
||||
//if ($user->rights->projet->creer) $arrayofmassactions['predelete']='<span class="fa fa-trash paddingrightonly"></span>'.$langs->trans("Delete");
|
||||
if (in_array($massaction, array('presend', 'predelete', 'generateinvoice'))) {
|
||||
$arrayofmassactions = array();
|
||||
}
|
||||
$massactionbutton = $form->selectMassAction('', $arrayofmassactions);
|
||||
}
|
||||
if ( ! empty($conf->ficheinter->enabled) && $user->rights->ficheinter->creer) {
|
||||
$langs->load("interventions");
|
||||
$arrayofmassactions['generateinter'] = $langs->trans("GenerateInter");
|
||||
}
|
||||
//if ($user->rights->projet->creer) $arrayofmassactions['predelete']='<span class="fa fa-trash paddingrightonly"></span>'.$langs->trans("Delete");
|
||||
if (in_array($massaction, array('presend', 'predelete', 'generateinvoice', 'generateinter'))) {
|
||||
$arrayofmassactions = array();
|
||||
}
|
||||
$massactionbutton = $form->selectMassAction('', $arrayofmassactions);
|
||||
|
||||
// Show section with information of task. If id of task is not defined and project id defined, then $projectidforalltimes is not empty.
|
||||
if (empty($projectidforalltimes)) {
|
||||
@ -944,6 +1024,8 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0) {
|
||||
print '<input type="hidden" name="action" value="addtimespent">';
|
||||
} elseif ($massaction == 'generateinvoice' && $user->rights->facture->lire) {
|
||||
print '<input type="hidden" name="action" value="confirm_generateinvoice">';
|
||||
} elseif ($massaction == 'generateinter' && $user->rights->ficheinter->lire) {
|
||||
print '<input type="hidden" name="action" value="confirm_generateinter">';
|
||||
} else {
|
||||
print '<input type="hidden" name="action" value="list">';
|
||||
}
|
||||
@ -1026,6 +1108,36 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0) {
|
||||
print '</div>';
|
||||
$massaction = '';
|
||||
}
|
||||
} elseif ($massaction == 'generateinter') {
|
||||
// Form to convert time spent into invoice
|
||||
print '<input type="hidden" name="massaction" value="confirm_createinter">';
|
||||
|
||||
if ($projectstatic->thirdparty->id > 0) {
|
||||
print '<table class="noborder" width="100%" >';
|
||||
print '<tr>';
|
||||
print '<td class="titlefield">';
|
||||
print $langs->trans('InterToUse');
|
||||
print '</td>';
|
||||
print '<td>';
|
||||
$forminter = new FormIntervention($db);
|
||||
print $forminter->select_interventions($projectstatic->thirdparty->id, '', 'interid', 24, $langs->trans('NewInter'), true);
|
||||
print '</td>';
|
||||
print '</tr>';
|
||||
print '</table>';
|
||||
|
||||
print '<br>';
|
||||
print '<div class="center">';
|
||||
print '<input type="submit" class="button" id="createinter" name="createinter" value="'.$langs->trans('GenerateInter').'"> ';
|
||||
print '<input type="submit" class="button" id="cancel" name="cancel" value="'.$langs->trans('Cancel').'">';
|
||||
print '</div>';
|
||||
print '<br>';
|
||||
} else {
|
||||
print '<div class="warning">'.$langs->trans("ThirdPartyRequiredToGenerateIntervention").'</div>';
|
||||
print '<div class="center">';
|
||||
print '<input type="submit" class="button" id="cancel" name="cancel" value="'.$langs->trans('Cancel').'">';
|
||||
print '</div>';
|
||||
$massaction = '';
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@ -185,6 +185,7 @@ $thirdpartygraph .= '</td></tr>';
|
||||
$thirdpartygraph .= '</table>';
|
||||
$thirdpartygraph .= '</div>';
|
||||
|
||||
$thirdpartycateggraph = '';
|
||||
if (!empty($conf->categorie->enabled) && !empty($conf->global->CATEGORY_GRAPHSTATS_ON_THIRDPARTIES)) {
|
||||
require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
|
||||
$elementtype = 'societe';
|
||||
|
||||
Loading…
Reference in New Issue
Block a user