Commit d621a4fd by Damien Moulard

allowance based on household

parent 4ce2d41f
...@@ -111,7 +111,7 @@ legend.required:after { ...@@ -111,7 +111,7 @@ legend.required:after {
margin-bottom: 20px; margin-bottom: 20px;
} }
.formEncaisserCotisationAdherent-no-profile { .formEncaisserCotisationAdherent-no-cotisation-amount {
font-style: italic; font-style: italic;
color: #ff4136; color: #ff4136;
} }
......
...@@ -542,20 +542,20 @@ $(function() { ...@@ -542,20 +542,20 @@ $(function() {
if (cotisationmontant === undefined) { if (cotisationmontant === undefined) {
$("#formEncaisserCotisationAdherent-montant-container").hide(); $("#formEncaisserCotisationAdherent-montant-container").hide();
$("#formEncaisserCotisationAdherent-no-profile").hide(); $("#formEncaisserCotisationAdherent-no-cotisation-amount").hide();
return; return;
} }
if (cotisationmontant !== null) { if (cotisationmontant !== null) {
$("#formEncaisserCotisationAdherent-montant-display").text(`${cotisationmontant} €`); $("#formEncaisserCotisationAdherent-montant-display").text(`${cotisationmontant} €`);
$("#formEncaisserCotisationAdherent-montant-container").show(); $("#formEncaisserCotisationAdherent-montant-container").show();
$("#formEncaisserCotisationAdherent-no-profile").hide(); $("#formEncaisserCotisationAdherent-no-cotisation-amount").hide();
$("#formEncaisserCotisationAdherent_save").prop("disabled",false); $("#formEncaisserCotisationAdherent_save").prop("disabled",false);
} else { } else {
// no cotisation profile // no cotisation profile
$("#formEncaisserCotisationAdherent-montant-container").hide(); $("#formEncaisserCotisationAdherent-montant-container").hide();
$("#formEncaisserCotisationAdherent-no-profile").show(); $("#formEncaisserCotisationAdherent-no-cotisation-amount").show();
$("#formEncaisserCotisationAdherent_save").prop("disabled",true); $("#formEncaisserCotisationAdherent_save").prop("disabled",true);
} }
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -3,10 +3,10 @@ ...@@ -3,10 +3,10 @@
"app": { "app": {
"js": [ "js": [
"/build/runtime.6ad5c9da.js", "/build/runtime.6ad5c9da.js",
"/build/app.a926d504.js" "/build/app.435420b4.js"
], ],
"css": [ "css": [
"/build/app.6350a995.css" "/build/app.7133af83.css"
] ]
}, },
"admin": { "admin": {
......
{ {
"build/app.css": "/build/app.6350a995.css", "build/app.css": "/build/app.7133af83.css",
"build/app.js": "/build/app.a926d504.js", "build/app.js": "/build/app.435420b4.js",
"build/admin.css": "/build/admin.4de55830.css", "build/admin.css": "/build/admin.4de55830.css",
"build/admin.js": "/build/admin.86a2d986.js", "build/admin.js": "/build/admin.86a2d986.js",
"build/runtime.js": "/build/runtime.6ad5c9da.js", "build/runtime.js": "/build/runtime.6ad5c9da.js",
......
(()=>{"use strict";var e={913:()=>{try{self["workbox:core:6.5.1"]&&_()}catch(e){}},977:()=>{try{self["workbox:precaching:6.5.1"]&&_()}catch(e){}},80:()=>{try{self["workbox:routing:6.5.1"]&&_()}catch(e){}},873:()=>{try{self["workbox:strategies:6.5.1"]&&_()}catch(e){}}},t={};function s(a){var n=t[a];if(void 0!==n)return n.exports;var r=t[a]={exports:{}};return e[a](r,r.exports,s),r.exports}(()=>{s(913);const e=(e,...t)=>{let s=e;return t.length>0&&(s+=` :: ${JSON.stringify(t)}`),s};class t extends Error{constructor(t,s){super(e(t,s)),this.name=t,this.details=s}}const a={googleAnalytics:"googleAnalytics",precache:"precache-v2",prefix:"workbox",runtime:"runtime",suffix:"undefined"!=typeof registration?registration.scope:""},n=e=>[a.prefix,e,a.suffix].filter((e=>e&&e.length>0)).join("-"),r=e=>e||n(a.precache),i=e=>e||n(a.runtime);function c(e,t){const s=t();return e.waitUntil(s),s}s(977);function o(e){if(!e)throw new t("add-to-cache-list-unexpected-type",{entry:e});if("string"==typeof e){const t=new URL(e,location.href);return{cacheKey:t.href,url:t.href}}const{revision:s,url:a}=e;if(!a)throw new t("add-to-cache-list-unexpected-type",{entry:e});if(!s){const e=new URL(a,location.href);return{cacheKey:e.href,url:e.href}}const n=new URL(a,location.href),r=new URL(a,location.href);return n.searchParams.set("__WB_REVISION__",s),{cacheKey:n.href,url:r.href}}class h{constructor(){this.updatedURLs=[],this.notUpdatedURLs=[],this.handlerWillStart=async({request:e,state:t})=>{t&&(t.originalRequest=e)},this.cachedResponseWillBeUsed=async({event:e,state:t,cachedResponse:s})=>{if("install"===e.type&&t&&t.originalRequest&&t.originalRequest instanceof Request){const e=t.originalRequest.url;s?this.notUpdatedURLs.push(e):this.updatedURLs.push(e)}return s}}}class l{constructor({precacheController:e}){this.cacheKeyWillBeUsed=async({request:e,params:t})=>{const s=(null==t?void 0:t.cacheKey)||this._precacheController.getCacheKeyForURL(e.url);return s?new Request(s,{headers:e.headers}):e},this._precacheController=e}}let u;async function f(e,s){let a=null;if(e.url){a=new URL(e.url).origin}if(a!==self.location.origin)throw new t("cross-origin-copy-response",{origin:a});const n=e.clone(),r={headers:new Headers(n.headers),status:n.status,statusText:n.statusText},i=s?s(r):r,c=function(){if(void 0===u){const e=new Response("");if("body"in e)try{new Response(e.body),u=!0}catch(e){u=!1}u=!1}return u}()?n.body:await n.blob();return new Response(c,i)}function d(e,t){const s=new URL(e);for(const e of t)s.searchParams.delete(e);return s.href}class p{constructor(){this.promise=new Promise(((e,t)=>{this.resolve=e,this.reject=t}))}}const g=new Set;s(873);function y(e){return"string"==typeof e?new Request(e):e}class w{constructor(e,t){this._cacheKeys={},Object.assign(this,t),this.event=t.event,this._strategy=e,this._handlerDeferred=new p,this._extendLifetimePromises=[],this._plugins=[...e.plugins],this._pluginStateMap=new Map;for(const e of this._plugins)this._pluginStateMap.set(e,{});this.event.waitUntil(this._handlerDeferred.promise)}async fetch(e){const{event:s}=this;let a=y(e);if("navigate"===a.mode&&s instanceof FetchEvent&&s.preloadResponse){const e=await s.preloadResponse;if(e)return e}const n=this.hasCallback("fetchDidFail")?a.clone():null;try{for(const e of this.iterateCallbacks("requestWillFetch"))a=await e({request:a.clone(),event:s})}catch(e){if(e instanceof Error)throw new t("plugin-error-request-will-fetch",{thrownErrorMessage:e.message})}const r=a.clone();try{let e;e=await fetch(a,"navigate"===a.mode?void 0:this._strategy.fetchOptions);for(const t of this.iterateCallbacks("fetchDidSucceed"))e=await t({event:s,request:r,response:e});return e}catch(e){throw n&&await this.runCallbacks("fetchDidFail",{error:e,event:s,originalRequest:n.clone(),request:r.clone()}),e}}async fetchAndCachePut(e){const t=await this.fetch(e),s=t.clone();return this.waitUntil(this.cachePut(e,s)),t}async cacheMatch(e){const t=y(e);let s;const{cacheName:a,matchOptions:n}=this._strategy,r=await this.getCacheKey(t,"read"),i=Object.assign(Object.assign({},n),{cacheName:a});s=await caches.match(r,i);for(const e of this.iterateCallbacks("cachedResponseWillBeUsed"))s=await e({cacheName:a,matchOptions:n,cachedResponse:s,request:r,event:this.event})||void 0;return s}async cachePut(e,s){const a=y(e);var n;await(n=0,new Promise((e=>setTimeout(e,n))));const r=await this.getCacheKey(a,"write");if(!s)throw new t("cache-put-with-no-response",{url:(i=r.url,new URL(String(i),location.href).href.replace(new RegExp(`^${location.origin}`),""))});var i;const c=await this._ensureResponseSafeToCache(s);if(!c)return!1;const{cacheName:o,matchOptions:h}=this._strategy,l=await self.caches.open(o),u=this.hasCallback("cacheDidUpdate"),f=u?await async function(e,t,s,a){const n=d(t.url,s);if(t.url===n)return e.match(t,a);const r=Object.assign(Object.assign({},a),{ignoreSearch:!0}),i=await e.keys(t,r);for(const t of i)if(n===d(t.url,s))return e.match(t,a)}(l,r.clone(),["__WB_REVISION__"],h):null;try{await l.put(r,u?c.clone():c)}catch(e){if(e instanceof Error)throw"QuotaExceededError"===e.name&&await async function(){for(const e of g)await e()}(),e}for(const e of this.iterateCallbacks("cacheDidUpdate"))await e({cacheName:o,oldResponse:f,newResponse:c.clone(),request:r,event:this.event});return!0}async getCacheKey(e,t){const s=`${e.url} | ${t}`;if(!this._cacheKeys[s]){let a=e;for(const e of this.iterateCallbacks("cacheKeyWillBeUsed"))a=y(await e({mode:t,request:a,event:this.event,params:this.params}));this._cacheKeys[s]=a}return this._cacheKeys[s]}hasCallback(e){for(const t of this._strategy.plugins)if(e in t)return!0;return!1}async runCallbacks(e,t){for(const s of this.iterateCallbacks(e))await s(t)}*iterateCallbacks(e){for(const t of this._strategy.plugins)if("function"==typeof t[e]){const s=this._pluginStateMap.get(t),a=a=>{const n=Object.assign(Object.assign({},a),{state:s});return t[e](n)};yield a}}waitUntil(e){return this._extendLifetimePromises.push(e),e}async doneWaiting(){let e;for(;e=this._extendLifetimePromises.shift();)await e}destroy(){this._handlerDeferred.resolve(null)}async _ensureResponseSafeToCache(e){let t=e,s=!1;for(const e of this.iterateCallbacks("cacheWillUpdate"))if(t=await e({request:this.request,response:t,event:this.event})||void 0,s=!0,!t)break;return s||t&&200!==t.status&&(t=void 0),t}}class m extends class{constructor(e={}){this.cacheName=i(e.cacheName),this.plugins=e.plugins||[],this.fetchOptions=e.fetchOptions,this.matchOptions=e.matchOptions}handle(e){const[t]=this.handleAll(e);return t}handleAll(e){e instanceof FetchEvent&&(e={event:e,request:e.request});const t=e.event,s="string"==typeof e.request?new Request(e.request):e.request,a="params"in e?e.params:void 0,n=new w(this,{event:t,request:s,params:a}),r=this._getResponse(n,s,t);return[r,this._awaitComplete(r,n,s,t)]}async _getResponse(e,s,a){let n;await e.runCallbacks("handlerWillStart",{event:a,request:s});try{if(n=await this._handle(s,e),!n||"error"===n.type)throw new t("no-response",{url:s.url})}catch(t){if(t instanceof Error)for(const r of e.iterateCallbacks("handlerDidError"))if(n=await r({error:t,event:a,request:s}),n)break;if(!n)throw t}for(const t of e.iterateCallbacks("handlerWillRespond"))n=await t({event:a,request:s,response:n});return n}async _awaitComplete(e,t,s,a){let n,r;try{n=await e}catch(r){}try{await t.runCallbacks("handlerDidRespond",{event:a,request:s,response:n}),await t.doneWaiting()}catch(e){e instanceof Error&&(r=e)}if(await t.runCallbacks("handlerDidComplete",{event:a,request:s,response:n,error:r}),t.destroy(),r)throw r}}{constructor(e={}){e.cacheName=r(e.cacheName),super(e),this._fallbackToNetwork=!1!==e.fallbackToNetwork,this.plugins.push(m.copyRedirectedCacheableResponsesPlugin)}async _handle(e,t){const s=await t.cacheMatch(e);return s||(t.event&&"install"===t.event.type?await this._handleInstall(e,t):await this._handleFetch(e,t))}async _handleFetch(e,s){let a;const n=s.params||{};if(!this._fallbackToNetwork)throw new t("missing-precache-entry",{cacheName:this.cacheName,url:e.url});{0;const t=n.integrity,r=e.integrity,i=!r||r===t;if(a=await s.fetch(new Request(e,{integrity:r||t})),t&&i){this._useDefaultCacheabilityPluginIfNeeded();await s.cachePut(e,a.clone());0}}return a}async _handleInstall(e,s){this._useDefaultCacheabilityPluginIfNeeded();const a=await s.fetch(e);if(!await s.cachePut(e,a.clone()))throw new t("bad-precaching-response",{url:e.url,status:a.status});return a}_useDefaultCacheabilityPluginIfNeeded(){let e=null,t=0;for(const[s,a]of this.plugins.entries())a!==m.copyRedirectedCacheableResponsesPlugin&&(a===m.defaultPrecacheCacheabilityPlugin&&(e=s),a.cacheWillUpdate&&t++);0===t?this.plugins.push(m.defaultPrecacheCacheabilityPlugin):t>1&&null!==e&&this.plugins.splice(e,1)}}m.defaultPrecacheCacheabilityPlugin={cacheWillUpdate:async({response:e})=>!e||e.status>=400?null:e},m.copyRedirectedCacheableResponsesPlugin={cacheWillUpdate:async({response:e})=>e.redirected?await f(e):e};class _{constructor({cacheName:e,plugins:t=[],fallbackToNetwork:s=!0}={}){this._urlsToCacheKeys=new Map,this._urlsToCacheModes=new Map,this._cacheKeysToIntegrities=new Map,this._strategy=new m({cacheName:r(e),plugins:[...t,new l({precacheController:this})],fallbackToNetwork:s}),this.install=this.install.bind(this),this.activate=this.activate.bind(this)}get strategy(){return this._strategy}precache(e){this.addToCacheList(e),this._installAndActiveListenersAdded||(self.addEventListener("install",this.install),self.addEventListener("activate",this.activate),this._installAndActiveListenersAdded=!0)}addToCacheList(e){const s=[];for(const a of e){"string"==typeof a?s.push(a):a&&void 0===a.revision&&s.push(a.url);const{cacheKey:e,url:n}=o(a),r="string"!=typeof a&&a.revision?"reload":"default";if(this._urlsToCacheKeys.has(n)&&this._urlsToCacheKeys.get(n)!==e)throw new t("add-to-cache-list-conflicting-entries",{firstEntry:this._urlsToCacheKeys.get(n),secondEntry:e});if("string"!=typeof a&&a.integrity){if(this._cacheKeysToIntegrities.has(e)&&this._cacheKeysToIntegrities.get(e)!==a.integrity)throw new t("add-to-cache-list-conflicting-integrities",{url:n});this._cacheKeysToIntegrities.set(e,a.integrity)}if(this._urlsToCacheKeys.set(n,e),this._urlsToCacheModes.set(n,r),s.length>0){const e=`Workbox is precaching URLs without revision info: ${s.join(", ")}\nThis is generally NOT safe. Learn more at https://bit.ly/wb-precache`;console.warn(e)}}}install(e){return c(e,(async()=>{const t=new h;this.strategy.plugins.push(t);for(const[t,s]of this._urlsToCacheKeys){const a=this._cacheKeysToIntegrities.get(s),n=this._urlsToCacheModes.get(t),r=new Request(t,{integrity:a,cache:n,credentials:"same-origin"});await Promise.all(this.strategy.handleAll({params:{cacheKey:s},request:r,event:e}))}const{updatedURLs:s,notUpdatedURLs:a}=t;return{updatedURLs:s,notUpdatedURLs:a}}))}activate(e){return c(e,(async()=>{const e=await self.caches.open(this.strategy.cacheName),t=await e.keys(),s=new Set(this._urlsToCacheKeys.values()),a=[];for(const n of t)s.has(n.url)||(await e.delete(n),a.push(n.url));return{deletedURLs:a}}))}getURLsToCacheKeys(){return this._urlsToCacheKeys}getCachedURLs(){return[...this._urlsToCacheKeys.keys()]}getCacheKeyForURL(e){const t=new URL(e,location.href);return this._urlsToCacheKeys.get(t.href)}getIntegrityForCacheKey(e){return this._cacheKeysToIntegrities.get(e)}async matchPrecache(e){const t=e instanceof Request?e.url:e,s=this.getCacheKeyForURL(t);if(s){return(await self.caches.open(this.strategy.cacheName)).match(s)}}createHandlerBoundToURL(e){const s=this.getCacheKeyForURL(e);if(!s)throw new t("non-precached-url",{url:e});return t=>(t.request=new Request(e),t.params=Object.assign({cacheKey:s},t.params),this.strategy.handle(t))}}let R;const v=()=>(R||(R=new _),R);s(80);const C=e=>e&&"object"==typeof e?e:{handle:e};class b{constructor(e,t,s="GET"){this.handler=C(t),this.match=e,this.method=s}setCatchHandler(e){this.catchHandler=C(e)}}class q extends b{constructor(e,t,s){super((({url:t})=>{const s=e.exec(t.href);if(s&&(t.origin===location.origin||0===s.index))return s.slice(1)}),t,s)}}class U{constructor(){this._routes=new Map,this._defaultHandlerMap=new Map}get routes(){return this._routes}addFetchListener(){self.addEventListener("fetch",(e=>{const{request:t}=e,s=this.handleRequest({request:t,event:e});s&&e.respondWith(s)}))}addCacheListener(){self.addEventListener("message",(e=>{if(e.data&&"CACHE_URLS"===e.data.type){const{payload:t}=e.data;0;const s=Promise.all(t.urlsToCache.map((t=>{"string"==typeof t&&(t=[t]);const s=new Request(...t);return this.handleRequest({request:s,event:e})})));e.waitUntil(s),e.ports&&e.ports[0]&&s.then((()=>e.ports[0].postMessage(!0)))}}))}handleRequest({request:e,event:t}){const s=new URL(e.url,location.href);if(!s.protocol.startsWith("http"))return void 0;const a=s.origin===location.origin,{params:n,route:r}=this.findMatchingRoute({event:t,request:e,sameOrigin:a,url:s});let i=r&&r.handler;const c=e.method;if(!i&&this._defaultHandlerMap.has(c)&&(i=this._defaultHandlerMap.get(c)),!i)return void 0;let o;try{o=i.handle({url:s,request:e,event:t,params:n})}catch(e){o=Promise.reject(e)}const h=r&&r.catchHandler;return o instanceof Promise&&(this._catchHandler||h)&&(o=o.catch((async a=>{if(h){0;try{return await h.handle({url:s,request:e,event:t,params:n})}catch(e){e instanceof Error&&(a=e)}}if(this._catchHandler)return this._catchHandler.handle({url:s,request:e,event:t});throw a}))),o}findMatchingRoute({url:e,sameOrigin:t,request:s,event:a}){const n=this._routes.get(s.method)||[];for(const r of n){let n;const i=r.match({url:e,sameOrigin:t,request:s,event:a});if(i)return n=i,(Array.isArray(n)&&0===n.length||i.constructor===Object&&0===Object.keys(i).length||"boolean"==typeof i)&&(n=void 0),{route:r,params:n}}return{}}setDefaultHandler(e,t="GET"){this._defaultHandlerMap.set(t,C(e))}setCatchHandler(e){this._catchHandler=C(e)}registerRoute(e){this._routes.has(e.method)||this._routes.set(e.method,[]),this._routes.get(e.method).push(e)}unregisterRoute(e){if(!this._routes.has(e.method))throw new t("unregister-route-but-not-found-with-method",{method:e.method});const s=this._routes.get(e.method).indexOf(e);if(!(s>-1))throw new t("unregister-route-route-not-registered");this._routes.get(e.method).splice(s,1)}}let L;class k extends b{constructor(e,t){super((({request:s})=>{const a=e.getURLsToCacheKeys();for(const n of function*(e,{ignoreURLParametersMatching:t=[/^utm_/,/^fbclid$/],directoryIndex:s="index.html",cleanURLs:a=!0,urlManipulation:n}={}){const r=new URL(e,location.href);r.hash="",yield r.href;const i=function(e,t=[]){for(const s of[...e.searchParams.keys()])t.some((e=>e.test(s)))&&e.searchParams.delete(s);return e}(r,t);if(yield i.href,s&&i.pathname.endsWith("/")){const e=new URL(i.href);e.pathname+=s,yield e.href}if(a){const e=new URL(i.href);e.pathname+=".html",yield e.href}if(n){const e=n({url:r});for(const t of e)yield t.href}}(s.url,t)){const t=a.get(n);if(t){return{cacheKey:t,integrity:e.getIntegrityForCacheKey(t)}}}}),e.strategy)}}function K(e){const s=v();!function(e,s,a){let n;if("string"==typeof e){const t=new URL(e,location.href);n=new b((({url:e})=>e.href===t.href),s,a)}else if(e instanceof RegExp)n=new q(e,s,a);else if("function"==typeof e)n=new b(e,s,a);else{if(!(e instanceof b))throw new t("unsupported-route-type",{moduleName:"workbox-routing",funcName:"registerRoute",paramName:"capture"});n=e}(L||(L=new U,L.addFetchListener(),L.addCacheListener()),L).registerRoute(n)}(new k(s,e))}var T;(function(e){v().precache(e)})([{'revision':null,'url':'/build/admin.4de55830.css'},{'revision':null,'url':'/build/admin.86a2d986.js'},{'revision':'ad79405d542b397996a3079203114b42','url':'/build/admin.86a2d986.js.LICENSE.txt'},{'revision':null,'url':'/build/app.6350a995.css'},{'revision':null,'url':'/build/app.a926d504.js'},{'revision':'4ff7361e3c3e359ae88c5fae5738746d','url':'/build/app.a926d504.js.LICENSE.txt'},{'revision':null,'url':'/build/fonts/fa-brands-400.3dc44d22.woff2'},{'revision':null,'url':'/build/fonts/fa-regular-400.3dc6ca01.woff2'},{'revision':null,'url':'/build/fonts/fa-solid-900.496d5fc1.woff2'},{'revision':null,'url':'/build/fonts/source-sans-pro-v14-latin-300.d2c7d5c5.woff2'},{'revision':null,'url':'/build/fonts/source-sans-pro-v14-latin-600.17c0392c.woff2'},{'revision':null,'url':'/build/fonts/source-sans-pro-v14-latin-600italic.cc34c6e7.woff2'},{'revision':null,'url':'/build/fonts/source-sans-pro-v14-latin-700.ed37bc60.woff2'},{'revision':null,'url':'/build/fonts/source-sans-pro-v14-latin-900.476756cd.woff2'},{'revision':null,'url':'/build/fonts/source-sans-pro-v14-latin-italic.a07cb9c5.woff2'},{'revision':null,'url':'/build/fonts/source-sans-pro-v14-latin-regular.f74389bd.woff2'},{'revision':null,'url':'/build/images/fa-brands-400.05d20183.svg'},{'revision':null,'url':'/build/images/fa-regular-400.9a0810d6.svg'},{'revision':null,'url':'/build/images/fa-solid-900.a838c42a.svg'},{'revision':null,'url':'/build/images/source-sans-pro-v14-latin-300.4e7fe004.svg'},{'revision':null,'url':'/build/images/source-sans-pro-v14-latin-600.cf2758ae.svg'},{'revision':null,'url':'/build/images/source-sans-pro-v14-latin-600italic.7249d863.svg'},{'revision':null,'url':'/build/images/source-sans-pro-v14-latin-700.3e4b9e19.svg'},{'revision':null,'url':'/build/images/source-sans-pro-v14-latin-900.060d8c51.svg'},{'revision':null,'url':'/build/images/source-sans-pro-v14-latin-italic.08dc9b1c.svg'},{'revision':null,'url':'/build/images/source-sans-pro-v14-latin-regular.3bb9538c.svg'},{'revision':null,'url':'/build/runtime.6ad5c9da.js'}]),K(T),self.addEventListener("fetch",(function(e){e.respondWith(caches.match(e.request).then((function(t){return t||fetch(e.request)})).catch((function(){return caches.match("/offline.html")})))}))})()})(); (()=>{"use strict";var e={913:()=>{try{self["workbox:core:6.5.1"]&&_()}catch(e){}},977:()=>{try{self["workbox:precaching:6.5.1"]&&_()}catch(e){}},80:()=>{try{self["workbox:routing:6.5.1"]&&_()}catch(e){}},873:()=>{try{self["workbox:strategies:6.5.1"]&&_()}catch(e){}}},t={};function s(a){var n=t[a];if(void 0!==n)return n.exports;var r=t[a]={exports:{}};return e[a](r,r.exports,s),r.exports}(()=>{s(913);const e=(e,...t)=>{let s=e;return t.length>0&&(s+=` :: ${JSON.stringify(t)}`),s};class t extends Error{constructor(t,s){super(e(t,s)),this.name=t,this.details=s}}const a={googleAnalytics:"googleAnalytics",precache:"precache-v2",prefix:"workbox",runtime:"runtime",suffix:"undefined"!=typeof registration?registration.scope:""},n=e=>[a.prefix,e,a.suffix].filter((e=>e&&e.length>0)).join("-"),r=e=>e||n(a.precache),i=e=>e||n(a.runtime);function c(e,t){const s=t();return e.waitUntil(s),s}s(977);function o(e){if(!e)throw new t("add-to-cache-list-unexpected-type",{entry:e});if("string"==typeof e){const t=new URL(e,location.href);return{cacheKey:t.href,url:t.href}}const{revision:s,url:a}=e;if(!a)throw new t("add-to-cache-list-unexpected-type",{entry:e});if(!s){const e=new URL(a,location.href);return{cacheKey:e.href,url:e.href}}const n=new URL(a,location.href),r=new URL(a,location.href);return n.searchParams.set("__WB_REVISION__",s),{cacheKey:n.href,url:r.href}}class h{constructor(){this.updatedURLs=[],this.notUpdatedURLs=[],this.handlerWillStart=async({request:e,state:t})=>{t&&(t.originalRequest=e)},this.cachedResponseWillBeUsed=async({event:e,state:t,cachedResponse:s})=>{if("install"===e.type&&t&&t.originalRequest&&t.originalRequest instanceof Request){const e=t.originalRequest.url;s?this.notUpdatedURLs.push(e):this.updatedURLs.push(e)}return s}}}class l{constructor({precacheController:e}){this.cacheKeyWillBeUsed=async({request:e,params:t})=>{const s=(null==t?void 0:t.cacheKey)||this._precacheController.getCacheKeyForURL(e.url);return s?new Request(s,{headers:e.headers}):e},this._precacheController=e}}let u;async function f(e,s){let a=null;if(e.url){a=new URL(e.url).origin}if(a!==self.location.origin)throw new t("cross-origin-copy-response",{origin:a});const n=e.clone(),r={headers:new Headers(n.headers),status:n.status,statusText:n.statusText},i=s?s(r):r,c=function(){if(void 0===u){const e=new Response("");if("body"in e)try{new Response(e.body),u=!0}catch(e){u=!1}u=!1}return u}()?n.body:await n.blob();return new Response(c,i)}function d(e,t){const s=new URL(e);for(const e of t)s.searchParams.delete(e);return s.href}class p{constructor(){this.promise=new Promise(((e,t)=>{this.resolve=e,this.reject=t}))}}const g=new Set;s(873);function y(e){return"string"==typeof e?new Request(e):e}class w{constructor(e,t){this._cacheKeys={},Object.assign(this,t),this.event=t.event,this._strategy=e,this._handlerDeferred=new p,this._extendLifetimePromises=[],this._plugins=[...e.plugins],this._pluginStateMap=new Map;for(const e of this._plugins)this._pluginStateMap.set(e,{});this.event.waitUntil(this._handlerDeferred.promise)}async fetch(e){const{event:s}=this;let a=y(e);if("navigate"===a.mode&&s instanceof FetchEvent&&s.preloadResponse){const e=await s.preloadResponse;if(e)return e}const n=this.hasCallback("fetchDidFail")?a.clone():null;try{for(const e of this.iterateCallbacks("requestWillFetch"))a=await e({request:a.clone(),event:s})}catch(e){if(e instanceof Error)throw new t("plugin-error-request-will-fetch",{thrownErrorMessage:e.message})}const r=a.clone();try{let e;e=await fetch(a,"navigate"===a.mode?void 0:this._strategy.fetchOptions);for(const t of this.iterateCallbacks("fetchDidSucceed"))e=await t({event:s,request:r,response:e});return e}catch(e){throw n&&await this.runCallbacks("fetchDidFail",{error:e,event:s,originalRequest:n.clone(),request:r.clone()}),e}}async fetchAndCachePut(e){const t=await this.fetch(e),s=t.clone();return this.waitUntil(this.cachePut(e,s)),t}async cacheMatch(e){const t=y(e);let s;const{cacheName:a,matchOptions:n}=this._strategy,r=await this.getCacheKey(t,"read"),i=Object.assign(Object.assign({},n),{cacheName:a});s=await caches.match(r,i);for(const e of this.iterateCallbacks("cachedResponseWillBeUsed"))s=await e({cacheName:a,matchOptions:n,cachedResponse:s,request:r,event:this.event})||void 0;return s}async cachePut(e,s){const a=y(e);var n;await(n=0,new Promise((e=>setTimeout(e,n))));const r=await this.getCacheKey(a,"write");if(!s)throw new t("cache-put-with-no-response",{url:(i=r.url,new URL(String(i),location.href).href.replace(new RegExp(`^${location.origin}`),""))});var i;const c=await this._ensureResponseSafeToCache(s);if(!c)return!1;const{cacheName:o,matchOptions:h}=this._strategy,l=await self.caches.open(o),u=this.hasCallback("cacheDidUpdate"),f=u?await async function(e,t,s,a){const n=d(t.url,s);if(t.url===n)return e.match(t,a);const r=Object.assign(Object.assign({},a),{ignoreSearch:!0}),i=await e.keys(t,r);for(const t of i)if(n===d(t.url,s))return e.match(t,a)}(l,r.clone(),["__WB_REVISION__"],h):null;try{await l.put(r,u?c.clone():c)}catch(e){if(e instanceof Error)throw"QuotaExceededError"===e.name&&await async function(){for(const e of g)await e()}(),e}for(const e of this.iterateCallbacks("cacheDidUpdate"))await e({cacheName:o,oldResponse:f,newResponse:c.clone(),request:r,event:this.event});return!0}async getCacheKey(e,t){const s=`${e.url} | ${t}`;if(!this._cacheKeys[s]){let a=e;for(const e of this.iterateCallbacks("cacheKeyWillBeUsed"))a=y(await e({mode:t,request:a,event:this.event,params:this.params}));this._cacheKeys[s]=a}return this._cacheKeys[s]}hasCallback(e){for(const t of this._strategy.plugins)if(e in t)return!0;return!1}async runCallbacks(e,t){for(const s of this.iterateCallbacks(e))await s(t)}*iterateCallbacks(e){for(const t of this._strategy.plugins)if("function"==typeof t[e]){const s=this._pluginStateMap.get(t),a=a=>{const n=Object.assign(Object.assign({},a),{state:s});return t[e](n)};yield a}}waitUntil(e){return this._extendLifetimePromises.push(e),e}async doneWaiting(){let e;for(;e=this._extendLifetimePromises.shift();)await e}destroy(){this._handlerDeferred.resolve(null)}async _ensureResponseSafeToCache(e){let t=e,s=!1;for(const e of this.iterateCallbacks("cacheWillUpdate"))if(t=await e({request:this.request,response:t,event:this.event})||void 0,s=!0,!t)break;return s||t&&200!==t.status&&(t=void 0),t}}class m extends class{constructor(e={}){this.cacheName=i(e.cacheName),this.plugins=e.plugins||[],this.fetchOptions=e.fetchOptions,this.matchOptions=e.matchOptions}handle(e){const[t]=this.handleAll(e);return t}handleAll(e){e instanceof FetchEvent&&(e={event:e,request:e.request});const t=e.event,s="string"==typeof e.request?new Request(e.request):e.request,a="params"in e?e.params:void 0,n=new w(this,{event:t,request:s,params:a}),r=this._getResponse(n,s,t);return[r,this._awaitComplete(r,n,s,t)]}async _getResponse(e,s,a){let n;await e.runCallbacks("handlerWillStart",{event:a,request:s});try{if(n=await this._handle(s,e),!n||"error"===n.type)throw new t("no-response",{url:s.url})}catch(t){if(t instanceof Error)for(const r of e.iterateCallbacks("handlerDidError"))if(n=await r({error:t,event:a,request:s}),n)break;if(!n)throw t}for(const t of e.iterateCallbacks("handlerWillRespond"))n=await t({event:a,request:s,response:n});return n}async _awaitComplete(e,t,s,a){let n,r;try{n=await e}catch(r){}try{await t.runCallbacks("handlerDidRespond",{event:a,request:s,response:n}),await t.doneWaiting()}catch(e){e instanceof Error&&(r=e)}if(await t.runCallbacks("handlerDidComplete",{event:a,request:s,response:n,error:r}),t.destroy(),r)throw r}}{constructor(e={}){e.cacheName=r(e.cacheName),super(e),this._fallbackToNetwork=!1!==e.fallbackToNetwork,this.plugins.push(m.copyRedirectedCacheableResponsesPlugin)}async _handle(e,t){const s=await t.cacheMatch(e);return s||(t.event&&"install"===t.event.type?await this._handleInstall(e,t):await this._handleFetch(e,t))}async _handleFetch(e,s){let a;const n=s.params||{};if(!this._fallbackToNetwork)throw new t("missing-precache-entry",{cacheName:this.cacheName,url:e.url});{0;const t=n.integrity,r=e.integrity,i=!r||r===t;if(a=await s.fetch(new Request(e,{integrity:r||t})),t&&i){this._useDefaultCacheabilityPluginIfNeeded();await s.cachePut(e,a.clone());0}}return a}async _handleInstall(e,s){this._useDefaultCacheabilityPluginIfNeeded();const a=await s.fetch(e);if(!await s.cachePut(e,a.clone()))throw new t("bad-precaching-response",{url:e.url,status:a.status});return a}_useDefaultCacheabilityPluginIfNeeded(){let e=null,t=0;for(const[s,a]of this.plugins.entries())a!==m.copyRedirectedCacheableResponsesPlugin&&(a===m.defaultPrecacheCacheabilityPlugin&&(e=s),a.cacheWillUpdate&&t++);0===t?this.plugins.push(m.defaultPrecacheCacheabilityPlugin):t>1&&null!==e&&this.plugins.splice(e,1)}}m.defaultPrecacheCacheabilityPlugin={cacheWillUpdate:async({response:e})=>!e||e.status>=400?null:e},m.copyRedirectedCacheableResponsesPlugin={cacheWillUpdate:async({response:e})=>e.redirected?await f(e):e};class _{constructor({cacheName:e,plugins:t=[],fallbackToNetwork:s=!0}={}){this._urlsToCacheKeys=new Map,this._urlsToCacheModes=new Map,this._cacheKeysToIntegrities=new Map,this._strategy=new m({cacheName:r(e),plugins:[...t,new l({precacheController:this})],fallbackToNetwork:s}),this.install=this.install.bind(this),this.activate=this.activate.bind(this)}get strategy(){return this._strategy}precache(e){this.addToCacheList(e),this._installAndActiveListenersAdded||(self.addEventListener("install",this.install),self.addEventListener("activate",this.activate),this._installAndActiveListenersAdded=!0)}addToCacheList(e){const s=[];for(const a of e){"string"==typeof a?s.push(a):a&&void 0===a.revision&&s.push(a.url);const{cacheKey:e,url:n}=o(a),r="string"!=typeof a&&a.revision?"reload":"default";if(this._urlsToCacheKeys.has(n)&&this._urlsToCacheKeys.get(n)!==e)throw new t("add-to-cache-list-conflicting-entries",{firstEntry:this._urlsToCacheKeys.get(n),secondEntry:e});if("string"!=typeof a&&a.integrity){if(this._cacheKeysToIntegrities.has(e)&&this._cacheKeysToIntegrities.get(e)!==a.integrity)throw new t("add-to-cache-list-conflicting-integrities",{url:n});this._cacheKeysToIntegrities.set(e,a.integrity)}if(this._urlsToCacheKeys.set(n,e),this._urlsToCacheModes.set(n,r),s.length>0){const e=`Workbox is precaching URLs without revision info: ${s.join(", ")}\nThis is generally NOT safe. Learn more at https://bit.ly/wb-precache`;console.warn(e)}}}install(e){return c(e,(async()=>{const t=new h;this.strategy.plugins.push(t);for(const[t,s]of this._urlsToCacheKeys){const a=this._cacheKeysToIntegrities.get(s),n=this._urlsToCacheModes.get(t),r=new Request(t,{integrity:a,cache:n,credentials:"same-origin"});await Promise.all(this.strategy.handleAll({params:{cacheKey:s},request:r,event:e}))}const{updatedURLs:s,notUpdatedURLs:a}=t;return{updatedURLs:s,notUpdatedURLs:a}}))}activate(e){return c(e,(async()=>{const e=await self.caches.open(this.strategy.cacheName),t=await e.keys(),s=new Set(this._urlsToCacheKeys.values()),a=[];for(const n of t)s.has(n.url)||(await e.delete(n),a.push(n.url));return{deletedURLs:a}}))}getURLsToCacheKeys(){return this._urlsToCacheKeys}getCachedURLs(){return[...this._urlsToCacheKeys.keys()]}getCacheKeyForURL(e){const t=new URL(e,location.href);return this._urlsToCacheKeys.get(t.href)}getIntegrityForCacheKey(e){return this._cacheKeysToIntegrities.get(e)}async matchPrecache(e){const t=e instanceof Request?e.url:e,s=this.getCacheKeyForURL(t);if(s){return(await self.caches.open(this.strategy.cacheName)).match(s)}}createHandlerBoundToURL(e){const s=this.getCacheKeyForURL(e);if(!s)throw new t("non-precached-url",{url:e});return t=>(t.request=new Request(e),t.params=Object.assign({cacheKey:s},t.params),this.strategy.handle(t))}}let R;const v=()=>(R||(R=new _),R);s(80);const C=e=>e&&"object"==typeof e?e:{handle:e};class b{constructor(e,t,s="GET"){this.handler=C(t),this.match=e,this.method=s}setCatchHandler(e){this.catchHandler=C(e)}}class q extends b{constructor(e,t,s){super((({url:t})=>{const s=e.exec(t.href);if(s&&(t.origin===location.origin||0===s.index))return s.slice(1)}),t,s)}}class U{constructor(){this._routes=new Map,this._defaultHandlerMap=new Map}get routes(){return this._routes}addFetchListener(){self.addEventListener("fetch",(e=>{const{request:t}=e,s=this.handleRequest({request:t,event:e});s&&e.respondWith(s)}))}addCacheListener(){self.addEventListener("message",(e=>{if(e.data&&"CACHE_URLS"===e.data.type){const{payload:t}=e.data;0;const s=Promise.all(t.urlsToCache.map((t=>{"string"==typeof t&&(t=[t]);const s=new Request(...t);return this.handleRequest({request:s,event:e})})));e.waitUntil(s),e.ports&&e.ports[0]&&s.then((()=>e.ports[0].postMessage(!0)))}}))}handleRequest({request:e,event:t}){const s=new URL(e.url,location.href);if(!s.protocol.startsWith("http"))return void 0;const a=s.origin===location.origin,{params:n,route:r}=this.findMatchingRoute({event:t,request:e,sameOrigin:a,url:s});let i=r&&r.handler;const c=e.method;if(!i&&this._defaultHandlerMap.has(c)&&(i=this._defaultHandlerMap.get(c)),!i)return void 0;let o;try{o=i.handle({url:s,request:e,event:t,params:n})}catch(e){o=Promise.reject(e)}const h=r&&r.catchHandler;return o instanceof Promise&&(this._catchHandler||h)&&(o=o.catch((async a=>{if(h){0;try{return await h.handle({url:s,request:e,event:t,params:n})}catch(e){e instanceof Error&&(a=e)}}if(this._catchHandler)return this._catchHandler.handle({url:s,request:e,event:t});throw a}))),o}findMatchingRoute({url:e,sameOrigin:t,request:s,event:a}){const n=this._routes.get(s.method)||[];for(const r of n){let n;const i=r.match({url:e,sameOrigin:t,request:s,event:a});if(i)return n=i,(Array.isArray(n)&&0===n.length||i.constructor===Object&&0===Object.keys(i).length||"boolean"==typeof i)&&(n=void 0),{route:r,params:n}}return{}}setDefaultHandler(e,t="GET"){this._defaultHandlerMap.set(t,C(e))}setCatchHandler(e){this._catchHandler=C(e)}registerRoute(e){this._routes.has(e.method)||this._routes.set(e.method,[]),this._routes.get(e.method).push(e)}unregisterRoute(e){if(!this._routes.has(e.method))throw new t("unregister-route-but-not-found-with-method",{method:e.method});const s=this._routes.get(e.method).indexOf(e);if(!(s>-1))throw new t("unregister-route-route-not-registered");this._routes.get(e.method).splice(s,1)}}let L;class k extends b{constructor(e,t){super((({request:s})=>{const a=e.getURLsToCacheKeys();for(const n of function*(e,{ignoreURLParametersMatching:t=[/^utm_/,/^fbclid$/],directoryIndex:s="index.html",cleanURLs:a=!0,urlManipulation:n}={}){const r=new URL(e,location.href);r.hash="",yield r.href;const i=function(e,t=[]){for(const s of[...e.searchParams.keys()])t.some((e=>e.test(s)))&&e.searchParams.delete(s);return e}(r,t);if(yield i.href,s&&i.pathname.endsWith("/")){const e=new URL(i.href);e.pathname+=s,yield e.href}if(a){const e=new URL(i.href);e.pathname+=".html",yield e.href}if(n){const e=n({url:r});for(const t of e)yield t.href}}(s.url,t)){const t=a.get(n);if(t){return{cacheKey:t,integrity:e.getIntegrityForCacheKey(t)}}}}),e.strategy)}}function K(e){const s=v();!function(e,s,a){let n;if("string"==typeof e){const t=new URL(e,location.href);n=new b((({url:e})=>e.href===t.href),s,a)}else if(e instanceof RegExp)n=new q(e,s,a);else if("function"==typeof e)n=new b(e,s,a);else{if(!(e instanceof b))throw new t("unsupported-route-type",{moduleName:"workbox-routing",funcName:"registerRoute",paramName:"capture"});n=e}(L||(L=new U,L.addFetchListener(),L.addCacheListener()),L).registerRoute(n)}(new k(s,e))}var T;(function(e){v().precache(e)})([{'revision':null,'url':'/build/admin.4de55830.css'},{'revision':null,'url':'/build/admin.86a2d986.js'},{'revision':'ad79405d542b397996a3079203114b42','url':'/build/admin.86a2d986.js.LICENSE.txt'},{'revision':null,'url':'/build/app.435420b4.js'},{'revision':'4ff7361e3c3e359ae88c5fae5738746d','url':'/build/app.435420b4.js.LICENSE.txt'},{'revision':null,'url':'/build/app.7133af83.css'},{'revision':null,'url':'/build/fonts/fa-brands-400.3dc44d22.woff2'},{'revision':null,'url':'/build/fonts/fa-regular-400.3dc6ca01.woff2'},{'revision':null,'url':'/build/fonts/fa-solid-900.496d5fc1.woff2'},{'revision':null,'url':'/build/fonts/source-sans-pro-v14-latin-300.d2c7d5c5.woff2'},{'revision':null,'url':'/build/fonts/source-sans-pro-v14-latin-600.17c0392c.woff2'},{'revision':null,'url':'/build/fonts/source-sans-pro-v14-latin-600italic.cc34c6e7.woff2'},{'revision':null,'url':'/build/fonts/source-sans-pro-v14-latin-700.ed37bc60.woff2'},{'revision':null,'url':'/build/fonts/source-sans-pro-v14-latin-900.476756cd.woff2'},{'revision':null,'url':'/build/fonts/source-sans-pro-v14-latin-italic.a07cb9c5.woff2'},{'revision':null,'url':'/build/fonts/source-sans-pro-v14-latin-regular.f74389bd.woff2'},{'revision':null,'url':'/build/images/fa-brands-400.05d20183.svg'},{'revision':null,'url':'/build/images/fa-regular-400.9a0810d6.svg'},{'revision':null,'url':'/build/images/fa-solid-900.a838c42a.svg'},{'revision':null,'url':'/build/images/source-sans-pro-v14-latin-300.4e7fe004.svg'},{'revision':null,'url':'/build/images/source-sans-pro-v14-latin-600.cf2758ae.svg'},{'revision':null,'url':'/build/images/source-sans-pro-v14-latin-600italic.7249d863.svg'},{'revision':null,'url':'/build/images/source-sans-pro-v14-latin-700.3e4b9e19.svg'},{'revision':null,'url':'/build/images/source-sans-pro-v14-latin-900.060d8c51.svg'},{'revision':null,'url':'/build/images/source-sans-pro-v14-latin-italic.08dc9b1c.svg'},{'revision':null,'url':'/build/images/source-sans-pro-v14-latin-regular.3bb9538c.svg'},{'revision':null,'url':'/build/runtime.6ad5c9da.js'}]),K(T),self.addEventListener("fetch",(function(e){e.respondWith(caches.match(e.request).then((function(t){return t||fetch(e.request)})).catch((function(){return caches.match("/offline.html")})))}))})()})();
\ No newline at end of file \ No newline at end of file
...@@ -429,26 +429,14 @@ class AdherentAdmin extends AbstractAdmin ...@@ -429,26 +429,14 @@ class AdherentAdmin extends AbstractAdmin
$adherent->addAccount($account); $adherent->addAccount($account);
$em->persist($account); $em->persist($account);
} }
$em->persist($adherent->getUser());
$em->persist($adherent);
$em->flush();
}
public function postUpdate($adherent)
{
$this->postUpdateAdherent($adherent);
}
public function postPersist($adherent)
{
$this->postUpdateAdherent($adherent);
}
private function postUpdateAdherent($adherent)
{
if ($this->getConfigurationPool()->getContainer()->getParameter('household_based_allowance')) { if ($this->getConfigurationPool()->getContainer()->getParameter('household_based_allowance')) {
$this->tavCotisationUtils->calculateAllowanceAccordingToHousehold($adherent); $this->tavCotisationUtils->calculateAllowanceAccordingToHousehold($adherent);
} }
$em->persist($adherent->getUser());
$em->persist($adherent);
$em->flush();
} }
/** /**
......
...@@ -136,8 +136,6 @@ class UserAdherentController extends FluxController ...@@ -136,8 +136,6 @@ class UserAdherentController extends FluxController
$form->handleRequest($request); $form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) { if ($form->isSubmitted() && $form->isValid()) {
// TODO: set CB payment when the functionality is validated
$flux = $form->getData(); $flux = $form->getData();
// Look for existing cotisation // Look for existing cotisation
...@@ -166,12 +164,13 @@ class UserAdherentController extends FluxController ...@@ -166,12 +164,13 @@ class UserAdherentController extends FluxController
$flux->setDon(null); $flux->setDon(null);
} }
// TODO redirect to paiement // Redirect to payment
return $this->forward('App\Controller\PaymentController::preparePaymentAction', [ return $this->forward('App\Controller\PaymentController::preparePaymentAction', [
'form' => $form, 'form' => $form,
'type' => Payment::TYPE_PAIEMENT_COTISATION_TAV // TODO 'type' => Payment::TYPE_PAIEMENT_COTISATION_TAV
]); ]);
/* For test purposes, comment redirections and uncomment following part to skip payment */
// $this->em->persist($flux); // $this->em->persist($flux);
// $this->operationUtils->executeOperations($flux); // $this->operationUtils->executeOperations($flux);
......
...@@ -215,25 +215,54 @@ class UserComptoirController extends FluxController ...@@ -215,25 +215,54 @@ class UserComptoirController extends FluxController
} }
$destinataire = $flux->getDestinataire(); $destinataire = $flux->getDestinataire();
$profile = $destinataire->getProfilDeCotisation();
if (is_null($profile)) { if ($this->getParameter('household_based_allowance') == true) {
$this->addFlash( /* Process: allowance based on household */
'error', $cotisationAmount = $destinataire->getCotisationAmount();
$this->translator->trans('Opération impossible : l\'habitant.e n\'a pas de profil de cotisation associé.')
);
return $this->redirectToRoute('index'); // Verifications
} if (is_null($cotisationAmount) || is_null($destinataire->getHouseholdAdultCount())) {
$this->addFlash(
'error',
$this->translator->trans("Opération impossible : le profil de l'habitant.e est incomplet, veuillez le compléter dans l'interface d'administration.")
);
$cotisationAmount = $profile->getMontant(); // Amount in € paid by the user return $this->redirectToRoute('index');
$flux->setMontant($cotisationAmount); }
$this->em->persist($flux); if (is_null($destinataire->getAllocationAmount())) {
$this->operationUtils->executeOperations($flux); $this->tavCotisationUtils->calculateAllowanceAccordingToHousehold($destinataire);
$this->em->persist($destinataire);
}
$flux->setMontant($cotisationAmount);
$this->em->persist($flux);
$this->operationUtils->executeOperations($flux);
// Apply cotisation rate, create new flux
$this->tavCotisationsUtils->applyHouseholdAllowance($flux);
} else {
/* Process: allowance based on cotisation profile with cotisation rate */
$profile = $destinataire->getProfilDeCotisation();
if (is_null($profile)) {
$this->addFlash(
'error',
$this->translator->trans('Opération impossible : l\'habitant.e n\'a pas de profil de cotisation associé.')
);
return $this->redirectToRoute('index');
}
// Apply cotisation rate, create new flux $cotisationAmount = $profile->getMontant(); // Amount in € paid by the user
$this->tavCotisationsUtils->applyTauxCotisation($flux); $flux->setMontant($cotisationAmount);
$this->em->persist($flux);
$this->operationUtils->executeOperations($flux);
// Apply cotisation rate, create new flux
$this->tavCotisationsUtils->applyTauxCotisation($flux);
}
$this->em->flush(); $this->em->flush();
......
...@@ -7,16 +7,19 @@ use App\Utils\OperationFactory; ...@@ -7,16 +7,19 @@ use App\Utils\OperationFactory;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
/** /**
* Application du taux de cotisation lors du paiement d'une cotisation (au sens TAV). * Application du calcul de l'allocation (emlc reçues) lors du paiement d'une cotisation (au sens TAV).
* *
* Au paiement d'une cotisation: * Au paiement d'une cotisation:
* - Un premier Flux est enregistré, correspondant à l'achat/vente d'emlc. * - Un premier Flux est enregistré, correspondant à l'achat/vente d'emlc.
* - Puis on applique le taux défini dans le ProfilDeCotisation de l'adhérent, * - On crée un nouveau flux pour compléter la cotisation, en fonction du système de calcul choisi.
* on crée un nouveau flux pour compléter la cositsation. *
* Systèmes de calculs possibles :
* - On applique le taux défini dans le ProfilDeCotisation de l'adhérent
* - On calcule le montant à recevoir en fonction du foyer de l'adhérent
* *
* @ORM\Entity * @ORM\Entity
*/ */
class TauxCotisationApplication extends Flux class CotisationTavApplication extends Flux
{ {
const TYPE_REVERSEMENT_COTISATION_ADHERENT = 'reversement_cotisation_adherent'; const TYPE_REVERSEMENT_COTISATION_ADHERENT = 'reversement_cotisation_adherent';
const TYPE_PRELEVEMENT_COTISATION_ADHERENT = 'prelevement_cotisation_adherent'; const TYPE_PRELEVEMENT_COTISATION_ADHERENT = 'prelevement_cotisation_adherent';
...@@ -26,7 +29,7 @@ class TauxCotisationApplication extends Flux ...@@ -26,7 +29,7 @@ class TauxCotisationApplication extends Flux
*/ */
public function getParenttype(): string public function getParenttype(): string
{ {
return parent::TYPE_APPLICATION_TAUX_COTISATION; return parent::TYPE_APPLICATION_COTISATION_TAV;
} }
public function getAllOperations($em) public function getAllOperations($em)
......
...@@ -7,12 +7,16 @@ use App\Utils\OperationFactory; ...@@ -7,12 +7,16 @@ use App\Utils\OperationFactory;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
/** /**
* En cas de taux < 1, l'adhérent•e reçoit moins d'emlc que ce qu'elle•il paye en € : * Dans les cas suivants :
* - [Profil de Cotisation] La taux est inférieur à 1
* - [Allocation selon foyer] Le montant reçu calculé est inférieur au montant payé
*
* L'adhérent•e reçoit moins d'emlc que ce qu'elle•il paye en €,
* un second flux est créé pour prélever le complément de la cotisation. * un second flux est créé pour prélever le complément de la cotisation.
* *
* @ORM\Entity * @ORM\Entity
*/ */
class TauxCotisationPrelevement extends TauxCotisationApplication class CotisationTavPrelevement extends CotisationTavApplication
{ {
/** /**
* @ORM\OneToOne(targetEntity="Adherent") * @ORM\OneToOne(targetEntity="Adherent")
......
...@@ -7,12 +7,16 @@ use App\Utils\OperationFactory; ...@@ -7,12 +7,16 @@ use App\Utils\OperationFactory;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
/** /**
* En cas de taux > 1, l'adhérent•e reçoit plus d'emlc que ce qu'elle•il paye en € : * * Dans les cas suivants :
* - [Profil de Cotisation] La taux est supérieur à 1
* - [Allocation selon foyer] Le montant reçu calculé est supérieur au montant payé
*
* L'adhérent•e reçoit plus d'emlc que ce qu'elle•il paye en €,
* un second flux est créé pour reverser le complément de la cotisation. * un second flux est créé pour reverser le complément de la cotisation.
* *
* @ORM\Entity * @ORM\Entity
*/ */
class TauxCotisationReversement extends TauxCotisationApplication class CotisationTavReversement extends CotisationTavApplication
{ {
/** /**
* @ORM\OneToOne(targetEntity="Siege") * @ORM\OneToOne(targetEntity="Siege")
......
...@@ -54,9 +54,9 @@ use Symfony\Component\Validator\Constraints as Assert; ...@@ -54,9 +54,9 @@ use Symfony\Component\Validator\Constraints as Assert;
* "ticket_fix" = "TicketFix", * "ticket_fix" = "TicketFix",
* "ticket_fix_print" = "TicketFixPrint", * "ticket_fix_print" = "TicketFixPrint",
* "ticket_fix_destroy" = "TicketFixDestroy", * "ticket_fix_destroy" = "TicketFixDestroy",
* "application_taux_cotisation" = "TauxCotisationApplication", * "application_cotisation_tav" = "CotisationTavApplication",
* "reversement_cotisation_adherent" = "TauxCotisationReversement", * "reversement_cotisation_adherent" = "CotisationTavReversement",
* "prelevement_cotisation_adherent" = "TauxCotisationPrelevement", * "prelevement_cotisation_adherent" = "CotisationTavPrelevement",
* }) * })
*/ */
abstract class Flux implements FluxInterface abstract class Flux implements FluxInterface
...@@ -74,7 +74,7 @@ abstract class Flux implements FluxInterface ...@@ -74,7 +74,7 @@ abstract class Flux implements FluxInterface
const TYPE_VENTE = 'vente'; const TYPE_VENTE = 'vente';
const TYPE_VENTE_EMLC = 'vente_emlc'; const TYPE_VENTE_EMLC = 'vente_emlc';
const TYPE_TICKET_FIX = 'ticket_fix'; const TYPE_TICKET_FIX = 'ticket_fix';
const TYPE_APPLICATION_TAUX_COTISATION = 'application_taux_cotisation'; const TYPE_APPLICATION_COTISATION_TAV = 'application_cotisation_tav';
/** /**
* @var \Ramsey\Uuid\UuidInterface * @var \Ramsey\Uuid\UuidInterface
......
...@@ -20,13 +20,17 @@ class EncaisserCotisationAdherentFormType extends VenteEmlcAdherentFormType ...@@ -20,13 +20,17 @@ class EncaisserCotisationAdherentFormType extends VenteEmlcAdherentFormType
// Get the cotisation amount for each adherent. Used for display purposes on the front end. // Get the cotisation amount for each adherent. Used for display purposes on the front end.
$adherents = $this->em->getRepository(Adherent::class)->findOrderByName(); $adherents = $this->em->getRepository(Adherent::class)->findOrderByName();
$adherentsProfiles = []; $adherentsCotisationAmounts = [];
foreach ($adherents as $adh) { foreach ($adherents as $adh) {
$montant = null; $montant = null;
if (!is_null($adh->getProfilDeCotisation()) ) {
if ($this->container->getParameter('household_based_allowance') && !is_null($adh->getCotisationAmount())) {
$montant = $adh->getCotisationAmount();
} else if (!$this->container->getParameter('household_based_allowance') && !is_null($adh->getProfilDeCotisation())) {
$montant = $adh->getProfilDeCotisation()->getMontant(); $montant = $adh->getProfilDeCotisation()->getMontant();
} }
$adherentsProfiles[strval($adh->getId())] = $montant;
$adherentsCotisationAmounts[strval($adh->getId())] = $montant;
} }
$builder $builder
...@@ -37,7 +41,7 @@ class EncaisserCotisationAdherentFormType extends VenteEmlcAdherentFormType ...@@ -37,7 +41,7 @@ class EncaisserCotisationAdherentFormType extends VenteEmlcAdherentFormType
'data' => 0 'data' => 0
]) ])
->add('cotisationMontants', HiddenType::class, [ ->add('cotisationMontants', HiddenType::class, [
'data' => json_encode($adherentsProfiles), 'data' => json_encode($adherentsCotisationAmounts),
'mapped' => false 'mapped' => false
]) ])
; ;
......
...@@ -5,8 +5,8 @@ namespace App\Utils; ...@@ -5,8 +5,8 @@ namespace App\Utils;
use App\Entity\Adherent; use App\Entity\Adherent;
use App\Entity\Siege; use App\Entity\Siege;
use App\Entity\Flux; use App\Entity\Flux;
use App\Entity\TauxCotisationReversement; use App\Entity\CotisationTavReversement;
use App\Entity\TauxCotisationPrelevement; use App\Entity\CotisationTavPrelevement;
use App\Enum\MoyenEnum; use App\Enum\MoyenEnum;
use App\Utils\CustomEntityManager; use App\Utils\CustomEntityManager;
use Symfony\Component\Security\Core\Security; use Symfony\Component\Security\Core\Security;
...@@ -75,14 +75,14 @@ class TAVCotisationUtils ...@@ -75,14 +75,14 @@ class TAVCotisationUtils
if ($amountDiff > 0) { if ($amountDiff > 0) {
// User should receive more than he•she paid: send a new flux to the user to complete its cotisation // User should receive more than he•she paid: send a new flux to the user to complete its cotisation
$fluxCotis = new TauxCotisationReversement(); $fluxCotis = new CotisationTavReversement();
$fluxCotis->setExpediteur($siege); $fluxCotis->setExpediteur($siege);
$fluxCotis->setDestinataire($flux->getDestinataire()); $fluxCotis->setDestinataire($flux->getDestinataire());
$fluxCotis->setMontant($amountDiff); $fluxCotis->setMontant($amountDiff);
$fluxCotis->setReference("Reversement cotisation après paiement de " . $cotisationAmount . "€ et application du taux " . $cotisationTaux); $fluxCotis->setReference("Reversement cotisation après paiement de " . $cotisationAmount . "€ et application du taux " . $cotisationTaux);
} else { } else {
// User should receive less than he•she paid: fetch the difference from his account // User should receive less than he•she paid: fetch the difference from his account
$fluxCotis = new TauxCotisationPrelevement(); $fluxCotis = new CotisationTavPrelevement();
$fluxCotis->setExpediteur($flux->getDestinataire()); $fluxCotis->setExpediteur($flux->getDestinataire());
$fluxCotis->setDestinataire($siege); $fluxCotis->setDestinataire($siege);
$fluxCotis->setMontant(-$amountDiff); $fluxCotis->setMontant(-$amountDiff);
...@@ -109,11 +109,11 @@ class TAVCotisationUtils ...@@ -109,11 +109,11 @@ class TAVCotisationUtils
* *
* Once the full amount is calculated, cap user's balance. * Once the full amount is calculated, cap user's balance.
* User account balance is capped at twice the amount previously calculated. * User account balance is capped at twice the amount previously calculated.
*
* @param Adherent $adherent (by ref)
*/ */
public function calculateAllowanceAccordingToHousehold($adherent) { public function calculateAllowanceAccordingToHousehold(&$adherent) {
$cotisationAmount = $adherent->getCotisationAmount(); // TODO base amounts to param in .env, or in global params ?
// TODO base amounts to param in .env)
// base allowance, for one adult // base allowance, for one adult
$mlcAllowanceAmount = 150; $mlcAllowanceAmount = 150;
...@@ -140,41 +140,45 @@ class TAVCotisationUtils ...@@ -140,41 +140,45 @@ class TAVCotisationUtils
} }
$adherent->setAllocationAmount($mlcAllowanceAmount); $adherent->setAllocationAmount($mlcAllowanceAmount);
$this->em->persist($adherent);
$this->em->flush();
} }
/** /**
* Method called to create Flux * Method called to create Flux based on allowance amount (for household based allowance)
* *
* TODO
*/ */
public function applyHouseholdAllowance(Flux $flux) { public function applyHouseholdAllowance(Flux $flux) {
// get allowance // get allowance
$adherent = $flux->getDestinataire();
$cotisationAmount = $flux->getMontant();
// get the mlc amount the user is supposed to receive
$mlcAllowanceAmount = $adherent->getAllocationAmount();
// Apply cap
$currentBalance = $adherent->getEmlcAccount()->getBalance();
$capped = false;
if ($currentBalance + $mlcAllowanceAmount >= 2 * $mlcAllowanceAmount) {
// Allow difference to reach max balance
$mlcAllowanceAmount = 2 * $mlcAllowanceAmount - $currentBalance;
$capped = true;
}
// Create Flux
if ($flux->getExpediteur() instanceof Siege) { if ($flux->getExpediteur() instanceof Siege) {
$siege = $flux->getExpediteur(); $siege = $flux->getExpediteur();
} else { } else {
$siege = $flux->getExpediteur()->getGroupe()->getSiege(); $siege = $flux->getExpediteur()->getGroupe()->getSiege();
} }
// TODO new flux entity ? use same entities ? // get the difference between what the user paid and what he•she's supposed to receive
$fluxCotis = new TauxCotisationReversement(); $amountDiff = $mlcAllowanceAmount - $cotisationAmount;
$fluxCotis->setExpediteur($siege);
$fluxCotis->setDestinataire($flux->getDestinataire()); if ($amountDiff > 0) {
$fluxCotis->setMontant($amountDiff); // User should receive more than he•she paid: send a new flux to the user to complete its cotisation
$fluxCotis->setReference("Reversement allocation après paiement de " . $cotisationAmount . "€ et calcul en fonction du foyer."); $fluxCotis = new CotisationTavReversement();
$fluxCotis->setExpediteur($siege);
$fluxCotis->setDestinataire($adherent);
$fluxCotis->setMontant($amountDiff);
$fluxCotis->setReference("Reversement du complément de cotisation après paiement de " . $cotisationAmount . "€ pour une allocation de " . $mlcAllowanceAmount . " MonA.");
} else {
// User should receive less than he•she paid: fetch the difference from his account
$fluxCotis = new CotisationTavPrelevement();
$fluxCotis->setExpediteur($adherent);
$fluxCotis->setDestinataire($siege);
$fluxCotis->setMontant(-$amountDiff);
$fluxCotis->setReference("Prélèvement du complément de cotisation après paiement de " . $cotisationAmount . "€ pour une allocation de " . $mlcAllowanceAmount . " MonA.");
}
$fluxCotis->setOperateur($flux->getOperateur()); $fluxCotis->setOperateur($flux->getOperateur());
$fluxCotis->setRole($flux->getRole()); $fluxCotis->setRole($flux->getRole());
$fluxCotis->setMoyen(MoyenEnum::MOYEN_EMLC); $fluxCotis->setMoyen(MoyenEnum::MOYEN_EMLC);
......
...@@ -9,9 +9,13 @@ ...@@ -9,9 +9,13 @@
<h5> <b>Montant de la cotisation : <span id="formEncaisserCotisationAdherent-montant-display"></span></b></h5> <h5> <b>Montant de la cotisation : <span id="formEncaisserCotisationAdherent-montant-display"></span></b></h5>
<br/> <br/>
</div> </div>
<div id="formEncaisserCotisationAdherent-no-profile" style="display:none"> <div id="formEncaisserCotisationAdherent-no-cotisation-amount" style="display:none">
<p class="formEncaisserCotisationAdherent-no-profile"> <p class="formEncaisserCotisationAdherent-no-cotisation-amount">
L'habitant•e n'a pas de profil de cotisation affecté, impossible de l'encaisser. {% if household_based_allowance %}
L'habitant•e n'a pas de montant de cotisation renseigné, impossible de l'encaisser.
{% else %}
L'habitant•e n'a pas de profil de cotisation affecté, impossible de l'encaisser.
{% endif %}
</p> </p>
</div> </div>
{% set form = getComptoirEncaisserCotisationForm(app.user) %} {% set form = getComptoirEncaisserCotisationForm(app.user) %}
......
...@@ -89,6 +89,7 @@ des_vente_adherent_email_subject: 'Vente de billets à un adhérent' ...@@ -89,6 +89,7 @@ des_vente_adherent_email_subject: 'Vente de billets à un adhérent'
des_vente_prestataire_email_subject: 'Vente de billets à un prestataire' des_vente_prestataire_email_subject: 'Vente de billets à un prestataire'
des_vente_emlc_adherent_email_subject: 'Vente de monnaie numérique à un adhérent' des_vente_emlc_adherent_email_subject: 'Vente de monnaie numérique à un adhérent'
des_vente_emlc_prestataire_email_subject: 'Vente de monnaie numérique à un prestataire' des_vente_emlc_prestataire_email_subject: 'Vente de monnaie numérique à un prestataire'
des_application_cotisation_tav: 'Complément de cotisation'
confirmation-cotisation-title: 'Cotisation bien reçue !' confirmation-cotisation-title: 'Cotisation bien reçue !'
confirmation-cotisation-content: 'Cotisation bien reçue, merci !' confirmation-cotisation-content: 'Cotisation bien reçue, merci !'
confirmation-cotisation-footer-cta: 'acheter de la monnaie locale numérique' confirmation-cotisation-footer-cta: 'acheter de la monnaie locale numérique'
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment