Franck 4 years ago
parent
commit
af77bf02c8
56 changed files with 1721 additions and 374 deletions
  1. 116
    0
      assets/exclusive/js/backOffice/individual/sessionplan_form.js
  2. 5
    6
      assets/shared/build/global/build_global-js.js
  3. 0
    161
      assets/shared/build/js/backOffice/select_autocomplete.js
  4. 10
    0
      assets/shared/build/js/common/datepicker.min.js
  5. 10
    0
      assets/shared/build/js/common/init.js
  6. 0
    24
      assets/shared/build/js/common/ressources.js
  7. 9
    0
      assets/shared/build/scss/plugins/datepicker.min.scss
  8. 1
    1
      config/doctrine/Person.orm.xml
  9. 5
    5
      config/doctrine/SessionPlan.SessionPlan.orm.xml
  10. 1
    1
      config/packages/framework.yaml
  11. 5
    0
      config/packages/twig.yaml
  12. 26
    1
      config/routes.yaml
  13. 25
    15
      src/CaptainLearning/Command/SetupCommand.php
  14. 1
    0
      src/CaptainLearning/Controller/AppController.php
  15. 51
    0
      src/CaptainLearning/Controller/BackOffice/BackOfficeController.php
  16. 0
    22
      src/CaptainLearning/Controller/BackOffice/Individual/IndividualController.php
  17. 419
    0
      src/CaptainLearning/Controller/BackOffice/Individual/SessionPlanController.php
  18. 12
    9
      src/CaptainLearning/Entity/Category/Category.php
  19. 8
    12
      src/CaptainLearning/Entity/Category/Constraints/BuisnessCode/BuisnessCode.php
  20. 10
    7
      src/CaptainLearning/Entity/Category/Constraints/BuisnessCode/BuisnessCodeValidator.php
  21. 1
    13
      src/CaptainLearning/Entity/Category/Constraints/Level/CategoryLevel.php
  22. 8
    12
      src/CaptainLearning/Entity/Category/Constraints/Type/CategoryType.php
  23. 26
    22
      src/CaptainLearning/Entity/Category/Constraints/Type/CategoryTypeValidator.php
  24. 1
    6
      src/CaptainLearning/Entity/Common/AbstractEntity.php
  25. 38
    43
      src/CaptainLearning/Entity/Company/Constraints/Siret/SiretValidator.php
  26. 23
    0
      src/CaptainLearning/Entity/Training/Training.php
  27. 2
    2
      src/CaptainLearning/Entity/User/User.php
  28. 31
    5
      src/CaptainLearning/Entity/sessionPlan/SessionPlan.php
  29. 28
    0
      src/CaptainLearning/Entity/sessionPlan/constraints/SessionPlanDates.php
  30. 34
    0
      src/CaptainLearning/Entity/sessionPlan/constraints/SessionPlanDatesValidator.php
  31. 1
    0
      src/CaptainLearning/Form/Admin/CategoryType.php
  32. 51
    0
      src/CaptainLearning/Form/Profil/SessionPlanRouteType.php
  33. 54
    0
      src/CaptainLearning/Form/Profil/SessionPlanWishType.php
  34. 58
    0
      src/CaptainLearning/Form/Type/CPTDateTimeType.php
  35. 104
    1
      src/CaptainLearning/Repository/SessionPlanRepository.php
  36. 1
    0
      src/CaptainLearning/Twig/BackOffice/EnumExtension.php
  37. 1
    0
      src/CaptainLearning/Twig/FilterExtension.php
  38. 18
    0
      templates/backOffice/common/form.html.twig
  39. 1
    2
      templates/backOffice/common/layout/menu.base.html.twig
  40. 18
    0
      templates/backOffice/common/list.html.twig
  41. 35
    0
      templates/backOffice/common/training/training.html.twig
  42. 5
    0
      templates/backOffice/common/widget/form.html.twig
  43. 32
    0
      templates/backOffice/common/widget/list.html.twig
  44. 6
    0
      templates/backOffice/individual/sessionPlan/common/form.html.twig
  45. 42
    0
      templates/backOffice/individual/sessionPlan/request/widget-request-list.html.twig
  46. 52
    0
      templates/backOffice/individual/sessionPlan/request/widget-session-plan.html.twig
  47. 1
    0
      templates/backOffice/individual/sessionPlan/route/bloc-list.html.twig
  48. 1
    0
      templates/backOffice/individual/sessionPlan/route/route.html.twig
  49. 53
    0
      templates/backOffice/individual/sessionPlan/route/widget-form.html.twig
  50. 131
    0
      templates/backOffice/individual/sessionPlan/route/widget-list.html.twig
  51. 65
    0
      templates/backOffice/individual/sessionPlan/wish/widget-wish-form.html.twig
  52. 38
    0
      templates/backOffice/individual/sessionPlan/wish/widget-wish-list.html.twig
  53. 42
    0
      templates/common/form/cptdatetime.html.twig
  54. 1
    1
      templates/common/layout/component/filter/label_list.html.twig
  55. 1
    1
      templates/common/layout/header/company.part.html.twig
  56. 3
    2
      webpack.config.js

+ 116
- 0
assets/exclusive/js/backOffice/individual/sessionplan_form.js View File

@@ -0,0 +1,116 @@
1
+$(document).ready(function()
2
+{
3
+    function initInterval(startName,endName)
4
+    {
5
+        let startdate = $("#" + startName + "_date");
6
+        let starthours = $("#" + startName + "_time_hour");
7
+        let startminutes = $("#" + startName + "_time_minute");
8
+        let enddate = $("#" + endName + "_date");
9
+        let endhours = $("#" + endName + "_time_hour");
10
+        let endminutes = $("#" + endName + "_time_minute");
11
+
12
+        function onchangefield()
13
+        {
14
+            function getMkTime(date,hours,minutes)
15
+            {
16
+                if (date.val() == "")
17
+                {
18
+                    return null;
19
+                }
20
+                let dateValue = date.datepicker('getDate');
21
+                let hoursValue = hours.val();
22
+                let minutesValue = minutes.val();
23
+                dateValue.setHours(hoursValue);
24
+                dateValue.setMinutes(minutesValue);
25
+
26
+                return dateValue.getTime();
27
+            }
28
+
29
+            console.log('change');
30
+            let field = $(this);
31
+            let start = getMkTime(startdate,starthours,startminutes);
32
+            let end = getMkTime(enddate,endhours,endminutes);
33
+
34
+            // erreur
35
+            if (start !== null && end !== null && start > end)
36
+            {
37
+                field[0].setCustomValidity(field.parents('[data-error-display]').attr('data-error-display'));
38
+            }
39
+            else
40
+            {
41
+                startdate[0].setCustomValidity("");
42
+                starthours[0].setCustomValidity("");
43
+                startminutes[0].setCustomValidity("");
44
+                enddate[0].setCustomValidity("");
45
+                endhours[0].setCustomValidity("");
46
+                endminutes[0].setCustomValidity("");
47
+            }
48
+        }
49
+        startdate.cptDatepicker();
50
+
51
+        startdate.on('change.date',onchangefield);
52
+        starthours.on('change.date',onchangefield);
53
+        startminutes.on('change.date',onchangefield);
54
+
55
+        enddate.cptDatepicker();
56
+
57
+        enddate.on('change.date',onchangefield);
58
+        endhours.on('change.date',onchangefield);
59
+        endminutes.on('change.date',onchangefield);
60
+    }
61
+
62
+
63
+    let cbPeriode = $('#add_periode');
64
+    if (cbPeriode.length > 0)
65
+    {
66
+        cbPeriode.on('change',function()
67
+        {
68
+            let div = $('#periode-content');
69
+            if ($(this).is(':checked'))
70
+            {
71
+                div.removeClass('d-none');
72
+                div.find('input,select').each(function()
73
+                {
74
+                    if ($(this).data('oldValue'))
75
+                    {
76
+                        $(this).val($(this).data('oldValue'));
77
+                    }
78
+                    $(this).attr('required','required');
79
+                });
80
+                initInterval('session_plan_wish_date_start','session_plan_wish_date_end');
81
+            }
82
+            else
83
+            {
84
+                div.find('input,select').each(function()
85
+                {
86
+                    $(this).removeAttr('required');
87
+    
88
+                    $(this).data('oldValue',$(this).val());
89
+                    $(this).val("");
90
+    
91
+                    $(this).off('change.date');
92
+                });
93
+                div.addClass('d-none');
94
+            }
95
+        });
96
+        cbPeriode.trigger('change.date');
97
+    }
98
+    else
99
+    {
100
+        let startDate = $('input[id$="start_date"]');
101
+        initInterval(startDate.attr('id').replace('start_date','start'),$('input[id$="end_date"]').attr('id').replace('end_date','end'));
102
+    }
103
+
104
+    $('#add_societe').on('change',function()
105
+    {
106
+        let div = $('#societe-content');
107
+        if ($(this).is(':checked'))
108
+        {
109
+            div.removeClass('d-none');
110
+        }
111
+        else
112
+        {
113
+            div.addClass('d-none');
114
+        }
115
+    });
116
+});

+ 5
- 6
assets/shared/build/global/build_global-js.js View File

@@ -5,6 +5,7 @@ require('bootstrap');
5 5
 //require('../js/init.js');
6 6
 
7 7
 // Jquery
8
+/*
8 9
 require('jquery-ui/core.js');
9 10
 require('jquery-ui/widget.js');
10 11
 require('jquery-ui/widgets/slider.js');
@@ -14,12 +15,11 @@ require('jquery-ui/widgets/resizable.js');
14 15
 require('jquery-ui/widgets/datepicker.js');
15 16
 require('jquery-ui/widgets/autocomplete.js');
16 17
 require('jquery-ui/widgets/button.js');
17
-
18
+*/
18 19
 // Gridstack
19
-require('gridstack-module/gridstack.js');
20
-require('gridstack-module/gridstack.jQueryUI.js');
20
+/*
21 21
 require('jquery-ui/ui/i18n/datepicker-fr');
22
-
22
+*/
23 23
 // d3 (graphique)
24 24
 //require('d3');
25 25
 
@@ -29,9 +29,8 @@ require('chart.js');
29 29
 require('../js/common/utility.js');
30 30
 require('../js/backOffice/menu.js');
31 31
 require('../js/backOffice/menu-back-office.js');
32
-require('../js/common/ressources.js');
33 32
 require('../js/common/barchart.js');
34
-require('../js/backOffice/select_autocomplete.js');
33
+require('../js/common/datepicker.min.js');
35 34
 
36 35
 require('../js/common/cpt-plugins.js');
37 36
 // pour le header

+ 0
- 161
assets/shared/build/js/backOffice/select_autocomplete.js View File

@@ -1,161 +0,0 @@
1
-$( document ).ready(function() {
2
-  $( ".combobox" ).combobox();
3
-});
4
-
5
-$.widget( "custom.combobox", {
6
-  _create: function() {
7
-    this.wrapper = $( "<span>" )
8
-      .addClass( "custom-combobox" )
9
-      .insertAfter( this.element );
10
-
11
-    this.element.hide();
12
-    this._createAutocomplete();
13
-    this._createShowAllButton();
14
-  },
15
-
16
-  _createAutocomplete: function() {
17
-    var selected = this.element.children( ":selected" ),
18
-      value = selected.val() ? selected.text() : "";
19
-
20
-      let savedAttributs = [];
21
-
22
-      let jqElement = this.element;
23
-      let wrapper = this.wrapper;
24
-      jqElement.children().each(function()
25
-	  {
26
-    	 $.each(this.attributes, function() {
27
-    		 let name = this.name;
28
-    		    // this.attributes is not a plain object, but an array
29
-    		    // of attribute nodes, which contain both the name and value
30
-    		    if(this.specified && name.indexOf('data-save') !== -1 && savedAttributs.indexOf(name) === -1)
31
-    		    {
32
-    		    	savedAttributs.push(name);
33
-
34
-    		    	 let input = $( "<input>", {type: "hidden", 'name': jqElement.attr("name")+"-" + name, value:value})
35
-    		         .appendTo(wrapper);
36
-    		    	 console.log(wrapper);
37
-    		    }
38
-    		  });
39
-	  });
40
-
41
-
42
-
43
-    this.input = $( "<input>" )
44
-      .appendTo( this.wrapper )
45
-      .val( value )
46
-      .attr( "title", "" )
47
-      .addClass( "custom-combobox-input ui-widget ui-widget-content ui-state-default ui-corner-left" )
48
-      .autocomplete({
49
-        delay: 0,
50
-        minLength: 0,
51
-        source: $.proxy( this, "_source" )
52
-      })
53
-      .tooltip({
54
-        classes: {
55
-          "ui-tooltip": "ui-state-highlight"
56
-        }
57
-      }).on('autocompletechange change', function () {
58
-    	  let option = jqElement.find('option:selected');
59
-    	  console.log(option.text());
60
-
61
-        $.each(savedAttributs,function(key,value)
62
-        {
63
-        	$('input[type="hidden"][name="' + jqElement.attr("name")+"-" +value + '"]').val(option.attr(value));
64
-        })
65
-      }).change();
66
-
67
-    this._on( this.input, {
68
-      autocompleteselect: function( event, ui ) {
69
-        ui.item.option.selected = true;
70
-        this._trigger( "select", event, {
71
-          item: ui.item.option
72
-        });
73
-      },
74
-
75
-      autocompletechange: "_removeIfInvalid"
76
-    });
77
-  },
78
-
79
-  _createShowAllButton: function() {
80
-    var input = this.input,
81
-      wasOpen = false;
82
-
83
-    $( "<a>" )
84
-      .attr( "tabIndex", -1 )
85
-      .appendTo( this.wrapper )
86
-      .button({
87
-        icons: {
88
-          primary: "ui-icon-triangle-1-s"
89
-        },
90
-        text: false
91
-      })
92
-      .removeClass( "ui-corner-all" )
93
-      .addClass( "custom-combobox-toggle ui-corner-right" )
94
-      .on( "mousedown", function() {
95
-        wasOpen = input.autocomplete( "widget" ).is( ":visible" );
96
-      })
97
-      .on( "click", function() {
98
-        input.trigger( "focus" );
99
-
100
-        // Close if already visible
101
-        if ( wasOpen ) {
102
-          return;
103
-        }
104
-
105
-        // Pass empty string as value to search for, displaying all results
106
-        input.autocomplete( "search", "" );
107
-      });
108
-  },
109
-
110
-  _source: function( request, response ) {
111
-    var matcher = new RegExp( $.ui.autocomplete.escapeRegex(request.term), "i" );
112
-
113
-    response( this.element.find("option").map(function() {
114
-      var text = $( this ).text();
115
-      if ( this.value && ( !request.term || matcher.test(text) ) )
116
-        return {
117
-          label: text,
118
-          value: text,
119
-          option: this
120
-        };
121
-    }));
122
-  },
123
-
124
-  _removeIfInvalid: function( event, ui ) {
125
-
126
-    // Selected an item, nothing to do
127
-    if ( ui.item ) {
128
-      return;
129
-    }
130
-
131
-    // Search for a match (case-insensitive)
132
-    var value = this.input.val(),
133
-      valueLowerCase = value.toLowerCase(),
134
-      valid = false;
135
-    this.element.children( "option" ).each(function() {
136
-      if ( $( this ).text().toLowerCase() === valueLowerCase ) {
137
-        this.selected = valid = true;
138
-        return false;
139
-      }
140
-    });
141
-
142
-    // Found a match, nothing to do
143
-    if ( valid ) {
144
-      return;
145
-    }
146
-
147
-    // Remove invalid value
148
-    this.input
149
-      .val( "" )
150
-    this.element.val( "" );
151
-    this._delay(function() {
152
-      this.input.tooltip( "close" ).attr( "title", "" );
153
-    }, 2500 );
154
-    this.input.autocomplete( "instance" ).term = "";
155
-  },
156
-
157
-  _destroy: function() {
158
-    this.wrapper.remove();
159
-    this.element.show();
160
-  }
161
-});

