33 Commits

Author SHA1 Message Date
e7eb6f87b1 Feat: basic datafile 2021-08-10 11:19:03 +02:00
6c006a15fe Feat: chart delta et banque 2021-08-10 11:17:53 +02:00
cb39fbe5dd Feat: CA chart!! 2021-08-10 10:46:05 +02:00
a3cd3864ce Feat: clean home 2021-08-10 09:16:21 +02:00
78bb4cb1ff Feat: functionnalize months calculus 2021-08-09 14:43:24 +02:00
c47062ce86 Feat: add hightlights 2021-08-09 14:07:42 +02:00
5020479b0a Feat: write data on edit 2021-08-09 11:48:24 +02:00
899fd95dbd Feat: restore state and fix hightlights numbers 2021-08-09 11:38:51 +02:00
1a2799e986 Feat: read data from csv file 2021-08-09 10:28:01 +02:00
7ca7af24b9 Feat: Write data in csv 2021-08-09 09:29:58 +02:00
6188337140 Fix: remove useless state 2021-08-09 09:17:11 +02:00
791aa12d2d Start working on csv 2021-08-09 09:09:58 +02:00
4a9e49fc20 Feat: fs is now working!! 2021-08-05 09:59:08 +02:00
0bd48159a4 Fix: remove unnecessary function parameters 2021-08-05 08:47:01 +02:00
b266e9de9b Fix: Update month input when clicking on preselected ranges 2021-08-04 21:49:07 +02:00
4d77e61b25 Fix: hightlights depends on period 2021-08-04 21:20:21 +02:00
5683b57e24 Fix: output number in month form 2021-08-04 21:17:40 +02:00
a021fe8093 Dev: installation de vls 2021-08-04 19:55:33 +02:00
6f43c03808 Feat: hightlights on the period 2021-08-04 19:55:13 +02:00
3a0141f961 Fix: orthographe de remuneration 2021-08-04 19:54:30 +02:00
7b742d599a Feat: improve month selector 2021-08-03 16:57:16 +02:00
7f9cecf06d Feat: month selector 2021-08-03 11:34:49 +02:00
820bf435e8 Feat: reverse month order 2021-08-03 08:20:54 +02:00
6a0b0b9c6e Feat: ajout d'un nouveau mois 2021-08-02 15:09:54 +02:00
5e241dadb8 Feat: presentation and edit months 2021-08-02 14:23:00 +02:00
091cee308a Feat: remove css 2021-07-08 20:50:36 +02:00
dd997d569a Feat: styling for months 2021-07-08 20:24:32 +02:00
c8f58cc20d Feat: css things 2021-07-08 16:52:43 +02:00
1309c9147a Feat: default month and list display 2021-07-08 11:08:03 +02:00
6d669e5ae4 Feat: structure for month and form 2021-07-07 15:07:46 +02:00
caaefc0972 Feat: display months in home 2021-07-07 10:51:22 +02:00
bdca2dc0a0 Feat: feed example datas to travail store 2021-07-07 10:19:35 +02:00
b6759c5682 Feat: init vuex 2021-07-07 09:00:33 +02:00
21 changed files with 10787 additions and 8594 deletions

0
jsconfig.json Normal file
View File

