Commit f67e18fb authored by Stephane Bouvry's avatar Stephane Bouvry
Browse files

- [up] Interface des avenants OK

 - Ajout d'un bouton VUE avec des confirmations automatiques (Supression, application)
 - Toutes les modifications des avenants s'appliquent
parent 9650899d
Loading
Loading
Loading
Loading
Loading
+130 −6
Original line number Diff line number Diff line
@@ -8,6 +8,8 @@ use Moment\Moment;
use Oscar\Entity\Activity;
use Oscar\Entity\ActivityAvenant;
use Oscar\Entity\ActivityAvenantModification;
use Oscar\Entity\ActivityOrganization;
use Oscar\Entity\ActivityPerson;
use Oscar\Entity\Organization;
use Oscar\Entity\OrganizationRole;
use Oscar\Entity\Person;
@@ -22,20 +24,25 @@ use Oscar\Traits\UseLoggerService;
use Oscar\Traits\UseLoggerServiceTrait;
use Oscar\Traits\UseOscarConfigurationService;
use Oscar\Traits\UseOscarConfigurationServiceTrait;
use Oscar\Traits\UseProjectGrantService;
use Oscar\Traits\UseProjectGrantServiceTrait;
use Oscar\Utils\DateTimeUtils;
use Oscar\Utils\FileSystemUtils;

class ActivityAvenantsService implements
    UseLoggerService,
    UseEntityManager,
    UseActivityLogService,
    UseOscarConfigurationService
    UseEntityManager,
    UseLoggerService,
    UseOscarConfigurationService,
    UseProjectGrantService
{

    use UseLoggerServiceTrait,
        UseEntityManagerTrait,
    use
        UseActivityLogServiceTrait,
        UseOscarConfigurationServiceTrait;
        UseEntityManagerTrait,
        UseLoggerServiceTrait,
        UseOscarConfigurationServiceTrait,
        UseProjectGrantServiceTrait;

    /**
     * Création d'un nouvel avenant.
@@ -82,6 +89,7 @@ class ActivityAvenantsService implements
    public function saveAvenantFromArray(Activity $activity, array $datas): void
    {
        if ($datas['id']) {
            $this->getLoggerService()->debug("UPDATE avenant");
            $mode = "update";
            $avenant = $this->getEntityManager()
                ->getRepository(ActivityAvenant::class)
@@ -91,6 +99,7 @@ class ActivityAvenantsService implements
            }
        }
        else {
            $this->getLoggerService()->debug("CREATE avenant");
            $mode = "create";
            $avenant = new ActivityAvenant();
            $avenant->setStatus(ActivityAvenant::STATUS_DRAFT);
@@ -191,12 +200,127 @@ class ActivityAvenantsService implements
                        $modification->setOldValue1($activity->getDateEndStr());
                        $activity->setDateEnd($modification->getNewValue1());
                        break;

                    case ActivityAvenantModification::TYPE_CHANGE_AMOUNT:
                        $this->getLoggerService()->info($modification->getNewValue1());
                        $modification->setOldValue1($activity->getAmount());
                        $activity->setAmount($modification->getNewValue1());
                        break;

                    case ActivityAvenantModification::TYPE_PERSON_ADD:
                        try {
                            $person = $this->getEntityManager()
                                ->getRepository(Person::class)
                                ->find($modification->getNewValue1());
                            $this->getLoggerService()->info('person: ' . $person);
                            $role = $this->getEntityManager()
                                ->getRepository(Role::class)
                                ->find($modification->getNewValue2());
                            $this->getLoggerService()->info('role: ' . $role);

                            $this->getProjectGrantService()->getPersonService()->personActivityAdd(
                                $activity,
                                $person,
                                $role);

                        } catch (\Exception $e){
                            $this->getLoggerService()->critical($e->getMessage());
                            throw new OscarException("Impossible d'ajouter la personne dans l'activité");
                        }
                        break;

                    case ActivityAvenantModification::TYPE_PERSON_DEL:
                        try {
                            $person = $this->getEntityManager()
                                ->getRepository(Person::class)
                                ->find($modification->getNewValue1());
                            $this->getLoggerService()->info('person: ' . $person);
                            $role = $this->getEntityManager()
                                ->getRepository(Role::class)
                                ->find($modification->getNewValue2());
                            $this->getLoggerService()->info('role: ' . $role);

                            /** @var ActivityPerson $repo */
                            $affectations = $this->getEntityManager()
                                ->getRepository(ActivityPerson::class)
                                ->findBy([
                                    'activity' => $activity,
                                    'person' => $person,
                                    'roleObj' => $role,
                                         ]);

                            if( count($affectations) === 0 ) {
                                throw new OscarException("Affectation non-trouvée");
                            }
                            foreach ($affectations as $affectation) {
                                $this->getProjectGrantService()
                                    ->getPersonService()
                                    ->personActivityRemove($affectation);
                            }

                        } catch (\Exception $e){
                            $this->getLoggerService()->critical($e->getMessage());
                            throw new OscarException("Impossible de supprimer la personne dans l'activité");
                        }
                        break;

                    case ActivityAvenantModification::TYPE_ORGANIZATION_ADD:
                        try {
                            $organization = $this->getEntityManager()
                                ->getRepository(Organization::class)
                                ->find($modification->getNewValue1());
                            $this->getLoggerService()->info('organization: ' . $organization);
                            $role = $this->getEntityManager()
                                ->getRepository(OrganizationRole::class)
                                ->find($modification->getNewValue2());
                            $this->getLoggerService()->info('role: ' . $role);

                            $this->getProjectGrantService()->organizationActivityAdd(
                                $organization,
                                $activity,
                                $role);

                        } catch (\Exception $e){
                            $this->getLoggerService()->critical($e->getMessage());
                            throw new OscarException("Impossible d'ajouter l'organisation dans l'activité");
                        }
                        break;

                    case ActivityAvenantModification::TYPE_ORGANIZATION_DEL:
                        try {
                            $organization = $this->getEntityManager()
                                ->getRepository(Organization::class)
                                ->find($modification->getNewValue1());
                            $role = $this->getEntityManager()
                                ->getRepository(OrganizationRole::class)
                                ->find($modification->getNewValue2());

                            /** @var ActivityPerson $repo */
                            $affectations = $this->getEntityManager()
                                ->getRepository(ActivityOrganization::class)
                                ->findBy([
                                             'activity' => $activity,
                                             'organization' => $organization,
                                             'roleObj' => $role,
                                         ]);

                            if( count($affectations) === 0 ) {
                                throw new OscarException("Affectation non-trouvée");
                            }
                            foreach ($affectations as $affectation) {
                                $this->getProjectGrantService()
                                    ->activityOrganizationRemove($affectation);
                            }

                        } catch (\Exception $e){
                            $this->getLoggerService()->critical($e->getMessage());
                            throw new OscarException("Impossible de supprimer l'organisation dans l'activité");
                        }
                        break;


                    default:

                        throw new OscarException("Type de modification '".$modification->getType()."' non-traité");
                }
            }