+ 10
- 0
assets/shared/build/js/common/datepicker.min.js
File diff suppressed because it is too large
View File


+ 10
- 0
assets/shared/build/js/common/init.js View File

@@ -2,6 +2,16 @@ require('./header/header.js');
2 2
 
3 3
 $( document ).ready(function()
4 4
 {
5
+	$.fn.datepicker.languages['fr-FR'] = {
6
+		format: 'dd/mm/yyyy',
7
+		days: ['Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi'],
8
+		daysShort: ['Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam'],
9
+		daysMin: ['Di', 'Lu', 'Ma', 'Me', 'Je', 'Ve', 'Sa'],
10
+		weekStart: 1,
11
+		months: ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Aout', 'Septembre', 'Octobre', 'Novembre', 'Décembre'],
12
+		monthsShort: ['Jan', 'Fev', 'Mar', 'Avr', 'Mai', 'Jun', 'Jui', 'Aou', 'Sep', 'Oct', 'Nov', 'Dec']
13
+	  };
14
+	  
5 15
 	// surcharge le tooltip d'origine
6 16
 	setTimeout(function(){ $.captain.initTooltip($( document )); }, 10);
7 17
 });

+ 0
- 24
assets/shared/build/js/common/ressources.js View File

@@ -1,24 +0,0 @@
1
-$( document ).ready(function() {
2
-  initSlider();
3
-  initDatepicker();
4
-});
5
-
6
-function initDatepicker()
7
-{
8
-  $( ".datepicker" ).datepicker();
9
-}
10
-
11
-function initSlider()
12
-{
13
-  $( "#slider-range" ).slider();
14
-  $( ".slider-range-d" ).slider({
15
-    range: true,
16
-    min: 0,
17
-    max: 500,
18
-    values: [ 75, 300 ],
19
-    slide: function( event, ui ) {
20
-      $( "#amount" ).val( "$" + ui.values[ 0 ] + " - $" + ui.values[ 1 ] );
21
-    }
22
-  });
23
-  $( "#amount" ).val( "$" + $( "#slider-range" ).slider( "values", 0 ) + " - $" + $( "#slider-range" ).slider( "values", 1 ) );
24
-}

+ 9
- 0
assets/shared/build/scss/plugins/datepicker.min.scss View File

