Bonjour Pierre,
Voici une proposition, Ă©tape par Ă©tape.
J’espère que ça complètera la documentation!
Rapport de requĂŞte (SQL):
-
On crée un nouveau rapport, de type Rapport de Requête avec un joli nom.
Je choisi un document de référence, qui permettra de placer le rapport dans le module correspondant à ce document et de conditionner les autorisations associées à ce rapport (modifiables dans les Autorisations du rôle pour la page et le rapport)
-
On souhaite obtenir les pointages liés au projet associé à une facture. Il faut donc qu’on puisse filtrer nos données soit par projet, soit par facture.
Je décide d’ajouter un filtre permettant de sélectionner une facture de vente:
Mon filtre est un champ de type Lien, qui permet de récupérer tous les documents liés. J’indique Sales Invoice dans les options pour faire cette liaison.
Le nom du filtre peut ĂŞtre celui que je veux. Il me servira de variable dans ma requĂŞte.
- J’ajoute des colonnes pour les données que je souhaite obtenir:
Les noms des champs peuvent être ce que vous voulez. Il faudra juste formatter la requête pour renvoyer une donnée avec le même nom.
Ici j’ai mis Lien pour le champ employee et Employee dans la case Options pour que ça fasse un lien vers la fiche Employé lors de la génération du rapport.
- J’écris ma requête:
SELECT DATE_FORMAT(td.from_time, '%%Y-%%m-%%d') as workday,
e.employee_name, e.designation,
td.hours as working_time
FROM `tabSales Invoice` si
LEFT JOIN `tabTimesheet Detail` td
ON td.project = si.project
RIGHT JOIN `tabTimesheet` t
ON td.parent = t.name
LEFT JOIN `tabEmployee` e
ON e.name = t.employee
WHERE si.name = %(sales_invoice)s
- Je cherche Ă obtenir les champs
from_time
et hours
depuis la table Timesheet Details
(la table enfant du type de document Feuille de temps), designation
et employee_name
(car employee dans la table Timesheet
ne donne que son identifiant) depuis la table employee
- Je vais donc requêter d’abord la table
Sales Invoice
pour récupérer le champ project
me permettant d’obtenir toutes les lignes liées à ce projet dans la table Timesheet Details
.
- Puis je récupère l’identifiant de l’employé correspondant depuis la table
Timesheet
grâce au champ parent
disponible dans toutes les tables enfant.
- Je récupère les champs
employee_name
et designation
dans la fiche Employé de cet employé
- Enfin, je filtre cette requête sur la facture sélectionnée dans mon filtre
Rapport de script (Python)
L’équivalent en Python.
Il faudrait optimiser le script en ne faisant qu’une seule requête pour les employés, sinon le résultat est le même qu’au dessus.
project = frappe.db.get_value("Sales Invoice", filters.sales_invoice, "project")
timesheet_details = frappe.get_all("Timesheet Detail", filters={"project": project}, fields=["name", "parent", "hours", "from_time"])
result = []
for timesheet_detail in timesheet_details:
employee_id = frappe.db.get_value("Timesheet", timesheet_detail.parent, "employee")
employee = frappe.db.get_value("Employee", employee_id, ["employee_name", "designation"], as_dict=True)
result.append(
{
"workday": frappe.utils.getdate(timesheet_detail.from_time),
"employee": employee.employee_name,
"designation": employee.designation,
"working_time": timesheet_detail.hours
}
)
Voici aussi un exemple d’ajout de tableau directement dans la facture, via un champ HTML personnalisé et un script en Jinja:
<div>
<table class="table table-bordered table-condensed">
<thead>
<tr>
<th>Jour de travail</th>
<th>Nom de la personne</th>
<th>Poste</th>
<th>Nombre d'heures passées dans la journée</th>
</tr>
</thead>
<tbody>
<tr>
{% for td in frappe.get_all("Timesheet Detail", filters={"project": doc.project}, fields=["name", "parent", "hours", "from_time"]) %}
{% set employee_id = frappe.db.get_value("Timesheet", td.parent, "employee") %}
{% set employee = frappe.db.get_value("Employee", employee_id, ["employee_name", "designation"], as_dict=True) %}
<td>
<div class="value">{{ frappe.utils.format_date(td.from_time) }}</div>
</td>
<td>
<div class="value">{{ employee.employee_name or "" }}</div>
</td>
<td>
<div class="value">{{ employee.designation or "" }}</div>
</td>
<td>
<div class="value">{{ td.hours }}</div>
</td>
{% endfor %}
</tr>
</tbody>
</table>
</div>
Voici ce que ça donne:
Bon week-end !