1627
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -13,9 +13,14 @@
},
"main": "background.js",
"dependencies": {
"chart.js": "2.9.4",
"core-js": "^3.6.5",
"date-fns": "^2.23.0",
"papaparse": "^5.3.1",
"vls": "^0.7.4",
"vue": "^3.0.0",
"vue-router": "^4.0.8"
"vue-router": "^4.0.8",
"vuex": "^4.0.2"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.0",

View File

@@ -9,7 +9,7 @@ import Nav from './components/nav.vue'
export default {
name: 'App',
components: {
Nav
Nav
}
}
</script>

View File

@@ -0,0 +1,134 @@
<template>
<div id="create-month" >
<div class="month-presentation" id="new-month">
<div class="date">
<input type="month" v-model="monthDate">
</div>
<div class="datas">
<ul>
<li>
<label for="ca-theo">CA théorique</label>
<input type="number" v-model.number="monthCopy.ca_theo" id="ca-theo" class="value" >
</li>
<li>
<label for="ca-retro">CA rétrocession</label>
<input type="number" v-model.number="monthCopy.ca_retro" id="ca-retro" class="value" >
</li>
<li>
<label for="ca-react">CA réactualisé</label>
<input type="number" v-model.number="monthCopy.ca_react" id="ca-react" class="value" >
</li>
<li>
<label for="nbr-seances">Nombre de séances effectuées</label>
<input type="number" v-model.number="monthCopy.nbr_seances" id="nbr-seances" class="value" >
</li>
<li>
<label for="retro">Montant de la rétrocession</label>
<input type="number" v-model.number="monthCopy.retro" id="retro" class="value" >
</li>
<li>
<label for="remuneration">Rémunération effectuée</label>
<input type="number" v-model.number="monthCopy.remuneration" id="remuneration" class="value">
</li>
</ul>
</div>
<div class="actions">
<button class="validate" @click="save"> Valider </button>
<button class="cancel" @click="cancel"> Annuler </button>
</div>
</div>
</div>
</template>
<script>
import { mapGetters, mapActions } from 'vuex'
const today = new Date();
function formatDate(date) {
var y = ''+date.getFullYear()
var m = ''+(date.getMonth()+1)
if (m.length < 2) { m = '0'+m}
return [y, m].join('-')
}
export default {
name: 'NewMonth',
props: {
},
components: {
},
data () {
return {
monthDate: formatDate(today),
monthCopy: Object,
}
},
mounted () {
this.monthCopy = this.theEmptyMonth
},
computed: {
...mapGetters('travail', {
'theEmptyMonth': 'TheEmptyMonth',
}),
},
methods: {
...mapActions('travail', {
'createMonth': 'createMonth',
}),
...mapActions('config', {
'writeData': 'writeData',
}),
save: function () {
console.log("save")
console.log(this.monthCopy)
this.createMonth({date: this.monthDate, month: this.monthCopy})
this.writeData()
},
cancel: function () {
this.monthCopy = this.theEmptyMonth
},
},
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.month-presentation {
display: inline-flex;
flex-direction: row;
background-color: palegreen;
align-items: center;
justify-content: space-between;
border-radius: 10px;
width: 100%;
}
.month-presentation > * {
margin: 20px;
}
.date > input {
font-size: 1.2em;
font-weight: bold;
display: inline-flex;
width: 6rem;
flex-wrap: wrap;
align-content: flex-start;
flex-direction: column;
align-items: flex-start;
}
ul {
list-style-type: none;
padding: 0;
display: flex;
flex-flow: row wrap;
}
li {
margin: 3px;
width: 30%;
display: flex;
flex-direction: column-reverse;
}
.value {
font-size: 1.5em;
font-weight: bold;
}
</style>

View File

@@ -0,0 +1,69 @@
<template>
<form>
<ul>
<li>
<label for="ca-theo">CA théorique</label>
<input type="number" id="ca-theo">
</li>
<li>
<label for="ca-retro">CA rétrocession</label>
<input type="number" id="ca-retro">
</li>
<li>
<label for="ca-react">CA réactualisé</label>
<input type="number" id="ca-react">
</li>
<li>
<label for="nbr-seance">Nombre de séances effectuées</label>
<input type="number" id="nbr-seance">
</li>
<li>
<label for="retro">Montant de la rétrocession</label>
<input type="number" id="retro">
</li>
<li>
<label for="remumeration">Rémunération effectuée</label>
<input type="number" id="remumeration">
</li>
</ul>
</form>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
name: 'MonthForm',
props: {
editMonth: {}
},
computed: {
...mapGetters({
TheEmpty: "travail/TheEmptyMonth",
})
},
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
ul {
list-style-type: none;
padding: 0;
display: flex;
flex-flow: row wrap;
}
li {
margin: 3px;
width: 30%;
display: flex;
flex-direction: column-reverse;
}
li > label {
font-size: 0.8em;
}
input {
width: 4em;
font-size: 1.5em;
}
</style>

View File

@@ -0,0 +1,132 @@
<template>
<div class="month-presentation">
<div class="date">
{{ TheDate }}
</div>
<div id="display">
<ul>
<li>
<label for="ca-theo">CA "Séances effectuées"</label>
<span class="value" v-show="!editing">{{ TheMonth.ca_theo ?? ""}}</span>
<input type="number" v-model.number="monthCopy.ca_theo" id="ca-theo" class="value" v-show="editing">
</li>
<li>
<label for="ca-retro">CA "Séances facturées"</label>
<span class="value" v-show="!editing">{{ TheMonth.ca_retro ?? ""}}</span>
<input type="number" v-model.number="monthCopy.ca_retro" id="ca-retro" class="value" v-show="editing">
</li>
<li>
<label for="ca-react">CA "Séances facturées" réactualisé</label>
<span class="value" v-show="!editing">{{ TheMonth.ca_react ?? ""}}</span>
<input type="number" v-model.number="monthCopy.ca_react" id="ca-react" class="value" v-show="editing">
</li>
<li>
<label for="nbr-seances">Nombre de séances effectuées</label>
<span class="value" v-show="!editing">{{ TheMonth.nbr_seances ?? ""}}</span>
<input type="number" v-model.number="monthCopy.nbr_seances" id="nbr-seances" class="value" v-show="editing">
</li>
<li>
<label for="retro">Montant de la rétrocession</label>
<span class="value" v-show="!editing">{{ TheMonth.retro ?? ""}}</span>
<input type="number" v-model.number="monthCopy.retro" id="retro" class="value" v-show="editing">
</li>
<li>
<label for="remuneration">Rémunération </label>
<span class="value" v-show="!editing">{{ TheMonth.remuneration ?? ""}}</span>
<input type="number" v-model.number="monthCopy.remuneration" id="remuneration" class="value" v-show="editing">
</li>
</ul>
</div>
<div class="actions">
<button class="edit" @click="toggleEdit" v-show="!editing"> Éditer </button>
<button class="validate" @click="save" v-show="editing"> Valider </button>
<button class="cancel" @click="cancel" v-show="editing"> Annuler </button>
</div>
</div>
</template>
<script>
import { mapActions } from 'vuex'
export default {
name: 'MonthPresentation',
props: {
TheDate: String,
TheMonth: {
type: Object,
}
},
data () {
return {
editing: false,
monthCopy: Object,
}
},
mounted: function () {
this.monthCopy = {...this.TheMonth}
},
computed: {
},
methods: {
...mapActions('travail', {
'updateMonth': 'updateMonth',
}),
...mapActions('config', {
'writeData': 'writeData',
}),
toggleEdit: function () {
this.editing = !this.editing
},
save: function () {
this.updateMonth({date: this.TheDate, month: {...this.monthCopy}})
this.writeData()
this.toggleEdit()
},
cancel: function () {
this.monthCopy = {...this.TheMonth}
this.toggleEdit()
},
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.month-presentation {
display: inline-flex;
flex-direction: row;
background-color: mintcream;
align-items: center;
justify-content: space-between;
width: 100%;
border-radius: 10px;
}
.month-presentation > * {
margin: 20px;
}
.date {
font-size: 1.5em;
font-weight: bold;
}
ul {
list-style-type: none;
padding: 0;
display: flex;
flex-flow: row wrap;
}
li {
margin: 3px;
width: 30%;
display: flex;
flex-direction: column-reverse;
}
.value {
font-size: 1.5em;
font-weight: bold;
}
.novisible {
display: None;
}
</style>

View File

@@ -0,0 +1,42 @@
<template>
<ul>
<li v-for="date in dates" :key="date">
<month-presentation :TheDate=date :TheMonth=getMonth(date)></month-presentation>
</li>
</ul>
</template>
<script>
import { mapGetters } from 'vuex'
import MonthPresentation from "./MonthPresentation"
export default {
name: 'Months',
components: {
MonthPresentation: MonthPresentation
},
props: {
},
computed: {
...mapGetters({
dates: "travail/MonthsDate",
getMonth: "travail/getMonth",
})
},
}
</script>
<style scoped>
ul {
list-style-type: none;
padding: 0;
}
li {
padding-bottom: 10px;
}
li:last-of-type {
padding-bottom: 0;
}
</style>

View File

@@ -0,0 +1,92 @@
<template>
<div>
<canvas id="revenus-chart"></canvas>
</div>
</template>
<script>
import Chart from 'chart.js'
import { mapGetters } from 'vuex'
import { monthCA, caPersoUntouch, caPerso, remuneration } from '../../lib/months'
export default {
name: 'RevenusChart',
data() {
return {
}
},
watch: {
months: function () {
const ctx = document.getElementById('revenus-chart');
new Chart(ctx, this.graphDatas);
},
},
computed: {
...mapGetters('config', {
caProPercentage: 'caProPercentage',
}),
...mapGetters('travail', {
months: "months",
}),
graphDatas: function () {
var datas = {
type: "bar",
data: {
labels: Object.keys(this.months),
datasets: [
{
type: "bar",
label: "Difference CA perso et remuneration",
data: Object.values(this.months).map(a => caPerso({bar: a}, this.caProPercentage) - remuneration({bar:a})),
backgroundColor: "red",
borderColor: "light-red",
borderWidth: 3
},
{
type: "bar",
label: "CA",
data: Object.values(this.months).map(a => monthCA(a)),
backgroundColor: "rgba(54,73,93,.5)",
borderColor: "#36495d",
borderWidth: 3
},
{
type: "line",
label: "Banque",
data: this.untouchEvo,
backgroundColor: "rgba(71, 183,132,.5)",
borderColor: "#47b784",
borderWidth: 3
},
],
},
options: {
responsive: true,
lineTension: 1,
scales: {
yAxes: [
{
ticks: {
beginAtZero: true,
padding: 25
}
}
]
}
}
}
return datas
},
untouchEvo: function () {
const cumulativeArray = (arr => value => {arr.push(value); return [...arr];})([]);
return Object.values(this.months).map(cumulativeArray).map(a => caPersoUntouch(a, this.caProPercentage))
},
},
methods: {
},
mounted() {
const ctx = document.getElementById('revenus-chart');
new Chart(ctx, this.graphDatas);
}
}
</script>

View File

@@ -0,0 +1,120 @@
<template>
<div id="hightlights">
<div class="hightlight">
<ul>
<li>{{ ca }}</li>
<li>CA</li>
</ul>
</div>
<div class="hightlight">
<ul>
<li>{{ caMean }}</li>
<li>CA moyen</li>
</ul>
</div>
<div class="hightlight">
<ul>
<li>{{ caTheo }}</li>
<li>CA des séances effectuées</li>
</ul>
</div>
<div class="hightlight">
<ul>
<li>{{ caTheo - ca }}</li>
<li>Non facturé</li>
</ul>
</div>
<div class="hightlight">
<ul>
<li>{{ remuneration }}</li>
<li>Rémunération</li>
</ul>
</div>
<div class="hightlight">
<ul>
<li>{{ remunerationMean }}</li>
<li>Rémunération moyenne</li>
</ul>
</div>
<div class="hightlight">
<ul>
<li>{{ retrocession }}</li>
<li>Rétrocession</li>
</ul>
</div>
<div class="hightlight">
<ul>
<li>{{ retrocessionMean }}</li>
<li>Rétrocession moyenne</li>
</ul>
</div>
<div class="hightlight">
<ul>
<li>{{ caPro }}</li>
<li> CA pour la partie pro ({{ caProPercentage*100}}% du CA)</li>
</ul>
</div>
<div class="hightlight">
<ul>
<li>{{ caPerso }}</li>
<li> CA pour la partie perso</li>
</ul>
</div>
<div class="hightlight">
<ul>
<li>{{ caPersoUntouch }}</li>
<li> CA perso non utilisé pour se rémunérer</li>
</ul>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import { caTotal,
caMean,
caTheo,
remuneration,
remunerationMean,
retrocession,
retrocessionMean,
caPro,
caPerso,
caPersoUntouch
} from '../lib/months'
export default {
name: 'Hightlights',
components: {
},
data () {
return {}
},
computed: {
...mapGetters('config', {
caProPercentage: 'caProPercentage',
}),
...mapGetters('travail', {
months: "months",
}),
ca: function () {return caTotal(this.months)},
caMean: function () {return caMean(this.months)},
caTheo: function () {return caTheo(this.months)},
remuneration: function () {return remuneration(this.months)},
remunerationMean: function () {return remunerationMean(this.months)},
retrocession: function () {return retrocession(this.months)},
retrocessionMean: function () {return retrocessionMean(this.months)},
caPro: function () {return caPro(this.months, this.caProPercentage)},
caPerso: function () {return caPerso(this.months, this.caProPercentage)},
caPersoUntouch: function () {return caPersoUntouch(this.months, this.caProPercentage)},
},
mounted () {
},
methods: {
},
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,135 @@
<template>
<ul>
<li>
<h2>Période</h2>
</li>
<li>
<input type="month" @input="updateStart" v-model="start">
<input type="month" @input="updateEnd" v-model="end">
</li>
<li>
<button @click="setRangeFromJanuary" :active='selected=="january"'>Depuis le début de l'année</button>
<button @click="setRange1year" :active='selected=="year"'>Sur 1 an</button>
<button @click="setRangeAll" :active='selected=="all"'>Tout</button>
</li>
</ul>
</template>
<script>
import { mapGetters, mapActions } from 'vuex'
import { setMonth, addMonths, format, parseISO } from 'date-fns'
const today = new Date();
export default {
name: 'MonthSelector',
components: {
},
data () {
return {
selected: "",
start: "",
end: "",
}
},
computed: {
...mapGetters('travail', {
range: "range",
monthsDate: "MonthsDate",
})
},
watch: {
range: function () {
this.start = this.range.start
this.end = this.range.end
},
},
mounted () {
this.setRangeFromJanuary()
this.start = this.range.start
this.end = this.range.end
},
methods: {
...mapActions('travail', {
setRange: "setRange",
}),
updateStart: function () {
this.selected = "custom"
this.setRange({start: this.start, end: this.end})
},
updateEnd: function () {
this.selected = "custom"
this.setRange({start: this.start, end: this.end})
},
setRangeFromJanuary: function () {
const start = setMonth(today, 0)
const range = {
start: format(start, 'yyyy-MM'),
end: format(today, 'yyyy-MM'),
}
this.selected = "january"
this.setRange(range)
},
setRange1year: function () {
const start = addMonths(new Date(), -12)
const range = {
start: format(start, 'yyyy-MM'),
end: format(today, 'yyyy-MM'),
}
this.selected = "year"
this.setRange(range)
},
setRangeAll: function () {
const dates = this.monthsDate.map(a => parseISO(a, "yyyy-MM", new Date()))
const start = dates.reduce((a, b) => (a.MeasureDate > b.MeasureDate ? a: b))
const end = dates.reduce((a, b) => (a.MeasureDate > b.MeasureDate ? b: a))
const range = {
start: format(start, 'yyyy-MM'),
end: format(end, 'yyyy-MM'),
}
this.selected = "all"
this.setRange(range)
},
},
}
</script>
<style scoped>
ul {
list-style-type: none;
padding: 0;
display: flex;
flex-flow: column wrap;
}
ul > * {
margin-top: 10px;
}
li {
list-style-type: none;
display: flex;
flex-flow: row;
justify-content: space-around;
}
h2 {
margin: 0;
}
input {
border: none;
color: white;
padding: 15px 32px;
text-align: center;
display: inline-block;
font-size: 16px;
border-radius: 5px;
color: black;
}
button {
flex-basis: 33%;
height: 3rem;
background-color: white;
}
</style>

78
src/lib/months.js Normal file
View File

@@ -0,0 +1,78 @@
export function monthCA(month) {
// Extract the CA of the month
if (month.ca_react) {
return month.ca_react
} else {
return month.ca_retro
}
}
export function count (months) {
// Count how many months there are
return Object.keys(months).length
}
export function caTotal (months) {
// Total CA (ca_react if sets, ca_retro otherwise)
return Object.values(months).map(a => monthCA(a)).reduce(
(acc, v) => acc + v
,0
)
}
export function caMean (months) {
return caTotal(months) / count(months)
}
export function caTheo (months) {
// Total theorical CA
return Object.values(months).map(a => a.ca_theo).reduce(
(acc, v) => acc + v,
0
)
}
export function remuneration (months) {
// Total remuneration
return Object.values(months).map(a => a.remuneration).reduce(
(acc, v) => acc + v,
0
)
}
export function remunerationMean (months) {
// Mean of remuneration
return Math.floor(remuneration(months) / count(months))
}
export function retrocession (months) {
// Total retrocession
return Object.values(months)
.map(a => a.retro)
.reduce(
(acc, v) => acc + v,
0
)
}
export function retrocessionMean (months) {
// Mean of retrocession
return Math.floor(retrocession(months) / count(months))
}
export function caPro (months, keepPercent) {
// Part of the CA to keep for professional use
return caTotal(months) * keepPercent
}
export function caPerso (months, keepPercent) {
// Part of the CA to keep for personal use
return caTotal(months) - caPro(months, keepPercent)
}
export function caPersoUntouch (months, keepPercent) {
// Part of the personnal use CA that haven't been use
return caPerso(months, keepPercent) - remuneration(months)
}

View File

@@ -1,8 +1,11 @@
import { createApp } from 'vue'
import App from '@/App.vue'
import router from '@/router'
import store from '@/store'
import '@/style.css'
const app = createApp(App)
app.use(router)
app.use(store)
app.mount('#app')

43
src/store/config/index.js Normal file
View File

@@ -0,0 +1,43 @@
import path from 'path'
import Papa from 'papaparse'
import { writeFile } from 'fs'
const config = {
namespaced: true,
state() {
return {
//userDir: '~/.config/sousmargot/',
userDir: './userDir/',
dataFile: 'datas.csv',
caProPercentage: 0.5,
}
},
getters: {
userDir (state) { return state.userDir },
dataFilePath (state) { return path.join(state.userDir, state.dataFile) },
caProPercentage (state) { return state.caProPercentage },
},
mutations: {
},
actions: {
loadConfig (context) {
// load config file at ~/.config/sousmargot/config.json
return context.state.userDir
},
writeData (context) {
// overwrite the dataFile with months datas
const months = context.rootGetters['travail/monthsAll']
const unpackMonths = Object.keys(months).map(k => {return { ...months[k], date: k}})
const csv = Papa.unparse(unpackMonths)
writeFile(context.getters.dataFilePath, csv, (err) => {
if (err) {
console.log(err)
} else {
console.log("Datas sauvegardées")
}
})
},
},
}
export default config

13
src/store/index.js Normal file
View File

@@ -0,0 +1,13 @@
import { createStore } from 'vuex'
import travailStore from "./travail"
import configStore from "./config"
// Create a new store instance.
const store = createStore({
modules:{
travail: travailStore,
config: configStore,
}
})
export default store

166
src/store/travail/index.js Normal file
View File

@@ -0,0 +1,166 @@
import { readFile } from 'fs'
import Papa from 'papaparse'
const travail = {
namespaced: true,
state() {
return {
empty: {
ca_theo: null, // ca théorique basé sur les séances effectuées
nbr_seances: null, // Nombre de séances effectuées sur le mois
ca_retro: null, // ca au moment de la rétrocession
ca_react: null, // ca réactualisé
retro: 0, // montant de la rétrocession
remuneration: 0, // rémunération décidée
},
months: {
"2021-01": {
ca_theo: null, // ca théorique basé sur les séances effectuées
nbr_seances: null, // Nombre de séances effectuées sur le mois
ca_retro: 6747, // ca au moment de la rétrocession
ca_react: null, // ca réactualisé
retro: 893, // montant de la rétrocession
remuneration: 2000, // rémunération décidée
},
"2021-02": {
ca_theo: null, // ca théorique basé sur les séances effectuées
nbr_seances: null, // Nombre de séances effectuées sur le mois
ca_retro: 5183, // ca au moment de la rétrocession
ca_react: null, // ca réactualisé
retro: 665, // montant de la rétrocession
remuneration: 1500, // rémunération décidée
},
"2021-03": {
ca_theo: null, // ca théorique basé sur les séances effectuées
nbr_seances: null, // Nombre de séances effectuées sur le mois
ca_retro: 7088, // ca au moment de la rétrocession
ca_react: null, // ca réactualisé
retro: 855, // montant de la rétrocession
remuneration: 2000, // rémunération décidée
},
"2021-04": {
ca_theo: null, // ca théorique basé sur les séances effectuées
nbr_seances: null, // Nombre de séances effectuées sur le mois
ca_retro: 4194, // ca au moment de la rétrocession
ca_react: 5630, // ca réactualisé
retro: 627, // montant de la rétrocession
remuneration: 2000, // rémunération décidée
},
"2021-05": {
ca_theo: null, // ca théorique basé sur les séances effectuées
nbr_seances: null, // Nombre de séances effectuées sur le mois
ca_retro: 5564, // ca au moment de la rétrocession
ca_react: 6335, // ca réactualisé
retro: 699, // montant de la rétrocession
remuneration: 2800, // rémunération décidée
},
"2021-06": {
ca_theo: null, // ca théorique basé sur les séances effectuées
nbr_seances: null, // Nombre de séances effectuées sur le mois
ca_retro: 5442, // ca au moment de la rétrocession
ca_react: 6335, // ca réactualisé
retro: 638, // montant de la rétrocession
remuneration: 2800, // rémunération décidée
},
},
range: {
start: "2021-01",
end: "2021-08",
},
}
},
getters: {
TheEmptyMonth(state) { return { ...state.empty } },
range(state) { return state.range },
MonthsDate(state) {
// Get months inside the range
return Object.keys(state.months).filter(date => (date >= state.range.start) && (date <= state.range.end)).sort().reverse()
},
MonthsAllDate(state) {
// Get all the months
return Object.keys(state.months).sort().reverse()
},
months: (state, getters) => {
// Get in range months
const a = Object.keys(state.months)
.filter(a => getters.MonthsDate.includes(a))
.reduce((acc, v) => {
acc[v] = state.months[v];
return acc;
}, {})
return a
},
monthsAll: (state) => {
// Get in range months
return state.months
},
getMonth: (state) => (date) => {
return state.months[date]
},
count: (state, getters) => {
// Amount of mounts
return Object.keys(getters.months).length
},
},
mutations: {
cleanMonths (state) {
// erase months
state.months = []
},
importMonths(state, months) {
// overwrite months
state.months = months
},
updateMonth(state, { date, month }) {
state.months[date] = month
},
createMonth (state, { date, month }) {
state.months[date] = month
},
setRange(state, range) {
state.range = range
},
},
actions: {
cleanMonths (context) {
context.commit("cleanMonths")
},
loadMonths (context) {
// import all months from storage
readFile(context.rootGetters["config/dataFilePath"], (err, data) => {
if (err) throw err;
const months = Papa.parse(data.toString(), {header: true, dynamicTyping:true, skipEmptyLines:true})
.data
.reduce(
(acc, el) => {
acc[el.date] = el;
return acc
}, {})
context.commit("importMonths", months)
})
},
updateMonth(context, { date, month }) {
// update month's datas
if (date in context.state.months) {
context.commit('updateMonth', { date, month })
} else {
console.log("This month does not exists")
}
},
createMonth(context, { date, month }) {
// Create a new month
if (!(date in context.state.months)) {
context.commit('createMonth', { date, month })
} else {
console.log("This month already exists")
}
},
setRange(context, range) {
context.commit("setRange", range)
},
},
}
export default travail

27
src/style.css Normal file
View File

@@ -0,0 +1,27 @@
.actions {
display: inline-flex;
flex-direction: column;
width: 120px;
}
button {
border: none;
color: white;
padding: 15px 32px;
text-align: center;
display: inline-block;
width: 100%;
font-size: 16px;
border-radius: 5px;
color: black;
}
.validate {
background-color: green;
}
.cancel {
background-color: red;
}
.edit {
background-color: orange;
}

View File

@@ -1,3 +1,65 @@
<template>
<h1>Home</h1>
<revenus-chart/>
<section id="selector">
<month-selector/>
</section>
<div id="content">
<section id="months">
<h2> Mois </h2>
<create-month/>
<months-list/>
</section>
<section id="stats">
<h2>Résumé</h2>
<highlights/>
</section>
</div>
</template>
<script>
import { mapActions } from 'vuex'
import MonthsList from '../components/MonthsUl.vue'
import CreateMonth from '../components/CreateMonth.vue'
import MonthSelector from '../components/monthSelector.vue'
import Highlights from '../components/hightlights.vue'
import RevenusChart from '../components/graphs/RevenusChart.vue'
export default {
name: 'home',
components: {
MonthsList: MonthsList,
CreateMonth: CreateMonth,
MonthSelector: MonthSelector,
highlights: Highlights,
RevenusChart: RevenusChart,
},
data () {
return {}
},
computed: {
},
methods: {
...mapActions('travail', {
'loadMonths': 'loadMonths',
}),
},
mounted () {
//this.loadMonths()
},
}
</script>
<style scoped>
#content {
display: inline-flex;
flex-direction: row;
background-color: red;
margin: 0;
}
#content > * {
margin: 10px;
}
#months {
flex-basis: 60%;
}
</style>

7
userDir/datas.csv Normal file
View File

@@ -0,0 +1,7 @@
ca_theo,nbr_seances,ca_retro,ca_react,retro,remuneration,date
,,6747,,893,2000,2021-01
,,5183,,665,1500,2021-02
,,7088,,855,2000,2021-03
,,4194,5630,627,2000,2021-04
,,5564,6335,699,2800,2021-05
,,5442,6335,638,2800,2021-06
1 ca_theo nbr_seances ca_retro ca_react retro remuneration date
2 6747 893 2000 2021-01
3 5183 665 1500 2021-02
4 7088 855 2000 2021-03
5 4194 5630 627 2000 2021-04
6 5564 6335 699 2800 2021-05
7 5442 6335 638 2800 2021-06

7
vue.config.js Normal file
View File

@@ -0,0 +1,7 @@
module.exports = {
pluginOptions: {
electronBuilder: {
nodeIntegration: true
}
}
}

16615
yarn.lock

File diff suppressed because it is too large Load Diff