@@ -0,0 +1,9 @@
1
+/*!
2
+ * Datepicker v0.6.4
3
+ * https://github.com/fengyuanchen/datepicker
4
+ *
5
+ * Copyright (c) 2014-2017 Chen Fengyuan
6
+ * Released under the MIT license
7
+ *
8
+ * Date: 2017-11-24T14:38:19.628Z
9
+ */.datepicker-container{background-color:#fff;direction:ltr;font-size:12px;left:0;line-height:30px;position:fixed;top:0;-ms-touch-action:none;touch-action:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;width:210px;z-index:-1;-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none}.datepicker-container:after,.datepicker-container:before{border:5px solid transparent;content:" ";display:block;height:0;position:absolute;width:0}.datepicker-dropdown{border:1px solid #ccc;box-shadow:0 3px 6px #ccc;box-sizing:content-box;position:absolute;z-index:1}.datepicker-inline{position:static}.datepicker-top-left,.datepicker-top-right{border-top-color:#39f}.datepicker-top-left:after,.datepicker-top-left:before,.datepicker-top-right:after,.datepicker-top-right:before{border-top:0;left:10px;top:-5px}.datepicker-top-left:before,.datepicker-top-right:before{border-bottom-color:#39f}.datepicker-top-left:after,.datepicker-top-right:after{border-bottom-color:#fff;top:-4px}.datepicker-bottom-left,.datepicker-bottom-right{border-bottom-color:#39f}.datepicker-bottom-left:after,.datepicker-bottom-left:before,.datepicker-bottom-right:after,.datepicker-bottom-right:before{border-bottom:0;bottom:-5px;left:10px}.datepicker-bottom-left:before,.datepicker-bottom-right:before{border-top-color:#39f}.datepicker-bottom-left:after,.datepicker-bottom-right:after{border-top-color:#fff;bottom:-4px}.datepicker-bottom-right:after,.datepicker-bottom-right:before,.datepicker-top-right:after,.datepicker-top-right:before{left:auto;right:10px}.datepicker-panel>ul{margin:0;padding:0;width:102%}.datepicker-panel>ul:after,.datepicker-panel>ul:before{content:" ";display:table}.datepicker-panel>ul:after{clear:both}.datepicker-panel>ul>li{background-color:#fff;cursor:pointer;float:left;height:30px;list-style:none;margin:0;padding:0;text-align:center;width:30px}.datepicker-panel>ul>li:hover{background-color:#e5f2ff}.datepicker-panel>ul>li.muted,.datepicker-panel>ul>li.muted:hover{color:#999}.datepicker-panel>ul>li.highlighted{background-color:#e5f2ff}.datepicker-panel>ul>li.highlighted:hover{background-color:#cce5ff}.datepicker-panel>ul>li.picked,.datepicker-panel>ul>li.picked:hover{color:#39f}.datepicker-panel>ul>li.disabled,.datepicker-panel>ul>li.disabled:hover{background-color:#fff;color:#ccc;cursor:default}.datepicker-panel>ul>li.disabled.highlighted,.datepicker-panel>ul>li.disabled:hover.highlighted{background-color:#e5f2ff}.datepicker-panel>ul>li[data-view="month next"],.datepicker-panel>ul>li[data-view="month prev"],.datepicker-panel>ul>li[data-view="year next"],.datepicker-panel>ul>li[data-view="year prev"],.datepicker-panel>ul>li[data-view="years next"],.datepicker-panel>ul>li[data-view="years prev"],.datepicker-panel>ul>li[data-view=next]{font-size:18px}.datepicker-panel>ul>li[data-view="month current"],.datepicker-panel>ul>li[data-view="year current"],.datepicker-panel>ul>li[data-view="years current"]{width:150px}.datepicker-panel>ul[data-view=months]>li,.datepicker-panel>ul[data-view=years]>li{height:52.5px;line-height:52.5px;width:52.5px}.datepicker-panel>ul[data-view=week]>li,.datepicker-panel>ul[data-view=week]>li:hover{background-color:#fff;cursor:default}.datepicker-hide{display:none}

+ 1
- 1
config/doctrine/Person.orm.xml View File

@@ -40,7 +40,7 @@
40 40
             <join-column nullable="true" name="ref_country" referenced-column-name="country_id"/>
41 41
         </many-to-one>
42 42
 
43
-		<many-to-many field="sessionPlans" mapped-by="persons" target-entity="Logipro\CaptainLearning\Entity\SessionPlan"/>
43
+		<many-to-many field="sessionPlans" mapped-by="persons" target-entity="Logipro\CaptainLearning\Entity\SessionPlan\SessionPlan"/>
44 44
 
45 45
 		<many-to-many field="sessions" inversed-by="persons" target-entity="Logipro\CaptainLearning\Entity\Session">
46 46
             <join-table name="cpt_map_person_session">

config/doctrine/SessionPlan.orm.xml → config/doctrine/SessionPlan.SessionPlan.orm.xml View File

@@ -4,9 +4,9 @@
4 4
     xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
5 5
         http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
6 6
 
7
-	<entity name="Logipro\CaptainLearning\Entity\SessionPlan"
7
+	<entity name="Logipro\CaptainLearning\Entity\SessionPlan\SessionPlan"
8 8
 		table="cpt_sessionplan"
9
-		repository-class="Logipro\CaptainLearning\Repository\SessionPlan">
9
+		repository-class="Logipro\CaptainLearning\Repository\SessionPlanRepository">
10 10
 
11 11
 	    <id name="sessionPlanId" column="sessionplan_id" type="integer">
12 12
 	        <generator strategy="AUTO" />
@@ -15,9 +15,9 @@
15 15
 		<field name="name" column="name" type="text" length="170" nullable="false" />
16 16
 		
17 17
 		
18
-		<field name="dateStart" column="date_start" type="datetime" nullable="false"/>
19
-		<field name="dateEnd" column="date_end" type="datetime" nullable="false"/>
20
-		<field name="duration" column="duration" type="integer" default="0" />
18
+		<field name="dateStart" column="date_start" type="datetime" nullable="true"/>
19
+		<field name="dateEnd" column="date_end" type="datetime" nullable="true"/>
20
+		<field name="duration" column="duration" type="integer" nullable="true"/>
21 21
 		<field name="createdAt" column="created_at" type="datetime" nullable="false"/>
22 22
 		<field name="type" column="type" type="captainEnumSessionPlanType"  />
23 23
 		<field name="description" column="description" type="text" nullable="true" />

+ 1
- 1
config/packages/framework.yaml View File

@@ -5,4 +5,4 @@ framework:
5 5
   assets:
6 6
     json_manifest_path: '%kernel.project_dir%/public/build/manifest.json'
7 7
   
8
-  validation: { enabled: true }
8
+  validation: { enabled: true }

+ 5
- 0
config/packages/twig.yaml View File

@@ -0,0 +1,5 @@
1
+twig:
2
+  debug: '%kernel.debug%'
3
+  #strict_variables: '%kernel.debug%'
4
+  form_themes:
5
+    - 'common/form/cptdatetime.html.twig'

+ 26
- 1
config/routes.yaml View File

@@ -87,7 +87,32 @@ linkOrCreateCompany:
87 87
 AddCompany:
88 88
   path: /profil/societes/add
89 89
   controller: \Logipro\CaptainLearning\Controller\BackOffice\Individual\CompanyController::addCompany
90
-  
90
+listSessionPlanWish:
91
+  path: /profil/sessionplan/wish
92
+  controller: \Logipro\CaptainLearning\Controller\BackOffice\Individual\SessionPlanController::drawListWish
93
+listSessionPlanRequest:
94
+  path: /profil/sessionplan/request
95
+  controller: \Logipro\CaptainLearning\Controller\BackOffice\Individual\SessionPlanController::drawListRequest
96
+manageSessionPlanWish:
97
+  path: /profil/sessionplan/wish/{sessionPlanId}
98
+  controller: \Logipro\CaptainLearning\Controller\BackOffice\Individual\SessionPlanController::manageWish
99
+  defaults:
100
+    sessionPlanId: 0
101
+deleteSessionPlanWish:
102
+  path: /profil/sessionplan/wish/delete/{sessionPlanId}
103
+  controller: \Logipro\CaptainLearning\Controller\BackOffice\Individual\SessionPlanController::deleteWish
104
+drawSessionPlanRequest:
105
+  path: /profil/sessionplan/request/{sessionPlanId}
106
+  controller: \Logipro\CaptainLearning\Controller\BackOffice\Individual\SessionPlanController::drawRequest
107
+drawSessionPlanRoute:
108
+  path: /profil/sessionplan/route
109
+  controller: \Logipro\CaptainLearning\Controller\BackOffice\Individual\SessionPlanController::drawRoute
110
+editSessionPlanRoute:
111
+  path: /profil/sessionplan/route/{sessionPlanId}
112
+  controller: \Logipro\CaptainLearning\Controller\BackOffice\Individual\SessionPlanController::manageRoute
113
+deleteSessionPlanRoute:
114
+  path: /profil/sessionplan/route/delete/{sessionPlanId}
115
+  controller: \Logipro\CaptainLearning\Controller\BackOffice\Individual\SessionPlanController::deleteRoute
91 116
 
92 117
   # Espace Vendeur
93 118
 drawWelcomeSeller:

+ 25
- 15
src/CaptainLearning/Command/SetupCommand.php View File

@@ -70,28 +70,38 @@ class SetupCommand extends ContainerAwareCommand
70 70
 		$manager->flush();
71 71
 
72 72
 		$userRepo = $manager->getRepository(User::class);
73
-		$userRepo->findOneBy(array('isSuperAdmin' => 1));
74
-		if ($userRepo->hasSuperAdmin())
73
+		$user = $userRepo->findOneBy(array('email' => "admin@logipro.com"));
74
+		$hasAdmin = false;
75
+		if ($user)
75 76
 		{
76
-			$output->writeln("<info>Un utilisateur super-admin existe déjà.</info>");
77
-			return;
77
+			$hasAdmin = true;
78
+			$user->setPassword($user->encodePassword('logipro'));
79
+			$user->setIsSuperAdmin(true);
80
+		}
81
+		else
82
+		{
83
+			// Création de l'utilisateur
84
+			$user = new User();
85
+			$user->setCivility(EnumUserCivilityType::CIVILITY_NA);
86
+			$user->setEmail('admin@logipro.com');
87
+			$user->setPassword($user->encodePassword('logipro'));
88
+			$user->setIsSuperAdmin(true);
89
+			$user->setRole(EnumUserRoleType::ROLE_ADMIN);
90
+			$user->setStatus(EnumUserStatusType::STATUS_ENABLED);
78 91
 		}
79
-
80
-		// Création de l'utilisateur
81
-		$user = new User();
82
-		$user->setCivility(EnumUserCivilityType::CIVILITY_NA);
83
-		$user->setEmail('admin@logipro.com');
84
-		$user->setPassword($user->encodePassword('logipro'));
85
-		$user->setIsSuperAdmin(true);
86
-		$user->setRole(EnumUserRoleType::ROLE_ADMIN);
87
-		$user->setStatus(EnumUserStatusType::STATUS_ENABLED);
88
-
89 92
 		try
90 93
 		{
91 94
 			$manager->persist($user);
92 95
 			$manager->flush();
93 96
 
94
-			$output->writeln("<info>Un utilisateur super-admin a été créé.</info>");
97
+			if (!$hasAdmin)
98
+			{
99
+				$output->writeln("<info>Un utilisateur super-admin a été créé.</info>");
100
+			}
101
+			else
102
+			{
103
+				$output->writeln("<info>Un utilisateur super-admin a été mis à jour.</info>");
104
+			}
95 105
 		}
96 106
 		catch (\Exception $e)
97 107
 		{

+ 1
- 0
src/CaptainLearning/Controller/AppController.php View File

@@ -83,6 +83,7 @@ class AppController extends Controller
83 83
 			"company" => $this->getEnvCompany(),
84 84
 			"companies" => $companies,
85 85
 			'password_policy' => PasswordValidator::renderError($this->get('translator'),$this->get('captainSettings'),""),
86
+			"withLogin" => false
86 87
 		);
87 88
 
88 89
 

+ 51
- 0
src/CaptainLearning/Controller/BackOffice/BackOfficeController.php View File

@@ -6,5 +6,56 @@ use Symfony\Component\HttpFoundation\Response;
6 6
 
7 7
 class BackOfficeController extends AppController
8 8
 {
9
+    public function renderList($filter,$renderVars,$widgetPath)
10
+	{
11
+		$renderVars['filter'] = $filter;
12
+		$this->addRenderWidget
13
+		(
14
+			$renderVars,
15
+			null,
16
+			$widgetPath,
17
+			'col-12',
18
+			$renderVars
19
+		);
20
+
21
+		return $this->render('backOffice/common/list.html.twig',$renderVars);
22
+	}
23
+
24
+    public function renderWidget($renderVars,$widgetPath,$renderPath = 'backOffice/common/form.html.twig')
25
+	{
26
+		$this->addRenderWidget
27
+		(
28
+			$renderVars,
29
+			null,
30
+			$widgetPath,
31
+			'col-12',
32
+			$renderVars
33
+		);
34
+
35
+		return $this->render($renderPath,$renderVars);
36
+	}
37
+
38
+	protected function addRenderWidget(
39
+		&$renderVars,
40
+		$title,
41
+		$path,
42
+		$class = "",
43
+		$parameters = array()
44
+	)
45
+	{
46
+		$parameters['widget_title'] = $title;
47
+		$parameters['widget_class'] = $class;
48
+		
49
+		$content = $this->renderView($path,$parameters);
50
+
51
+
52
+		/*$widgetData = array(
53
+			'widget_title' => $title,
54
+			'widget_content' => $content,
55
+			'widget_class' => ''
56
+		);*/
57
+
58
+		$renderVars['widgets'][] = $content;
59
+	}
9 60
 }
10 61
 ?>

+ 0
- 22
src/CaptainLearning/Controller/BackOffice/Individual/IndividualController.php View File

@@ -6,27 +6,5 @@ use Symfony\Component\HttpFoundation\Response;
6 6
 
7 7
 class IndividualController extends BackOfficeController
8 8
 {
9
-	protected function addRenderWidget(
10
-		&$renderVars,
11
-		$title,
12
-		$path,
13
-		$class = "",
14
-		$parameters = array()
15
-	)
16
-	{
17
-		$parameters['widget_title'] = $title;
18
-		$parameters['widget_class'] = $class;
19
-		
20
-		$content = $this->renderView($path,$parameters);
21
-
22
-
23
-		/*$widgetData = array(
24
-			'widget_title' => $title,
25
-			'widget_content' => $content,
26
-			'widget_class' => ''
27
-		);*/
28
-
29
-		$renderVars['widgets'][] = $content;
30
-	}
31 9
 }
32 10
 ?>

+ 419
- 0
src/CaptainLearning/Controller/BackOffice/Individual/SessionPlanController.php View File

@@ -0,0 +1,419 @@
1
+<?php
2
+namespace Logipro\CaptainLearning\Controller\BackOffice\Individual;
3
+
4
+use Symfony\Component\HttpFoundation\Request;
5
+use Logipro\CaptainLearning\Entity\SessionPlan\SessionPlan;
6
+use Logipro\CaptainLearning\Component\Filter\Filter;
7
+use Logipro\CaptainLearning\Entity\Type\EnumSessionPlanType;
8
+use Logipro\CaptainLearning\Form\Profil\SessionPlanWishType;
9
+use Logipro\CaptainLearning\Form\Profil\SessionPlanRouteType;
10
+use Symfony\Component\Validator\Validator\ValidatorInterface;
11
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
12
+
13
+class SessionPlanController extends IndividualController
14
+{
15
+	private $viewPath = 'backOffice/individual/sessionPlan/';
16
+	public function drawListWish(Request $request)
17
+	{
18
+		// test l'accès utilisateur
19
+		if ($response = $this->denyAccessUnless($request))
20
+		{
21
+			return $response;
22
+		}
23
+
24
+		// récupère les société de l'utilisateur
25
+		$manager = $this->getDoctrine()->getManager();
26
+		$repository = $manager->getRepository(SessionPlan::class);
27
+
28
+		// Paramétrage du filtre
29
+		$filter = new Filter();
30
+		$filter->setRouteName('listSessionPlanWish');
31
+		$filter->addSortKey('name');
32
+		$filter->addSortKey('start');
33
+		$filter->addSortKey('end');
34
+		$filter->addFilter('name');
35
+
36
+		// injecte le request
37
+		$filter->setFromRequest($request);
38
+
39
+		$user = $this->getUser();
40
+		$sessionPlans = $repository->getWishByFilter($filter,array('user' => $user,'company' => null));
41
+
42
+			//$user->getUserId(),array(EnumRoleType::ROLE_GESTIONNARY,EnumRoleType::ROLE_SALARIED,EnumRoleType::ROLE_PERSONNAL_MANAGER));
43
+	
44
+		$renderVars = array
45
+		(
46
+			'objects' => $sessionPlans,
47
+			'path_add' => '',
48
+			'list_title' => 'toto',
49
+			'object_name' => 'session plan',
50
+		);
51
+
52
+		// widget de la liste
53
+		return $this->renderList($filter,$renderVars,$this->viewPath . 'wish/widget-wish-list.html.twig');
54
+	}
55
+
56
+	public function manageWish(Request $request,$sessionPlanId = 0)
57
+	{
58
+		// test l'accès utilisateur
59
+		if ($response = $this->denyAccessUnless($request))
60
+		{
61
+			return $response;
62
+		}
63
+		$user = $this->getUser();
64
+
65
+		$sessionPlanRepository = $this->getRepository(SessionPlan::class);
66
+		if ($sessionPlanId == 0)
67
+		{
68
+			$sessionPlan = new SessionPlan();
69
+			$sessionPlan->setType(EnumSessionPlanType::TYPE_USER_WISH);
70
+			$sessionPlan->setUser($user);
71
+		}
72
+		else
73
+		{
74
+			$sessionPlan = $sessionPlanRepository->find($sessionPlanId);
75
+			$sessionPlanUser = $sessionPlan->getUser();
76
+
77
+			// le session plan doit exister et être un souhait
78
+			if (!$sessionPlan || $sessionPlan->getType() != EnumSessionPlanType::TYPE_USER_WISH 
79
+			|| !$sessionPlanUser || $sessionPlanUser->getUserId() != $user->getUserId())
80
+			{
81
+				throw new AccessDeniedException();
82
+			}
83
+		}
84
+
85
+		// Créer le formulaire
86
+		$form = $this->createForm(SessionPlanWishType::class,$sessionPlan);
87
+
88
+
89
+		// Validation du formulaire
90
+		if ($request->isMethod('POST'))
91
+		{
92
+			$form->handleRequest($request);
93
+
94
+			if ($form->isSubmitted() && $form->isValid())
95
+			{
96
+				$exist = $sessionPlan->getSessionPlanId();
97
+
98
+				// controle les checkbox
99
+				if (!$request->request->get('add_periode'))
100
+				{
101
+					$sessionPlan->setDateStart(null);
102
+					$sessionPlan->setDateEnd(null);
103
+				}
104
+				if (!$request->request->get('add_societe'))
105
+				{
106
+					$sessionPlan->setCompany(null);
107
+				}
108
+
109
+				$sessionPlan->setUser($user);
110
+
111
+				$manager = $this->getDoctrine()->getManager();
112
+
113
+				if (!$exist)
114
+				{
115
+					$manager->persist($sessionPlan);
116
+				}
117
+				
118
+				$manager->flush();
119
+
120
+				// Notification de succes
121
+				if (!$exist)
122
+				{
123
+					$this->addFlash(
124
+						'success',
125
+						$this->get('translator')->trans('label_success_session_plan_create')
126
+					);
127
+				}
128
+				else
129
+				{
130
+					$this->addFlash(
131
+						'success',
132
+						$this->get('translator')->trans('label_success_session_plan_update')
133
+					);
134
+				}
135
+				return $this->redirectToRoute('manageSessionPlanWish',array('sessionPlanId' => $sessionPlan->getSessionPlanId()));
136
+			}
137
+		}
138
+
139
+		// Déclaration des variables
140
+		$renderVariables = array();
141
+		$renderVariables["form"] = $form->createView();
142
+		$renderVariables["sessionplan"] = $sessionPlan;
143
+		
144
+		// Fil d'Ariane
145
+		/*$breadcrumb = $this->createBreadcrumb($renderVariables);
146
+		$breadcrumb->addRouteItem($this->get('translator')->trans('admin_category_link'), 'admin_category');
147
+		$breadcrumb->addActiveItem($category->getName());*/
148
+
149
+		// Affichage du formulaire
150
+		return $this->renderWidget($renderVariables,$this->viewPath . 'wish/widget-wish-form.html.twig',$this->viewPath . 'common/form.html.twig');
151
+	}
152
+
153
+	public function deleteWish(Request $request,$sessionPlanId = 0)
154
+	{
155
+		// test l'accès utilisateur
156
+		if ($response = $this->denyAccessUnless($request))
157
+		{
158
+			return $response;
159
+		}
160
+
161
+		try
162
+		{
163
+			$sessionPlanRepository = $this->getRepository(SessionPlan::class);
164
+			$sessionPlan = $sessionPlanRepository->find($sessionPlanId);
165
+			$user = $this->getUser();
166
+			$sessionPlanUser = $sessionPlan->getUser();
167
+			// le session plan doit exister et être un souhait
168
+			if (!$sessionPlan || $sessionPlan->getType() != EnumSessionPlanType::TYPE_USER_WISH 
169
+			|| !$sessionPlanUser || $sessionPlanUser->getUserId() != $user->getUserId())
170
+			{
171
+				throw new AccessDeniedException();
172
+			}
173
+
174
+			$manager = $this->getManager();
175
+			$manager->remove($sessionPlan);
176
+			$manager->flush();
177
+
178
+			$this->addFlash(
179
+				'success',
180
+				$this->get('translator')->trans('label_success_session_plan_delete')
181
+			);
182
+			
183
+			return $this->redirectToRoute('listSessionPlanWish');
184
+		}
185
+		catch (\Exception $exp)
186
+		{
187
+			$this->addFlash(
188
+				'danger',
189
+				$exp->getMessage()
190
+			);
191
+			return $this->redirectToRoute('listSessionPlanWish');
192
+			//return $this->redirectToRoute('manageSessionPlanWish',array('sessionPlanId' => $sessionPlanId));
193
+		}
194
+	}
195
+
196
+	public function drawListRequest(Request $request)
197
+	{
198
+		// test l'accès utilisateur
199
+		if ($response = $this->denyAccessUnless($request))
200
+		{
201
+			return $response;
202
+		}
203
+
204
+		// récupère les société de l'utilisateur
205
+		$manager = $this->getDoctrine()->getManager();
206
+		$repository = $manager->getRepository(SessionPlan::class);
207
+
208
+		// Paramétrage du filtre
209
+		$filter = new Filter();
210
+		$filter->setRouteName('listSessionPlanRequest');
211
+		$filter->addSortKey('name');
212
+		$filter->addSortKey('start');
213
+		$filter->addSortKey('end');
214
+		$filter->addSortKey('companyname');
215
+
216
+		// nombre par défaut d'element dans la page
217
+		$filter->setMaxResults(25);
218
+
219
+		// injecte le request
220
+		$filter->setFromRequest($request);
221
+
222
+		$user = $this->getUser();
223
+		$sessionPlans = $repository->getRequestByFilter($filter,array('user' => $user));
224
+
225
+			//$user->getUserId(),array(EnumRoleType::ROLE_GESTIONNARY,EnumRoleType::ROLE_SALARIED,EnumRoleType::ROLE_PERSONNAL_MANAGER));
226
+	
227
+		$renderVars = array
228
+		(
229
+			'objects' => $sessionPlans,
230
+			'path_add' => '',
231
+			'list_title' => 'toto',
232
+			'object_name' => 'session plan',
233
+		);
234
+
235
+		// widget de la liste
236
+		return $this->renderList($filter,$renderVars,$this->viewPath . 'request/widget-request-list.html.twig');
237
+	}
238
+
239
+	public function drawRequest(Request $request,$sessionPlanId)
240
+	{
241
+		// test l'accès utilisateur
242
+		if ($response = $this->denyAccessUnless($request))
243
+		{
244
+			return $response;
245
+		}
246
+
247
+		$sessionPlanRepository = $this->getRepository(SessionPlan::class);
248
+		$sessionPlan = $sessionPlanRepository->find($sessionPlanId);
249
+		$sessionPlanUser = $sessionPlan->getUser();
250
+
251
+		// le session plan doit exister et être un souhait
252
+		$user = $this->getUser();
253
+		if (!$sessionPlan || $sessionPlan->getType() != EnumSessionPlanType::TYPE_USER_WISH 
254
+		|| !$sessionPlanUser || $sessionPlanUser->getUserId() != $user->getUserId())
255
+		{
256
+			throw new AccessDeniedException();
257
+		}
258
+
259
+		$renderVars['sessionplan'] = $sessionPlan;
260
+
261
+		// Affichage du formulaire
262
+		return $this->renderWidget($renderVars,$this->viewPath . 'request/widget-session-plan.html.twig');
263
+	}
264
+
265
+
266
+	public function drawRoute(Request $request)
267
+	{
268
+		// test l'accès utilisateur
269
+		if ($response = $this->denyAccessUnless($request))
270
+		{
271
+			return $response;
272
+		}
273
+
274
+		// récupère les société de l'utilisateur
275
+		$manager = $this->getDoctrine()->getManager();
276
+		$repository = $manager->getRepository(SessionPlan::class);
277
+
278
+		$user = $this->getUser();
279
+		$sessionPlans = $repository->getForRoute($user);
280
+			//$user->getUserId(),array(EnumRoleType::ROLE_GESTIONNARY,EnumRoleType::ROLE_SALARIED,EnumRoleType::ROLE_PERSONNAL_MANAGER));
281
+	
282
+		$renderVars = array
283
+		(
284
+			'objects' => $sessionPlans,
285
+		);
286
+
287
+		// widget de la liste
288
+		return $this->renderWidget($renderVars,$this->viewPath . 'route/widget-list.html.twig',$this->viewPath . 'route/route.html.twig');
289
+	}
290
+
291
+	public function manageRoute(Request $request,$sessionPlanId)
292
+	{
293
+		// test l'accès utilisateur
294
+		if ($response = $this->denyAccessUnless($request))
295
+		{
296
+			return $response;
297
+		}
298
+		$user = $this->getUser();
299
+
300
+		$sessionPlanRepository = $this->getRepository(SessionPlan::class);
301
+		if ($sessionPlanId == 0)
302
+		{
303
+			$sessionPlan = new SessionPlan();
304
+			$sessionPlan->setType(EnumSessionPlanType::TYPE_USER_ROUTE);
305
+			$sessionPlan->setUser($user);
306
+		}
307
+		else
308
+		{
309
+			$sessionPlan = $sessionPlanRepository->find($sessionPlanId);
310
+			$sessionPlanUser = $sessionPlan->getUser();
311
+
312
+			// le session plan doit exister et être un souhait
313
+			if (!$sessionPlan || $sessionPlan->getType() != EnumSessionPlanType::TYPE_USER_ROUTE 
314
+			|| !$sessionPlanUser || $sessionPlanUser->getUserId() != $user->getUserId())
315
+			{
316
+				throw new AccessDeniedException();
317
+			}
318
+		}
319
+
320
+		// Créer le formulaire
321
+		$form = $this->createForm(SessionPlanRouteType::class,$sessionPlan);
322
+
323
+
324
+		// Validation du formulaire
325
+		if ($request->isMethod('POST'))
326
+		{
327
+			$form->handleRequest($request);
328
+
329
+			if ($form->isSubmitted() && $form->isValid())
330
+			{
331
+				$exist = $sessionPlan->getSessionPlanId();
332
+
333
+				$sessionPlan->setUser($user);
334
+
335
+				$manager = $this->getDoctrine()->getManager();
336
+
337
+				if (!$exist)
338
+				{
339
+					$manager->persist($sessionPlan);
340
+				}
341
+				
342
+				$manager->flush();
343
+
344
+				// Notification de succes
345
+				if (!$exist)
346
+				{
347
+					$this->addFlash(
348
+						'success',
349
+						$this->get('translator')->trans('label_success_session_plan_create')
350
+					);
351
+				}
352
+				else
353
+				{
354
+					$this->addFlash(
355
+						'success',
356
+						$this->get('translator')->trans('label_success_session_plan_update')
357
+					);
358
+				}
359
+				return $this->redirectToRoute('editSessionPlanRoute',array('sessionPlanId' => $sessionPlan->getSessionPlanId()));
360
+			}
361
+		}
362
+
363
+		// Déclaration des variables
364
+		$renderVariables = array();
365
+		$renderVariables["form"] = $form->createView();
366
+		$renderVariables["sessionplan"] = $sessionPlan;
367
+		
368
+		// Fil d'Ariane
369
+		/*$breadcrumb = $this->createBreadcrumb($renderVariables);
370
+		$breadcrumb->addRouteItem($this->get('translator')->trans('admin_category_link'), 'admin_category');
371
+		$breadcrumb->addActiveItem($category->getName());*/
372
+
373
+		// Affichage du formulaire
374
+		return $this->renderWidget($renderVariables,$this->viewPath . 'route/widget-form.html.twig',$this->viewPath . 'common/form.html.twig');
375
+	}
376
+
377
+	public function deleteRoute(Request $request,$sessionPlanId = 0)
378
+	{
379
+		// test l'accès utilisateur
380
+		if ($response = $this->denyAccessUnless($request))
381
+		{
382
+			return $response;
383
+		}
384
+
385
+		try
386
+		{
387
+			$sessionPlanRepository = $this->getRepository(SessionPlan::class);
388
+			$sessionPlan = $sessionPlanRepository->find($sessionPlanId);
389
+			$user = $this->getUser();
390
+			$sessionPlanUser = $sessionPlan->getUser();
391
+			// le session plan doit exister et être un souhait
392
+			if (!$sessionPlan || $sessionPlan->getType() != EnumSessionPlanType::TYPE_USER_ROUTE 
393
+			|| !$sessionPlanUser || $sessionPlanUser->getUserId() != $user->getUserId())
394
+			{
395
+				throw new AccessDeniedException();
396
+			}
397
+
398
+			$manager = $this->getManager();
399
+			$manager->remove($sessionPlan);
400
+			$manager->flush();
401
+
402
+			$this->addFlash(
403
+				'success',
404
+				$this->get('translator')->trans('label_success_session_plan_delete')
405
+			);
406
+			
407
+			return $this->redirectToRoute('drawSessionPlanRoute');
408
+		}
409
+		catch (\Exception $exp)
410
+		{
411
+			$this->addFlash(
412
+				'danger',
413
+				$exp->getMessage()
414
+			);
415
+			return $this->redirectToRoute('drawSessionPlanRoute');
416
+		}
417
+	}
418
+}
419
+?>

+ 12
- 9
src/CaptainLearning/Entity/Category/Category.php View File

@@ -3,14 +3,15 @@ namespace Logipro\CaptainLearning\Entity\Category;
3 3
 
4 4
 use Doctrine\ORM\Event\PreUpdateEventArgs;
5 5
 use Doctrine\Common\Collections\ArrayCollection;
6
-use Symfony\Component\Security\Core\User\UserInterface;
7
-use Logipro\CaptainLearning\Entity\Common\AbstractEntity;
6
+use Symfony\Component\Validator\Constraints as Assert;
7
+use Symfony\Component\Validator\Mapping\ClassMetadata;
8 8
 
9 9
 // validator
10
-use Symfony\Component\Validator\Mapping\ClassMetadata;
10
+use Symfony\Component\Security\Core\User\UserInterface;
11
+use Logipro\CaptainLearning\Entity\Common\AbstractEntity;
12
+use Logipro\CaptainLearning\Entity\Type\EnumCategoryType;
11 13
 use Symfony\Component\Form\Extension\Core\Type\IntegerType;
12 14
 use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
13
-use Symfony\Component\Validator\Constraints as Assert;
14 15
 use Logipro\CaptainLearning\Entity\Category\Constraints\Type\CategoryType;
15 16
 use Logipro\CaptainLearning\Entity\Category\Constraints\Level\CategoryLevel;
16 17
 use Logipro\CaptainLearning\Entity\Category\Constraints\BuisnessCode\BuisnessCode;
@@ -43,6 +44,8 @@ class Category extends AbstractEntity
43 44
     public function __construct()
44 45
     {
45 46
         $this->children = new ArrayCollection();
47
+
48
+        $this->typeClassification = EnumCategoryType::TYPE_CATEGORY;
46 49
     }
47 50
 
48 51
     public function getChildren()
@@ -251,9 +254,9 @@ class Category extends AbstractEntity
251 254
         
252 255
         // test le type
253 256
          // test le type parent
254
-		/*$metadata->addPropertyConstraint('name', new CategoryType(array(
257
+		$metadata->addConstraint(new CategoryType(array(
255 258
 			'message' => 'label_category_type_error',
256
-        )));*/
259
+        )));
257 260
 