+1 −0
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@ class ActivityAvenantsServiceFactory implements FactoryInterface
        $s->setEntityManager($container->get(EntityManager::class));
        $s->setOscarConfigurationService($container->get(OscarConfigurationService::class));
        $s->setLoggerService($container->get('Logger'));
        $s->setProjectGrantService($container->get(ProjectGrantService::class));
        return $s;
    }
}
 No newline at end of file
+119 −0
Original line number Diff line number Diff line
<template>
  <div v-if="modal" class="overlay confirm-dialog">
    <div class="overlay-content">
      <h3>
        <i class="icon-attention-1"></i>
        <slot name="title">
          Confirmer ?
        </slot>
      </h3>
      <div class="overlay-message">
        <slot name="message">
          Voulez-vous continuer ?
        </slot>
      </div>
      <div v-if="checkbox">
        <label for="confirm_ok" class="checkbox">
          <input type="checkbox" id="confirm_ok" v-model="checked" />
          J'ai bien compris
        </label>
      </div>
      <nav>
        <a href="#" @click.prevent="handlerCancel" class="btn btn-danger">
          <i class="icon-block"></i>
          Annuler
        </a>
        <a href="#" @click.prevent="handlerConfirm" class="btn btn-success" :class="{'disabled': !confirmEnabled}">
          <i class="icon-ok-circled"></i>
          Confirmer</a>
      </nav>
    </div>
  </div>
  <a href="#" :class="class" @click.prevent="modal = true">
    <slot>Texte par défaut</slot>
  </a>
