Browse Source

Accès à basi compta pour les administrateurs: https://ressources-opentalent.atlassian.net/wiki/spaces/SPEC/pages/32637034/Acc+s+basi+compta+pour+les+structures+de+la+CMF\#Acces-a-Basicompta-pour-les-administrateurs

maha bouchiba 1 year ago
parent
commit
3c50907335

+ 1 - 0
components/Layout/MainMenu.vue

@@ -24,6 +24,7 @@ Prend en paramètre une liste de ItemMenu et les met en forme
           :prepend-icon="item.icon.name"
           :prepend-icon="item.icon.name"
           :href="!isInternalLink(item) ? item.to : undefined"
           :href="!isInternalLink(item) ? item.to : undefined"
           :to="isInternalLink(item) ? item.to : undefined"
           :to="isInternalLink(item) ? item.to : undefined"
+          :target="item.target"
           exact
           exact
           height="48px"
           height="48px"
           class="menu-item"
           class="menu-item"

+ 8 - 0
config/abilities/pages/basicompta.yaml

@@ -0,0 +1,8 @@
+basicompta_page:
+  action: 'display'
+  conditions:
+    - { function: organizationHasAnyModule, parameters: ['Basicompta'] }
+    - {
+        function: accessHasAnyRoleAbility,
+        parameters: [{ action: 'read', subject: 'basicompta' }],
+      }

+ 1 - 0
lang/fr.json

@@ -420,6 +420,7 @@
   "attendances": "Absences",
   "attendances": "Absences",
   "attendances_breadcrumbs": "Absences",
   "attendances_breadcrumbs": "Absences",
   "equipment": "Parc matériel",
   "equipment": "Parc matériel",
+  "basicompta_admin": "Comptabilité BasiCompta",
   "education_state": "Suivi pédagogique",
   "education_state": "Suivi pédagogique",
   "criteria_notations": "Critères d'évaluation",
   "criteria_notations": "Critères d'évaluation",
   "education_notation_configs": "Grilles d'évaluation",
   "education_notation_configs": "Grilles d'évaluation",

+ 9 - 4
services/layout/menuBuilder/abstractMenuBuilder.ts