258 261
         // test le niveau
259 262
         /*$metadata->addPropertyConstraint('name', new CategoryLevel(array(
@@ -261,9 +264,9 @@ class Category extends AbstractEntity
261 264
         )));*/
262 265
 
263 266
         // code métier non vide quand type=métier
264
-        /*$metadata->addPropertyConstraint('buisness_code', new BuisnessCode(array(
267
+        $metadata->addConstraint(new BuisnessCode(array(
265 268
             'message' => 'label_category_buisness_code_not_be_empty',
266
-        )));*/
269
+        )));
267 270
 
268 271
     // -- test les doublons
269 272
         $metadata->addConstraint(new UniqueEntity(array(
@@ -283,7 +286,7 @@ class Category extends AbstractEntity
283 286
 	public function calculateLevel()
284 287
 	{
285 288
 		// récupère le parent
286
-		$parent = $beanCategorie->getParent();
289
+		$parent = $this->getParent();
287 290
 		if (!$parent)
288 291
 		{
289 292
 			return 0;

+ 8
- 12
src/CaptainLearning/Entity/Category/Constraints/BuisnessCode/BuisnessCode.php View File

@@ -3,8 +3,6 @@ namespace Logipro\CaptainLearning\Entity\Category\Constraints\BuisnessCode;
3 3
 
4 4
 use Symfony\Component\Validator\Constraint;
5 5
 
6
-use Logipro\CaptainLearning\Entity\Category\Constraints\Level\CategoryLevelValidator;
7
-
8 6
 class BuisnessCode extends Constraint
9 7
 {
10 8
 	public $message = 'This value is already used.';
@@ -16,17 +14,15 @@ class BuisnessCode extends Constraint
16 14
 	 */
17 15
 	public function validatedBy()
18 16
 	{
19
-		return BuisnessCodeValidator::class;
20
-	}
21
-
22
-
23
-	public function getRequiredOptions()
24
-	{
17
+		return 'Logipro\CaptainLearning\Entity\Category\Constraints\BuisnessCode\BuisnessCodeValidator';
25 18
 	}
26 19
 
27
-	public function getTargets()
28
-	{
29
-		return self::CLASS_CONSTRAINT;
30
-	}
20
+	/**
21
+     * {@inheritdoc}
22
+     */
23
+    public function getTargets()
24
+    {
25
+        return self::CLASS_CONSTRAINT;
26
+    }
31 27
 }
32 28
 ?>

+ 10
- 7
src/CaptainLearning/Entity/Category/Constraints/BuisnessCode/BuisnessCodeValidator.php View File

@@ -8,15 +8,18 @@ use Symfony\Component\Validator\Constraint;
8 8
 
9 9
 class BuisnessCodeValidator extends ConstraintValidator
10 10
 {
11
-	public function validate(Category $entity, Constraint $constraint)
11
+	public function validate($entity, Constraint $constraint)
12 12
 	{
13
-		if ($entity->getBuisnessCode() == "" && 
14
-		$entity->getTypeClassification() == Category::CLASSIFICATION_BUISNESS)
13
+		if (is_a($entity,Category::class))
15 14
 		{
16
-			$this->context->buildViolation($constraint->message)
17
-			->atPath('buisnessCode')
18
-			->setParameter('{{ value }}', $this->formatValue($type))
19
-			->addViolation();
15
+			if ($entity->getBuisnessCode() == "" && 
16
+			$entity->getTypeClassification() == Category::CLASSIFICATION_BUISNESS)
17
+			{
18
+				$this->context->buildViolation($constraint->message)
19
+				->atPath('buisnessCode')
20
+				->setParameter('{{ value }}', $this->formatValue($type))
21
+				->addViolation();
22
+			}
20 23
 		}
21 24
 	}
22 25
 }

+ 1
- 13
src/CaptainLearning/Entity/Category/Constraints/Level/CategoryLevel.php View File

@@ -3,8 +3,6 @@ namespace Logipro\CaptainLearning\Entity\Category\Constraints\Level;
3 3
 
4 4
 use Symfony\Component\Validator\Constraint;
5 5
 
6
-use Logipro\CaptainLearning\Entity\Category\Constraints\Level\CategoryLevelValidator;
7
-
8 6
 class CategoryLevel extends Constraint
9 7
 {
10 8
 	public $message = 'This value is already used.';
@@ -16,17 +14,7 @@ class CategoryLevel extends Constraint
16 14
 	 */
17 15
 	public function validatedBy()
18 16
 	{
19
-		return CategoryLevelValidator::class;
20
-	}
21
-
22
-
23
-	public function getRequiredOptions()
24
-	{
25
-	}
26
-
27
-	public function getTargets()
28
-	{
29
-		return self::CLASS_CONSTRAINT;
17
+		return 'Logipro\CaptainLearning\Entity\Category\Constraints\Level\CategoryLevelValidator';
30 18
 	}
31 19
 }
32 20
 ?>

+ 8
- 12
src/CaptainLearning/Entity/Category/Constraints/Type/CategoryType.php View File

@@ -3,8 +3,6 @@ namespace Logipro\CaptainLearning\Entity\Category\Constraints\Type;
3 3
 
4 4
 use Symfony\Component\Validator\Constraint;
5 5
 
6
-use Logipro\CaptainLEarning\Entity\Category\Constraints\Type\CategoryTypeValidator;
7
-
8 6
 class CategoryType extends Constraint
9 7
 {
10 8
 	public $message = 'This value is already used.';
@@ -16,17 +14,15 @@ class CategoryType extends Constraint
16 14
 	 */
17 15
 	public function validatedBy()
18 16
 	{
19
-		return CategoryTypeValidator::class;
20
-	}
21
-
22
-
23
-	public function getRequiredOptions()
24
-	{
17
+		return 'Logipro\CaptainLearning\Entity\Category\Constraints\Type\CategoryTypeValidator';
25 18
 	}
26 19
 
27
-	public function getTargets()
28
-	{
29
-		return self::CLASS_CONSTRAINT;
30
-	}
20
+	/**
21
+     * {@inheritdoc}
22
+     */
23
+    public function getTargets()
24
+    {
25
+        return self::CLASS_CONSTRAINT;
26
+    }
31 27
 }
32 28
 ?>

+ 26
- 22
src/CaptainLearning/Entity/Category/Constraints/Type/CategoryTypeValidator.php View File

@@ -1,35 +1,39 @@
1 1
 <?php
2 2
 namespace Logipro\CaptainLearning\Entity\Category\Constraints\Type;
3 3
 
4
+use Symfony\Component\Validator\Constraint;
4 5
 use Symfony\Component\Validator\ConstraintValidator;
5
-use Logipro\CaptainLearning\Entity\Category\Category;
6 6
 
7
-use Symfony\Component\Validator\Constraint;
7
+use Logipro\CaptainLearning\Entity\Category\Category;
8
+use Logipro\CaptainLearning\Entity\Type\EnumCategoryType;
8 9
 
9 10
 class CategoryTypeValidator extends ConstraintValidator
10 11
 {
11
-	public function validate(Category $entity, Constraint $constraint)
12
-{
13
-		// test le choix du type
14
-		$type = $entity->getTypeClassification();
15
-		$choices = EnumCategoryType::getFormChoices();
16
-
17
-		if (!isset($choices[$type]))
12
+	public function validate($entity, Constraint $constraint)
13
+	{
14
+		if (is_a($entity,Category::class))
18 15
 		{
19
-			$this->context->buildViolation($constraint->message)
20
-			->atPath('url')
21
-			->setParameter('{{ value }}', $this->formatValue($type))
22
-			->addViolation();
23
-		}
16
+			// test le choix du type
17
+			$type = $entity->getTypeClassification();
18
+			$choices = EnumCategoryType::getFormChoices();
24 19
 
25
-		// test la référence et le type parent
26
-		$categoryParent = $entity->getParent();
27
-		if ($categoryParent->getTypeClassification() != $type)
28
-		{
29
-			$this->context->buildViolation($constraint->message)
30
-			->atPath('url')
31
-			->setParameter('{{ value }}', $this->formatValue($type))
32
-			->addViolation();
20
+			if (!isset($choices[$type]))
21
+			{
22
+				$this->context->buildViolation($constraint->message)
23
+				->atPath('url')
24
+				->setParameter('{{ value }}', $this->formatValue($type))
25
+				->addViolation();
26
+			}
27
+
28
+			// test la référence et le type parent
29
+			$categoryParent = $entity->getParent();
30
+			if ($categoryParent->getTypeClassification() != $type)
31
+			{
32
+				$this->context->buildViolation($constraint->message)
33
+				->atPath('url')
34
+				->setParameter('{{ value }}', $this->formatValue($type))
35
+				->addViolation();
36
+			}
33 37
 		}
34 38
 	}
35 39
 }

+ 1
- 6
src/CaptainLearning/Entity/Common/AbstractEntity.php View File

@@ -30,13 +30,8 @@ abstract class AbstractEntity
30 30
 		}
31 31
 	}
32 32
 
33
-	public function canDelete($resetError = true) : bool
33
+	public function canDelete() : bool
34 34
 	{
35
-		if ($resetError)
36
-		{
37
-			$this->resetErrors();
38
-		}
39
-
40 35
 		return true;
41 36
 	}
42 37
 

+ 38
- 43
src/CaptainLearning/Entity/Company/Constraints/Siret/SiretValidator.php View File

@@ -8,59 +8,54 @@ use Symfony\Component\Validator\ConstraintValidator;
8 8
 
9 9
 class SiretValidator extends ConstraintValidator
10 10
 {
11
-	public function validate($entity, Constraint $constraint)
11
+	public function validate($siret, Constraint $constraint)
12 12
 	{
13
-		if (is_a($entity,Company::class))
13
+		// le SIRET doit contenir 14 caractères
14
+		if (strlen($siret) != 14)
14 15
 		{
15
-			$siret = $entity->getSiret();
16
-			
17
-			// le SIRET doit contenir 14 caractères
18
-			if (strlen($siret) != 14)
19
-			{
20
-				$this->context->buildViolation($constraint->message)
21
-				->atPath('siret')
22
-				->setParameter('{{ value }}', 'label_company_siret_length_error')
23
-				->addViolation();
24
-			}
16
+			$this->context->buildViolation($constraint->message)
17
+			->atPath('siret')
18
+			->setParameter('{{ value }}', 'label_company_siret_length_error')
19
+			->addViolation();
20
+		}
25 21
 
26
-			// le SIRET ne doit contenir que des chiffres
27
-			if (!is_numeric($siret))
22
+		// le SIRET ne doit contenir que des chiffres
23
+		if (!is_numeric($siret))
24
+		{
25
+			$this->context->buildViolation($constraint->message)
26
+			->atPath('siret')
27
+			->setParameter('{{ value }}', 'label_company_siret_type_error')
28
+			->addViolation();
29
+		}
30
+
31
+		// on prend chaque chiffre un par un
32
+		// si son index (position dans la chaîne en commence à 0 au premier caractère) est pair
33
+		// on double sa valeur et si cette dernière est supérieure à 9, on lui retranche 9
34
+		// on ajoute cette valeur à la somme totale
35
+		$sum = 0;
36
+		for ($index = 0; $index < 14; $index ++)
37
+		{
38
+			if (!isset($siret[$index]))
28 39
 			{
29 40
 				$this->context->buildViolation($constraint->message)
30 41
 				->atPath('siret')
31
-				->setParameter('{{ value }}', 'label_company_siret_type_error')
42
+				->setParameter('{{ value }}', 'label_company_siret_size_error')
32 43
 				->addViolation();
33
-			}
34
-
35
-			// on prend chaque chiffre un par un
36
-			// si son index (position dans la chaîne en commence à 0 au premier caractère) est pair
37
-			// on double sa valeur et si cette dernière est supérieure à 9, on lui retranche 9
38
-			// on ajoute cette valeur à la somme totale
39
-			$sum = 0;
40
-			for ($index = 0; $index < 14; $index ++)
41
-			{
42
-				if (!isset($siret[$index]))
43
-				{
44
-					$this->context->buildViolation($constraint->message)
45
-					->atPath('siret')
46
-					->setParameter('{{ value }}', 'label_company_siret_size_error')
47
-					->addViolation();
48 44
 
49
-					break;
50
-				}
51
-				$number = (int) $siret[$index];
52
-				if (($index % 2) == 0) { if (($number *= 2) > 9) $number -= 9; }
53
-				$sum += $number;
45
+				break;
54 46
 			}
47
+			$number = (int) $siret[$index];
48
+			if (($index % 2) == 0) { if (($number *= 2) > 9) $number -= 9; }
49
+			$sum += $number;
50
+		}
55 51
 
56
-			// le numéro est valide si la somme des chiffres est multiple de 10
57
-			if (($sum % 10) != 0)
58
-			{
59
-				$this->context->buildViolation($constraint->message)
60
-				->atPath('siret')
61
-				->setParameter('{{ value }}', 'label_company_siret_error')
62
-				->addViolation();
63
-			}
52
+		// le numéro est valide si la somme des chiffres est multiple de 10
53
+		if (($sum % 10) != 0)
54
+		{
55
+			$this->context->buildViolation($constraint->message)
56
+			->atPath('siret')
57
+			->setParameter('{{ value }}', 'label_company_siret_error')
58
+			->addViolation();
64 59
 		}
65 60
 	}
66 61
 }

+ 23
- 0
src/CaptainLearning/Entity/Training/Training.php View File

@@ -1138,5 +1138,28 @@ class Training extends AbstractEntity
1138 1138
 		)));
1139 1139
 	}