</template>
<script>
export default {
  name: 'ButtonConfirm',
  props: {
    class: {
      type: String,
      default: 'btn btn-default'
    },
    checkbox: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      modal: false,
      checked: false
    }
  },
  computed: {
    confirmEnabled () {
      return (this.checkbox && this.checked) || this.checkbox === false;
    }
  },
  watch: {
    modal(val) {
      this.checked = false;
    }
  },
  methods: {
    handlerClick() {
      this.$emit('click');
    },
    handlerCancel() {
      this.modal = false;
      this.$emit('cancel');
    },
    handlerConfirm() {
      if( this.confirmEnabled ){
        this.modal = false;
        this.$emit('confirm');
      }
    }
  },
  activated() {
    console.log('ButtonConfirm activated');
  }
}
</script>
<style scoped>
.confirm-dialog {
  z-index: 10000;

  .overlay-content {
    flex-basis: 30% !important;

    h3 {
      border-bottom: thin solid #eee;
      margin: .25em .5em;
      padding: .25em .5em;
    }

    .overlay-message {
      font-size: 1.4em;
    }

    nav {
      height: 50px;
      width: 100%;
      padding: .25em .5em;
      margin: .25em .5em;
      border-top: thin solid #eee;
      display: flex;
      flex-wrap: wrap;
      justify-content: space-between;
      align-content: space-between;

      a.btn {

      }
    }
  }
}
</style>
 No newline at end of file
+39 −14
Original line number Diff line number Diff line
@@ -141,7 +141,7 @@

  <section class="avenants">
    <article class="avenant card" v-for="a in avenants.avenants">
      <h3>
      <h4>
        <i class="icon-ok-circled text-success" v-if="a.status == 200"></i>
        <i class="icon-pencil" v-if="a.status == 100"></i>
        <strong>
@@ -150,9 +150,8 @@
        <small>
          - {{ a.status_text }}
        </small>
      </h3>
      {{ a }}
      <section class="modification">
      </h4>
      <section class="modification small">
        <article class="change" v-for="change in a.modifications">
          <i class="icon-calendar" v-if="change.type === 'dateEnd'"></i>
          <i class="icon-user" v-if="change.type === 'personAdd'"></i>
@@ -167,20 +166,37 @@
      </section>
      <p>{{ a.comment }}</p>
      <nav>

        <a :href="a.url_download" class="btn btn-xs btn-primary">
          <i class="icon-file-pdf"></i>
          Télécharger</a>
        <a href="#" class="btn btn-xs btn-danger" @click.prevent="handlerDelete(a)" v-if="manage">

        <ButtonConfirm @confirm="handlerDelete(a)"
                       :class="'btn btn-xs btn-danger'"
                       v-if="manage" :checkbox="true">
          <i class="icon-trash"></i>
          Supprimer</a>
          Supprimer
          <template #message>
            Supprimer <strong>définitivement</strong> cet avenant ?
          </template>
        </ButtonConfirm>

        <a href="#" class="btn btn-xs btn-default" @click.prevent="handlerEdit(a)" v-if="manage && a.editable">
          <i class="icon-pencil"></i>
          Editer
        </a>
        <a href="#" class="btn btn-xs btn-success" @click.prevent="handlerApplyAvenant(a)" v-if="a.status === 100 && manage">
          <i class="icon-valid"></i>
          Appliquer l'avenant
        </a>

        <ButtonConfirm @confirm="handlerApplyAvenant(a)"
                       :class="'btn btn-xs btn-success'"
                       v-if="a.status === 100 && manage">
          <i class="icon-trash"></i>
          Appliquer
          <template #message>
            Confirmer l'application de l'avenant pour cette activité ?
            <strong>L'activité sera verrouillée</strong>
          </template>
        </ButtonConfirm>

      </nav>
    </article>
  </section>
@@ -188,9 +204,6 @@
  <button class="btn btn-primary" @click="handlerNew" v-if="manage">
    Nouvel avenant
  </button>
  <button class="btn btn-primary" @click="fetch">
    Fetch
  </button>
</template>
<script>

@@ -201,11 +214,13 @@ import PersonAutoCompleter from "../components/PersonAutoCompleter.vue";
import AxiosOscar from "../utils/AxiosOscar.js";
import OrganizationAutoComplete from "../components/OrganizationAutoComplete.vue";
import Amount from "../components/Amount.vue";
import ButtonConfirm from "../utils/ButtonConfirm.vue";
//import Test from "../../../vendor/unicaen/signature/public/src/views/SignatureFlows.vue";

export default {
  name: 'ActivityAvenants',
  components: {
    ButtonConfirm,
    Amount,
    AvenantDate,
    Datepicker,
@@ -277,6 +292,16 @@ export default {
  },

  methods: {
    handlerConfirm(message, handler, args){
      console.log("confirm", message);
      handler.call(this, args);
    },

    handlerOk(arg){
      console.log(JSON.stringify(arg));
      console.log(this.avenants.url_api);
    },

    handlerNew() {
      this.edit = {
        id: null,
@@ -381,7 +406,7 @@ export default {
        firstName: event.firstName,
        lastName: event.lastName,
      };
      change.value1 = event.valueObj.id;
      change.value1 = event.id;
    },

    handlerUpdateOrganizationChange(change, event) {