@@ -92,15 +92,14 @@ abstract class AbstractMenuBuilder implements MenuBuilder {
     icon?: IconItem,
     icon?: IconItem,
     to: string = '',
     to: string = '',
     type: MENU_LINK_TYPE = MENU_LINK_TYPE.INTERNAL,
     type: MENU_LINK_TYPE = MENU_LINK_TYPE.INTERNAL,
+    newTab: boolean = false,
   ): MenuItem {
   ): MenuItem {
     let url: string
     let url: string
-
     if (type === MENU_LINK_TYPE.INTERNAL) {
     if (type === MENU_LINK_TYPE.INTERNAL) {
       console.warn(
       console.warn(
         "'createItem()' should not be used for internal links, use 'addChildItemIfAllowed()'",
         "'createItem()' should not be used for internal links, use 'addChildItemIfAllowed()'",
       )
       )
     }
     }
-
     switch (type) {
     switch (type) {
       case MENU_LINK_TYPE.V1:
       case MENU_LINK_TYPE.V1:
         // eslint-disable-next-line no-case-declarations
         // eslint-disable-next-line no-case-declarations
@@ -115,8 +114,14 @@ abstract class AbstractMenuBuilder implements MenuBuilder {
       default:
       default:
         url = to
         url = to
     }
     }
-
-    return { icon, label, to: url, type, active: false }
+    return {
+      icon,
+      label,
+      to: url,
+      type,
+      active: false,
+      target: newTab ? '_blank' : '_self',
+    }
   }
   }
 
 
   protected buildSubmenu(menuBuilder: typeof AbstractMenuBuilder) {
   protected buildSubmenu(menuBuilder: typeof AbstractMenuBuilder) {

+ 30 - 0
services/layout/menuBuilder/basicomptaMenuBuilder.ts

@@ -0,0 +1,30 @@
+import type { MenuItem } from '~/types/layout'
+import { MENU_LINK_TYPE } from '~/types/enum/layout'
+import AbstractMenuBuilder from '~/services/layout/menuBuilder/abstractMenuBuilder'
+
+/**
+ * Menu Basicompta
+ */
+export default class BasicomptaMenuBuilder extends AbstractMenuBuilder {
+  static readonly menuName = 'Basicompta'
+
+  build(): MenuItem | null {
+    // cf droit : https://ressources-opentalent.atlassian.net/wiki/spaces/SPEC/pages/32637034/Acc+s+basi+compta+pour+les+structures+de+la+CMF#Acces-a-Basicompta-pour-les-administrateurs
+    if (
+      this.accessProfile.isAdminAccess ||
+      this.accessProfile.isAdministratifManager ||
+      this.accessProfile.isFinancialManager
+    ) {
+      const url = 'https://app.basicompta.fr/'
+      return this.createItem(
+        'basicompta_admin',
+        { name: 'fas fa-suitcase' },
+        url,
+        MENU_LINK_TYPE.EXTERNAL,
+        true,
+      )
+    }
+
+    return null
+  }
+}

+ 2 - 0
services/layout/menuBuilder/mainMenuBuilder.ts

@@ -12,6 +12,7 @@ import WebsiteAdminMenuBuilder from '~/services/layout/menuBuilder/websiteAdminM
 import CotisationsMenuBuilder from '~/services/layout/menuBuilder/cotisationsMenuBuilder'
 import CotisationsMenuBuilder from '~/services/layout/menuBuilder/cotisationsMenuBuilder'
 import StatsMenuBuilder from '~/services/layout/menuBuilder/statsMenuBuilder'
 import StatsMenuBuilder from '~/services/layout/menuBuilder/statsMenuBuilder'
 import Admin2iosMenuBuilder from '~/services/layout/menuBuilder/admin2iosMenuBuilder'
 import Admin2iosMenuBuilder from '~/services/layout/menuBuilder/admin2iosMenuBuilder'
+import BasicomptaMenuBuilder from '~/services/layout/menuBuilder/basicomptaMenuBuilder'
 
 
 /**
 /**
  * Menu principal (ou menu lateral)
  * Menu principal (ou menu lateral)
@@ -36,6 +37,7 @@ export default class MainMenuBuilder extends AbstractMenuBuilder {
       this.buildSubmenu(CotisationsMenuBuilder),
       this.buildSubmenu(CotisationsMenuBuilder),
       this.buildSubmenu(StatsMenuBuilder),
       this.buildSubmenu(StatsMenuBuilder),
       this.buildSubmenu(Admin2iosMenuBuilder),
       this.buildSubmenu(Admin2iosMenuBuilder),
+      this.buildSubmenu(BasicomptaMenuBuilder),
     ].filter((m: MenuItem | MenuGroup | null) => m !== null)
     ].filter((m: MenuItem | MenuGroup | null) => m !== null)
 
 
     if (children.length > 1) {
     if (children.length > 1) {

+ 85 - 0
tests/units/services/layout/menuBuilder/basicomptaMenuBuilder.ts

@@ -0,0 +1,85 @@
+import { describe, test, expect, vi, beforeEach } from 'vitest'
+import type { RuntimeConfig } from '@nuxt/schema'
+import type { AnyAbility } from '@casl/ability'
+import type { Router } from 'vue-router'
+import type { AccessProfile, organizationState } from '~/types/interfaces'
+import BasicomptaMenuBuilder from '~/services/layout/menuBuilder/basicomptaMenuBuilder'
+import { MENU_LINK_TYPE } from '~/types/enum/layout'
+
+let runtimeConfig: RuntimeConfig
+let ability: AnyAbility
+let organizationProfile: organizationState
+let accessProfile: AccessProfile
+let menuBuilder: BasicomptaMenuBuilder
+let router: Router
+
+beforeEach(() => {
+  runtimeConfig = vi.fn() as any as RuntimeConfig
+  ability = vi.fn() as any as AnyAbility
+  organizationProfile = vi.fn() as any as organizationState
+  accessProfile = vi.fn() as any as AccessProfile
+  // @ts-ignore
+  router = vi.fn() as Router
+
+  menuBuilder = new BasicomptaMenuBuilder(
+    runtimeConfig,
+    ability,
+    organizationProfile,
+    accessProfile,
+    router,
+  )
+})
+
+describe('getMenuName', () => {
+  test('validate name', () => {
+    expect(menuBuilder.getMenuName()).toEqual('Basicompta')
+  })
+})
+
+describe('build', () => {
+  test('without admin, administratif, or financial manager access', () => {
+    accessProfile.isAdminAccess = false
+    accessProfile.isAdministratifManager = false
+    accessProfile.isFinancialManager = false
+    expect(menuBuilder.build()).toEqual(null)
+  })
+
+  test('with admin access', () => {
+    accessProfile.isAdminAccess = true
+    expect(menuBuilder.build()).toEqual({
+      label: 'basicompta_admin',
+      icon: { name: 'fas fa-suitcase' },
+      to: 'https://app.basicompta.fr/',
+      type: MENU_LINK_TYPE.EXTERNAL,
+      active: false,
+      target: '_blank',
+    })
+  })
+
+  test('with administratif manager access', () => {
+    accessProfile.isAdminAccess = false
+    accessProfile.isAdministratifManager = true
+    expect(menuBuilder.build()).toEqual({
+      label: 'basicompta_admin',
+      icon: { name: 'fas fa-suitcase' },
+      to: 'https://app.basicompta.fr/',
+      type: MENU_LINK_TYPE.EXTERNAL,
+      active: false,
+      target: '_blank',
+    })
+  })
+
+  test('with financial manager access', () => {
+    accessProfile.isAdminAccess = false
+    accessProfile.isAdministratifManager = false
+    accessProfile.isFinancialManager = true
+    expect(menuBuilder.build()).toEqual({
+      label: 'basicompta_admin',
+      icon: { name: 'fas fa-suitcase' },
+      to: 'https://app.basicompta.fr/',
+      type: MENU_LINK_TYPE.EXTERNAL,
+      active: false,
+      target: '_blank',
+    })
+  })
+})

+ 3 - 0
types/layout.d.ts

@@ -18,6 +18,8 @@ interface MenuItem {
   avatar?: number
   avatar?: number
   /** Correspond à la page actuelle */
   /** Correspond à la page actuelle */
   active: boolean
   active: boolean
+  /** Ouvre le lien dans un nouvel onglet */
+  target?: string
 }
 }
 
 
 /**
 /**
@@ -28,6 +30,7 @@ interface MenuGroup {
   icon?: IconItem
   icon?: IconItem
   children?: MenuItems
   children?: MenuItems
   actions?: MenuItems
   actions?: MenuItems
+  target?: string
 }
 }
 
 
 type MenuItems = Array<MenuItem | MenuGroup>
 type MenuItems = Array<MenuItem | MenuGroup>