1140 1140
 
1141
+    /**
1142
+     * Get prix
1143
+     *
1144
+     * @return  decimal
1145
+     */ 
1146
+    public function getPrice()
1147
+    {
1148
+        return $this->price;
1149
+    }
1150
+
1151
+    /**
1152
+     * Set prix
1153
+     *
1154
+     * @param  decimal  $price  prix
1155
+     *
1156
+     * @return  self
1157
+     */ 
1158
+    public function setPrice(float $price)
1159
+    {
1160
+        $this->price = $price;
1161
+
1162
+        return $this;
1163
+    }
1141 1164
 }
1142 1165
 ?>

+ 2
- 2
src/CaptainLearning/Entity/User/User.php View File

@@ -148,7 +148,7 @@ implements UserInterface
148 148
 	 * {@inheritDoc}
149 149
 	 * @see \Logipro\LAMA\Entity\Common\AbstractEntity::canDelete()
150 150
 	 */
151
-	public function canDelete($resetError = true): bool
151
+	public function canDelete(): bool
152 152
 	{
153 153
 		//@TODO Ecrire les tests de suppression
154 154
 		if (true)
@@ -156,7 +156,7 @@ implements UserInterface
156 156
 			return false;
157 157
 		}
158 158
 
159
-		return parent::canDelete($resetError);
159
+		return parent::canDelete();
160 160
 	}
161 161
 
