Loading doc/connectors.md +42 −8 Changes for doc/connectors.md: 42 added lines, 8 removed lines. Original line number Diff line number Diff line Loading @@ -174,16 +174,50 @@ Pour l'URL "liste", le service REST doit retourner un tableau composé d'objets ```JSON [ { "uid": "person1", "login": "etc..." }, { "uid": "person2", "login": "etc..." "uid": "p1001", "login": "alberteinstein", "firstname": "Albert", "lastname": "Einstein", "displayname": "Albert Einstein", "mail": "albert.einstein@univ-berne.com", "civilite": "", "preferedlanguage": "", "status": "", "affectation": "", "structure": "", "inm": "", "phone": "", "birthday": "", "datefininscription": "", "datecreated": "", "dateupdated": "1905-07-04", "datecached": "2020-07-04", "address": null, "groups": [], "roles": {} }, { "uid": "person3", "login": "etc..." "uid": "p1002", "login": "maxplank", "firstname": "Max", "lastname": "Plank", "displayname": "Max Plank", "mail": "max.plank@univ-berlin.com", "civilite": "", "preferedlanguage": "", "status": "", "affectation": "", "structure": "", "inm": "", "phone": "", "birthday": "", "datefininscription": "", "datecreated": "", "dateupdated": "1905-07-04", "datecached": "2020-07-04", "address": null, "groups": [], "roles": {} } ] ``` Loading front/src/ActivityTimesheetSynthesisMenu.vue +370 −18 Changes for front/src/ActivityTimesheetSynthesisMenu.vue: 370 added lines, 18 removed lines. Original line number Diff line number Diff line <template> <div> <div class="overlay" v-if="open"> <button class="btn btn-primary" @click="handlerOpenSynthesis()" :class="{'disabled': loading}"> <i class="icon-spinner animate-spin" v-if="loading"></i> <i class="icon-calendar" v-else></i> Synthèse des déclarations </button> <div class="overlay-content"> <a href="#" class="overlay-closer" @click="handlerCloseSynthesis()">Close</a> OPTIONS ICI <div v-if="synthese" class="activity-timesheet-synthesis"> <nav class="text-center"> <button v-for="p, person_id in persons" class="btn" :class="filterPersons.indexOf(parseInt(person_id)) < 0 ? 'btn-primary' : 'btn-default'" @click="handlerTooglePerson(person_id)"> {{ p }} </button> </nav> <section v-for="y in sortedDatas.years" class="year" :class="{'open': y.open }"> <h3 class="line" @click="handlerOpenYear(y)"> <strong> <i class="icon-angle-right" v-show="!y.open"></i> <i class="icon-angle-down" v-show="y.open"></i> {{ y.label }} </strong> <em class="total" v-show="!y.open">{{ y.totalmain | hours }}</em> </h3> <section v-for="p in y.periods" class="month" v-show="y.open" :class="{'open': y.open }"> <h4 class="line" @click="handlerOpenPeriod(p)"> <strong> <i class="icon-angle-right" v-show="!p.open"></i> <i class="icon-angle-down" v-show="p.open"></i> {{ p.label }} </strong> <em class="total" v-show="!p.open">{{ p.totalmain | hours }}</em> </h4> <section v-for="pers in p.persons" class="person" v-show="p.open" :class="{'open': p.open }" @click="handlerOpenPerson(pers)"> <h5 class="line"> <strong>{{ pers.label }}</strong> <em class="total">{{ pers.totalmain | hours }}</em> </h5> <section class="details-person" v-if="pers.open"> <article class="line"> <strong> <i class="icon-cube"></i> {{ mainContext }} </strong> <em> {{ pers.totalmain | hours }} </em> </article> <section class="othersprojects" v-if="pers.othersprojects.total > 0"> <article v-for="projectDuration, projectName in pers.othersprojects.projects" class="line"> <strong> <i class="icon-cube"></i> {{ projectName }} </strong> <em style="font-weight: 800"> {{ projectDuration | hours }} </em> </article> </section> <section class="othersprojects" v-if="pers.others.total > 0"> <article v-for="otherDuration, otherName in pers.others.context" class="line"> <strong> {{ otherName | contextLabel }} </strong> <em> {{ otherDuration | hours }} </em> </article> </section> <article class="line totalline"> <strong> Total pour cette période : </strong> <em> {{ pers.total | hours }} </em> </article> </section> </section> <section class="person" v-show="p.open"> <h5 class="line totalline"> <strong>Total pour la période {{ p.label }}</strong> <em class="total">{{ p.totalmain | hours }}</em> </h5> </section> </section> <section class="person" v-show="y.open"> <h5 class="line totalline"> <strong>Total pour {{ y.label }}</strong> <em class="total">{{ y.totalmain | hours }}</em> </h5> </section> </section> </div> </div> <pre>{{ url }}</pre> <button class="btn btn-primary" @click="handlerOpenSynthesis()"> <i class="icon-calendar"></i> Synthèse des déclarations </button> <div class="overlay" v-if="open"> </div> </div> </template> <script> Loading @@ -28,15 +124,25 @@ node node_modules/.bin/gulp activityTimesheetSynthesisMenu */ // import AjaxOscar from "./remote/AjaxOscar"; // import OscarRemoteData from "./remote/OscarRemoteData"; let periodStr = function (year, month) { return year + '-' + (month < 10 ? '0' + month : month); }; // test export default { let months = ["", "Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Aout", "Septembre", "Octobre", "Novembre", "Décembre"]; let periodFullStr = function (year, month) { return months[month] + ' ' + year; }; // components: { // "ajax-oscar": AjaxOscar // }, let contextsLabels = { 'research' : "Autres recherches", 'conges' : "Congès", 'training' : "Formation", 'sickleave' : "Arrêt maladie", 'other' : "Autre activité" }; export default { props: { url: {require: true} Loading @@ -46,33 +152,279 @@ export default { return { configuration: null, open: false, synthese: null // Donnèes brutes synthese: null, structuredDatas: {}, // Filtres filterPersons: [], // Donnèes calculées au fetch mainContext: null, // Projet référent mainContextId: null, // Projet référent contexts: null, // Autres contextes periods: null, // Liste des périodes persons: null, // Liste des déclarants years: null, // Années // openYear: [], openPeriod: [], openPerson: [], } }, filters: { hours(str) { let t = parseFloat(str); let rnd = Math.round(t * 100); return (rnd / 100).toFixed(2); }, contextLabel(contextKey){ if( contextsLabels.hasOwnProperty(contextKey) ){ return contextsLabels[contextKey]; } return contextKey+"*"; } }, computed: { byDate() { let bydate = {}; }, sortedDatas() { // Structure racine let out = { "totaux": { "all": 0.0, "totalmain": 0.0, "othersprojects": { "projects": {}, "total": 0.0 }, "others": { "context": {}, "total": 0.0 }, }, "years": {}, }; // Annèes this.years.forEach(year => { out.years[year] = { "key": year, "label": year, "totalmain": 0.0, "open": this.openYear.indexOf(year) >= 0, "periods": {} } }); // this.periods.forEach(period => { let year = period.substring(0, 4); let month = period.substring(5, 7); out.years[year].periods[period] = { "key": period, "label": periodFullStr(year, parseInt(month)), "totalmain": 0.0, "persons": {}, "open": this.openPeriod.indexOf(period) >= 0, } }); this.synthese.synthesis.forEach(d => { let period = d.period; let year = parseInt(d.period.substring(0, 4)); let month = parseInt(d.period.substring(5, 7)); let person_id = d.person_id; let person = d.displayname; let context = d.context; let activity_id = d.activity_id; let type = d.type; let duration = parseFloat(d.duration); if (this.filterPersons.indexOf(person_id) >= 0) { return; } if (!out.years[year].periods[period].persons.hasOwnProperty(person_id)) { let indexOpen = year+"-"+period+"-"+person_id; out.years[year].periods[period].persons[person_id] = { "key": person_id, "label": person, "indexOpen": indexOpen, "open": this.openPerson.indexOf(indexOpen) >= 0, "totalmain": 0.0, "total": 0.0, "othersprojects": { "projects": {}, "total": 0.0 }, "others": { "context": {}, "total": 0.0 }, } } // --- Comptabilisé pour le projet principal if (activity_id == this.mainContextId) { out.totaux.totalmain += duration; out.years[year].totalmain += duration; out.years[year].periods[period].totalmain += duration; out.years[year].periods[period].persons[person_id].totalmain += duration; } // --- Comptabilisé pour les autres projets else if (type == "wp") { out.years[year].periods[period].persons[person_id].othersprojects.total += duration; // if (!out.years[year].periods[period].persons[person_id].othersprojects.projects.hasOwnProperty(context)) { out.years[year].periods[period].persons[person_id].othersprojects.projects[context] = 0.0; } out.years[year].periods[period].persons[person_id].othersprojects.projects[context] += duration; let project = context; if (!out.totaux.othersprojects.projects.hasOwnProperty(project)) { out.totaux.othersprojects.projects[project] = 0.0; } out.totaux.othersprojects.projects[project] += duration; out.totaux.othersprojects.total += duration; } // --- Autre (Congès, enseignement, etc...) else { out.years[year].periods[period].persons[person_id].others.total += duration; if (!out.years[year].periods[period].persons[person_id].others.context.hasOwnProperty(context)) { out.years[year].periods[period].persons[person_id].others.context[context] = 0.0; } out.years[year].periods[period].persons[person_id].others.context[context] += duration; } out.years[year].periods[period].persons[person_id].total += duration; out.totaux.all += duration; }); return out; } }, methods: { handlerTooglePerson(id) { let personId = parseInt(id); let indexId = this.filterPersons.indexOf(personId); if (indexId < 0) { this.filterPersons.push(personId); } else { this.filterPersons.splice(indexId, 1); } }, handlerOpenPerson(person) { console.log(person); let indexId = this.openPerson.indexOf(person.indexOpen); if (indexId < 0) { this.openPerson.push(person.indexOpen); } else { this.openPerson.splice(indexId, 1); } }, handlerOpenYear(year) { let i = this.openYear.indexOf(year.key); if (i < 0) { this.openYear.push(year.key); } else { this.openYear.splice(i, 1); } }, handlerOpenPeriod(period) { console.log(period.key, this.openPeriod); let i = this.openPeriod.indexOf(period.key); if (i < 0) { this.openPeriod.push(period.key); } else { this.openPeriod.splice(i, 1); } }, handlerOpenSynthesis() { this.open = true; this.loadSynthesis(); }, handlerCloseSynthesis() { this.open = false; console.log("CLOSE Synthesis"); console.log("CLOSE Synthesis 'update'"); }, buildStructuredDatas() { // @deprecated }, buildSynthese(datas) { // TODO Tester les dates de début/fin // ... this.mainContext = datas.acronym; this.mainContextId = datas.activity_id; // Constuction de la liste des périodes let fromYear = parseInt(datas.start.substring(0, 4)); let toYear = parseInt(datas.end.substring(0, 4)); let fromMonth = parseInt(datas.start.substring(5, 7)); let toMonth = parseInt(datas.end.substring(5, 7)); let periods = []; let years = []; let j = fromMonth; for (let i = fromYear; i <= toYear; i++) { years.push(i); for (; j <= 12 || (j <= toMonth && i == toYear); j++) { periods.push(periodStr(i, j)); } j = 1; } let persons = {}; let contexts = []; datas.synthesis.forEach(e => { if (!persons.hasOwnProperty(e.person_id)) { persons[e.person_id] = e.displayname; } if (contexts.indexOf(e.context) < 0 && e.activity_id != this.mainContextId) { contexts.push(e.context) } }); this.periods = periods; this.contexts = contexts; this.persons = persons; this.years = years; }, loadSynthesis() { this.loading = "Chargement de la synthèse..."; this.$http.get(this.url).then( ok => { console.log(ok); this.synthese = ok.body; this.buildSynthese(ok.body); }, ko => { } ) ).then(foo => { this.loading = false; }) } }, mounted() { console.log("ActivityTimesheetSynthesisMenu.vue") console.log("ActivityTimesheetSynthesisMenu.vue"); this.loadSynthesis(); } } Loading module/Oscar/Module.php +0 −1 Changes for module/Oscar/Module.php: 0 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -48,7 +48,6 @@ class Module public function init(ModuleManager $manager) { $sharedEventManager = $manager->getEventManager()->getSharedManager(); $sharedEventManager->attach('*', 'authentification.ldap.fail', [$this, 'onLdapError'], 100); } public function onLdapError(Event $event) Loading module/Oscar/src/Oscar/Controller/TimesheetController.php +15 −0 Changes for module/Oscar/src/Oscar/Controller/TimesheetController.php: 15 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ use Oscar\Formatter\TimesheetActivityPeriodHtmlFormatter; use Oscar\Formatter\TimesheetActivityPeriodPdfFormatter; use Oscar\Formatter\TimesheetPersonPeriodHtmlFormatter; use Oscar\Formatter\TimesheetPersonPeriodPdfFormatter; use Oscar\OscarVersion; use Oscar\Provider\Privileges; use Oscar\Service\PersonService; use Oscar\Service\ProjectGrantService; Loading Loading @@ -662,6 +663,7 @@ class TimesheetController extends AbstractOscarController $person_id = $this->params()->fromQuery('person_id', null); $format = $this->params()->fromQuery('format', ''); $period = $this->params()->fromQuery('period', null); $version = $this->params()->fromQuery('v', 1); $error = null; $validations = null; Loading Loading @@ -804,6 +806,19 @@ class TimesheetController extends AbstractOscarController } if( $format == "json" || $this->isAjax() ){ if( $version == "2" ){ $json = [ 'date' => date("Y-m-d H:i:s"), 'version' => OscarVersion::getBuild(), 'activity_id' => $activity->getId(), 'acronym' => $activity->getAcronym(), 'label' => $activity->getLabel(), 'start' => $activity->getDateStartStr(), 'end' => $activity->getDateEndStr(), 'synthesis' => $datas ]; return $this->jsonOutput($json); } return $this->jsonOutput($datas); } Loading module/Oscar/view/oscar/public/test.phtml +1 −1 Changes for module/Oscar/view/oscar/public/test.phtml: 1 added line, 1 removed line. Original line number Diff line number Diff line Loading @@ -13,7 +13,7 @@ render: function (h) { return h(ActivityTimesheetSynthesisMenu, { props: { url: '<?= $this->url('timesheet/synthesis') ?>?activity_id=9310' url: '<?= $this->url('timesheet/synthesis') ?>?activity_id=9310&v=2' } }) }, Loading Loading
doc/connectors.md +42 −8 Changes for doc/connectors.md: 42 added lines, 8 removed lines. Original line number Diff line number Diff line Loading @@ -174,16 +174,50 @@ Pour l'URL "liste", le service REST doit retourner un tableau composé d'objets ```JSON [ { "uid": "person1", "login": "etc..." }, { "uid": "person2", "login": "etc..." "uid": "p1001", "login": "alberteinstein", "firstname": "Albert", "lastname": "Einstein", "displayname": "Albert Einstein", "mail": "albert.einstein@univ-berne.com", "civilite": "", "preferedlanguage": "", "status": "", "affectation": "", "structure": "", "inm": "", "phone": "", "birthday": "", "datefininscription": "", "datecreated": "", "dateupdated": "1905-07-04", "datecached": "2020-07-04", "address": null, "groups": [], "roles": {} }, { "uid": "person3", "login": "etc..." "uid": "p1002", "login": "maxplank", "firstname": "Max", "lastname": "Plank", "displayname": "Max Plank", "mail": "max.plank@univ-berlin.com", "civilite": "", "preferedlanguage": "", "status": "", "affectation": "", "structure": "", "inm": "", "phone": "", "birthday": "", "datefininscription": "", "datecreated": "", "dateupdated": "1905-07-04", "datecached": "2020-07-04", "address": null, "groups": [], "roles": {} } ] ``` Loading
front/src/ActivityTimesheetSynthesisMenu.vue +370 −18 Changes for front/src/ActivityTimesheetSynthesisMenu.vue: 370 added lines, 18 removed lines. Original line number Diff line number Diff line <template> <div> <div class="overlay" v-if="open"> <button class="btn btn-primary" @click="handlerOpenSynthesis()" :class="{'disabled': loading}"> <i class="icon-spinner animate-spin" v-if="loading"></i> <i class="icon-calendar" v-else></i> Synthèse des déclarations </button> <div class="overlay-content"> <a href="#" class="overlay-closer" @click="handlerCloseSynthesis()">Close</a> OPTIONS ICI <div v-if="synthese" class="activity-timesheet-synthesis"> <nav class="text-center"> <button v-for="p, person_id in persons" class="btn" :class="filterPersons.indexOf(parseInt(person_id)) < 0 ? 'btn-primary' : 'btn-default'" @click="handlerTooglePerson(person_id)"> {{ p }} </button> </nav> <section v-for="y in sortedDatas.years" class="year" :class="{'open': y.open }"> <h3 class="line" @click="handlerOpenYear(y)"> <strong> <i class="icon-angle-right" v-show="!y.open"></i> <i class="icon-angle-down" v-show="y.open"></i> {{ y.label }} </strong> <em class="total" v-show="!y.open">{{ y.totalmain | hours }}</em> </h3> <section v-for="p in y.periods" class="month" v-show="y.open" :class="{'open': y.open }"> <h4 class="line" @click="handlerOpenPeriod(p)"> <strong> <i class="icon-angle-right" v-show="!p.open"></i> <i class="icon-angle-down" v-show="p.open"></i> {{ p.label }} </strong> <em class="total" v-show="!p.open">{{ p.totalmain | hours }}</em> </h4> <section v-for="pers in p.persons" class="person" v-show="p.open" :class="{'open': p.open }" @click="handlerOpenPerson(pers)"> <h5 class="line"> <strong>{{ pers.label }}</strong> <em class="total">{{ pers.totalmain | hours }}</em> </h5> <section class="details-person" v-if="pers.open"> <article class="line"> <strong> <i class="icon-cube"></i> {{ mainContext }} </strong> <em> {{ pers.totalmain | hours }} </em> </article> <section class="othersprojects" v-if="pers.othersprojects.total > 0"> <article v-for="projectDuration, projectName in pers.othersprojects.projects" class="line"> <strong> <i class="icon-cube"></i> {{ projectName }} </strong> <em style="font-weight: 800"> {{ projectDuration | hours }} </em> </article> </section> <section class="othersprojects" v-if="pers.others.total > 0"> <article v-for="otherDuration, otherName in pers.others.context" class="line"> <strong> {{ otherName | contextLabel }} </strong> <em> {{ otherDuration | hours }} </em> </article> </section> <article class="line totalline"> <strong> Total pour cette période : </strong> <em> {{ pers.total | hours }} </em> </article> </section> </section> <section class="person" v-show="p.open"> <h5 class="line totalline"> <strong>Total pour la période {{ p.label }}</strong> <em class="total">{{ p.totalmain | hours }}</em> </h5> </section> </section> <section class="person" v-show="y.open"> <h5 class="line totalline"> <strong>Total pour {{ y.label }}</strong> <em class="total">{{ y.totalmain | hours }}</em> </h5> </section> </section> </div> </div> <pre>{{ url }}</pre> <button class="btn btn-primary" @click="handlerOpenSynthesis()"> <i class="icon-calendar"></i> Synthèse des déclarations </button> <div class="overlay" v-if="open"> </div> </div> </template> <script> Loading @@ -28,15 +124,25 @@ node node_modules/.bin/gulp activityTimesheetSynthesisMenu */ // import AjaxOscar from "./remote/AjaxOscar"; // import OscarRemoteData from "./remote/OscarRemoteData"; let periodStr = function (year, month) { return year + '-' + (month < 10 ? '0' + month : month); }; // test export default { let months = ["", "Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Aout", "Septembre", "Octobre", "Novembre", "Décembre"]; let periodFullStr = function (year, month) { return months[month] + ' ' + year; }; // components: { // "ajax-oscar": AjaxOscar // }, let contextsLabels = { 'research' : "Autres recherches", 'conges' : "Congès", 'training' : "Formation", 'sickleave' : "Arrêt maladie", 'other' : "Autre activité" }; export default { props: { url: {require: true} Loading @@ -46,33 +152,279 @@ export default { return { configuration: null, open: false, synthese: null // Donnèes brutes synthese: null, structuredDatas: {}, // Filtres filterPersons: [], // Donnèes calculées au fetch mainContext: null, // Projet référent mainContextId: null, // Projet référent contexts: null, // Autres contextes periods: null, // Liste des périodes persons: null, // Liste des déclarants years: null, // Années // openYear: [], openPeriod: [], openPerson: [], } }, filters: { hours(str) { let t = parseFloat(str); let rnd = Math.round(t * 100); return (rnd / 100).toFixed(2); }, contextLabel(contextKey){ if( contextsLabels.hasOwnProperty(contextKey) ){ return contextsLabels[contextKey]; } return contextKey+"*"; } }, computed: { byDate() { let bydate = {}; }, sortedDatas() { // Structure racine let out = { "totaux": { "all": 0.0, "totalmain": 0.0, "othersprojects": { "projects": {}, "total": 0.0 }, "others": { "context": {}, "total": 0.0 }, }, "years": {}, }; // Annèes this.years.forEach(year => { out.years[year] = { "key": year, "label": year, "totalmain": 0.0, "open": this.openYear.indexOf(year) >= 0, "periods": {} } }); // this.periods.forEach(period => { let year = period.substring(0, 4); let month = period.substring(5, 7); out.years[year].periods[period] = { "key": period, "label": periodFullStr(year, parseInt(month)), "totalmain": 0.0, "persons": {}, "open": this.openPeriod.indexOf(period) >= 0, } }); this.synthese.synthesis.forEach(d => { let period = d.period; let year = parseInt(d.period.substring(0, 4)); let month = parseInt(d.period.substring(5, 7)); let person_id = d.person_id; let person = d.displayname; let context = d.context; let activity_id = d.activity_id; let type = d.type; let duration = parseFloat(d.duration); if (this.filterPersons.indexOf(person_id) >= 0) { return; } if (!out.years[year].periods[period].persons.hasOwnProperty(person_id)) { let indexOpen = year+"-"+period+"-"+person_id; out.years[year].periods[period].persons[person_id] = { "key": person_id, "label": person, "indexOpen": indexOpen, "open": this.openPerson.indexOf(indexOpen) >= 0, "totalmain": 0.0, "total": 0.0, "othersprojects": { "projects": {}, "total": 0.0 }, "others": { "context": {}, "total": 0.0 }, } } // --- Comptabilisé pour le projet principal if (activity_id == this.mainContextId) { out.totaux.totalmain += duration; out.years[year].totalmain += duration; out.years[year].periods[period].totalmain += duration; out.years[year].periods[period].persons[person_id].totalmain += duration; } // --- Comptabilisé pour les autres projets else if (type == "wp") { out.years[year].periods[period].persons[person_id].othersprojects.total += duration; // if (!out.years[year].periods[period].persons[person_id].othersprojects.projects.hasOwnProperty(context)) { out.years[year].periods[period].persons[person_id].othersprojects.projects[context] = 0.0; } out.years[year].periods[period].persons[person_id].othersprojects.projects[context] += duration; let project = context; if (!out.totaux.othersprojects.projects.hasOwnProperty(project)) { out.totaux.othersprojects.projects[project] = 0.0; } out.totaux.othersprojects.projects[project] += duration; out.totaux.othersprojects.total += duration; } // --- Autre (Congès, enseignement, etc...) else { out.years[year].periods[period].persons[person_id].others.total += duration; if (!out.years[year].periods[period].persons[person_id].others.context.hasOwnProperty(context)) { out.years[year].periods[period].persons[person_id].others.context[context] = 0.0; } out.years[year].periods[period].persons[person_id].others.context[context] += duration; } out.years[year].periods[period].persons[person_id].total += duration; out.totaux.all += duration; }); return out; } }, methods: { handlerTooglePerson(id) { let personId = parseInt(id); let indexId = this.filterPersons.indexOf(personId); if (indexId < 0) { this.filterPersons.push(personId); } else { this.filterPersons.splice(indexId, 1); } }, handlerOpenPerson(person) { console.log(person); let indexId = this.openPerson.indexOf(person.indexOpen); if (indexId < 0) { this.openPerson.push(person.indexOpen); } else { this.openPerson.splice(indexId, 1); } }, handlerOpenYear(year) { let i = this.openYear.indexOf(year.key); if (i < 0) { this.openYear.push(year.key); } else { this.openYear.splice(i, 1); } }, handlerOpenPeriod(period) { console.log(period.key, this.openPeriod); let i = this.openPeriod.indexOf(period.key); if (i < 0) { this.openPeriod.push(period.key); } else { this.openPeriod.splice(i, 1); } }, handlerOpenSynthesis() { this.open = true; this.loadSynthesis(); }, handlerCloseSynthesis() { this.open = false; console.log("CLOSE Synthesis"); console.log("CLOSE Synthesis 'update'"); }, buildStructuredDatas() { // @deprecated }, buildSynthese(datas) { // TODO Tester les dates de début/fin // ... this.mainContext = datas.acronym; this.mainContextId = datas.activity_id; // Constuction de la liste des périodes let fromYear = parseInt(datas.start.substring(0, 4)); let toYear = parseInt(datas.end.substring(0, 4)); let fromMonth = parseInt(datas.start.substring(5, 7)); let toMonth = parseInt(datas.end.substring(5, 7)); let periods = []; let years = []; let j = fromMonth; for (let i = fromYear; i <= toYear; i++) { years.push(i); for (; j <= 12 || (j <= toMonth && i == toYear); j++) { periods.push(periodStr(i, j)); } j = 1; } let persons = {}; let contexts = []; datas.synthesis.forEach(e => { if (!persons.hasOwnProperty(e.person_id)) { persons[e.person_id] = e.displayname; } if (contexts.indexOf(e.context) < 0 && e.activity_id != this.mainContextId) { contexts.push(e.context) } }); this.periods = periods; this.contexts = contexts; this.persons = persons; this.years = years; }, loadSynthesis() { this.loading = "Chargement de la synthèse..."; this.$http.get(this.url).then( ok => { console.log(ok); this.synthese = ok.body; this.buildSynthese(ok.body); }, ko => { } ) ).then(foo => { this.loading = false; }) } }, mounted() { console.log("ActivityTimesheetSynthesisMenu.vue") console.log("ActivityTimesheetSynthesisMenu.vue"); this.loadSynthesis(); } } Loading
module/Oscar/Module.php +0 −1 Changes for module/Oscar/Module.php: 0 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -48,7 +48,6 @@ class Module public function init(ModuleManager $manager) { $sharedEventManager = $manager->getEventManager()->getSharedManager(); $sharedEventManager->attach('*', 'authentification.ldap.fail', [$this, 'onLdapError'], 100); } public function onLdapError(Event $event) Loading
module/Oscar/src/Oscar/Controller/TimesheetController.php +15 −0 Changes for module/Oscar/src/Oscar/Controller/TimesheetController.php: 15 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ use Oscar\Formatter\TimesheetActivityPeriodHtmlFormatter; use Oscar\Formatter\TimesheetActivityPeriodPdfFormatter; use Oscar\Formatter\TimesheetPersonPeriodHtmlFormatter; use Oscar\Formatter\TimesheetPersonPeriodPdfFormatter; use Oscar\OscarVersion; use Oscar\Provider\Privileges; use Oscar\Service\PersonService; use Oscar\Service\ProjectGrantService; Loading Loading @@ -662,6 +663,7 @@ class TimesheetController extends AbstractOscarController $person_id = $this->params()->fromQuery('person_id', null); $format = $this->params()->fromQuery('format', ''); $period = $this->params()->fromQuery('period', null); $version = $this->params()->fromQuery('v', 1); $error = null; $validations = null; Loading Loading @@ -804,6 +806,19 @@ class TimesheetController extends AbstractOscarController } if( $format == "json" || $this->isAjax() ){ if( $version == "2" ){ $json = [ 'date' => date("Y-m-d H:i:s"), 'version' => OscarVersion::getBuild(), 'activity_id' => $activity->getId(), 'acronym' => $activity->getAcronym(), 'label' => $activity->getLabel(), 'start' => $activity->getDateStartStr(), 'end' => $activity->getDateEndStr(), 'synthesis' => $datas ]; return $this->jsonOutput($json); } return $this->jsonOutput($datas); } Loading
module/Oscar/view/oscar/public/test.phtml +1 −1 Changes for module/Oscar/view/oscar/public/test.phtml: 1 added line, 1 removed line. Original line number Diff line number Diff line Loading @@ -13,7 +13,7 @@ render: function (h) { return h(ActivityTimesheetSynthesisMenu, { props: { url: '<?= $this->url('timesheet/synthesis') ?>?activity_id=9310' url: '<?= $this->url('timesheet/synthesis') ?>?activity_id=9310&v=2' } }) }, Loading