162 162
 	public function getPassword() {

src/CaptainLearning/Entity/SessionPlan.php → src/CaptainLearning/Entity/sessionPlan/SessionPlan.php View File

@@ -1,10 +1,16 @@
1 1
 <?php
2
-namespace Logipro\CaptainLearning\Entity;
2
+namespace Logipro\CaptainLearning\Entity\SessionPlan;
3 3
 
4 4
 use Logipro\CaptainLearning\Entity\User\User;
5
+use Doctrine\Common\Collections\ArrayCollection;
5 6
 use Logipro\CaptainLearning\Entity\Company\Company;
6 7
 use Logipro\CaptainLearning\Entity\Training\Training;
8
+
9
+use Symfony\Component\Validator\Constraints as Assert;
10
+use Symfony\Component\Validator\Mapping\ClassMetadata;
7 11
 use Logipro\CaptainLearning\Entity\Common\AbstractEntity;
12
+use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
13
+use Logipro\CaptainLearning\Entity\SessionPlan\Constraints\SessionPlanDates;
8 14
 
9 15
 class SessionPlan extends AbstractEntity
10 16
 {
@@ -142,7 +148,7 @@ class SessionPlan extends AbstractEntity
142 148
 	 *
143 149
 	 * @return  self
144 150
 	 */ 
145
-	public function setDateStart(string $dateStart)
151
+	public function setDateStart($dateStart)
146 152
 	{
147 153
 		$this->dateStart = $dateStart;
148 154
 
@@ -166,7 +172,7 @@ class SessionPlan extends AbstractEntity
166 172
 	 *
167 173
 	 * @return  self
168 174
 	 */ 
169
-	public function setDateEnd(string $dateEnd)
175
+	public function setDateEnd($dateEnd)
170 176
 	{
171 177
 		$this->dateEnd = $dateEnd;
172 178
 
@@ -190,7 +196,7 @@ class SessionPlan extends AbstractEntity
190 196
 	 *
191 197
 	 * @return  self
192 198
 	 */ 
193
-	public function setSession(Session $session)
199
+	public function setSession($session)
194 200
 	{
195 201
 		$this->session = $session;
196 202
 
@@ -238,7 +244,7 @@ class SessionPlan extends AbstractEntity
238 244
 	 *
239 245
 	 * @return  self
240 246
 	 */ 
241
-	public function setCompany(Company $company)
247
+	public function setCompany($company)
242 248
 	{
243 249
 		$this->company = $company;
244 250
 
@@ -334,5 +340,25 @@ class SessionPlan extends AbstractEntity
334 340
 	{
335 341
 		return $this->persons;
336 342
 	}
343
+
344
+	
345
+    /**
346
+	 * Définit les contraintes de validation des données de formulaire.
347
+	 * @param ClassMetadata $metadata
348
+	 */
349
+	public static function loadValidatorMetadata(ClassMetadata $metadata)
350
+	{
351
+	 // -- test les attributs
352
+		// test les dates
353
+		$metadata->addConstraint(new SessionPlanDates(array(
354
+			'message' => 'label_session_plan_dates_error',
355
+        )));
356
+        
357
+    // -- test les doublons
358
+        $metadata->addConstraint(new UniqueEntity(array(
359
+            'fields' => array('name'),
360
+            'message' => "validator_label_session_plan_duplicate_error",
361
+        )));
362
+    }
337 363
 }
338 364
 ?>

+ 28
- 0
src/CaptainLearning/Entity/sessionPlan/constraints/SessionPlanDates.php View File

@@ -0,0 +1,28 @@
1
+<?php
2
+namespace Logipro\CaptainLearning\Entity\SessionPlan\Constraints;
3
+
4
+use Symfony\Component\Validator\Constraint;
5
+
6
+class SessionPlanDates extends Constraint
7
+{
8
+	public $message = 'This value is already used.';
9
+
10
+	/**
11
+	 * The validator must be defined as a service with this name.
12
+	 *
13
+	 * @return string
14
+	 */
15
+	public function validatedBy()
16
+	{
17
+		return "Logipro\CaptainLearning\Entity\SessionPlan\Constraints\SessionPlanDatesValidator";
18
+	}
19
+
20
+	/**
21
+     * {@inheritdoc}
22
+     */
23
+    public function getTargets()
24
+    {
25
+        return self::CLASS_CONSTRAINT;
26
+    }
27
+}
28
+?>

+ 34
- 0
src/CaptainLearning/Entity/sessionPlan/constraints/SessionPlanDatesValidator.php View File

@@ -0,0 +1,34 @@
1
+<?php
2
+namespace Logipro\CaptainLearning\Entity\SessionPlan\Constraints;
3
+
4
+use Symfony\Component\Validator\Constraint;
5
+use Logipro\CaptainLearning\Entity\SessionPlan\SessionPlan;
6
+
7
+use Symfony\Component\Validator\ConstraintValidator;
8
+
9
+class SessionPlanDatesValidator extends ConstraintValidator
10
+{
11
+	public function validate($entity, Constraint $constraint)
12
+	{
13
+		if (is_a($entity,SessionPlan::class))
14
+		{
15
+			$start = $entity->getDateStart();
16
+			$end = $entity->getDateEnd();
17
+
18
+			// le numéro est valide si la somme des chiffres est multiple de 10
19
+			if ($start && $end && $start->getTimeStamp() > $end->getTimeStamp())
20
+			{
21
+				$this->context->buildViolation($constraint->message)
22
+				->atPath('date_start')
23
+				->setParameter('{{ value }}', $this->formatValue($start))
24
+				->addViolation();
25
+
26
+				$this->context->buildViolation($constraint->message)
27
+				->atPath('date_end')
28
+				->setParameter('{{ value }}',$this->formatValue($end))
29
+				->addViolation();
30
+			}
31
+		}
32
+	}
33
+}
34
+?>

+ 1
- 0
src/CaptainLearning/Form/Admin/CategoryType.php View File

@@ -33,6 +33,7 @@ class CategoryType extends AbstractType
33 33
 			},
34 34
             'choice_label' => 'name',
35 35
 			'required' => false,
36
+			'mapped'=> false,
36 37
 		))
37 38
 		->add('metaTitle', TextType::class, array(
38 39
 			'required' => false,

+ 51
- 0
src/CaptainLearning/Form/Profil/SessionPlanRouteType.php View File

@@ -0,0 +1,51 @@
1
+<?php
2
+namespace Logipro\CaptainLearning\Form\Profil;
3
+
4
+use Symfony\Component\Form\AbstractType;
5
+use Logipro\CaptainLearning\Entity\SessionPlan\SessionPlan;
6
+use Symfony\Component\Form\FormBuilderInterface;
7
+use Vich\UploaderBundle\Form\Type\VichImageType;
8
+use Symfony\Bridge\Doctrine\Form\Type\EntityType;
9
+use Logipro\CaptainLearning\Entity\Company\Company;
10
+use Symfony\Component\Validator\Constraints\DateTime;
11
+use Logipro\CaptainLearning\Form\Type\CPTDateTimeType;
12
+use Symfony\Component\OptionsResolver\OptionsResolver;
13
+use Symfony\Component\Form\Extension\Core\Type\TextType;
14
+use Symfony\Component\Form\Extension\Core\Type\TimeType;
15
+use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
16
+use Symfony\Component\Form\Extension\Core\Type\TextareaType;
17
+
18
+class SessionPlanRouteType extends AbstractType
19
+{
20
+	public function buildForm(FormBuilderInterface $builder, array $options)
21
+	{
22
+        $builder
23
+        ->add('name', TextType::class, array(
24
+			'required' => true
25
+		))
26
+        ->add('date_start', CPTDateTimeType::class, array(
27
+            'required' => false,
28
+            'date_widget' => 'single_text',
29
+            'date_format' => 'dd/MM/yyyy',
30
+            'required' => true
31
+            
32
+        ))
33
+        ->add('date_end', CPTDateTimeType::class, array(
34
+            'required' => false,
35
+            'date_widget' => 'single_text',
36
+            'date_format' => 'dd/MM/yyyy',
37
+            'required' => true
38
+        ))
39
+        ->add('description', TextareaType::class, array(
40
+			'required' => false,
41
+        ));
42
+	}
43
+
44
+    public function configureOptions(OptionsResolver $resolver)
45
+    {
46
+        $resolver->setDefaults(array(
47
+            'data_class' => SessionPlan::class,
48
+            'label_format' => 'form_%id%'
49
+        ));
50
+    }
51
+}

+ 54
- 0
src/CaptainLearning/Form/Profil/SessionPlanWishType.php View File

@@ -0,0 +1,54 @@
1
+<?php
2
+namespace Logipro\CaptainLearning\Form\Profil;
3
+
4
+use Symfony\Component\Form\AbstractType;
5
+use Logipro\CaptainLearning\Entity\SessionPlan\SessionPlan;
6
+use Symfony\Component\Form\FormBuilderInterface;
7
+use Vich\UploaderBundle\Form\Type\VichImageType;
8
+use Symfony\Bridge\Doctrine\Form\Type\EntityType;
9
+use Logipro\CaptainLearning\Entity\Company\Company;
10
+use Symfony\Component\Validator\Constraints\DateTime;
11
+use Logipro\CaptainLearning\Form\Type\CPTDateTimeType;
12
+use Symfony\Component\OptionsResolver\OptionsResolver;
13
+use Symfony\Component\Form\Extension\Core\Type\TextType;
14
+use Symfony\Component\Form\Extension\Core\Type\TimeType;
15
+use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
16
+use Symfony\Component\Form\Extension\Core\Type\TextareaType;
17
+
18
+class SessionPlanWishType extends AbstractType
19
+{
20
+    public function buildForm(FormBuilderInterface $builder, array $options)
21
+	{
22
+        $builder
23
+        ->add('name', TextType::class, array(
24
+			'required' => true
25
+		))
26
+        ->add('date_start', CPTDateTimeType::class, array(
27
+            'required' => false,
28
+            'date_widget' => 'single_text',
29
+            'date_format' => 'dd/MM/yyyy',
30
+            
31
+        ))
32
+        ->add('date_end', CPTDateTimeType::class, array(
33
+            'required' => false,
34
+            'date_widget' => 'single_text',
35
+            'date_format' => 'dd/MM/yyyy',
36
+        ))
37
+        ->add('description', TextareaType::class, array(
38
+			'required' => false,
39
+        ))
40
+        ->add('company', EntityType::class, array(
41
+            'class' => Company::class,
42
+            'choice_label' => 'name',
43
+			'required' => true,
44
+        ));
45
+	}
46
+
47
+    public function configureOptions(OptionsResolver $resolver)
48
+    {
49
+        $resolver->setDefaults(array(
50
+            'data_class' => SessionPlan::class,
51
+            'label_format' => 'form_%id%'
52
+        ));
53
+    }
54
+}

+ 58
- 0
src/CaptainLearning/Form/Type/CPTDateTimeType.php View File

@@ -0,0 +1,58 @@
1
+<?php
2
+namespace Logipro\CaptainLearning\Form\Type;
3
+
4
+use Symfony\Component\Form\FormView;
5
+use Symfony\Component\Form\AbstractType;
6
+use Symfony\Component\Form\FormInterface;
7
+use Symfony\Component\OptionsResolver\OptionsResolver;
8
+use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
9
+
10
+class CPTDateTimeType extends AbstractType
11
+{
12
+	/**
13
+	 *
14
+	 * @param FileUploader $uploader
15
+	 */
16
+	public function __construct()
17
+	{
18
+	}
19
+
20
+	public function getParent()
21
+    {
22
+        return DateTimeType::class;
23
+    }
24
+
25
+	/**
26
+	 *
27
+	 * {@inheritDoc}
28
+	 * @see \Symfony\Component\Form\AbstractType::getBlockPrefix()
29
+	 */
30
+	public function getBlockPrefix()
31
+	{
32
+		return 'captain_datetime';
33
+	}
34
+
35
+	/**
36
+	 *
37
+	 * {@inheritDoc}
38
+	 * @see \Symfony\Component\Form\AbstractType::configureOptions()
39
+	 */
40
+	public function configureOptions(OptionsResolver $resolver)
41
+	{
42
+		/*$resolver->setDefaults(array(
43
+			'label' => false,
44
+			'compound' => false,
45
+		));*/
46
+	}
47
+
48
+	/**
49
+	 *
50
+	 * {@inheritDoc}
51
+	 * @see \Symfony\Component\Form\AbstractType::buildView()
52
+	 */
53
+	public function buildView(FormView $view, FormInterface $form, array $options)
54
+	{
55
+		// Taille max de l'upload
56
+		//$view->vars['upload_max_size'] = $this->uploader->getUploadMaxSize();
57
+	}
58
+}

+ 104
- 1
src/CaptainLearning/Repository/SessionPlanRepository.php View File

@@ -1,12 +1,14 @@
1 1
 <?php
2 2
 namespace Logipro\CaptainLearning\Repository;
3 3
 
4
-use Logipro\CaptainLearning\Entity\SessionPlan;
5 4
 use Doctrine\ORM\Tools\Pagination\Paginator;
5
+use Logipro\CaptainLearning\Entity\User\User;
6 6
 
7 7
 use Symfony\Bridge\Doctrine\RegistryInterface;
8 8
 
9 9
 use Logipro\CaptainLearning\Component\Filter\Filter;
10
+use Logipro\CaptainLearning\Entity\SessionPlan\SessionPlan;
11
+use Logipro\CaptainLearning\Entity\Type\EnumSessionPlanType;
10 12
 use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
11 13
 
12 14
 class SessionPlanRepository extends ServiceEntityRepository
@@ -15,4 +17,105 @@ class SessionPlanRepository extends ServiceEntityRepository
15 17
 	{
16 18
 		parent::__construct($registry, SessionPlan::class);
17 19
 	}
20
+
21
+	public function getWishByFilter(Filter $filter,$options)
22
+	{
23
+		$queryBuilder = $this->createQueryBuilder('plan');
24
+
25
+		// Tri
26
+		$sortName = $filter->getSortKey();
27
+		$sortOrder = $filter->getSortOrder();
28
+		switch ($sortName)
29
+		{
30
+			case 'start':
31
+				$queryBuilder->orderBy('plan.date_start', $sortOrder);
32
+				break;
33
+			case 'end':
34
+				$queryBuilder->orderBy('plan.date_end', $sortOrder);
35
+				break;
36
+
37
+			default:
38
+				$queryBuilder->orderBy('plan.name', $sortOrder);
39
+				break;
40
+		}
41
+
42
+		foreach ($options as $name =>  $option)
43
+		{
44
+			$queryBuilder->andWhere('plan.' . $name . ' = :' . 'option_' . $name);
45
+			$queryBuilder->setParameter('option_' . $name,$option);
46
+		}
47
+
48
+		$queryBuilder->andWhere($queryBuilder->expr()->isNull('plan.company'));
49
+		$queryBuilder->andWhere('plan.type = :option_type');
50
+		$queryBuilder->setParameter('option_type',EnumSessionPlanType::TYPE_USER_WISH);
51
+		
52
+
53
+		$query = $queryBuilder->getQuery();
54
+		$paginator = new Paginator($query);
55
+
56
+		$filter->paginate($paginator);
57
+
58
+		return $paginator;
59
+	}
60
+	public function getRequestByFilter(Filter $filter,$options)
61
+	{
62
+		$queryBuilder = $this->createQueryBuilder('plan');
63
+		$queryBuilder->leftJoin('plan.company', 'company');
64
+		// Tri
65
+		$sortName = $filter->getSortKey();
66
+		$sortOrder = $filter->getSortOrder();
67
+		switch ($sortName)
68
+		{
69
+			case 'start':
70
+				$queryBuilder->orderBy('plan.date_start', $sortOrder);
71
+				break;
72
+			case 'end':
73
+				$queryBuilder->orderBy('plan.date_end', $sortOrder);
74
+				break;
75
+			case 'companyname':
76
+				$queryBuilder->orderBy('company.name', $sortOrder);
77
+				break;
78
+
79
+			default:
80
+				$queryBuilder->orderBy('plan.name', $sortOrder);
81
+				break;
82
+		}
83
+
84
+		foreach ($options as $name =>  $option)
85
+		{
86
+			$queryBuilder->andWhere('plan.' . $name . ' = :' . 'option_' . $name);
87
+			$queryBuilder->setParameter('option_' . $name,$option);
88
+		}
89
+
90
+		$queryBuilder->andWhere($queryBuilder->expr()->isNotNull('plan.company'));
91
+		$queryBuilder->andWhere('plan.type = :option_type');
92
+		$queryBuilder->setParameter('option_type',EnumSessionPlanType::TYPE_USER_WISH);
93
+
94
+		$query = $queryBuilder->getQuery();
95
+		$paginator = new Paginator($query);
96
+
97
+		$filter->paginate($paginator);
98
+
99
+		return $paginator;
100
+	}
101
+
102
+	/**
103
+	 * retourne les session plan pour le plan de formation
104
+	 * 
105
+	 * @param User $user
106
+	 */
107
+	public function getForRoute(User $user)
108
+	{
109
+		$queryBuilder = $this->createQueryBuilder('plan');
110
+
111
+		$queryBuilder->andWhere('plan.type = :option_type');
112
+		$queryBuilder->setParameter('option_type',EnumSessionPlanType::TYPE_USER_ROUTE);
113
+		$queryBuilder->andWhere('plan.user = :option_user');
114
+		$queryBuilder->setParameter('option_user',$user);
115
+
116
+		$queryBuilder->orderBy('plan.dateStart', 'DESC');
117
+
118
+		$query = $queryBuilder->getQuery();
119
+		return $query->execute();
120
+	}
18 121
 }

+ 1
- 0
src/CaptainLearning/Twig/BackOffice/EnumExtension.php View File

@@ -7,6 +7,7 @@ use Logipro\CaptainLearning\Entity\Role;
7 7
 
8 8
 use Logipro\CaptainLearning\Entity\Type\EnumRoleType;
9 9
 use Symfony\Component\DependencyInjection\ContainerInterface;
10
+use Logipro\CaptainLearning\Entity\Type\EnumTrainingTypeType;
10 11
 
11 12
 class EnumExtension extends AbstractExtension
12 13
 {

+ 1
- 0
src/CaptainLearning/Twig/FilterExtension.php View File

@@ -119,6 +119,7 @@ class FilterExtension extends AbstractExtension
119 119
 			'parameters' => $filter->getParameters(),
120 120
 			'routeName' => $filter->getRouteName(),
121 121
 			'routeParameters' => $filter->getRouteParameters(),
122
+			'currentSortKey' => $filter->getSortKey()
122 123
 		);
123 124
 		return $this->renderView('common/layout/component/filter/label_list.html.twig',$parameters);
124 125
 	}

+ 18
- 0
templates/backOffice/common/form.html.twig View File

@@ -0,0 +1,18 @@
1
+{% extends "backOffice/individual/layout/layout.base.html.twig" %}
2
+{% block body %}
3
+    <div class="my-3 w-100">
4
+        <div class="">
5
+            <div class="d-flex flex-wrap-reverse pr-1 pr-md-3">
6
+                <h1 class="m-0 mx-1 mx-md-3 font-weight-bold text-dark align-self-center">{{ list_title }}</h1>
7
+                <div class="d-flex ml-auto">
8
+                    {% if path_add %}
9
+                        <a href="{{ path_add }}"{% if title_add %} title="{{ title_add }}"{% endif %} class="ml-auto ion-android-add btn-primary btn-add" data-toggle="tooltip" data-placement="bottom"></a>
10
+                    {% endif %}
11
+                </div>
12
+            </div>
13
+            <div class="row mx-0">
14
+                {{ cpt_drawwidgets(widgets)|raw }}
15
+            </div>
16
+        </div>
17
+    </div>
18
+{% endblock %}

+ 1
- 2
templates/backOffice/common/layout/menu.base.html.twig View File

@@ -1,5 +1,4 @@
1
-{% set currentRoute = path(app.request.attributes.get('_route')) %}
2
-{% set currentRouteWithParam = path(app.request.attributes.get('_route'),
1
+{% set currentRoute = path(app.request.attributes.get('_route'),
3 2
 	app.request.attributes.get('_route_params')) %}
4 3
 	  
5 4
 <div class="nave-space-background"></div>

+ 18
- 0
templates/backOffice/common/list.html.twig View File

@@ -0,0 +1,18 @@
1
+{% extends "backOffice/individual/layout/layout.base.html.twig" %}
2
+{% block body %}
3
+    <div class="my-3 w-100">
4
+        <div class="">
5
+            <div class="d-flex flex-wrap-reverse pr-1 pr-md-3">
6
+                <h1 class="m-0 mx-1 mx-md-3 font-weight-bold text-dark align-self-center">{{ list_title }}</h1>
7
+                <div class="d-flex ml-auto">
8
+                    {% if path_add %}
9
+                        <a href="{{ path_add }}"{% if title_add %} title="{{ title_add }}"{% endif %} class="ml-auto ion-android-add btn-primary btn-add" data-toggle="tooltip" data-placement="bottom"></a>
10
+                    {% endif %}
11
+                </div>
12
+            </div>
13
+            <div class="row mx-0">
14
+                {{ cpt_drawwidgets(widgets)|raw }}
15
+            </div>
16
+        </div>
17
+    </div>
18
+{% endblock %}

+ 35
- 0
templates/backOffice/common/training/training.html.twig View File

@@ -0,0 +1,35 @@
1
+<div>
2
+	<div class="form-separator d-flex border-bottom py-3 mb-3">
3
+        <h2>Formation liée</h2>
4
+    </div>
5
+
6
+    <div class="row  m-1 py-3 border">
7
+        <div class="col-12">
8
+            <h3><a href="" target="_blank">{{ training.getName() }}</a></h3>
9
+        </div>
10
+        <div class="col-12 col-md-auto align-self-center pr-0 text-center">
11
+            <div class="text-center mx-auto" style="width: 200px;">
12
+                <img class="img-fluid" src="" alt="Aperçu">
13
+            </div>
14
+        </div>
15
+
16
+        <div class="col-12 col-md">
17
+            <div class="mx-1 py-1 border-bottom d-lg-flex">
18
+                <div><ion-icon class="ion-document mr-2 d-inline-block text-center" style="width: 20px; font-size: 20px;"></ion-icon><span class="h5 d-inline-block" style="width:120px;">Modalités</span></div>
19
+
20
+                <div style="margin-left: 29px;" class="col p-1 d-flex d-lg-block flex-wrap">
21
+                {{ training.getModality() }}
22
+                </div>
23
+            </div>
24
+
25
+
26
+            <div class="mx-1 py-1 border-bottom d-lg-flex">
27
+                <div><ion-icon class="ion-social-euro mr-2 d-inline-block text-center" style="width: 20px; font-size: 20px;"></ion-icon><span class="h5 d-inline-block" style="width:120px;">Prix indicatif</span></div>
28
+
29
+                <div style="margin-left: 29px;" class="col p-1 d-flex d-lg-block flex-wrap">
30
+                    <span class=" mr-2 mb-2">{{ training.getPrice()|number_format(2, '.', ' ') }}&nbsp;€ <sup>HT</sup> /place</span>
31
+                </div>
32
+            </div>
33
+        </div>
34
+    </div>
35
+</div>

+ 5
- 0
templates/backOffice/common/widget/form.html.twig View File

@@ -0,0 +1,5 @@
1
+{% extends "backOffice/common/widget/layout.html.twig" %}
2
+{% block nav_list %}
3
+{% endblock %}
4
+{% block body %}
5
+{% endblock %}

+ 32
- 0
templates/backOffice/common/widget/list.html.twig View File

@@ -0,0 +1,32 @@
1
+{% extends "backOffice/common/widget/layout.html.twig" %}
2
+{% block nav_list %}
3
+{% endblock %}
4
+{% block body %}
5
+    {% if objects %}
6
+        <table class="table w-100">
7
+        <thead>
8
+            <tr>
9
+                {% block header_list %}
10
+                {% endblock %}
11
+            </tr>
12
+        </thead>
13
+        <tbody>
14
+            <div class="float-right mb-2">
15
+                <div class="d-flex justify-content-end align-items-center ml-auto ">
16
+                    <div class="form-group mb-0 ml-2">
17
+                        {{ cpt_drawlimit(filter)|raw }}
18
+                    </div>
19
+                </div>
20
+            </div>
21
+            <div class="mb-2">
22
+			<div>
23
+                {{ filter.getNumResults() }} {{ object_name }}
24
+            </div>            
25
+            {% block body_list %}
26
+            {% endblock %}
27
+        </tbody>
28
+        </table>
29
+        {{ cpt_drawpagination(filter)|raw }}
30
+    {% else %}
31
+    {% endif %}
32
+{% endblock %}

+ 6
- 0
templates/backOffice/individual/sessionPlan/common/form.html.twig View File

@@ -0,0 +1,6 @@
1
+{% extends "backOffice/common/form.html.twig" %}
2
+
3
+{% block body_javascripts %}
4
+	{{ parent() }}
5
+	<script src="{{ asset('build/individual.sessionplan.form.js') }}"></script>
6
+{% endblock %}

+ 42
- 0
templates/backOffice/individual/sessionPlan/request/widget-request-list.html.twig View File

@@ -0,0 +1,42 @@
1
+{% extends "backOffice/common/widget/list.html.twig" %}
2
+{% block header_list %}
3
+	<th scope="col" class="header">
4
+		<a class="text-nowrap" href="" data-toggle="tooltip" title="" data-original-title="">{{ cpt_setsort(filter,'name', 'label_session_plan_name'|trans)|raw }}
5
+		</a>
6
+	</th>
7
+	<th scope="col" class="header">
8
+		<a class="text-nowrap" href="" data-toggle="tooltip" title="" data-original-title="">{{ cpt_setsort(filter,'start', 'label_session_plan_date_start'|trans)|raw }}
9
+		</a>
10
+	</th>
11
+	<th scope="col" class="header">
12
+		<a class="text-nowrap" href="" data-toggle="tooltip" title="" data-original-title="">{{ cpt_setsort(filter,'end', 'label_session_plan_date_end'|trans)|raw }}
13
+		</a>
14
+	</th>
15
+	<th scope="col" class="header">
16
+		<a class="text-nowrap" href="" data-toggle="tooltip" title="" data-original-title="">{{ cpt_setsort(filter,'companyname', 'label_session_plan_company_name'|trans)|raw }}
17
+		</a>
18
+	</th>
19
+	<th scope="col" class="header">
20
+		{{'label_list_action'|trans }}
21
+	</th>
22
+{% endblock %}
23
+{% block body_list %}
24
+{% if not objects is empty %}
25
+	{% for object in objects %}
26
+	<tr>
27
+		<td class="table__cell">{{ object.getName() }}</td>
28
+		<td class="table__cell">{{ object.getDateStart()|date("d/m/Y") }}</td>
29
+		<td class="table__cell">{{ object.getDateEnd()|date("d/m/Y") }}</td>
30
+		<td class="table__cell">{{ object.getCompany().getName() }}</td>
31
+		<td class="">
32
+			<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButtonList{{ object.getSessionPlanId() }}" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
33
+			</button>
34
+			<div class="dropdown-menu" aria-labelledby="dropdownMenuButtonList{{ object.getSessionPlanId() }}">
35
+				<a class="dropdown-item" href="{{ path('drawSessionPlanRequest',{'sessionPlanId': object.getSessionPlanId() }) }}">{{ 'label_list_view'|trans }}</a>
36
+			</div>
37
+		</td>
38
+	</tr>
39
+	{% endfor %}
40
+	
41
+{% endif %}
42
+{% endblock %}

+ 52
- 0
templates/backOffice/individual/sessionPlan/request/widget-session-plan.html.twig View File

@@ -0,0 +1,52 @@
1
+{% extends "backOffice/common/widget/form.html.twig" %}
2
+
3
+{% block body %}
4
+	<div class="form-separator d-flex border-bottom py-3 mb-3">
5
+		<h2>Informations générales</h2>
6
+	</div>
7
+
8
+	<div class="row">
9
+		<div class="col-md">
10
+			<h3 class="d-block h5 font-weight-bold">Intitulé</h3>
11
+			<p class="ml-4">{{ sessionplan.getName() }}</p>
12
+		</div>
13
+	</div>
14
+
15
+	
16
+	<div class="">
17
+		<div>
18
+			<h3 class="d-block h5 font-weight-bold">Date</h3>
19
+
20
+			<p class="ml-4">
21
+				Du {{ sessionplan.getDateStart()|date("d/m/Y H:i") }}
22
+				au {{ sessionplan.getDateEnd()|date("d/m/Y H:i") }}
23
+			</p>
24
+		</div>
25
+	</div>
26
+	
27
+	<div class="row">
28
+		<div class="col-md-4 col-sm-12">
29
+			<div class="row">
30
+				<div class="col">
31
+					<h3 class="d-block h5 font-weight-bold">Description</h3>
32
+					<p class="ml-4">{{ sessionplan.getDescription() }}</p>
33
+				</div>
34
+			</div>
35
+		</div>
36
+	</div>
37
+
38
+
39
+	<div class="row">
40
+		<div class="col-md-4 col-sm-12">
41
+			<div class="row">
42
+				<div class="col">
43
+					<h3 class="d-block h5 font-weight-bold">Société liée à la demande</h3>
44
+					<p class="ml-4">{{ sessionplan.getCompany().getName() }}</p>
45
+				</div>
46
+			</div>
47
+		</div>
48
+	</div>
49
+
50
+{% set training = sessionplan.getTraining() %}
51
+{% include 'backOffice/common/training/training.html.twig' %}
52
+{% endblock %}

+ 1
- 0
templates/backOffice/individual/sessionPlan/route/bloc-list.html.twig View File

@@ -0,0 +1 @@
1
+{% extends "backOffice/common/widget/layout.html.twig" %}

+ 1
- 0
templates/backOffice/individual/sessionPlan/route/route.html.twig View File

@@ -0,0 +1 @@
1
+{% extends "backOffice/common/form.html.twig" %}

+ 53
- 0
templates/backOffice/individual/sessionPlan/route/widget-form.html.twig View File

@@ -0,0 +1,53 @@
1
+{% extends "backOffice/common/widget/form.html.twig" %}
2
+
3
+{% block body %}
4
+{{ form_start(form, {attr: {class: 'form-with-validation needs-validation pb-0'} }) }}
5
+<div class="form-separator d-flex border-bottom py-3 mb-3">
6
+    <h2>{{ 'label_session_plan_edit_title'|trans }}</h2>
7
+</div>
8
+
9
+<div class="form-row">
10
+    <div class="form-group col-md">
11
+         {{ form_label(form.name) }}
12
+         {{ form_widget(form.name,{attr: {class: 'form-control'}}) }}
13
+        <div class="invalid-feedback">
14
+           {{ 'label_session_plan_name_error'|trans }}
15
+        </div>
16
+    </div>
17
+</div>
18
+
19
+{% set checked = sessionplan.getDateStart() != null %}
20
+<div class="form-group row">
21
+    <div class="col">
22
+        {{ form_label(form.date_start) }}
23
+        {{ form_widget(form.date_start,{attr: {class: 'custom-date ml-0','data-toggle':'datepicker','data-error-display':"erreur de date, la date de début doit etre inférieur ou égale a la date de fin"}}) }}
24
+    </div>
25
+</div>
26
+<div class="form-group row">
27
+    <div class="col">
28
+        {{ form_label(form.date_end) }}
29
+        {{ form_widget(form.date_end,{attr: {class: 'custom-date ml-0','data-toggle':'datepicker','data-error-display':"erreur de date, la date de début doit etre inférieur ou égale a la date de fin"}}) }}
30
+    </div>
31
+</div>
32
+
33
+<div class="form-row">
34
+    <div class="form-group col-md">
35
+        {{ form_label(form.description) }}
36
+        {{ form_widget(form.description,{attr: {class: 'form-control'}}) }}
37
+        <div class="invalid-feedback">
38
+        {{ 'label_session_plan_description_error'|trans }}
39
+        </div>
40
+    </div>
41
+</div>
42
+
43
+{% set training = sessionplan.getTraining() %}
44
+{% if training %}
45
+{% include 'backOffice/common/training/training.html.twig' %}
46
+{% endif %}
47
+
48
+ <div class="text-center form-lama-validate">
49
+    <button type="submit" class="btn btn-primary">{{ 'label_button_validate_edit'|trans }}</button>
50
+</div>
51
+
52
+{{ form_end(form) }}
53
+{% endblock %}

+ 131
- 0
templates/backOffice/individual/sessionPlan/route/widget-list.html.twig View File

@@ -0,0 +1,131 @@
1
+{% extends "backOffice/common/widget/layout.html.twig" %}
2
+{% block body %}
3
+<!-- legende -->
4
+<ul class="cpt-parcours-legende float-right p-0" >
5
+    <li class="parcours-statut-old">{{ 'label_session_plan_passed'|trans }}</li>
6
+    <li class="parcours-statut-now">{{ 'label_session_plan_in_progress'|trans }}</li>
7
+    <li class="parcours-statut-coming">{{ 'label_session_plan_coming'|trans }}</li>
8
+</ul>
9
+<div class="clear-both"></div>
10
+
11
+<!-- parcours -->
12
+<div class="cpt-parcours">
13
+    {% set parseYear = 0 %}
14
+    
15
+    {% for session_plan in objects %}
16
+		{% set increment = increment + 1 %}
17
+		{% set isImpair = increment%2 %}
18
+        {% set sessionPlanEnd = session_plan.getDateEnd() %}
19
+        {% set sessionPlanYear = sessionPlanEnd.format('Y') %}
20
+
21
+		{# premier parcours, on initialise les couleurs à aprtir du premier #}
22
+		{% if not classColor %}
23
+			{% set oldClassColor = '' %}
24
+			{% set classColor = 'parcours-statut-old' %}
25
+			{% if sessionPlanEnd|date("Y-m-d") > "now"|date("Y-m-d") %}
26
+				{% set classColor = 'parcours-statut-coming' %}
27
+				{% if sessionPlanStart|date("Y-m-d") < "now"|date("Y-m-d") %}
28
+					{% set classColor = 'parcours-statut-now' %}
29
+				{% endif %}
30
+			{% endif %}
31
+		{% endif %}
32
+
33
+         <!-- annee -->
34
+        {% if parseYear != sessionPlanYear %}
35
+            {% set parseYear = sessionPlanYear %}
36
+
37
+            <div class="row cpt-parcours-element cpt-parcours-element-annee">
38
+				<!-- bloc alignement -->
39
+                <div class="col order-1 order-lg-0 pr-0 pr-lg-2">
40
+                </div>
41
+				<!-- année -->
42
+                <div class="cpt-parcours-date-valign cpt-parcours-annee {{ classColor }} {{ oldClassColor }} d-flex order-0 order-lg-1">
43
+                    <div class="w-100 text-center">{{ parseYear }}</div>
44
+                </div>
45
+				<!-- bloc alignement -->
46
+                <div class="col order-1 order-lg-2 pr-0 pr-lg-2>">
47
+                </div>
48
+            </div>
49
+        {% endif %}
50
+
51
+		<!-- Contenu -->
52
+		<div class="row cpt-parcours-element">
53
+			{# initialise les placements des div #}
54
+			{% set description_class = 'cpt-arrow-right cpt-arrow-sm-down-top mr-lg-0 my-1 ml-4' %}
55
+			{% set description_left_class = 'col order-1 px-0' %}
56
+			{% set description_right_class = 'col order-1 px-0 d-none d-lg-block' %}
57
+
58
+			{% if isImpair %}
59
+				{% set description_left_class = description_left_class ~ " order-lg-2" %}
60
+				{% set description_right_class = description_right_class ~ " order-lg-0" %}
61
+			{% else %}
62
+				{% set description_left_class = description_left_class ~ " order-lg-0" %}
63
+				{% set description_right_class = description_right_class ~ " order-lg-2"  %}
64
+				{% set description_class = description_class ~ " mr-0 mr-lg-4 ml-lg-0 cpt-arrow-lg-left" %}
65
+			{% endif %}
66
+
67
+			<!-- div 1 -->
68
+			<div class="{{ description_left_class }}">
69
+				<div class="cpt-parcours-desc {{ description_class }}">
70
+					<!-- bouton edition -->
71
+					<div class="cpt-parcours-menu">
72
+						<button class="btn btn-secondary py-0 menu-element-parcours" type="button" id="dropdownMenuButton{{ session_plan.getSessionPlanId() }}" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
73
+							<ion-icon class="ion-android-more-vertical"></ion-icon>
74
+						</button>
75
+						<div class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownMenuButton{{ session_plan.getSessionPlanId() }}">
76
+							<a class="dropdown-item" href="{{ path('editSessionPlanRoute',{'sessionPlanId' : session_plan.getSessionPlanId() })}}">
77
+								{{ 'label_edit'|trans }}
78
+							</a>
79
+							<a class="dropdown-item delete-btn" href="{{ path('deleteSessionPlanRoute',{'sessionPlanId' : session_plan.getSessionPlanId() })}}">
80
+								{{ 'label_delete'|trans }}
81
+							</a>
82
+						</div>
83
+					</div>
84
+
85
+					<div class="p-2">
86
+						<div class="d-inline">
87
+							<h2 class="h3 mx-4" title="{{ session_plan.getName() }}">{{ session_plan.getName() }}</h2>
88
+							{% if session_plan.getDateStart()|date('d-m-Y') == session_plan.getDateEnd()|date('d-m-Y') %}
89
+								le {{ session_plan.getDateStart()|date('d/m/Y') }}
90
+							{% else %}
91
+								du {{ session_plan.getDateStart()|date('d/m/Y') }} au {{ session_plan.getDateEnd()|date('d/m/Y') }}
92
+							{% endif %}
93
+							{% set company = session_plan.getCompany() %}
94
+							{% if session_plan.getCompany() %}
95
+								<p class="m-0">Entr : {{ company.getName() }}</p>
96
+							{% endif %}
97
+						</div>
98
+					</div>
99
+				</div>
100
+			</div>
101
+
102
+			{% set oldClassColor = classColor ~ "-before" %}
103
+			{% set classColor = 'parcours-statut-old' %}
104
+			{% if sessionPlanEnd|date("Y-m-d") > "now"|date("Y-m-d") %}
105
+				{% set classColor = 'parcours-statut-coming' %}
106
+				{% if sessionPlanStart|date("Y-m-d") < "now"|date("Y-m-d") %}
107
+					{% set classColor = 'parcours-statut-now' %}
108
+				{% endif %}
109
+			{% endif %}
110
+
111
+			<!-- div 2 = rond coloré -->
112
+			<div class="cpt-parcours-date-valign {{ classColor }} {{ oldClassColor }} d-flex order-0 order-lg-1 ml-0 mx-1">
113
+				<div class="cpt-parcours-date-content {{ classColor }} align-self-center">
114
+					<div class="cpt-parcours-date {{ classColor }}">
115
+						<div class="cpt-parcours-day">
116
+							{{ session_plan.getDateEnd()|date('d') }}
117
+						</div>
118
+						<div class="cpt-parcours-month">
119
+							{{ session_plan.getDateEnd()|date('M') }}
120
+						</div>
121
+					</div>
122
+				</div>
123
+			</div>
124
+
125
+			<!-- div 3 vide pour alignement -->
126
+			<div class="{{ description_right_class }}">
127
+			</div>
128
+		</div>
129
+    {% endfor %}
130
+</div>
131
+{% endblock %}

+ 65
- 0
templates/backOffice/individual/sessionPlan/wish/widget-wish-form.html.twig View File

@@ -0,0 +1,65 @@
1
+{% extends "backOffice/common/widget/form.html.twig" %}
2
+
3
+{% block body %}
4
+{{ form_start(form, {attr: {class: 'form-with-validation needs-validation pb-0'} }) }}
5
+<div class="form-separator d-flex border-bottom py-3 mb-3">
6
+    <h2>{{ 'label_session_plan_edit_title'|trans }}</h2>
7
+</div>
8
+
9
+<div class="form-row">
10
+    <div class="form-group col-md">
11
+         {{ form_label(form.name) }}
12
+         {{ form_widget(form.name,{attr: {class: 'form-control'}}) }}
13
+        <div class="invalid-feedback">
14
+           {{ 'label_session_plan_name_error'|trans }}
15
+        </div>
16
+    </div>
17
+</div>
18
+
19
+{% set checked = sessionplan.getDateStart() != null %}
20
+<input class="mr-2 custom-checkbox" type="checkbox" name="add_periode" id="add_periode"{% if checked %} checked{% endif %}>
21
+<label class="like-label" for="add_periode">Envisager une période</label>
22
+<div id="periode-content" class="{% if not checked %}d-none{% endif %}">
23
+    <div class="form-group row ml-2">
24
+        <div class="col">
25
+            {{ form_label(form.date_start) }}
26
+            {{ form_widget(form.date_start,{attr: {class: 'custom-date','data-toggle':'datepicker','data-error-display':"erreur de date, la date de début doit etre inférieur ou égale a la date de fin"}}) }}
27
+        </div>
28
+    </div>
29
+    <div class="form-group row ml-2">
30
+        <div class="col">
31
+            {{ form_label(form.date_end) }}
32
+            {{ form_widget(form.date_end,{attr: {class: 'custom-date','data-toggle':'datepicker','data-error-display':"erreur de date, la date de début doit etre inférieur ou égale a la date de fin"}}) }}
33
+        </div>
34
+    </div>
35
+</div>
36
+
37
+<div class="form-row">
38
+    <div class="form-group col-md">
39
+        {{ form_label(form.description) }}
40
+        {{ form_widget(form.description,{attr: {class: 'form-control'}}) }}
41
+        <div class="invalid-feedback">
42
+        {{ 'label_session_plan_description_error'|trans }}
43
+        </div>
44
+    </div>
45
+</div>
46
+
47
+{% set checked = sessionplan.getCompany() != null %}
48
+<input class="mr-2 custom-checkbox" type="checkbox" name="add_societe" id="add_societe"{% if checked %} checked{% endif %}>
49
+<label class="like-label" for="add_societe">{{ 'label_session_plan_add_society'|trans }}</label>
50
+<div id="societe-content"  class="{% if not checked %}d-none{% endif %}">
51
+    <div class="p-3 mb-2 bg-info text-white font-weight-bold">{{ 'label_session_plan_add_society_help'|trans }}</div>
52
+        {{ form_widget(form.company,{attr: {class: 'form-control'}}) }}
53
+</div>
54
+
55
+{% set training = sessionplan.getTraining() %}
56
+{% if training %}
57
+{% include 'backOffice/common/training/training.html.twig' %}
58
+{% endif %}
59
+
60
+ <div class="text-center form-lama-validate">
61
+    <button type="submit" class="btn btn-primary">{{ 'label_button_validate_edit'|trans }}</button>
62
+</div>
63
+
64
+{{ form_end(form) }}
65
+{% endblock %}

+ 38
- 0
templates/backOffice/individual/sessionPlan/wish/widget-wish-list.html.twig View File

@@ -0,0 +1,38 @@
1
+{% extends "backOffice/common/widget/list.html.twig" %}
2
+{% block header_list %}
3
+	<th scope="col" class="header">
4
+		<a class="text-nowrap" href="" data-toggle="tooltip" title="" data-original-title="">{{ cpt_setsort(filter,'name', 'label_session_plan_name'|trans)|raw }}
5
+		</a>
6
+	</th>
7
+	<th scope="col" class="header">
8
+		<a class="text-nowrap" href="" data-toggle="tooltip" title="" data-original-title="">{{ cpt_setsort(filter,'start', 'label_session_plan_date_start'|trans)|raw }}
9
+		</a>
10
+	</th>
11
+	<th scope="col" class="header">
12
+		<a class="text-nowrap" href="" data-toggle="tooltip" title="" data-original-title="">{{ cpt_setsort(filter,'end', 'label_session_plan_date_end'|trans)|raw }}
13
+		</a>
14
+	</th>
15
+	<th scope="col" class="header">
16
+		{{'label_list_action'|trans }}
17
+	</th>
18
+{% endblock %}
19
+{% block body_list %}
20
+{% if not objects is empty %}
21
+	{% for object in objects %}
22
+	<tr>
23
+		<td class="table__cell">{{ object.getName() }}</td>
24
+		<td class="table__cell">{{ object.getDateStart()|date("d/m/Y") }}</td>
25
+		<td class="table__cell">{{ object.getDateEnd()|date("d/m/Y") }}</td>
26
+		<td class="">
27
+			<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButtonList{{ object.getSessionPlanId() }}" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
28
+			</button>
29
+			<div class="dropdown-menu" aria-labelledby="dropdownMenuButtonList{{ object.getSessionPlanId() }}">
30
+				<a class="dropdown-item" href="{{ path('manageSessionPlanWish',{'sessionPlanId': object.getSessionPlanId() }) }}">{{ 'label_list_edit'|trans }}</a>
31
+				<a class="dropdown-item delete-btn" href="{{ path('deleteSessionPlanWish',{'sessionPlanId': object.getSessionPlanId() }) }}">{{ 'label_list_delete'|trans }}</a>
32
+			</div>
33
+		</td>
34
+	</tr>
35
+	{% endfor %}
36
+	
37
+{% endif %}
38
+{% endblock %}

+ 42
- 0
templates/common/form/cptdatetime.html.twig View File

@@ -0,0 +1,42 @@
1
+{% extends "form_div_layout.html.twig" %}
2
+
3
+{# Based on Foundation 5 Doc #}
4
+{# Widgets #}
5
+
6
+{% block datetime_widget -%}
7
+    {% if widget == 'single_text' %}
8
+        {{- block('form_widget_simple') -}}
9
+    {% else %}
10
+        {% set attr = attr|merge({class: (attr.class|default('') ~ ' row')|trim}) %}
11
+        <div class="row">
12
+            <div class="large-5 columns">{{ form_errors(form.date) }}</div>
13
+            <div class="large-7 columns">{{ form_errors(form.time) }}</div>
14
+        </div>
15
+        <div {{ block('widget_container_attributes') }}>
16
+            <div class="large-5 columns pr-0 pr-sm-1">{{ form_widget(form.date, { datetime: true } ) }}</div>
17
+            <div class="large-7 columns pt-