Changes In Branch dev Through [f5fe8e1fa6] Excluding Merge-Ins

This is equivalent to a diff from 0277842dc6 to f5fe8e1fa6

2020-12-06
18:40
Merge dev into trunk check-in: 81dd73fb26 user: bohwaz
2020-12-02
23:11
Fix plugin install check-in: 530ac81be6 user: bohwaz tags: dev
13:02
Fix arguments order in date filters check-in: f5fe8e1fa6 user: bohwaz tags: dev, 1.0.0-rc4
12:31
Order fees by amount check-in: b63a216b8b user: bohwaz tags: dev, 1.0.0-rc4
2020-10-26
20:45
Merge back changes from trunk check-in: 13b04f66ad user: bohwaz tags: dev
2020-09-08
18:53
Limiter la longueur du champ de recherche check-in: 0277842dc6 user: bohwaz tags: trunk, stable
18:42
Fix: erreur quand le fichier de fond d'écran a déjà été supprimé (race condition) check-in: 41baaae90b user: bohwaz tags: trunk, stable

Modified .travis.yml from [ab9c965cec] to [4da8c0eef1].

1
2
3
4
5
6
7
8
9
10
11
12
language: php
php:
  - '5.6'
  - '7.0'
  - '7.1'
  - '7.2'
  - '7.3'
  - '7.4'

install:
  - make -C src deps



<
<
<







1
2



3
4
5
6
7
8
9
language: php
php:



  - '7.2'
  - '7.3'
  - '7.4'

install:
  - make -C src deps

Added COPYING version [78e50e186b].











































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
                    GNU AFFERO GENERAL PUBLIC LICENSE
                       Version 3, 19 November 2007

 Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

                            Preamble

  The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.

  The licenses for most software and other practical works are designed
to take away your freedom to share and change the works.  By contrast,
our General Public Licenses are intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.

  Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.

  A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate.  Many developers of free software are heartened and
encouraged by the resulting cooperation.  However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.

  The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community.  It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server.  Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.

  An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals.  This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.

  The precise terms and conditions for copying, distribution and
modification follow.

                       TERMS AND CONDITIONS

  0. Definitions.

  "This License" refers to version 3 of the GNU Affero General Public License.

  "Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.

  "The Program" refers to any copyrightable work licensed under this
License.  Each licensee is addressed as "you".  "Licensees" and
"recipients" may be individuals or organizations.

  To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy.  The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.

  A "covered work" means either the unmodified Program or a work based
on the Program.

  To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy.  Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.

  To "convey" a work means any kind of propagation that enables other
parties to make or receive copies.  Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.

  An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License.  If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.

  1. Source Code.

  The "source code" for a work means the preferred form of the work
for making modifications to it.  "Object code" means any non-source
form of a work.

  A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.

  The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form.  A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.

  The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities.  However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work.  For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.

  The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.

  The Corresponding Source for a work in source code form is that
same work.

  2. Basic Permissions.

  All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met.  This License explicitly affirms your unlimited
permission to run the unmodified Program.  The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work.  This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.

  You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force.  You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright.  Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.

  Conveying under any other circumstances is permitted solely under
the conditions stated below.  Sublicensing is not allowed; section 10
makes it unnecessary.

  3. Protecting Users' Legal Rights From Anti-Circumvention Law.

  No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.

  When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.

  4. Conveying Verbatim Copies.

  You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.

  You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.

  5. Conveying Modified Source Versions.

  You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:

    a) The work must carry prominent notices stating that you modified
    it, and giving a relevant date.

    b) The work must carry prominent notices stating that it is
    released under this License and any conditions added under section
    7.  This requirement modifies the requirement in section 4 to
    "keep intact all notices".

    c) You must license the entire work, as a whole, under this
    License to anyone who comes into possession of a copy.  This
    License will therefore apply, along with any applicable section 7
    additional terms, to the whole of the work, and all its parts,
    regardless of how they are packaged.  This License gives no
    permission to license the work in any other way, but it does not
    invalidate such permission if you have separately received it.

    d) If the work has interactive user interfaces, each must display
    Appropriate Legal Notices; however, if the Program has interactive
    interfaces that do not display Appropriate Legal Notices, your
    work need not make them do so.

  A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit.  Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.

  6. Conveying Non-Source Forms.

  You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:

    a) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by the
    Corresponding Source fixed on a durable physical medium
    customarily used for software interchange.

    b) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by a
    written offer, valid for at least three years and valid for as
    long as you offer spare parts or customer support for that product
    model, to give anyone who possesses the object code either (1) a
    copy of the Corresponding Source for all the software in the
    product that is covered by this License, on a durable physical
    medium customarily used for software interchange, for a price no
    more than your reasonable cost of physically performing this
    conveying of source, or (2) access to copy the
    Corresponding Source from a network server at no charge.

    c) Convey individual copies of the object code with a copy of the
    written offer to provide the Corresponding Source.  This
    alternative is allowed only occasionally and noncommercially, and
    only if you received the object code with such an offer, in accord
    with subsection 6b.

    d) Convey the object code by offering access from a designated
    place (gratis or for a charge), and offer equivalent access to the
    Corresponding Source in the same way through the same place at no
    further charge.  You need not require recipients to copy the
    Corresponding Source along with the object code.  If the place to
    copy the object code is a network server, the Corresponding Source
    may be on a different server (operated by you or a third party)
    that supports equivalent copying facilities, provided you maintain
    clear directions next to the object code saying where to find the
    Corresponding Source.  Regardless of what server hosts the
    Corresponding Source, you remain obligated to ensure that it is
    available for as long as needed to satisfy these requirements.

    e) Convey the object code using peer-to-peer transmission, provided
    you inform other peers where the object code and Corresponding
    Source of the work are being offered to the general public at no
    charge under subsection 6d.

  A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.

  A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling.  In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage.  For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product.  A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.

  "Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source.  The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.

  If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information.  But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).

  The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed.  Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.

  Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.

  7. Additional Terms.

  "Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law.  If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.

  When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it.  (Additional permissions may be written to require their own
removal in certain cases when you modify the work.)  You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.

  Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:

    a) Disclaiming warranty or limiting liability differently from the
    terms of sections 15 and 16 of this License; or

    b) Requiring preservation of specified reasonable legal notices or
    author attributions in that material or in the Appropriate Legal
    Notices displayed by works containing it; or

    c) Prohibiting misrepresentation of the origin of that material, or
    requiring that modified versions of such material be marked in
    reasonable ways as different from the original version; or

    d) Limiting the use for publicity purposes of names of licensors or
    authors of the material; or

    e) Declining to grant rights under trademark law for use of some
    trade names, trademarks, or service marks; or

    f) Requiring indemnification of licensors and authors of that
    material by anyone who conveys the material (or modified versions of
    it) with contractual assumptions of liability to the recipient, for
    any liability that these contractual assumptions directly impose on
    those licensors and authors.

  All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10.  If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term.  If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.

  If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.

  Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.

  8. Termination.

  You may not propagate or modify a covered work except as expressly
provided under this License.  Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).

  However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.

  Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.

  Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License.  If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.

  9. Acceptance Not Required for Having Copies.

  You are not required to accept this License in order to receive or
run a copy of the Program.  Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance.  However,
nothing other than this License grants you permission to propagate or
modify any covered work.  These actions infringe copyright if you do
not accept this License.  Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.

  10. Automatic Licensing of Downstream Recipients.

  Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License.  You are not responsible
for enforcing compliance by third parties with this License.

  An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations.  If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.

  You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License.  For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.

  11. Patents.

  A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based.  The
work thus licensed is called the contributor's "contributor version".

  A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version.  For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.

  Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.

  In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement).  To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.

  If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients.  "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.

  If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.

  A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License.  You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.

  Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.

  12. No Surrender of Others' Freedom.

  If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all.  For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.

  13. Remote Network Interaction; Use with the GNU General Public License.

  Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software.  This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.

  Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU General Public License into a single
combined work, and to convey the resulting work.  The terms of this
License will continue to apply to the part which is the covered work,
but the work with which it is combined will remain governed by version
3 of the GNU General Public License.

  14. Revised Versions of this License.

  The Free Software Foundation may publish revised and/or new versions of
the GNU Affero General Public License from time to time.  Such new versions
will be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

  Each version is given a distinguishing version number.  If the
Program specifies that a certain numbered version of the GNU Affero General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation.  If the Program does not specify a version number of the
GNU Affero General Public License, you may choose any version ever published
by the Free Software Foundation.

  If the Program specifies that a proxy can decide which future
versions of the GNU Affero General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.

  Later license versions may give you additional or different
permissions.  However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.

  15. Disclaimer of Warranty.

  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

  16. Limitation of Liability.

  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.

  17. Interpretation of Sections 15 and 16.

  If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.

                     END OF TERMS AND CONDITIONS

            How to Apply These Terms to Your New Programs

  If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

  To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

Also add information on how to contact you by electronic and paper mail.

  If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source.  For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code.  There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for the
specific requirements.

  You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see
<http://www.gnu.org/licenses/>.

Added README.md version [b535b9dd6a].

























































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# Garradin - Le gestionnaire d'association

Garradin est un logiciel de gestion de petite et moyenne association.

Plus d'infos sur le site de développement ici : [fossil.kd2.org/garradin](https://fossil.kd2.org/garradin/)

[Documentation développeuse⋅développeur](https://fossil.kd2.org/garradin/wiki?name=Documentation+d%C3%A9veloppeur)

Il est possible d'essayer et utiliser gratuitement Garradin sur la plateforme [Garradin.eu](https://garradin.eu/).

Le code sur Github, n'est qu'un miroir, le développement principal se passe sur Fossil.

## Licence

GNU Affero GPL v3 (voir fichier COPYING)

Cette licence permet la libre redistribution, utilisation et modification du logiciel.

La seule condition est de re-partager les éventuelles modifications apportées.

Cette clause s'applique même si le logiciel n'est pas distribué et simplement installé sur un serveur.

## Code utilisé

Inclus les bibliothèques suivantes :

* [KD2fw](https://fossil.kd2.org/kd2fw/) - Copyright : 2001-2020+ BohwaZ - Licence : GNU AGPL v3
* [Gibberish AES](https://github.com/mdp/gibberish-aes) - Copyright : Mark Percival 2008 - http://markpercival.us -Licence : MIT

Added archives/0.7.0_migration.sql version [acaa57e895].

































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
CREATE TABLE plugins_signaux
-- Association entre plugins et signaux (hooks)
(
    signal TEXT NOT NULL,
    plugin TEXT NOT NULL REFERENCES plugins (id),
    callback TEXT NOT NULL,
    PRIMARY KEY (signal, plugin)
);

CREATE TABLE compta_rapprochement
-- Rapprochement entre compta et relevés de comptes
(
    operation INTEGER NOT NULL PRIMARY KEY REFERENCES compta_journal (id),
    date TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
    auteur INTEGER NOT NULL REFERENCES membres (id)
);

CREATE TABLE fichiers
-- Données sur les fichiers
(
    id INTEGER NOT NULL PRIMARY KEY,
    nom TEXT NOT NULL, -- nom de fichier (par exemple image1234.jpeg)
    type TEXT NULL, -- Type MIME
    image INTEGER NOT NULL DEFAULT 0, -- 1 = image reconnue
    datetime TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP, -- Date d'ajout ou mise à jour du fichier
    id_contenu INTEGER NOT NULL REFERENCES fichiers_contenu (id)
);

CREATE INDEX fichiers_date ON fichiers (datetime);

CREATE TABLE fichiers_contenu
-- Contenu des fichiers
(
    id INTEGER NOT NULL PRIMARY KEY,
    hash TEXT NOT NULL, -- Hash SHA1 du contenu du fichier
    taille INTEGER NOT NULL, -- Taille en octets
    contenu BLOB NULL
);

CREATE UNIQUE INDEX fichiers_hash ON fichiers_contenu (hash);

CREATE TABLE fichiers_membres
-- Associations entre fichiers et membres (photo de profil par exemple)
(
    fichier INTEGER NOT NULL REFERENCES fichiers (id),
    id INTEGER NOT NULL REFERENCES membres (id),
    PRIMARY KEY(fichier, id)
);

CREATE TABLE fichiers_wiki_pages
-- Associations entre fichiers et pages du wiki
(
    fichier INTEGER NOT NULL REFERENCES fichiers (id),
    id INTEGER NOT NULL REFERENCES wiki_pages (id),
    PRIMARY KEY(fichier, id)
);

CREATE TABLE fichiers_compta_journal
-- Associations entre fichiers et journal de compta (pièce comptable par exemple)
(
    fichier INTEGER NOT NULL REFERENCES fichiers (id),
    id INTEGER NOT NULL REFERENCES compta_journal (id),
    PRIMARY KEY(fichier, id)
);

Added archives/0.7.2_migration.sql version [ba4b5fbcc7].

















































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
-- Colonne manquante
ALTER TABLE rappels_envoyes ADD COLUMN id_rappel INTEGER NULL REFERENCES rappels (id);

-- Un bug a permis d'insérer des comptes avec des lettres minuscules, créant des problèmes
-- corrigeons donc les comptes pour les mettre en majuscules.

UPDATE compta_comptes SET id = UPPER(id);

-- Le champ id_auteur était à NOT NULL, il faut corriger ça pour pouvoir avoir un rapprochement anonyme
-- une fois que le membre a été supprimé

CREATE TABLE compta_rapprochement2
-- Rapprochement entre compta et relevés de comptes
(
    id_operation INTEGER NOT NULL PRIMARY KEY REFERENCES compta_journal (id),
    date TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
    id_auteur INTEGER NULL REFERENCES membres (id)
);

INSERT INTO compta_rapprochement2 SELECT operation, date, auteur FROM compta_rapprochement;

DROP TABLE compta_rapprochement;

ALTER TABLE compta_rapprochement2 RENAME TO compta_rapprochement;

Added archives/0.8.0_migration.sql version [b56b968950].











































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
-- Ajouter champ pour OTP
ALTER TABLE membres ADD COLUMN secret_otp TEXT NULL;

-- Ajouter champ clé PGP
ALTER TABLE membres ADD COLUMN clef_pgp TEXT NULL;

--------------------------------------------------------------------------------
-- Mise à jour des tables contenant un champ date pour ajouter la contrainte  --
-- Ceci afin de forcer les champs à contenir un format de date correct        --
-- On en profite pour ajouter les ON DELETE nécessaires                       --
--------------------------------------------------------------------------------

-- Convertir les dates UNIX en date Y-m-d, apparemment il y en a encore parfois ?
UPDATE wiki_pages SET date_creation = datetime(date_creation, "unixepoch") WHERE CAST(date_creation AS INT) = date_creation;
UPDATE wiki_pages SET date_creation = datetime(date_creation) WHERE datetime(date_creation) != date_creation;

-- Renommage des tables qu'il faut mettre à jour
ALTER TABLE cotisations_membres RENAME TO cotisations_membres_old;
ALTER TABLE rappels RENAME TO rappels_old;
ALTER TABLE rappels_envoyes RENAME TO rappels_envoyes_old;
ALTER TABLE wiki_pages RENAME TO wiki_pages_old;
ALTER TABLE wiki_revisions RENAME TO wiki_revisions_old;
ALTER TABLE compta_categories RENAME TO compta_categories_old;
ALTER TABLE compta_comptes_bancaires RENAME TO compta_comptes_bancaires_old;
ALTER TABLE compta_exercices RENAME TO compta_exercices_old;
ALTER TABLE compta_journal RENAME TO compta_journal_old;
ALTER TABLE compta_rapprochement RENAME TO compta_rapprochement_old;
ALTER TABLE fichiers RENAME TO fichiers_old;
ALTER TABLE membres_operations RENAME TO membres_operations_old;
ALTER TABLE membres_categories RENAME TO membres_categories_old;

-- Suppression des index pour que les nouveaux soient liés aux nouvelles tables
DROP INDEX cm_unique;
DROP INDEX wiki_uri;
DROP INDEX wiki_revisions_id_page;
DROP INDEX wiki_revisions_id_auteur;
DROP INDEX compta_operations_exercice;
DROP INDEX compta_operations_date;
DROP INDEX compta_operations_comptes;
DROP INDEX compta_operations_auteur;
DROP INDEX fichiers_date;

-- Suppression ancienne table recherche
DROP TABLE wiki_recherche;

-- Suppression des triggers
-- Sinon les nouveaux ne seront pas créés sur la nouvelle table
DROP TRIGGER wiki_recherche_delete;
DROP TRIGGER wiki_recherche_update;
DROP TRIGGER wiki_recherche_contenu_insert;
DROP TRIGGER wiki_recherche_contenu_chiffre;

-- Création des tables mises à jour (et de leurs index)
.read 0.8.0_schema.sql

-- Copie des données
INSERT INTO cotisations_membres SELECT * FROM cotisations_membres_old;
INSERT INTO rappels SELECT * FROM rappels_old;
INSERT INTO rappels_envoyes SELECT id, id_membre, id_cotisation, id_rappel, date, media FROM rappels_envoyes_old;
INSERT INTO wiki_pages SELECT * FROM wiki_pages_old;
INSERT INTO wiki_revisions SELECT * FROM wiki_revisions_old;
INSERT INTO compta_categories SELECT * FROM compta_categories_old;
INSERT INTO compta_comptes_bancaires SELECT * FROM compta_comptes_bancaires_old;
INSERT INTO compta_exercices SELECT * FROM compta_exercices_old;
INSERT INTO compta_journal SELECT *, NULL FROM compta_journal_old;
INSERT INTO compta_rapprochement SELECT * FROM compta_rapprochement_old;
INSERT INTO fichiers SELECT * FROM fichiers_old;
INSERT INTO membres_operations SELECT * FROM membres_operations_old;
INSERT INTO membres_categories SELECT id, nom, droit_wiki, droit_membres, droit_compta,
	droit_inscription, droit_connexion, droit_config, cacher, id_cotisation_obligatoire FROM membres_categories_old;

-- Suppression des anciennes tables
DROP TABLE cotisations_membres_old;
DROP TABLE rappels_old;
DROP TABLE rappels_envoyes_old;
DROP TABLE wiki_pages_old;
DROP TABLE wiki_revisions_old;
DROP TABLE compta_categories_old;
DROP TABLE compta_comptes_bancaires_old;
DROP TABLE compta_exercices_old;
DROP TABLE compta_journal_old;
DROP TABLE compta_rapprochement_old;
DROP TABLE fichiers_old;
DROP TABLE membres_operations_old;
DROP TABLE membres_categories_old;

Added archives/0.8.0_schema.sql version [1c0ae41b79].













































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
CREATE TABLE IF NOT EXISTS config (
-- Configuration de Garradin
    cle TEXT PRIMARY KEY NOT NULL,
    valeur TEXT
);

-- On stocke ici les ID de catégorie de compta correspondant aux types spéciaux
-- compta_categorie_cotisations => id_categorie
-- compta_categorie_dons => id_categorie

CREATE TABLE IF NOT EXISTS membres_categories
-- Catégories de membres
(
    id INTEGER PRIMARY KEY NOT NULL,
    nom TEXT NOT NULL,
    description TEXT NULL,

    droit_wiki INTEGER NOT NULL DEFAULT 1,
    droit_membres INTEGER NOT NULL DEFAULT 1,
    droit_compta INTEGER NOT NULL DEFAULT 1,
    droit_inscription INTEGER NOT NULL DEFAULT 0,
    droit_connexion INTEGER NOT NULL DEFAULT 1,
    droit_config INTEGER NOT NULL DEFAULT 0,
    cacher INTEGER NOT NULL DEFAULT 0,

    id_cotisation_obligatoire INTEGER NULL REFERENCES cotisations (id) ON DELETE SET NULL
);

-- Membres de l'asso
-- Table dynamique générée par l'application
-- voir Garradin\Membres\Champs.php

CREATE TABLE IF NOT EXISTS membres_sessions
-- Sessions
(
    selecteur TEXT NOT NULL,
    hash TEXT NOT NULL,
    id_membre INTEGER NOT NULL REFERENCES membres (id) ON DELETE CASCADE,
    expire INT NOT NULL,

    PRIMARY KEY (selecteur, id_membre)
);

CREATE TABLE IF NOT EXISTS cotisations
-- Types de cotisations et activités
(
    id INTEGER PRIMARY KEY NOT NULL,
    id_categorie_compta INTEGER NULL, -- NULL si le type n'est pas associé automatiquement à la compta

    intitule TEXT NOT NULL,
    description TEXT NULL,
    montant REAL NOT NULL,

    duree INTEGER NULL, -- En jours
    debut TEXT NULL, -- timestamp
    fin TEXT NULL,

    FOREIGN KEY (id_categorie_compta) REFERENCES compta_categories (id)
);

CREATE TABLE IF NOT EXISTS cotisations_membres
-- Enregistrement des cotisations et activités
(
    id INTEGER NOT NULL PRIMARY KEY,
    id_membre INTEGER NOT NULL REFERENCES membres (id) ON DELETE CASCADE,
    id_cotisation INTEGER NOT NULL REFERENCES cotisations (id) ON DELETE CASCADE,

    date TEXT NOT NULL DEFAULT CURRENT_DATE CHECK (date(date) IS NOT NULL AND date(date) = date)
);

CREATE UNIQUE INDEX IF NOT EXISTS cm_unique ON cotisations_membres (id_membre, id_cotisation, date);

CREATE TABLE IF NOT EXISTS membres_operations
-- Liaision des enregistrement des paiements en compta
(
    id_membre INTEGER NOT NULL REFERENCES membres (id) ON DELETE CASCADE,
    id_operation INTEGER NOT NULL REFERENCES compta_journal (id) ON DELETE CASCADE,
    id_cotisation INTEGER NULL REFERENCES cotisations_membres (id) ON DELETE SET NULL,

    PRIMARY KEY (id_membre, id_operation)
);

CREATE TABLE IF NOT EXISTS rappels
-- Rappels de devoir renouveller une cotisation
(
    id INTEGER NOT NULL PRIMARY KEY,
    id_cotisation INTEGER NOT NULL REFERENCES cotisations (id) ON DELETE CASCADE,

    delai INTEGER NOT NULL, -- Délai en jours pour envoyer le rappel

    sujet TEXT NOT NULL,
    texte TEXT NOT NULL
);

CREATE TABLE IF NOT EXISTS rappels_envoyes
-- Enregistrement des rappels envoyés à qui et quand
(
    id INTEGER NOT NULL PRIMARY KEY,

    id_membre INTEGER NOT NULL REFERENCES membres (id) ON DELETE CASCADE,
    id_cotisation INTEGER NOT NULL REFERENCES cotisations (id) ON DELETE CASCADE,
    id_rappel INTEGER NULL REFERENCES rappels (id) ON DELETE CASCADE,

    date TEXT NOT NULL DEFAULT CURRENT_DATE CHECK (date(date) IS NOT NULL AND date(date) = date),

    media INTEGER NOT NULL -- Média utilisé pour le rappel : 1 = email, 2 = courrier, 3 = autre
);

--
-- WIKI
--

CREATE TABLE IF NOT EXISTS wiki_pages
-- Pages du wiki
(
    id INTEGER PRIMARY KEY NOT NULL,
    uri TEXT NOT NULL, -- URI unique (équivalent NomPageWiki)
    titre TEXT NOT NULL,
    date_creation TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP CHECK (datetime(date_creation) IS NOT NULL AND datetime(date_creation) = date_creation),
    date_modification TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP CHECK (datetime(date_modification) IS NOT NULL AND datetime(date_modification) = date_modification),
    parent INTEGER NOT NULL DEFAULT 0, -- ID de la page parent
    revision INTEGER NOT NULL DEFAULT 0, -- Numéro de révision (commence à 0 si pas de texte, +1 à chaque changement du texte)
    droit_lecture INTEGER NOT NULL DEFAULT 0, -- Accès en lecture (-1 = public [site web], 0 = tous ceux qui ont accès en lecture au wiki, 1+ = ID de groupe)
    droit_ecriture INTEGER NOT NULL DEFAULT 0 -- Accès en écriture (0 = tous ceux qui ont droit d'écriture sur le wiki, 1+ = ID de groupe)
);

CREATE UNIQUE INDEX IF NOT EXISTS wiki_uri ON wiki_pages (uri);

CREATE VIRTUAL TABLE IF NOT EXISTS wiki_recherche USING fts4
-- Table dupliquée pour chercher une page
(
    id INT PRIMARY KEY NOT NULL, -- Clé externe obligatoire
    titre TEXT NOT NULL,
    contenu TEXT NULL, -- Contenu de la dernière révision
    FOREIGN KEY (id) REFERENCES wiki_pages(id)
);

CREATE TABLE IF NOT EXISTS wiki_revisions
-- Révisions du contenu des pages
(
    id_page INTEGER NOT NULL REFERENCES wiki_pages (id) ON DELETE CASCADE,
    revision INTEGER NULL,

    id_auteur INTEGER NULL REFERENCES membres (id) ON DELETE SET NULL,

    contenu TEXT NOT NULL,
    modification TEXT NULL, -- Description des modifications effectuées
    chiffrement INTEGER NOT NULL DEFAULT 0, -- 1 si le contenu est chiffré, 0 sinon
    date TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP CHECK (datetime(date) IS NOT NULL AND datetime(date) = date),

    PRIMARY KEY(id_page, revision)
);

CREATE INDEX IF NOT EXISTS wiki_revisions_id_page ON wiki_revisions (id_page);
CREATE INDEX IF NOT EXISTS wiki_revisions_id_auteur ON wiki_revisions (id_auteur);

-- Triggers pour synchro avec table wiki_pages
CREATE TRIGGER IF NOT EXISTS wiki_recherche_delete AFTER DELETE ON wiki_pages
    BEGIN
        DELETE FROM wiki_recherche WHERE id = old.id;
    END;

CREATE TRIGGER IF NOT EXISTS wiki_recherche_update AFTER UPDATE OF id, titre ON wiki_pages
    BEGIN
        UPDATE wiki_recherche SET id = new.id, titre = new.titre WHERE id = old.id;
    END;

-- Trigger pour mettre à jour le contenu de la table de recherche lors d'une nouvelle révision
CREATE TRIGGER IF NOT EXISTS wiki_recherche_contenu_insert AFTER INSERT ON wiki_revisions WHEN new.chiffrement != 1
    BEGIN
        UPDATE wiki_recherche SET contenu = new.contenu WHERE id = new.id_page;
    END;

-- Si le contenu est chiffré, la recherche n'affiche pas de contenu
CREATE TRIGGER IF NOT EXISTS wiki_recherche_contenu_chiffre AFTER INSERT ON wiki_revisions WHEN new.chiffrement = 1
    BEGIN
        UPDATE wiki_recherche SET contenu = '' WHERE id = new.id_page;
    END;

/*
CREATE TABLE wiki_suivi
-- Suivi des pages
(
    id_membre INTEGER NOT NULL,
    id_page INTEGER NOT NULL,

    PRIMARY KEY (id_membre, id_page),

    FOREIGN KEY (id_page) REFERENCES wiki_pages (id), -- Clé externe obligatoire
    FOREIGN KEY (id_membre) REFERENCES membres (id) -- Clé externe obligatoire
);
*/

--
-- COMPTA
--

CREATE TABLE IF NOT EXISTS compta_exercices
-- Exercices
(
    id INTEGER NOT NULL PRIMARY KEY,

    libelle TEXT NOT NULL,

    debut TEXT NOT NULL DEFAULT CURRENT_DATE CHECK (date(debut) IS NOT NULL AND date(debut) = debut),
    fin TEXT NULL DEFAULT NULL CHECK (fin IS NULL OR (date(fin) IS NOT NULL AND date(fin) = fin)),

    cloture INTEGER NOT NULL DEFAULT 0
);


CREATE TABLE IF NOT EXISTS compta_comptes
-- Plan comptable
(
    id TEXT NOT NULL PRIMARY KEY, -- peut contenir des lettres, eg. 53A, 53B, etc.
    parent TEXT NOT NULL DEFAULT 0,

    libelle TEXT NOT NULL,

    position INTEGER NOT NULL, -- position actif/passif/charge/produit
    plan_comptable INTEGER NOT NULL DEFAULT 1, -- 1 = fait partie du plan comptable, 0 = a été ajouté par l'utilisateur
    desactive INTEGER NOT NULL DEFAULT 0 -- 1 = compte historique désactivé
);

CREATE INDEX IF NOT EXISTS compta_comptes_parent ON compta_comptes (parent);

CREATE TABLE IF NOT EXISTS compta_comptes_bancaires
-- Comptes bancaires
(
    id TEXT NOT NULL PRIMARY KEY,

    banque TEXT NOT NULL,

    iban TEXT NULL,
    bic TEXT NULL,

    FOREIGN KEY(id) REFERENCES compta_comptes(id) ON DELETE CASCADE
);

CREATE TABLE IF NOT EXISTS compta_projets
-- Projets (compta analytique)
(
    id INTEGER PRIMARY KEY NOT NULL,

    libelle TEXT NOT NULL
);

CREATE TABLE IF NOT EXISTS compta_journal
-- Journal des opérations comptables
(
    id INTEGER PRIMARY KEY NOT NULL,

    libelle TEXT NOT NULL,
    remarques TEXT NULL,
    numero_piece TEXT NULL, -- N° de pièce comptable

    montant REAL NOT NULL,

    date TEXT NOT NULL DEFAULT CURRENT_DATE CHECK (date(date) IS NOT NULL AND date(date) = date),
    moyen_paiement TEXT NULL,
    numero_cheque TEXT NULL,

    compte_debit TEXT NULL, -- N° du compte dans le plan, NULL est utilisé pour une opération qui vient d'un exercice précédent
    compte_credit TEXT NULL, -- N° du compte dans le plan

    id_exercice INTEGER NULL DEFAULT NULL, -- En cas de compta simple, l'exercice est permanent (NULL)
    id_auteur INTEGER NULL,
    id_categorie INTEGER NULL, -- Numéro de catégorie (en mode simple)
    id_projet INTEGER NULL,

    FOREIGN KEY(moyen_paiement) REFERENCES compta_moyens_paiement(code),
    FOREIGN KEY(compte_debit) REFERENCES compta_comptes(id),
    FOREIGN KEY(compte_credit) REFERENCES compta_comptes(id),
    FOREIGN KEY(id_exercice) REFERENCES compta_exercices(id),
    FOREIGN KEY(id_auteur) REFERENCES membres(id) ON DELETE SET NULL,
    FOREIGN KEY(id_categorie) REFERENCES compta_categories(id) ON DELETE SET NULL,
    FOREIGN KEY(id_projet) REFERENCES compta_projets(id) ON DELETE SET NULL
);

CREATE INDEX IF NOT EXISTS compta_operations_exercice ON compta_journal (id_exercice);
CREATE INDEX IF NOT EXISTS compta_operations_date ON compta_journal (date);
CREATE INDEX IF NOT EXISTS compta_operations_comptes ON compta_journal (compte_debit, compte_credit);
CREATE INDEX IF NOT EXISTS compta_operations_auteur ON compta_journal (id_auteur);

CREATE TABLE IF NOT EXISTS compta_moyens_paiement
-- Moyens de paiement
(
    code TEXT NOT NULL PRIMARY KEY,
    nom TEXT NOT NULL
);

--INSERT INTO compta_moyens_paiement (code, nom) VALUES ('AU', 'Autre');
INSERT OR IGNORE INTO compta_moyens_paiement (code, nom) VALUES ('CB', 'Carte bleue');
INSERT OR IGNORE INTO compta_moyens_paiement (code, nom) VALUES ('CH', 'Chèque');
INSERT OR IGNORE INTO compta_moyens_paiement (code, nom) VALUES ('ES', 'Espèces');
INSERT OR IGNORE INTO compta_moyens_paiement (code, nom) VALUES ('PR', 'Prélèvement');
INSERT OR IGNORE INTO compta_moyens_paiement (code, nom) VALUES ('TI', 'TIP');
INSERT OR IGNORE INTO compta_moyens_paiement (code, nom) VALUES ('VI', 'Virement');

CREATE TABLE IF NOT EXISTS compta_categories
-- Catégories pour simplifier le plan comptable
(
    id INTEGER NOT NULL PRIMARY KEY,
    type INTEGER NOT NULL DEFAULT 1, -- 1 = recette, -1 = dépense, 0 = autre (utilisé uniquement pour l'interface)

    intitule TEXT NOT NULL,
    description TEXT NULL,

    compte TEXT NOT NULL, -- Compte affecté par cette catégorie

    FOREIGN KEY(compte) REFERENCES compta_comptes(id) ON DELETE CASCADE
);

CREATE TABLE IF NOT EXISTS plugins
(
    id TEXT NOT NULL PRIMARY KEY,
    officiel INTEGER NOT NULL DEFAULT 0,
    nom TEXT NOT NULL,
    description TEXT NULL,
    auteur TEXT NULL,
    url TEXT NULL,
    version TEXT NOT NULL,
    menu INTEGER NOT NULL DEFAULT 0,
    config TEXT NULL
);

CREATE TABLE IF NOT EXISTS plugins_signaux
-- Association entre plugins et signaux (hooks)
(
    signal TEXT NOT NULL,
    plugin TEXT NOT NULL REFERENCES plugins (id),
    callback TEXT NOT NULL,
    PRIMARY KEY (signal, plugin)
);

CREATE TABLE IF NOT EXISTS compta_rapprochement
-- Rapprochement entre compta et relevés de comptes
(
    id_operation INTEGER NOT NULL PRIMARY KEY REFERENCES compta_journal (id) ON DELETE CASCADE,
    date TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP CHECK (datetime(date) IS NOT NULL AND datetime(date) = date),
    id_auteur INTEGER NULL REFERENCES membres (id)
);

CREATE TABLE IF NOT EXISTS fichiers
-- Données sur les fichiers
(
    id INTEGER NOT NULL PRIMARY KEY,
    nom TEXT NOT NULL, -- nom de fichier (par exemple image1234.jpeg)
    type TEXT NULL, -- Type MIME
    image INTEGER NOT NULL DEFAULT 0, -- 1 = image reconnue
    datetime TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP CHECK (datetime(datetime) IS NOT NULL AND datetime(datetime) = datetime), -- Date d'ajout ou mise à jour du fichier
    id_contenu INTEGER NOT NULL REFERENCES fichiers_contenu (id) ON DELETE CASCADE
);

CREATE INDEX IF NOT EXISTS fichiers_date ON fichiers (datetime);

CREATE TABLE IF NOT EXISTS fichiers_contenu
-- Contenu des fichiers
(
    id INTEGER NOT NULL PRIMARY KEY,
    hash TEXT NOT NULL, -- Hash SHA1 du contenu du fichier
    taille INTEGER NOT NULL, -- Taille en octets
    contenu BLOB NULL
);

CREATE UNIQUE INDEX IF NOT EXISTS fichiers_hash ON fichiers_contenu (hash);

CREATE TABLE IF NOT EXISTS fichiers_membres
-- Associations entre fichiers et membres (photo de profil par exemple)
(
    fichier INTEGER NOT NULL REFERENCES fichiers (id),
    id INTEGER NOT NULL REFERENCES membres (id),
    PRIMARY KEY(fichier, id)
);

CREATE TABLE IF NOT EXISTS fichiers_wiki_pages
-- Associations entre fichiers et pages du wiki
(
    fichier INTEGER NOT NULL REFERENCES fichiers (id),
    id INTEGER NOT NULL REFERENCES wiki_pages (id),
    PRIMARY KEY(fichier, id)
);

CREATE TABLE IF NOT EXISTS fichiers_compta_journal
-- Associations entre fichiers et journal de compta (pièce comptable par exemple)
(
    fichier INTEGER NOT NULL REFERENCES fichiers (id),
    id INTEGER NOT NULL REFERENCES compta_journal (id),
    PRIMARY KEY(fichier, id)
);

Added archives/0.8.3_migration.sql version [78f64dc820].























>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
-- Ajout d'une clause ON DELETE SET NULL sur la table cotisations
ALTER TABLE cotisations_membres RENAME TO cotisations_membres_old;

-- Création des tables mises à jour (et de leurs index)
.read 0.8.3_schema.sql

-- Copie des données
INSERT INTO cotisations_membres SELECT * FROM cotisations_membres_old;

-- Suppression des anciennes tables
DROP TABLE cotisations_membres_old;

Added archives/0.8.3_schema.sql version [80be656e5d].









































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
CREATE TABLE IF NOT EXISTS config (
-- Configuration de Garradin
    cle TEXT PRIMARY KEY NOT NULL,
    valeur TEXT
);

-- On stocke ici les ID de catégorie de compta correspondant aux types spéciaux
-- compta_categorie_cotisations => id_categorie
-- compta_categorie_dons => id_categorie

CREATE TABLE IF NOT EXISTS membres_categories
-- Catégories de membres
(
    id INTEGER PRIMARY KEY NOT NULL,
    nom TEXT NOT NULL,
    description TEXT NULL,

    droit_wiki INTEGER NOT NULL DEFAULT 1,
    droit_membres INTEGER NOT NULL DEFAULT 1,
    droit_compta INTEGER NOT NULL DEFAULT 1,
    droit_inscription INTEGER NOT NULL DEFAULT 0,
    droit_connexion INTEGER NOT NULL DEFAULT 1,
    droit_config INTEGER NOT NULL DEFAULT 0,
    cacher INTEGER NOT NULL DEFAULT 0,

    id_cotisation_obligatoire INTEGER NULL REFERENCES cotisations (id) ON DELETE SET NULL
);

-- Membres de l'asso
-- Table dynamique générée par l'application
-- voir Garradin\Membres\Champs.php

CREATE TABLE IF NOT EXISTS membres_sessions
-- Sessions
(
    selecteur TEXT NOT NULL,
    hash TEXT NOT NULL,
    id_membre INTEGER NOT NULL REFERENCES membres (id) ON DELETE CASCADE,
    expire INT NOT NULL,

    PRIMARY KEY (selecteur, id_membre)
);

CREATE TABLE IF NOT EXISTS cotisations
-- Types de cotisations et activités
(
    id INTEGER PRIMARY KEY NOT NULL,
    id_categorie_compta INTEGER NULL REFERENCES compta_categories (id) ON DELETE SET NULL, -- NULL si le type n'est pas associé automatiquement à la compta

    intitule TEXT NOT NULL,
    description TEXT NULL,
    montant REAL NOT NULL,

    duree INTEGER NULL, -- En jours
    debut TEXT NULL, -- timestamp
    fin TEXT NULL
);

CREATE TABLE IF NOT EXISTS cotisations_membres
-- Enregistrement des cotisations et activités
(
    id INTEGER NOT NULL PRIMARY KEY,
    id_membre INTEGER NOT NULL REFERENCES membres (id) ON DELETE CASCADE,
    id_cotisation INTEGER NOT NULL REFERENCES cotisations (id) ON DELETE CASCADE,

    date TEXT NOT NULL DEFAULT CURRENT_DATE CHECK (date(date) IS NOT NULL AND date(date) = date)
);

CREATE UNIQUE INDEX IF NOT EXISTS cm_unique ON cotisations_membres (id_membre, id_cotisation, date);

CREATE TABLE IF NOT EXISTS membres_operations
-- Liaison des enregistrement des paiements en compta
(
    id_membre INTEGER NOT NULL REFERENCES membres (id) ON DELETE CASCADE,
    id_operation INTEGER NOT NULL REFERENCES compta_journal (id) ON DELETE CASCADE,
    id_cotisation INTEGER NULL REFERENCES cotisations_membres (id) ON DELETE SET NULL,

    PRIMARY KEY (id_membre, id_operation)
);

CREATE TABLE IF NOT EXISTS rappels
-- Rappels de devoir renouveller une cotisation
(
    id INTEGER NOT NULL PRIMARY KEY,
    id_cotisation INTEGER NOT NULL REFERENCES cotisations (id) ON DELETE CASCADE,

    delai INTEGER NOT NULL, -- Délai en jours pour envoyer le rappel

    sujet TEXT NOT NULL,
    texte TEXT NOT NULL
);

CREATE TABLE IF NOT EXISTS rappels_envoyes
-- Enregistrement des rappels envoyés à qui et quand
(
    id INTEGER NOT NULL PRIMARY KEY,

    id_membre INTEGER NOT NULL REFERENCES membres (id) ON DELETE CASCADE,
    id_cotisation INTEGER NOT NULL REFERENCES cotisations (id) ON DELETE CASCADE,
    id_rappel INTEGER NULL REFERENCES rappels (id) ON DELETE CASCADE,

    date TEXT NOT NULL DEFAULT CURRENT_DATE CHECK (date(date) IS NOT NULL AND date(date) = date),

    media INTEGER NOT NULL -- Média utilisé pour le rappel : 1 = email, 2 = courrier, 3 = autre
);

--
-- WIKI
--

CREATE TABLE IF NOT EXISTS wiki_pages
-- Pages du wiki
(
    id INTEGER PRIMARY KEY NOT NULL,
    uri TEXT NOT NULL, -- URI unique (équivalent NomPageWiki)
    titre TEXT NOT NULL,
    date_creation TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP CHECK (datetime(date_creation) IS NOT NULL AND datetime(date_creation) = date_creation),
    date_modification TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP CHECK (datetime(date_modification) IS NOT NULL AND datetime(date_modification) = date_modification),
    parent INTEGER NOT NULL DEFAULT 0, -- ID de la page parent
    revision INTEGER NOT NULL DEFAULT 0, -- Numéro de révision (commence à 0 si pas de texte, +1 à chaque changement du texte)
    droit_lecture INTEGER NOT NULL DEFAULT 0, -- Accès en lecture (-1 = public [site web], 0 = tous ceux qui ont accès en lecture au wiki, 1+ = ID de groupe)
    droit_ecriture INTEGER NOT NULL DEFAULT 0 -- Accès en écriture (0 = tous ceux qui ont droit d'écriture sur le wiki, 1+ = ID de groupe)
);

CREATE UNIQUE INDEX IF NOT EXISTS wiki_uri ON wiki_pages (uri);

CREATE VIRTUAL TABLE IF NOT EXISTS wiki_recherche USING fts4
-- Table dupliquée pour chercher une page
(
    id INT PRIMARY KEY NOT NULL, -- Clé externe obligatoire
    titre TEXT NOT NULL,
    contenu TEXT NULL, -- Contenu de la dernière révision
    FOREIGN KEY (id) REFERENCES wiki_pages(id)
);

CREATE TABLE IF NOT EXISTS wiki_revisions
-- Révisions du contenu des pages
(
    id_page INTEGER NOT NULL REFERENCES wiki_pages (id) ON DELETE CASCADE,
    revision INTEGER NULL,

    id_auteur INTEGER NULL REFERENCES membres (id) ON DELETE SET NULL,

    contenu TEXT NOT NULL,
    modification TEXT NULL, -- Description des modifications effectuées
    chiffrement INTEGER NOT NULL DEFAULT 0, -- 1 si le contenu est chiffré, 0 sinon
    date TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP CHECK (datetime(date) IS NOT NULL AND datetime(date) = date),

    PRIMARY KEY(id_page, revision)
);

CREATE INDEX IF NOT EXISTS wiki_revisions_id_page ON wiki_revisions (id_page);
CREATE INDEX IF NOT EXISTS wiki_revisions_id_auteur ON wiki_revisions (id_auteur);

-- Triggers pour synchro avec table wiki_pages
CREATE TRIGGER IF NOT EXISTS wiki_recherche_delete AFTER DELETE ON wiki_pages
    BEGIN
        DELETE FROM wiki_recherche WHERE id = old.id;
    END;

CREATE TRIGGER IF NOT EXISTS wiki_recherche_update AFTER UPDATE OF id, titre ON wiki_pages
    BEGIN
        UPDATE wiki_recherche SET id = new.id, titre = new.titre WHERE id = old.id;
    END;

-- Trigger pour mettre à jour le contenu de la table de recherche lors d'une nouvelle révision
CREATE TRIGGER IF NOT EXISTS wiki_recherche_contenu_insert AFTER INSERT ON wiki_revisions WHEN new.chiffrement != 1
    BEGIN
        UPDATE wiki_recherche SET contenu = new.contenu WHERE id = new.id_page;
    END;

-- Si le contenu est chiffré, la recherche n'affiche pas de contenu
CREATE TRIGGER IF NOT EXISTS wiki_recherche_contenu_chiffre AFTER INSERT ON wiki_revisions WHEN new.chiffrement = 1
    BEGIN
        UPDATE wiki_recherche SET contenu = '' WHERE id = new.id_page;
    END;

/*
CREATE TABLE wiki_suivi
-- Suivi des pages
(
    id_membre INTEGER NOT NULL,
    id_page INTEGER NOT NULL,

    PRIMARY KEY (id_membre, id_page),

    FOREIGN KEY (id_page) REFERENCES wiki_pages (id), -- Clé externe obligatoire
    FOREIGN KEY (id_membre) REFERENCES membres (id) -- Clé externe obligatoire
);
*/

--
-- COMPTA
--

CREATE TABLE IF NOT EXISTS compta_exercices
-- Exercices
(
    id INTEGER NOT NULL PRIMARY KEY,

    libelle TEXT NOT NULL,

    debut TEXT NOT NULL DEFAULT CURRENT_DATE CHECK (date(debut) IS NOT NULL AND date(debut) = debut),
    fin TEXT NULL DEFAULT NULL CHECK (fin IS NULL OR (date(fin) IS NOT NULL AND date(fin) = fin)),

    cloture INTEGER NOT NULL DEFAULT 0
);


CREATE TABLE IF NOT EXISTS compta_comptes
-- Plan comptable
(
    id TEXT NOT NULL PRIMARY KEY, -- peut contenir des lettres, eg. 53A, 53B, etc.
    parent TEXT NOT NULL DEFAULT 0,

    libelle TEXT NOT NULL,

    position INTEGER NOT NULL, -- position actif/passif/charge/produit
    plan_comptable INTEGER NOT NULL DEFAULT 1, -- 1 = fait partie du plan comptable, 0 = a été ajouté par l'utilisateur
    desactive INTEGER NOT NULL DEFAULT 0 -- 1 = compte historique désactivé
);

CREATE INDEX IF NOT EXISTS compta_comptes_parent ON compta_comptes (parent);

CREATE TABLE IF NOT EXISTS compta_comptes_bancaires
-- Comptes bancaires
(
    id TEXT NOT NULL PRIMARY KEY,

    banque TEXT NOT NULL,

    iban TEXT NULL,
    bic TEXT NULL,

    FOREIGN KEY(id) REFERENCES compta_comptes(id) ON DELETE CASCADE
);

CREATE TABLE IF NOT EXISTS compta_projets
-- Projets (compta analytique)
(
    id INTEGER PRIMARY KEY NOT NULL,

    libelle TEXT NOT NULL
);

CREATE TABLE IF NOT EXISTS compta_journal
-- Journal des opérations comptables
(
    id INTEGER PRIMARY KEY NOT NULL,

    libelle TEXT NOT NULL,
    remarques TEXT NULL,
    numero_piece TEXT NULL, -- N° de pièce comptable

    montant REAL NOT NULL,

    date TEXT NOT NULL DEFAULT CURRENT_DATE CHECK (date(date) IS NOT NULL AND date(date) = date),
    moyen_paiement TEXT NULL,
    numero_cheque TEXT NULL,

    compte_debit TEXT NULL, -- N° du compte dans le plan, NULL est utilisé pour une opération qui vient d'un exercice précédent
    compte_credit TEXT NULL, -- N° du compte dans le plan

    id_exercice INTEGER NULL DEFAULT NULL, -- En cas de compta simple, l'exercice est permanent (NULL)
    id_auteur INTEGER NULL,
    id_categorie INTEGER NULL, -- Numéro de catégorie (en mode simple)
    id_projet INTEGER NULL,

    FOREIGN KEY(moyen_paiement) REFERENCES compta_moyens_paiement(code),
    FOREIGN KEY(compte_debit) REFERENCES compta_comptes(id),
    FOREIGN KEY(compte_credit) REFERENCES compta_comptes(id),
    FOREIGN KEY(id_exercice) REFERENCES compta_exercices(id),
    FOREIGN KEY(id_auteur) REFERENCES membres(id) ON DELETE SET NULL,
    FOREIGN KEY(id_categorie) REFERENCES compta_categories(id) ON DELETE SET NULL,
    FOREIGN KEY(id_projet) REFERENCES compta_projets(id) ON DELETE SET NULL
);

CREATE INDEX IF NOT EXISTS compta_operations_exercice ON compta_journal (id_exercice);
CREATE INDEX IF NOT EXISTS compta_operations_date ON compta_journal (date);
CREATE INDEX IF NOT EXISTS compta_operations_comptes ON compta_journal (compte_debit, compte_credit);
CREATE INDEX IF NOT EXISTS compta_operations_auteur ON compta_journal (id_auteur);

CREATE TABLE IF NOT EXISTS compta_moyens_paiement
-- Moyens de paiement
(
    code TEXT NOT NULL PRIMARY KEY,
    nom TEXT NOT NULL
);

--INSERT INTO compta_moyens_paiement (code, nom) VALUES ('AU', 'Autre');
INSERT OR IGNORE INTO compta_moyens_paiement (code, nom) VALUES ('CB', 'Carte bleue');
INSERT OR IGNORE INTO compta_moyens_paiement (code, nom) VALUES ('CH', 'Chèque');
INSERT OR IGNORE INTO compta_moyens_paiement (code, nom) VALUES ('ES', 'Espèces');
INSERT OR IGNORE INTO compta_moyens_paiement (code, nom) VALUES ('PR', 'Prélèvement');
INSERT OR IGNORE INTO compta_moyens_paiement (code, nom) VALUES ('TI', 'TIP');
INSERT OR IGNORE INTO compta_moyens_paiement (code, nom) VALUES ('VI', 'Virement');

CREATE TABLE IF NOT EXISTS compta_categories
-- Catégories pour simplifier le plan comptable
(
    id INTEGER NOT NULL PRIMARY KEY,
    type INTEGER NOT NULL DEFAULT 1, -- 1 = recette, -1 = dépense, 0 = autre (utilisé uniquement pour l'interface)

    intitule TEXT NOT NULL,
    description TEXT NULL,

    compte TEXT NOT NULL, -- Compte affecté par cette catégorie

    FOREIGN KEY(compte) REFERENCES compta_comptes(id) ON DELETE CASCADE
);

CREATE TABLE IF NOT EXISTS plugins
(
    id TEXT NOT NULL PRIMARY KEY,
    officiel INTEGER NOT NULL DEFAULT 0,
    nom TEXT NOT NULL,
    description TEXT NULL,
    auteur TEXT NULL,
    url TEXT NULL,
    version TEXT NOT NULL,
    menu INTEGER NOT NULL DEFAULT 0,
    config TEXT NULL
);

CREATE TABLE IF NOT EXISTS plugins_signaux
-- Association entre plugins et signaux (hooks)
(
    signal TEXT NOT NULL,
    plugin TEXT NOT NULL REFERENCES plugins (id),
    callback TEXT NOT NULL,
    PRIMARY KEY (signal, plugin)
);

CREATE TABLE IF NOT EXISTS compta_rapprochement
-- Rapprochement entre compta et relevés de comptes
(
    id_operation INTEGER NOT NULL PRIMARY KEY REFERENCES compta_journal (id) ON DELETE CASCADE,
    date TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP CHECK (datetime(date) IS NOT NULL AND datetime(date) = date),
    id_auteur INTEGER NULL REFERENCES membres (id)
);

CREATE TABLE IF NOT EXISTS fichiers
-- Données sur les fichiers
(
    id INTEGER NOT NULL PRIMARY KEY,
    nom TEXT NOT NULL, -- nom de fichier (par exemple image1234.jpeg)
    type TEXT NULL, -- Type MIME
    image INTEGER NOT NULL DEFAULT 0, -- 1 = image reconnue
    datetime TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP CHECK (datetime(datetime) IS NOT NULL AND datetime(datetime) = datetime), -- Date d'ajout ou mise à jour du fichier
    id_contenu INTEGER NOT NULL REFERENCES fichiers_contenu (id) ON DELETE CASCADE
);

CREATE INDEX IF NOT EXISTS fichiers_date ON fichiers (datetime);

CREATE TABLE IF NOT EXISTS fichiers_contenu
-- Contenu des fichiers
(
    id INTEGER NOT NULL PRIMARY KEY,
    hash TEXT NOT NULL, -- Hash SHA1 du contenu du fichier
    taille INTEGER NOT NULL, -- Taille en octets
    contenu BLOB NULL
);

CREATE UNIQUE INDEX IF NOT EXISTS fichiers_hash ON fichiers_contenu (hash);

CREATE TABLE IF NOT EXISTS fichiers_membres
-- Associations entre fichiers et membres (photo de profil par exemple)
(
    fichier INTEGER NOT NULL REFERENCES fichiers (id),
    id INTEGER NOT NULL REFERENCES membres (id),
    PRIMARY KEY(fichier, id)
);

CREATE TABLE IF NOT EXISTS fichiers_wiki_pages
-- Associations entre fichiers et pages du wiki
(
    fichier INTEGER NOT NULL REFERENCES fichiers (id),
    id INTEGER NOT NULL REFERENCES wiki_pages (id),
    PRIMARY KEY(fichier, id)
);

CREATE TABLE IF NOT EXISTS fichiers_compta_journal
-- Associations entre fichiers et journal de compta (pièce comptable par exemple)
(
    fichier INTEGER NOT NULL REFERENCES fichiers (id),
    id INTEGER NOT NULL REFERENCES compta_journal (id),
    PRIMARY KEY(fichier, id)
);

Added archives/0.8.4_migration.sql version [107bec2b2d].







>
>
>
1
2
3
-- Mise à jour des URI du wiki pour ne pas inclure les tirets en début et fin de chaîne
-- (problème de concordance entre API PHP et données SQLite)
UPDATE wiki_pages SET uri = trim(uri, '-') WHERE uri != trim(uri, '-');

Added archives/0.9.0_migration.sql version [90ab72f7f4].







































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
-- Désactivation de l'accès aux membres, pour les groupes qui n'avaient que le droit de lecture
-- car maintenant ce droit permet de voir les fiches de membres complètes
UPDATE membres_categories SET droit_membres = 0 WHERE droit_membres = 1;

-- Suppression de la colonne description des catégories
ALTER TABLE membres_categories RENAME TO membres_categories_old;

-- Mise à jour table compta_rapprochement: la foreign key sur membres est passée
-- à ON DELETE SET NULL
ALTER TABLE compta_rapprochement RENAME TO compta_rapprochement_old;

-- Re-créer la table
-- Créer également les nouvelles tables email
.read 0.9.0_schema.sql

-- Copie des données, sauf la colonne description
INSERT INTO membres_categories SELECT id, nom, droit_wiki,
	droit_membres, droit_compta, droit_inscription,
	droit_connexion, droit_config, cacher,
	id_cotisation_obligatoire FROM membres_categories_old;

-- Suppression des anciennes tables
DROP TABLE membres_categories_old;

-- Migration des données
INSERT INTO compta_rapprochement SELECT * FROM compta_rapprochement_old;
DROP TABLE compta_rapprochement_old;

-- Cette variable n'est plus utilisée
DELETE FROM config WHERE cle = 'email_envoi_automatique';

ALTER TABLE plugins ADD COLUMN menu_condition TEXT NULL;

-- Supprimer le début dans le nom des plugins
UPDATE plugins_signaux SET callback = replace(callback, 'Garradin\Plugin\', '');

Added archives/0.9.0_schema.sql version [9f23495ff4].







































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
-- Désactivation de l'accès aux membres, pour les groupes qui n'avaient que le droit de lecture
-- car maintenant ce droit permet de voir les fiches de membres complètes
UPDATE membres_categories SET droit_membres = 0 WHERE droit_membres = 1;

-- Suppression de la colonne description des catégories
ALTER TABLE membres_categories RENAME TO membres_categories_old;

-- Mise à jour table compta_rapprochement: la foreign key sur membres est passée
-- à ON DELETE SET NULL
ALTER TABLE compta_rapprochement RENAME TO compta_rapprochement_old;

-- Re-créer la table
-- Créer également les nouvelles tables email
.read schema.sql

-- Copie des données, sauf la colonne description
INSERT INTO membres_categories SELECT id, nom, droit_wiki,
	droit_membres, droit_compta, droit_inscription,
	droit_connexion, droit_config, cacher,
	id_cotisation_obligatoire FROM membres_categories_old;

-- Suppression des anciennes tables
DROP TABLE membres_categories_old;

-- Migration des données
INSERT INTO compta_rapprochement SELECT * FROM compta_rapprochement_old;
DROP TABLE compta_rapprochement_old;

-- Cette variable n'est plus utilisée
DELETE FROM config WHERE cle = 'email_envoi_automatique';

ALTER TABLE plugins ADD COLUMN menu_condition TEXT NULL;

-- Supprimer le début dans le nom des plugins
UPDATE plugins_signaux SET callback = replace(callback, 'Garradin\Plugin\', '');

Added archives/0.9.1_migration.sql version [6227606b97].





























>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
-- Il manquait une clause ON DELETE SET NULL sur la foreign key
-- de cotisations quand on faisait une mise à jour depuis une
-- ancienne version
ALTER TABLE cotisations RENAME TO cotisations_old;

.read 0.9.1_schema.sql

INSERT INTO cotisations SELECT * FROM cotisations_old;

DROP TABLE cotisations_old;

-- Changer le compte des reports automatiques
UPDATE compta_journal SET compte_debit = '890' WHERE compte_debit IS NULL;
UPDATE compta_journal SET compte_credit = '890' WHERE compte_credit IS NULL;

Added archives/0.9.1_schema.sql version [efe750515a].

































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
CREATE TABLE IF NOT EXISTS config (
-- Configuration de Garradin
    cle TEXT PRIMARY KEY NOT NULL,
    valeur TEXT
);

-- On stocke ici les ID de catégorie de compta correspondant aux types spéciaux
-- compta_categorie_cotisations => id_categorie
-- compta_categorie_dons => id_categorie

CREATE TABLE IF NOT EXISTS membres_categories
-- Catégories de membres
(
    id INTEGER PRIMARY KEY NOT NULL,
    nom TEXT NOT NULL,

    droit_wiki INTEGER NOT NULL DEFAULT 1,
    droit_membres INTEGER NOT NULL DEFAULT 1,
    droit_compta INTEGER NOT NULL DEFAULT 1,
    droit_inscription INTEGER NOT NULL DEFAULT 0,
    droit_connexion INTEGER NOT NULL DEFAULT 1,
    droit_config INTEGER NOT NULL DEFAULT 0,
    cacher INTEGER NOT NULL DEFAULT 0,

    id_cotisation_obligatoire INTEGER NULL REFERENCES cotisations (id) ON DELETE SET NULL
);

-- Membres de l'asso
-- Table dynamique générée par l'application
-- voir Garradin\Membres\Champs.php

CREATE TABLE IF NOT EXISTS membres_sessions
-- Sessions
(
    selecteur TEXT NOT NULL,
    hash TEXT NOT NULL,
    id_membre INTEGER NOT NULL REFERENCES membres (id) ON DELETE CASCADE,
    expire INT NOT NULL,

    PRIMARY KEY (selecteur, id_membre)
);

CREATE TABLE IF NOT EXISTS cotisations
-- Types de cotisations et activités
(
    id INTEGER PRIMARY KEY NOT NULL,
    id_categorie_compta INTEGER NULL REFERENCES compta_categories (id) ON DELETE SET NULL, -- NULL si le type n'est pas associé automatiquement à la compta

    intitule TEXT NOT NULL,
    description TEXT NULL,
    montant REAL NOT NULL,

    duree INTEGER NULL, -- En jours
    debut TEXT NULL, -- timestamp
    fin TEXT NULL
);

CREATE TABLE IF NOT EXISTS cotisations_membres
-- Enregistrement des cotisations et activités
(
    id INTEGER NOT NULL PRIMARY KEY,
    id_membre INTEGER NOT NULL REFERENCES membres (id) ON DELETE CASCADE,
    id_cotisation INTEGER NOT NULL REFERENCES cotisations (id) ON DELETE CASCADE,

    date TEXT NOT NULL DEFAULT CURRENT_DATE CHECK (date(date) IS NOT NULL AND date(date) = date)
);

CREATE UNIQUE INDEX IF NOT EXISTS cm_unique ON cotisations_membres (id_membre, id_cotisation, date);

CREATE TABLE IF NOT EXISTS membres_operations
-- Liaison des enregistrement des paiements en compta
(
    id_membre INTEGER NOT NULL REFERENCES membres (id) ON DELETE CASCADE,
    id_operation INTEGER NOT NULL REFERENCES compta_journal (id) ON DELETE CASCADE,
    id_cotisation INTEGER NULL REFERENCES cotisations_membres (id) ON DELETE SET NULL,

    PRIMARY KEY (id_membre, id_operation)
);

CREATE TABLE IF NOT EXISTS rappels
-- Rappels de devoir renouveller une cotisation
(
    id INTEGER NOT NULL PRIMARY KEY,
    id_cotisation INTEGER NOT NULL REFERENCES cotisations (id) ON DELETE CASCADE,

    delai INTEGER NOT NULL, -- Délai en jours pour envoyer le rappel

    sujet TEXT NOT NULL,
    texte TEXT NOT NULL
);

CREATE TABLE IF NOT EXISTS rappels_envoyes
-- Enregistrement des rappels envoyés à qui et quand
(
    id INTEGER NOT NULL PRIMARY KEY,

    id_membre INTEGER NOT NULL REFERENCES membres (id) ON DELETE CASCADE,
    id_cotisation INTEGER NOT NULL REFERENCES cotisations (id) ON DELETE CASCADE,
    id_rappel INTEGER NULL REFERENCES rappels (id) ON DELETE CASCADE,

    date TEXT NOT NULL DEFAULT CURRENT_DATE CHECK (date(date) IS NOT NULL AND date(date) = date),

    media INTEGER NOT NULL -- Média utilisé pour le rappel : 1 = email, 2 = courrier, 3 = autre
);

--
-- WIKI
--

CREATE TABLE IF NOT EXISTS wiki_pages
-- Pages du wiki
(
    id INTEGER PRIMARY KEY NOT NULL,
    uri TEXT NOT NULL, -- URI unique (équivalent NomPageWiki)
    titre TEXT NOT NULL,
    date_creation TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP CHECK (datetime(date_creation) IS NOT NULL AND datetime(date_creation) = date_creation),
    date_modification TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP CHECK (datetime(date_modification) IS NOT NULL AND datetime(date_modification) = date_modification),
    parent INTEGER NOT NULL DEFAULT 0, -- ID de la page parent
    revision INTEGER NOT NULL DEFAULT 0, -- Numéro de révision (commence à 0 si pas de texte, +1 à chaque changement du texte)
    droit_lecture INTEGER NOT NULL DEFAULT 0, -- Accès en lecture (-1 = public [site web], 0 = tous ceux qui ont accès en lecture au wiki, 1+ = ID de groupe)
    droit_ecriture INTEGER NOT NULL DEFAULT 0 -- Accès en écriture (0 = tous ceux qui ont droit d'écriture sur le wiki, 1+ = ID de groupe)
);

CREATE UNIQUE INDEX IF NOT EXISTS wiki_uri ON wiki_pages (uri);

CREATE VIRTUAL TABLE IF NOT EXISTS wiki_recherche USING fts4
-- Table dupliquée pour chercher une page
(
    id INT PRIMARY KEY NOT NULL, -- Clé externe obligatoire
    titre TEXT NOT NULL,
    contenu TEXT NULL, -- Contenu de la dernière révision
    FOREIGN KEY (id) REFERENCES wiki_pages(id)
);

CREATE TABLE IF NOT EXISTS wiki_revisions
-- Révisions du contenu des pages
(
    id_page INTEGER NOT NULL REFERENCES wiki_pages (id) ON DELETE CASCADE,
    revision INTEGER NULL,

    id_auteur INTEGER NULL REFERENCES membres (id) ON DELETE SET NULL,

    contenu TEXT NOT NULL,
    modification TEXT NULL, -- Description des modifications effectuées
    chiffrement INTEGER NOT NULL DEFAULT 0, -- 1 si le contenu est chiffré, 0 sinon
    date TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP CHECK (datetime(date) IS NOT NULL AND datetime(date) = date),

    PRIMARY KEY(id_page, revision)
);

CREATE INDEX IF NOT EXISTS wiki_revisions_id_page ON wiki_revisions (id_page);
CREATE INDEX IF NOT EXISTS wiki_revisions_id_auteur ON wiki_revisions (id_auteur);

-- Triggers pour synchro avec table wiki_pages
CREATE TRIGGER IF NOT EXISTS wiki_recherche_delete AFTER DELETE ON wiki_pages
    BEGIN
        DELETE FROM wiki_recherche WHERE id = old.id;
    END;

CREATE TRIGGER IF NOT EXISTS wiki_recherche_update AFTER UPDATE OF id, titre ON wiki_pages
    BEGIN
        UPDATE wiki_recherche SET id = new.id, titre = new.titre WHERE id = old.id;
    END;

-- Trigger pour mettre à jour le contenu de la table de recherche lors d'une nouvelle révision
CREATE TRIGGER IF NOT EXISTS wiki_recherche_contenu_insert AFTER INSERT ON wiki_revisions WHEN new.chiffrement != 1
    BEGIN
        UPDATE wiki_recherche SET contenu = new.contenu WHERE id = new.id_page;
    END;

-- Si le contenu est chiffré, la recherche n'affiche pas de contenu
CREATE TRIGGER IF NOT EXISTS wiki_recherche_contenu_chiffre AFTER INSERT ON wiki_revisions WHEN new.chiffrement = 1
    BEGIN
        UPDATE wiki_recherche SET contenu = '' WHERE id = new.id_page;
    END;

/*
CREATE TABLE wiki_suivi
-- Suivi des pages
(
    id_membre INTEGER NOT NULL,
    id_page INTEGER NOT NULL,

    PRIMARY KEY (id_membre, id_page),

    FOREIGN KEY (id_page) REFERENCES wiki_pages (id), -- Clé externe obligatoire
    FOREIGN KEY (id_membre) REFERENCES membres (id) -- Clé externe obligatoire
);
*/

--
-- COMPTA
--

CREATE TABLE IF NOT EXISTS compta_exercices
-- Exercices
(
    id INTEGER NOT NULL PRIMARY KEY,

    libelle TEXT NOT NULL,

    debut TEXT NOT NULL DEFAULT CURRENT_DATE CHECK (date(debut) IS NOT NULL AND date(debut) = debut),
    fin TEXT NULL DEFAULT NULL CHECK (fin IS NULL OR (date(fin) IS NOT NULL AND date(fin) = fin)),

    cloture INTEGER NOT NULL DEFAULT 0
);


CREATE TABLE IF NOT EXISTS compta_comptes
-- Plan comptable
(
    id TEXT NOT NULL PRIMARY KEY, -- peut contenir des lettres, eg. 53A, 53B, etc.
    parent TEXT NOT NULL DEFAULT 0,

    libelle TEXT NOT NULL,

    position INTEGER NOT NULL, -- position actif/passif/charge/produit
    plan_comptable INTEGER NOT NULL DEFAULT 1, -- 1 = fait partie du plan comptable, 0 = a été ajouté par l'utilisateur
    desactive INTEGER NOT NULL DEFAULT 0 -- 1 = compte historique désactivé
);

CREATE INDEX IF NOT EXISTS compta_comptes_parent ON compta_comptes (parent);

CREATE TABLE IF NOT EXISTS compta_comptes_bancaires
-- Comptes bancaires
(
    id TEXT NOT NULL PRIMARY KEY,

    banque TEXT NOT NULL,

    iban TEXT NULL,
    bic TEXT NULL,

    FOREIGN KEY(id) REFERENCES compta_comptes(id) ON DELETE CASCADE
);

CREATE TABLE IF NOT EXISTS compta_projets
-- Projets (compta analytique)
(
    id INTEGER PRIMARY KEY NOT NULL,

    libelle TEXT NOT NULL
);

CREATE TABLE IF NOT EXISTS compta_journal
-- Journal des opérations comptables
(
    id INTEGER PRIMARY KEY NOT NULL,

    libelle TEXT NOT NULL,
    remarques TEXT NULL,
    numero_piece TEXT NULL, -- N° de pièce comptable

    montant REAL NOT NULL,

    date TEXT NOT NULL DEFAULT CURRENT_DATE CHECK (date(date) IS NOT NULL AND date(date) = date),
    moyen_paiement TEXT NULL,
    numero_cheque TEXT NULL,

    compte_debit TEXT NULL, -- N° du compte dans le plan, NULL est utilisé pour une opération qui vient d'un exercice précédent
    compte_credit TEXT NULL, -- N° du compte dans le plan

    id_exercice INTEGER NULL DEFAULT NULL, -- En cas de compta simple, l'exercice est permanent (NULL)
    id_auteur INTEGER NULL,
    id_categorie INTEGER NULL, -- Numéro de catégorie (en mode simple)
    id_projet INTEGER NULL,

    FOREIGN KEY(moyen_paiement) REFERENCES compta_moyens_paiement(code),
    FOREIGN KEY(compte_debit) REFERENCES compta_comptes(id),
    FOREIGN KEY(compte_credit) REFERENCES compta_comptes(id),
    FOREIGN KEY(id_exercice) REFERENCES compta_exercices(id),
    FOREIGN KEY(id_auteur) REFERENCES membres(id) ON DELETE SET NULL,
    FOREIGN KEY(id_categorie) REFERENCES compta_categories(id) ON DELETE SET NULL,
    FOREIGN KEY(id_projet) REFERENCES compta_projets(id) ON DELETE SET NULL
);

CREATE INDEX IF NOT EXISTS compta_operations_exercice ON compta_journal (id_exercice);
CREATE INDEX IF NOT EXISTS compta_operations_date ON compta_journal (date);
CREATE INDEX IF NOT EXISTS compta_operations_comptes ON compta_journal (compte_debit, compte_credit);
CREATE INDEX IF NOT EXISTS compta_operations_auteur ON compta_journal (id_auteur);

CREATE TABLE IF NOT EXISTS compta_moyens_paiement
-- Moyens de paiement
(
    code TEXT NOT NULL PRIMARY KEY,
    nom TEXT NOT NULL
);

--INSERT INTO compta_moyens_paiement (code, nom) VALUES ('AU', 'Autre');
INSERT OR IGNORE INTO compta_moyens_paiement (code, nom) VALUES ('CB', 'Carte bleue');
INSERT OR IGNORE INTO compta_moyens_paiement (code, nom) VALUES ('CH', 'Chèque');
INSERT OR IGNORE INTO compta_moyens_paiement (code, nom) VALUES ('ES', 'Espèces');
INSERT OR IGNORE INTO compta_moyens_paiement (code, nom) VALUES ('PR', 'Prélèvement');
INSERT OR IGNORE INTO compta_moyens_paiement (code, nom) VALUES ('TI', 'TIP');
INSERT OR IGNORE INTO compta_moyens_paiement (code, nom) VALUES ('VI', 'Virement');

CREATE TABLE IF NOT EXISTS compta_categories
-- Catégories pour simplifier le plan comptable
(
    id INTEGER NOT NULL PRIMARY KEY,
    type INTEGER NOT NULL DEFAULT 1, -- 1 = recette, -1 = dépense, 0 = autre (utilisé uniquement pour l'interface)

    intitule TEXT NOT NULL,
    description TEXT NULL,

    compte TEXT NOT NULL, -- Compte affecté par cette catégorie

    FOREIGN KEY(compte) REFERENCES compta_comptes(id) ON DELETE CASCADE
);

CREATE TABLE IF NOT EXISTS plugins
(
    id TEXT NOT NULL PRIMARY KEY,
    officiel INTEGER NOT NULL DEFAULT 0,
    nom TEXT NOT NULL,
    description TEXT NULL,
    auteur TEXT NULL,
    url TEXT NULL,
    version TEXT NOT NULL,
    menu INTEGER NOT NULL DEFAULT 0,
    menu_condition TEXT NULL,
    config TEXT NULL
);

CREATE TABLE IF NOT EXISTS plugins_signaux
-- Association entre plugins et signaux (hooks)
(
    signal TEXT NOT NULL,
    plugin TEXT NOT NULL REFERENCES plugins (id),
    callback TEXT NOT NULL,
    PRIMARY KEY (signal, plugin)
);

CREATE TABLE IF NOT EXISTS compta_rapprochement
-- Rapprochement entre compta et relevés de comptes
(
    id_operation INTEGER NOT NULL PRIMARY KEY REFERENCES compta_journal (id) ON DELETE CASCADE,
    date TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP CHECK (datetime(date) IS NOT NULL AND datetime(date) = date),
    id_auteur INTEGER NULL REFERENCES membres (id) ON DELETE SET NULL
);

CREATE TABLE IF NOT EXISTS fichiers
-- Données sur les fichiers
(
    id INTEGER NOT NULL PRIMARY KEY,
    nom TEXT NOT NULL, -- nom de fichier (par exemple image1234.jpeg)
    type TEXT NULL, -- Type MIME
    image INTEGER NOT NULL DEFAULT 0, -- 1 = image reconnue
    datetime TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP CHECK (datetime(datetime) IS NOT NULL AND datetime(datetime) = datetime), -- Date d'ajout ou mise à jour du fichier
    id_contenu INTEGER NOT NULL REFERENCES fichiers_contenu (id) ON DELETE CASCADE
);

CREATE INDEX IF NOT EXISTS fichiers_date ON fichiers (datetime);

CREATE TABLE IF NOT EXISTS fichiers_contenu
-- Contenu des fichiers
(
    id INTEGER NOT NULL PRIMARY KEY,
    hash TEXT NOT NULL, -- Hash SHA1 du contenu du fichier
    taille INTEGER NOT NULL, -- Taille en octets
    contenu BLOB NULL
);

CREATE UNIQUE INDEX IF NOT EXISTS fichiers_hash ON fichiers_contenu (hash);

CREATE TABLE IF NOT EXISTS fichiers_membres
-- Associations entre fichiers et membres (photo de profil par exemple)
(
    fichier INTEGER NOT NULL REFERENCES fichiers (id),
    id INTEGER NOT NULL REFERENCES membres (id),
    PRIMARY KEY(fichier, id)
);

CREATE TABLE IF NOT EXISTS fichiers_wiki_pages
-- Associations entre fichiers et pages du wiki
(
    fichier INTEGER NOT NULL REFERENCES fichiers (id),
    id INTEGER NOT NULL REFERENCES wiki_pages (id),
    PRIMARY KEY(fichier, id)
);

CREATE TABLE IF NOT EXISTS fichiers_compta_journal
-- Associations entre fichiers et journal de compta (pièce comptable par exemple)
(
    fichier INTEGER NOT NULL REFERENCES fichiers (id),
    id INTEGER NOT NULL REFERENCES compta_journal (id),
    PRIMARY KEY(fichier, id)
);

CREATE TABLE IF NOT EXISTS recherches
-- Recherches enregistrées
(
    id INTEGER NOT NULL PRIMARY KEY,
    id_membre INTEGER NULL REFERENCES membres (id) ON DELETE CASCADE, -- Si non NULL, alors la recherche ne sera visible que par le membre associé
    intitule TEXT NOT NULL,
    creation TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP CHECK (datetime(creation) IS NOT NULL AND datetime(creation) = creation),
    cible TEXT NOT NULL, -- "membres" ou "compta_journal"
    type TEXT NOT NULL, -- "json" ou "sql"
    contenu TEXT NOT NULL
);

Added archives/0.9.5_schema.sql version [c8df01c2dd].





























































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
CREATE TABLE IF NOT EXISTS config (
-- Configuration de Garradin
    cle TEXT PRIMARY KEY NOT NULL,
    valeur TEXT
);

-- On stocke ici les ID de catégorie de compta correspondant aux types spéciaux
-- compta_categorie_cotisations => id_categorie
-- compta_categorie_dons => id_categorie

CREATE TABLE IF NOT EXISTS membres_categories
-- Catégories de membres
(
    id INTEGER PRIMARY KEY NOT NULL,
    nom TEXT NOT NULL,

    droit_wiki INTEGER NOT NULL DEFAULT 1,
    droit_membres INTEGER NOT NULL DEFAULT 1,
    droit_compta INTEGER NOT NULL DEFAULT 1,
    droit_inscription INTEGER NOT NULL DEFAULT 0,
    droit_connexion INTEGER NOT NULL DEFAULT 1,
    droit_config INTEGER NOT NULL DEFAULT 0,
    cacher INTEGER NOT NULL DEFAULT 0,

    id_cotisation_obligatoire INTEGER NULL REFERENCES cotisations (id) ON DELETE SET NULL
);

-- Membres de l'asso
-- Table dynamique générée par l'application
-- voir Garradin\Membres\Champs.php

CREATE TABLE IF NOT EXISTS membres_sessions
-- Sessions
(
    selecteur TEXT NOT NULL,
    hash TEXT NOT NULL,
    id_membre INTEGER NOT NULL REFERENCES membres (id) ON DELETE CASCADE,
    expire INT NOT NULL,

    PRIMARY KEY (selecteur, id_membre)
);

CREATE TABLE IF NOT EXISTS cotisations
-- Types de cotisations et activités
(
    id INTEGER PRIMARY KEY NOT NULL,
    id_categorie_compta INTEGER NULL REFERENCES compta_categories (id) ON DELETE SET NULL, -- NULL si le type n'est pas associé automatiquement à la compta

    intitule TEXT NOT NULL,
    description TEXT NULL,
    montant REAL NOT NULL,

    duree INTEGER NULL, -- En jours
    debut TEXT NULL, -- timestamp
    fin TEXT NULL
);

CREATE TABLE IF NOT EXISTS cotisations_membres
-- Enregistrement des cotisations et activités
(
    id INTEGER NOT NULL PRIMARY KEY,
    id_membre INTEGER NOT NULL REFERENCES membres (id) ON DELETE CASCADE,
    id_cotisation INTEGER NOT NULL REFERENCES cotisations (id) ON DELETE CASCADE,

    date TEXT NOT NULL DEFAULT CURRENT_DATE CHECK (date(date) IS NOT NULL AND date(date) = date)
);

CREATE UNIQUE INDEX IF NOT EXISTS cm_unique ON cotisations_membres (id_membre, id_cotisation, date);

CREATE TABLE IF NOT EXISTS membres_operations
-- Liaison des enregistrement des paiements en compta
(
    id_membre INTEGER NOT NULL REFERENCES membres (id) ON DELETE CASCADE,
    id_operation INTEGER NOT NULL REFERENCES compta_journal (id) ON DELETE CASCADE,
    id_cotisation INTEGER NULL REFERENCES cotisations_membres (id) ON DELETE SET NULL,

    PRIMARY KEY (id_membre, id_operation)
);

CREATE TABLE IF NOT EXISTS rappels
-- Rappels de devoir renouveller une cotisation
(
    id INTEGER NOT NULL PRIMARY KEY,
    id_cotisation INTEGER NOT NULL REFERENCES cotisations (id) ON DELETE CASCADE,

    delai INTEGER NOT NULL, -- Délai en jours pour envoyer le rappel

    sujet TEXT NOT NULL,
    texte TEXT NOT NULL
);

CREATE TABLE IF NOT EXISTS rappels_envoyes
-- Enregistrement des rappels envoyés à qui et quand
(
    id INTEGER NOT NULL PRIMARY KEY,

    id_membre INTEGER NOT NULL REFERENCES membres (id) ON DELETE CASCADE,
    id_cotisation INTEGER NOT NULL REFERENCES cotisations (id) ON DELETE CASCADE,
    id_rappel INTEGER NULL REFERENCES rappels (id) ON DELETE CASCADE,

    date TEXT NOT NULL DEFAULT CURRENT_DATE CHECK (date(date) IS NOT NULL AND date(date) = date),

    media INTEGER NOT NULL -- Média utilisé pour le rappel : 1 = email, 2 = courrier, 3 = autre
);

--
-- WIKI
--

CREATE TABLE IF NOT EXISTS wiki_pages
-- Pages du wiki
(
    id INTEGER PRIMARY KEY NOT NULL,
    uri TEXT NOT NULL, -- URI unique (équivalent NomPageWiki)
    titre TEXT NOT NULL,
    date_creation TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP CHECK (datetime(date_creation) IS NOT NULL AND datetime(date_creation) = date_creation),
    date_modification TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP CHECK (datetime(date_modification) IS NOT NULL AND datetime(date_modification) = date_modification),
    parent INTEGER NOT NULL DEFAULT 0, -- ID de la page parent
    revision INTEGER NOT NULL DEFAULT 0, -- Numéro de révision (commence à 0 si pas de texte, +1 à chaque changement du texte)
    droit_lecture INTEGER NOT NULL DEFAULT 0, -- Accès en lecture (-1 = public [site web], 0 = tous ceux qui ont accès en lecture au wiki, 1+ = ID de groupe)
    droit_ecriture INTEGER NOT NULL DEFAULT 0 -- Accès en écriture (0 = tous ceux qui ont droit d'écriture sur le wiki, 1+ = ID de groupe)
);

CREATE UNIQUE INDEX IF NOT EXISTS wiki_uri ON wiki_pages (uri);

CREATE VIRTUAL TABLE IF NOT EXISTS wiki_recherche USING fts4
-- Table dupliquée pour chercher une page
(
    id INT PRIMARY KEY NOT NULL, -- Clé externe obligatoire
    titre TEXT NOT NULL,
    contenu TEXT NULL, -- Contenu de la dernière révision
    FOREIGN KEY (id) REFERENCES wiki_pages(id)
);

CREATE TABLE IF NOT EXISTS wiki_revisions
-- Révisions du contenu des pages
(
    id_page INTEGER NOT NULL REFERENCES wiki_pages (id) ON DELETE CASCADE,
    revision INTEGER NULL,

    id_auteur INTEGER NULL REFERENCES membres (id) ON DELETE SET NULL,

    contenu TEXT NOT NULL,
    modification TEXT NULL, -- Description des modifications effectuées
    chiffrement INTEGER NOT NULL DEFAULT 0, -- 1 si le contenu est chiffré, 0 sinon
    date TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP CHECK (datetime(date) IS NOT NULL AND datetime(date) = date),

    PRIMARY KEY(id_page, revision)
);

CREATE INDEX IF NOT EXISTS wiki_revisions_id_page ON wiki_revisions (id_page);
CREATE INDEX IF NOT EXISTS wiki_revisions_id_auteur ON wiki_revisions (id_auteur);

-- Triggers pour synchro avec table wiki_pages
CREATE TRIGGER IF NOT EXISTS wiki_recherche_delete AFTER DELETE ON wiki_pages
    BEGIN
        DELETE FROM wiki_recherche WHERE id = old.id;
    END;

CREATE TRIGGER IF NOT EXISTS wiki_recherche_update AFTER UPDATE OF id, titre ON wiki_pages
    BEGIN
        UPDATE wiki_recherche SET id = new.id, titre = new.titre WHERE id = old.id;
    END;

-- Trigger pour mettre à jour le contenu de la table de recherche lors d'une nouvelle révision
CREATE TRIGGER IF NOT EXISTS wiki_recherche_contenu_insert AFTER INSERT ON wiki_revisions WHEN new.chiffrement != 1
    BEGIN
        UPDATE wiki_recherche SET contenu = new.contenu WHERE id = new.id_page;
    END;

-- Si le contenu est chiffré, la recherche n'affiche pas de contenu
CREATE TRIGGER IF NOT EXISTS wiki_recherche_contenu_chiffre AFTER INSERT ON wiki_revisions WHEN new.chiffrement = 1
    BEGIN
        UPDATE wiki_recherche SET contenu = '' WHERE id = new.id_page;
    END;

/*
CREATE TABLE wiki_suivi
-- Suivi des pages
(
    id_membre INTEGER NOT NULL,
    id_page INTEGER NOT NULL,

    PRIMARY KEY (id_membre, id_page),

    FOREIGN KEY (id_page) REFERENCES wiki_pages (id), -- Clé externe obligatoire
    FOREIGN KEY (id_membre) REFERENCES membres (id) -- Clé externe obligatoire
);
*/

--
-- COMPTA
--

CREATE TABLE IF NOT EXISTS compta_exercices
-- Exercices
(
    id INTEGER NOT NULL PRIMARY KEY,

    libelle TEXT NOT NULL,

    debut TEXT NOT NULL DEFAULT CURRENT_DATE CHECK (date(debut) IS NOT NULL AND date(debut) = debut),
    fin TEXT NULL DEFAULT NULL CHECK (fin IS NULL OR (date(fin) IS NOT NULL AND date(fin) = fin)),

    cloture INTEGER NOT NULL DEFAULT 0
);


CREATE TABLE IF NOT EXISTS compta_comptes
-- Plan comptable
(
    id TEXT NOT NULL PRIMARY KEY, -- peut contenir des lettres, eg. 53A, 53B, etc.
    parent TEXT NOT NULL DEFAULT 0,

    libelle TEXT NOT NULL,

    position INTEGER NOT NULL, -- position actif/passif/charge/produit
    plan_comptable INTEGER NOT NULL DEFAULT 1, -- 1 = fait partie du plan comptable, 0 = a été ajouté par l'utilisateur
    desactive INTEGER NOT NULL DEFAULT 0 -- 1 = compte historique désactivé
);

CREATE INDEX IF NOT EXISTS compta_comptes_parent ON compta_comptes (parent);

CREATE TABLE IF NOT EXISTS compta_comptes_bancaires
-- Comptes bancaires
(
    id TEXT NOT NULL PRIMARY KEY,

    banque TEXT NOT NULL,

    iban TEXT NULL,
    bic TEXT NULL,

    FOREIGN KEY(id) REFERENCES compta_comptes(id) ON DELETE CASCADE
);

CREATE TABLE IF NOT EXISTS compta_projets
-- Projets (compta analytique)
(
    id INTEGER PRIMARY KEY NOT NULL,

    libelle TEXT NOT NULL
);

CREATE TABLE IF NOT EXISTS compta_journal
-- Journal des opérations comptables
(
    id INTEGER PRIMARY KEY NOT NULL,

    libelle TEXT NOT NULL,
    remarques TEXT NULL,
    numero_piece TEXT NULL, -- N° de pièce comptable

    montant REAL NOT NULL,

    date TEXT NOT NULL DEFAULT CURRENT_DATE CHECK (date(date) IS NOT NULL AND date(date) = date),
    moyen_paiement TEXT NULL,
    numero_cheque TEXT NULL,

    compte_debit TEXT NULL, -- N° du compte dans le plan, NULL est utilisé pour une opération qui vient d'un exercice précédent
    compte_credit TEXT NULL, -- N° du compte dans le plan

    id_exercice INTEGER NULL DEFAULT NULL, -- En cas de compta simple, l'exercice est permanent (NULL)
    id_auteur INTEGER NULL,
    id_categorie INTEGER NULL, -- Numéro de catégorie (en mode simple)
    id_projet INTEGER NULL,

    FOREIGN KEY(moyen_paiement) REFERENCES compta_moyens_paiement(code),
    FOREIGN KEY(compte_debit) REFERENCES compta_comptes(id),
    FOREIGN KEY(compte_credit) REFERENCES compta_comptes(id),
    FOREIGN KEY(id_exercice) REFERENCES compta_exercices(id),
    FOREIGN KEY(id_auteur) REFERENCES membres(id) ON DELETE SET NULL,
    FOREIGN KEY(id_categorie) REFERENCES compta_categories(id) ON DELETE SET NULL,
    FOREIGN KEY(id_projet) REFERENCES compta_projets(id) ON DELETE SET NULL
);

CREATE INDEX IF NOT EXISTS compta_operations_exercice ON compta_journal (id_exercice);
CREATE INDEX IF NOT EXISTS compta_operations_date ON compta_journal (date);
CREATE INDEX IF NOT EXISTS compta_operations_comptes ON compta_journal (compte_debit, compte_credit);
CREATE INDEX IF NOT EXISTS compta_operations_auteur ON compta_journal (id_auteur);

CREATE TABLE IF NOT EXISTS compta_moyens_paiement
-- Moyens de paiement
(
    code TEXT NOT NULL PRIMARY KEY,
    nom TEXT NOT NULL
);

--INSERT INTO compta_moyens_paiement (code, nom) VALUES ('AU', 'Autre');
INSERT OR IGNORE INTO compta_moyens_paiement (code, nom) VALUES ('CB', 'Carte bleue');
INSERT OR IGNORE INTO compta_moyens_paiement (code, nom) VALUES ('CH', 'Chèque');
INSERT OR IGNORE INTO compta_moyens_paiement (code, nom) VALUES ('ES', 'Espèces');
INSERT OR IGNORE INTO compta_moyens_paiement (code, nom) VALUES ('PR', 'Prélèvement');
INSERT OR IGNORE INTO compta_moyens_paiement (code, nom) VALUES ('TI', 'TIP');
INSERT OR IGNORE INTO compta_moyens_paiement (code, nom) VALUES ('VI', 'Virement');

CREATE TABLE IF NOT EXISTS compta_categories
-- Catégories pour simplifier le plan comptable
(
    id INTEGER NOT NULL PRIMARY KEY,
    type INTEGER NOT NULL DEFAULT 1, -- 1 = recette, -1 = dépense, 0 = autre (utilisé uniquement pour l'interface)

    intitule TEXT NOT NULL,
    description TEXT NULL,

    compte TEXT NOT NULL, -- Compte affecté par cette catégorie

    FOREIGN KEY(compte) REFERENCES compta_comptes(id) ON DELETE CASCADE
);

CREATE TABLE IF NOT EXISTS plugins
(
    id TEXT NOT NULL PRIMARY KEY,
    officiel INTEGER NOT NULL DEFAULT 0,
    nom TEXT NOT NULL,
    description TEXT NULL,
    auteur TEXT NULL,
    url TEXT NULL,
    version TEXT NOT NULL,
    menu INTEGER NOT NULL DEFAULT 0,
    menu_condition TEXT NULL,
    config TEXT NULL
);

CREATE TABLE IF NOT EXISTS plugins_signaux
-- Association entre plugins et signaux (hooks)
(
    signal TEXT NOT NULL,
    plugin TEXT NOT NULL REFERENCES plugins (id),
    callback TEXT NOT NULL,
    PRIMARY KEY (signal, plugin)
);

CREATE TABLE IF NOT EXISTS compta_rapprochement
-- Rapprochement entre compta et relevés de comptes
(
    id_operation INTEGER NOT NULL PRIMARY KEY REFERENCES compta_journal (id) ON DELETE CASCADE,
    date TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP CHECK (datetime(date) IS NOT NULL AND datetime(date) = date),
    id_auteur INTEGER NULL REFERENCES membres (id) ON DELETE SET NULL
);

CREATE TABLE IF NOT EXISTS fichiers
-- Données sur les fichiers
(
    id INTEGER NOT NULL PRIMARY KEY,
    nom TEXT NOT NULL, -- nom de fichier (par exemple image1234.jpeg)
    type TEXT NULL, -- Type MIME
    image INTEGER NOT NULL DEFAULT 0, -- 1 = image reconnue
    datetime TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP CHECK (datetime(datetime) IS NOT NULL AND datetime(datetime) = datetime), -- Date d'ajout ou mise à jour du fichier
    id_contenu INTEGER NOT NULL REFERENCES fichiers_contenu (id) ON DELETE CASCADE
);

CREATE INDEX IF NOT EXISTS fichiers_date ON fichiers (datetime);

CREATE TABLE IF NOT EXISTS fichiers_contenu
-- Contenu des fichiers
(
    id INTEGER NOT NULL PRIMARY KEY,
    hash TEXT NOT NULL, -- Hash SHA1 du contenu du fichier
    taille INTEGER NOT NULL, -- Taille en octets
    contenu BLOB NULL
);

CREATE UNIQUE INDEX IF NOT EXISTS fichiers_hash ON fichiers_contenu (hash);

CREATE TABLE IF NOT EXISTS fichiers_membres
-- Associations entre fichiers et membres (photo de profil par exemple)
(
    fichier INTEGER NOT NULL REFERENCES fichiers (id),
    id INTEGER NOT NULL REFERENCES membres (id),
    PRIMARY KEY(fichier, id)
);

CREATE TABLE IF NOT EXISTS fichiers_wiki_pages
-- Associations entre fichiers et pages du wiki
(
    fichier INTEGER NOT NULL REFERENCES fichiers (id),
    id INTEGER NOT NULL REFERENCES wiki_pages (id),
    PRIMARY KEY(fichier, id)
);

CREATE TABLE IF NOT EXISTS fichiers_compta_journal
-- Associations entre fichiers et journal de compta (pièce comptable par exemple)
(
    fichier INTEGER NOT NULL REFERENCES fichiers (id),
    id INTEGER NOT NULL REFERENCES compta_journal (id),
    PRIMARY KEY(fichier, id)
);

CREATE TABLE IF NOT EXISTS recherches
-- Recherches enregistrées
(
    id INTEGER NOT NULL PRIMARY KEY,
    id_membre INTEGER NULL REFERENCES membres (id) ON DELETE CASCADE, -- Si non NULL, alors la recherche ne sera visible que par le membre associé
    intitule TEXT NOT NULL,
    creation TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP CHECK (datetime(creation) IS NOT NULL AND datetime(creation) = creation),
    cible TEXT NOT NULL, -- "membres" ou "compta_journal"
    type TEXT NOT NULL, -- "json" ou "sql"
    contenu TEXT NOT NULL
);


CREATE TABLE IF NOT EXISTS compromised_passwords_cache
-- Cache des hash de mots de passe compromis
(
    hash TEXT NOT NULL PRIMARY KEY
);

CREATE TABLE IF NOT EXISTS compromised_passwords_cache_ranges
-- Cache des préfixes de mots de passe compromis
(
    prefix TEXT NOT NULL PRIMARY KEY,
    date INTEGER NOT NULL
);

Added archives/plan_comptable.json version [c496246466].

































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
{
    "1": {
        "code": 1,
        "nom": "Classe 1 \u2014 Comptes de capitaux (Fonds propres, emprunts et dettes assimil\u00e9s)",
        "parent": 0,
        "position": 1
    },
    "10": {
        "code": 10,
        "nom": "FONDS ASSOCIATIFS ET R\u00c9SERVES",
        "parent": 1,
        "position": 1
    },
    "102": {
        "code": 102,
        "nom": "Fonds associatif sans droit de reprise",
        "parent": 10,
        "position": 1
    },
    "1021": {
        "code": 1021,
        "nom": "Valeur du patrimoine int\u00e9gr\u00e9",
        "parent": 102,
        "position": 1
    },
    "1022": {
        "code": 1022,
        "nom": "Fonds statutaire",
        "parent": 102,
        "position": 1
    },
    "1024": {
        "code": 1024,
        "nom": "Apports sans droit de reprise",
        "parent": 102,
        "position": 1
    },
    "103": {
        "code": 103,
        "nom": "Fonds associatif avec droit de reprise",
        "parent": 10,
        "position": 1
    },
    "1034": {
        "code": 1034,
        "nom": "Apports avec droit de reprise",
        "parent": 103,
        "position": 1
    },
    "105": {
        "code": 105,
        "nom": "\u00c9carts de r\u00e9\u00e9valuation",
        "parent": 10,
        "position": 1
    },
    "106": {
        "code": 106,
        "nom": "R\u00e9serves",
        "parent": 10,
        "position": 1
    },
    "1063": {
        "code": 1063,
        "nom": "R\u00e9serves statutaires ou contractuelles",
        "parent": 106,
        "position": 1
    },
    "1064": {
        "code": 1064,
        "nom": "R\u00e9serves r\u00e9glement\u00e9es",
        "parent": 106,
        "position": 1
    },
    "1068": {
        "code": 1068,
        "nom": "Autres r\u00e9serves (dont r\u00e9serves pour projet associatif)",
        "parent": 106,
        "position": 1
    },
    "11": {
        "code": 11,
        "nom": "REPORT \u00c0 NOUVEAU",
        "parent": 1,
        "position": 1
    },
    "110": {
        "code": 110,
        "nom": "Report \u00e0 nouveau (Solde cr\u00e9diteur)",
        "parent": 11,
        "position": 1
    },
    "119": {
        "code": 119,
        "nom": "Report \u00e0 nouveau (Solde d\u00e9biteur)",
        "parent": 11,
        "position": 1
    },
    "12": {
        "code": 12,
        "nom": "R\u00c9SULTAT NET DE L'EXERCICE",
        "parent": 1,
        "position": 1
    },
    "120": {
        "code": 120,
        "nom": "R\u00e9sultat de l'exercice (exc\u00e9dent)",
        "parent": 12,
        "position": 1
    },
    "129": {
        "code": 129,
        "nom": "R\u00e9sultat de l'exercice (d\u00e9ficit)",
        "parent": 12,
        "position": 1
    },
    "13": {
        "code": 13,
        "nom": "SUBVENTIONS D'INVESTISSEMENT AFFECT\u00c9ES A DES BIENS NON RENOUVELABLES",
        "parent": 1,
        "position": 1
    },
    "131": {
        "code": 131,
        "nom": "Subventions d'investissement (renouvelables)",
        "parent": 13,
        "position": 1
    },
    "139": {
        "code": 139,
        "nom": "Subventions d'investissement inscrites au compte de r\u00e9sultat",
        "parent": 13,
        "position": 1
    },
    "14": {
        "code": 14,
        "nom": "PROVISIONS REGLEMENT\u00c9ES",
        "parent": 1,
        "position": 1
    },
    "15": {
        "code": 15,
        "nom": "PROVISIONS",
        "parent": 1,
        "position": 1
    },
    "151": {
        "code": 151,
        "nom": "Provisions pour risques",
        "parent": 15,
        "position": 1
    },
    "157": {
        "code": 157,
        "nom": "Provisions pour charges \u00e0 r\u00e9partir sur plusieurs exercices",
        "parent": 15,
        "position": 1
    },
    "158": {
        "code": 158,
        "nom": "Autres provisions pour charges",
        "parent": 15,
        "position": 1
    },
    "16": {
        "code": 16,
        "nom": "EMPRUNTS ET DETTES ASSIMIL\u00c9ES",
        "parent": 1,
        "position": 1
    },
    "164": {
        "code": 164,
        "nom": "Emprunts aupr\u00e8s des \u00e9tablissements de cr\u00e9dits",
        "parent": 16,
        "position": 1
    },
    "165": {
        "code": 165,
        "nom": "D\u00e9p\u00f4ts et cautionnements re\u00e7us",
        "parent": 16,
        "position": 1
    },
    "167": {
        "code": 167,
        "nom": "Emprunts et dettes assorties de conditions particuli\u00e8res",
        "parent": 16,
        "position": 1
    },
    "168": {
        "code": 168,
        "nom": "Autres emprunts et dettes assimil\u00e9s",
        "parent": 16,
        "position": 1
    },
    "17": {
        "code": 17,
        "nom": "DETTES RATTACH\u00c9ES \u00c0 DES PARTICIPATIONS",
        "parent": 1,
        "position": 1
    },
    "18": {
        "code": 18,
        "nom": "COMPTES DE LIAISON DES \u00c9TABLISSEMENTS",
        "parent": 1,
        "position": 1
    },
    "181": {
        "code": 181,
        "nom": "Apports permanents entre si\u00e8ge social et \u00e9tablissements",
        "parent": 18,
        "position": 1
    },
    "185": {
        "code": 185,
        "nom": "Biens et prestations de services \u00e9chang\u00e9s entre \u00e9tablissements et si\u00e8ge social",
        "parent": 18,
        "position": 1
    },
    "186": {
        "code": 186,
        "nom": "Biens et prestations de services \u00e9chang\u00e9s entre \u00e9tablissements (charges)",
        "parent": 18,
        "position": 1
    },
    "187": {
        "code": 187,
        "nom": "Biens et prestations de services \u00e9chang\u00e9s entre \u00e9tablissements (produits)",
        "parent": 18,
        "position": 1
    },
    "19": {
        "code": 19,
        "nom": "FONDS D\u00c9DI\u00c9S",
        "parent": 1,
        "position": 1
    },
    "194": {
        "code": 194,
        "nom": "Fonds d\u00e9di\u00e9s sur subventions de fonctionnement",
        "parent": 19,
        "position": 1
    },
    "195": {
        "code": 195,
        "nom": "Fonds d\u00e9di\u00e9s sur dons manuels affect\u00e9s",
        "parent": 19,
        "position": 1
    },
    "197": {
        "code": 197,
        "nom": "Fonds d\u00e9di\u00e9s sur legs et donations affect\u00e9s",
        "parent": 19,
        "position": 1
    },
    "198": {
        "code": 198,
        "nom": "Exc\u00e9dent disponible apr\u00e8s affectation au projet associatif",
        "parent": 19,
        "position": 1
    },
    "199": {
        "code": 199,
        "nom": "Reprise des fonds affect\u00e9s au projet associatif",
        "parent": 19,
        "position": 1
    },
    "2": {
        "code": 2,
        "nom": "Classe 2 \u2014 Comptes d'immobilisations",
        "parent": 0,
        "position": 2
    },
    "20": {
        "code": 20,
        "nom": "IMMOBILISATIONS INCORPORELLES",
        "parent": 2,
        "position": 2
    },
    "200": {
        "code": 200,
        "nom": "Immobilisations incorporelles",
        "parent": 20,
        "position": 2
    },
    "21": {
        "code": 21,
        "nom": "IMMOBILISATIONS CORPORELLES",
        "parent": 2,
        "position": 2
    },
    "210": {
        "code": 210,
        "nom": "Investissements",
        "parent": 21,
        "position": 2
    },
    "22": {
        "code": 22,
        "nom": "IMMOBILISATIONS GREV\u00c9ES DE DROITS",
        "parent": 2,
        "position": 2
    },
    "228": {
        "code": 228,
        "nom": "Immobilisations grev\u00e9es de droits",
        "parent": 22,
        "position": 2
    },
    "229": {
        "code": 229,
        "nom": "Droits des propri\u00e9taires",
        "parent": 22,
        "position": 2
    },
    "23": {
        "code": 23,
        "nom": "IMMOBILISATIONS EN COURS",
        "parent": 2,
        "position": 2
    },
    "231": {
        "code": 231,
        "nom": "Immobilisations corporelles en cours",
        "parent": 23,
        "position": 2
    },
    "238": {
        "code": 238,
        "nom": "Avances et acomptes vers\u00e9s sur commande d'immobilisations corporelles",
        "parent": 23,
        "position": 2
    },
    "26": {
        "code": 26,
        "nom": "PARTICIPATIONS ET CR\u00c9ANCES RATTACH\u00c9ES A DES PARTICIPATIONS",
        "parent": 2,
        "position": 2
    },
    "261": {
        "code": 261,
        "nom": "Titres de participation",
        "parent": 26,
        "position": 2
    },
    "27": {
        "code": 27,
        "nom": "AUTRES IMMOBILISATIONS FINANCI\u00c8RES",
        "parent": 2,
        "position": 2
    },
    "270": {
        "code": 270,
        "nom": "Participations financi\u00e8res",
        "parent": 27,
        "position": 2
    },
    "275": {
        "code": 275,
        "nom": "D\u00e9p\u00f4ts et cautionnements vers\u00e9s",
        "parent": 27,
        "position": 2
    },
    "28": {
        "code": 28,
        "nom": "AMORTISSEMENTS DES IMMOBILISATIONS",
        "parent": 2,
        "position": 2
    },
    "280": {
        "code": 280,
        "nom": "Amortissements des immobilisations incorporelles",
        "parent": 28,
        "position": 2
    },
    "281": {
        "code": 281,
        "nom": "Amortissements des immobilisations corporelles",
        "parent": 28,
        "position": 2
    },
    "29": {
        "code": 29,
        "nom": "D\u00c9PR\u00c9CIATION DES IMMOBILISATIONS",
        "parent": 2,
        "position": 2
    },
    "290": {
        "code": 290,
        "nom": "D\u00e9pr\u00e9ciation des immobilisations incorporelles",
        "parent": 29,
        "position": 2
    },
    "291": {
        "code": 291,
        "nom": "D\u00e9pr\u00e9ciation des immobilisations corporelles",
        "parent": 29,
        "position": 2
    },
    "3": {
        "code": 3,
        "nom": "Classe 3 \u2014 Comptes de stocks",
        "parent": 0,
        "position": 2
    },
    "31": {
        "code": 31,
        "nom": "MATIERES PREMIERES ET FOURNITURES",
        "parent": 3,
        "position": 2
    },
    "311": {
        "code": 311,
        "nom": "Mati\u00e8res",
        "parent": 31,
        "position": 2
    },
    "317": {
        "code": 317,
        "nom": "Fournitures",
        "parent": 31,
        "position": 2
    },
    "32": {
        "code": 32,
        "nom": "AUTRES APPROVISIONNEMENTS",
        "parent": 3,
        "position": 2
    },
    "321": {
        "code": 321,
        "nom": "Mati\u00e8res consommables",
        "parent": 32,
        "position": 2
    },
    "322": {
        "code": 322,
        "nom": "Fournitures consommables",
        "parent": 32,
        "position": 2
    },
    "33": {
        "code": 33,
        "nom": "EN-COURS DE PRODUCTION DE BIENS",
        "parent": 3,
        "position": 2
    },
    "331": {
        "code": 331,
        "nom": "Produits en cours",
        "parent": 33,
        "position": 2
    },
    "335": {
        "code": 335,
        "nom": "Travaux en cours",
        "parent": 33,
        "position": 2
    },
    "34": {
        "code": 34,
        "nom": "EN-COURS DE PRODUCTION DE SERVICES",
        "parent": 3,
        "position": 2
    },
    "35": {
        "code": 35,
        "nom": "STOCKS DE PRODUITS",
        "parent": 3,
        "position": 2
    },
    "351": {
        "code": 351,
        "nom": "Produits interm\u00e9diaires",
        "parent": 35,
        "position": 2
    },
    "355": {
        "code": 355,
        "nom": "Produits finis",
        "parent": 35,
        "position": 2
    },
    "358": {
        "code": 358,
        "nom": "Produits r\u00e9siduels",
        "parent": 35,
        "position": 2
    },
    "3581": {
        "code": 3581,
        "nom": "D\u00e9chets",
        "parent": 358,
        "position": 2
    },
    "3585": {
        "code": 3585,
        "nom": "Rebuts",
        "parent": 358,
        "position": 2
    },
    "3586": {
        "code": 3586,
        "nom": "Mati\u00e8re de r\u00e9cup\u00e9ration",
        "parent": 358,
        "position": 2
    },
    "37": {
        "code": 37,
        "nom": "STOCKS DE MARCHANDISES",
        "parent": 3,
        "position": 2
    },
    "370": {
        "code": 370,
        "nom": "Autres stocks de marchandises",
        "parent": 37,
        "position": 2
    },
    "39": {
        "code": 39,
        "nom": "PROVISIONS POUR DEPRECIATION DES STOCKS ET EN-COURS",
        "parent": 3,
        "position": 2
    },
    "391": {
        "code": 391,
        "nom": "Provisions pour d\u00e9pr\u00e9ciation des mati\u00e8res premi\u00e8res et fournitures",
        "parent": 39,
        "position": 2
    },
    "4": {
        "code": 4,
        "nom": "Classe 4 \u2014 Comptes de tiers",
        "parent": 0,
        "position": 3
    },
    "40": {
        "code": 40,
        "nom": "FOURNISSEURS ET COMPTES RATTACH\u00c9S",
        "parent": 4,
        "position": 1
    },
    "401": {
        "code": 401,
        "nom": "Fournisseurs",
        "parent": 40,
        "position": 1
    },
    "4010": {
        "code": 4010,
        "nom": "Autres fournisseurs",
        "parent": 401,
        "position": 1
    },
    "408": {
        "code": 408,
        "nom": "Fournisseurs - Factures non parvenues",
        "parent": 40,
        "position": 1
    },
    "409": {
        "code": 409,
        "nom": "Avances aux fournisseurs",
        "parent": 40,
        "position": 2
    },
    "41": {
        "code": 41,
        "nom": "USAGERS ET COMPTES RATTACH\u00c9S",
        "parent": 4,
        "position": 2
    },
    "411": {
        "code": 411,
        "nom": "Usagers",
        "parent": 41,
        "position": 2
    },
    "4110": {
        "code": 4110,
        "nom": "Autres usagers",
        "parent": 411,
        "position": 2
    },
    "419": {
        "code": 419,
        "nom": "Avances aux usagers",
        "parent": 41,
        "position": 1
    },
    "42": {
        "code": 42,
        "nom": "PERSONNEL ET COMPTES RATTACH\u00c9S",
        "parent": 4,
        "position": 1
    },
    "421": {
        "code": 421,
        "nom": "Personnel - R\u00e9mun\u00e9rations dues",
        "parent": 42,
        "position": 1
    },
    "4210": {
        "code": 4210,
        "nom": "Autres membres du personnel",
        "parent": 421,
        "position": 1
    },
    "425": {
        "code": 425,
        "nom": "Personnel - Avances et acomptes",
        "parent": 42,
        "position": 2
    },
    "428": {
        "code": 428,
        "nom": "Personnel - Charges \u00e0 payer et produits \u00e0 recevoir",
        "parent": 42,
        "position": 1
    },
    "43": {
        "code": 43,
        "nom": "S\u00c9CURIT\u00c9 SOCIALE ET AUTRES ORGANISMES SOCIAUX",
        "parent": 4,
        "position": 1
    },
    "430": {
        "code": 430,
        "nom": "Dettes et cr\u00e9dits envers les organismes sociaux",
        "parent": 43,
        "position": 1
    },
    "431": {
        "code": 431,
        "nom": "S\u00e9curit\u00e9 sociale",
        "parent": 43,
        "position": 1
    },
    "437": {
        "code": 437,
        "nom": "Autres organismes sociaux",
        "parent": 43,
        "position": 1
    },
    "4372": {
        "code": 4372,
        "nom": "Mutuelles",
        "parent": 437,
        "position": 1
    },
    "4373": {
        "code": 4373,
        "nom": "Caisse de retraite et de pr\u00e9voyance",
        "parent": 437,
        "position": 1
    },
    "4374": {
        "code": 4374,
        "nom": "Caisse d'allocations de ch\u00f4mage - P\u00f4le emploi",
        "parent": 437,
        "position": 1
    },
    "4375": {
        "code": 4375,
        "nom": "AGESSA",
        "parent": 437,
        "position": 1
    },
    "4378": {
        "code": 4378,
        "nom": "Autres organismes sociaux - Divers",
        "parent": 437,
        "position": 1
    },
    "438": {
        "code": 438,
        "nom": "Organismes sociaux - Charges \u00e0 payer et produits \u00e0 recevoir",
        "parent": 43,
        "position": 1
    },
    "4382": {
        "code": 4382,
        "nom": "Charges sociales sur cong\u00e9s \u00e0 payer",
        "parent": 438,
        "position": 1
    },
    "4386": {
        "code": 4386,
        "nom": "Autres charges \u00e0 payer",
        "parent": 438,
        "position": 1
    },
    "4387": {
        "code": 4387,
        "nom": "Produits \u00e0 recevoir",
        "parent": 438,
        "position": 2
    },
    "439": {
        "code": 439,
        "nom": "Avances aupr\u00e8s des organismes sociaux",
        "parent": 43,
        "position": 1
    },
    "44": {
        "code": 44,
        "nom": "\u00c9TAT ET AUTRES COLLECTIVIT\u00c9S PUBLIQUES",
        "parent": 4,
        "position": 2
    },
    "441": {
        "code": 441,
        "nom": "\u00c9tat - Subventions \u00e0 recevoir",
        "parent": 44,
        "position": 2
    },
    "4411": {
        "code": 4411,
        "nom": "Subventions d'investissement",
        "parent": 441,
        "position": 2
    },
    "4417": {
        "code": 4417,
        "nom": "Subventions d'exploitation",
        "parent": 441,
        "position": 2
    },
    "4418": {
        "code": 4418,
        "nom": "Subventions d'\u00e9quilibre",
        "parent": 441,
        "position": 2
    },
    "4419": {
        "code": 4419,
        "nom": "Avances sur subventions",
        "parent": 441,
        "position": 2
    },
    "442": {
        "code": 442,
        "nom": "\u00c9tat - Imp\u00f4ts et taxes recouvrables sur des tiers",
        "parent": 44,
        "position": 1
    },
    "444": {
        "code": 444,
        "nom": "\u00c9tat - Imp\u00f4ts sur les b\u00e9n\u00e9fices",
        "parent": 44,
        "position": 2
    },
    "445": {
        "code": 445,
        "nom": "\u00c9tat - Taxes sur le chiffre d'affaires",
        "parent": 44,
        "position": 2
    },
    "4455": {
        "code": 4455,
        "nom": "Taxes sur le chiffre d'affaires \u00e0 d\u00e9caisser",
        "parent": 445,
        "position": 2
    },
    "44551": {
        "code": 44551,
        "nom": "TVA \u00e0 d\u00e9caisser",
        "parent": 4455,
        "position": 2
    },
    "44558": {
        "code": 44558,
        "nom": "Taxes assimil\u00e9es \u00e0 la TVA",
        "parent": 4455,
        "position": 2
    },
    "4456": {
        "code": 4456,
        "nom": "Taxes sur le chiffre d'affaires d\u00e9ductibles",
        "parent": 445,
        "position": 2
    },
    "44562": {
        "code": 44562,
        "nom": "TVA sur immobilisations",
        "parent": 4456,
        "position": 2
    },
    "44566": {
        "code": 44566,
        "nom": "TVA sur autres biens et services",
        "parent": 4456,
        "position": 2
    },
    "4457": {
        "code": 4457,
        "nom": "Taxes sur le chiffre d'affaires collect\u00e9es par l'association",
        "parent": 445,
        "position": 2
    },
    "4458": {
        "code": 4458,
        "nom": "Taxes sur le chiffre d'affaires \u00e0 r\u00e9gulariser ou en attente",
        "parent": 445,
        "position": 2
    },
    "44581": {
        "code": 44581,
        "nom": "Acomptes - R\u00e9gime simplifi\u00e9 d'imposition",
        "parent": 4458,
        "position": 2
    },
    "44582": {
        "code": 44582,
        "nom": "Acomptes - R\u00e9gime du forfait",
        "parent": 4458,
        "position": 2
    },
    "44583": {
        "code": 44583,
        "nom": "Remboursement de taxes sur le chiffre d'affaires demand\u00e9",
        "parent": 4458,
        "position": 2
    },
    "44584": {
        "code": 44584,
        "nom": "TVA r\u00e9cup\u00e9r\u00e9e d'avance",
        "parent": 4458,
        "position": 2
    },
    "44586": {
        "code": 44586,
        "nom": "Taxes sur le chiffre d'affaires sur factures non parvenues",
        "parent": 4458,
        "position": 2
    },
    "44587": {
        "code": 44587,
        "nom": "Taxes sur le chiffre d'affaires sur factures \u00e0 \u00e9tablir",
        "parent": 4458,
        "position": 2
    },
    "447": {
        "code": 447,
        "nom": "Autres imp\u00f4ts, taxes et versements assimil\u00e9s",
        "parent": 44,
        "position": 1
    },
    "4471": {
        "code": 4471,
        "nom": "Autres imp\u00f4ts, taxes et versements assimil\u00e9s sur r\u00e9mun\u00e9rations (Administration des imp\u00f4ts)",
        "parent": 447,
        "position": 1
    },
    "44711": {
        "code": 44711,
        "nom": "Taxe sur les salaires",
        "parent": 4471,
        "position": 1
    },
    "44713": {
        "code": 44713,
        "nom": "Participation des employeurs \u00e0 la formation professionnelle continue",
        "parent": 4471,
        "position": 1
    },
    "44714": {
        "code": 44714,
        "nom": "Cotisation par d\u00e9faut d'investissement obligatoire dans la construction",
        "parent": 4471,
        "position": 1
    },
    "44718": {
        "code": 44718,
        "nom": "Autres imp\u00f4ts, taxes et versements assimil\u00e9s",
        "parent": 4471,
        "position": 1
    },
    "4473": {
        "code": 4473,
        "nom": "Autres imp\u00f4ts, taxes et versements assimil\u00e9s sur r\u00e9mun\u00e9rations (Autres organismes)",
        "parent": 447,
        "position": 1
    },
    "44733": {
        "code": 44733,
        "nom": "Participation des employeurs \u00e0 la formation professionnelle continue",
        "parent": 4473,
        "position": 1
    },
    "44734": {
        "code": 44734,
        "nom": "Participation des employeurs \u00e0 l'effort de construction (versements \u00e0 fonds perdus)",
        "parent": 4473,
        "position": 1
    },
    "4475": {
        "code": 4475,
        "nom": "Autres imp\u00f4ts, taxes et versements assimil\u00e9s (Administration des imp\u00f4ts)",
        "parent": 447,
        "position": 1
    },
    "4477": {
        "code": 4477,
        "nom": "Autres imp\u00f4ts, taxes et versements assimil\u00e9s (Autres organismes)",
        "parent": 447,
        "position": 1
    },
    "448": {
        "code": 448,
        "nom": "\u00c9tat - Charges \u00e0 payer et produits \u00e0 recevoir",
        "parent": 44,
        "position": 1
    },
    "4482": {
        "code": 4482,
        "nom": "Charges fiscales sur cong\u00e9s \u00e0 payer",
        "parent": 448,
        "position": 1
    },
    "4486": {
        "code": 4486,
        "nom": "Autres charges \u00e0 payer",
        "parent": 448,
        "position": 1
    },
    "4487": {
        "code": 4487,
        "nom": "Produits \u00e0 recevoir",
        "parent": 448,
        "position": 2
    },
    "449": {
        "code": 449,
        "nom": "Avances aupr\u00e8s de l'\u00e9tat et des collectivit\u00e9s publiques",
        "parent": 44,
        "position": 1
    },
    "45": {
        "code": 45,
        "nom": "CONF\u00c9D\u00c9RATION, F\u00c9D\u00c9RATION, UNIONS ET ASSOCIATIONS AFFILI\u00c9ES",
        "parent": 4,
        "position": 3
    },
    "451": {
        "code": 451,
        "nom": "Conf\u00e9d\u00e9ration, f\u00e9d\u00e9ration et associations affili\u00e9es - Compte courant",
        "parent": 45,
        "position": 3
    },
    "455": {
        "code": 455,
        "nom": "Soci\u00e9taires - Comptes courants",
        "parent": 45,
        "position": 3
    },
    "46": {
        "code": 46,
        "nom": "D\u00c9BITEURS DIVERS ET CR\u00c9DITEURS DIVERS",
        "parent": 4,
        "position": 3
    },
    "467": {
        "code": 467,
        "nom": "Autres comptes d\u00e9biteurs et cr\u00e9diteurs",
        "parent": 46,
        "position": 3
    },
    "468": {
        "code": 468,
        "nom": "Divers - Charges \u00e0 payer et produits \u00e0 recevoir",
        "parent": 46,
        "position": 3
    },
    "4686": {
        "code": 4686,
        "nom": "Charges \u00e0 payer",
        "parent": 468,
        "position": 1
    },
    "4687": {
        "code": 4687,
        "nom": "Produits \u00e0 recevoir",
        "parent": 468,
        "position": 2
    },
    "47": {
        "code": 47,
        "nom": "COMPTES TRANSITOIRES OU D'ATTENTE",
        "parent": 4,
        "position": 3
    },
    "471": {
        "code": 471,
        "nom": "Recettes \u00e0 classer",
        "parent": 47,
        "position": 1
    },
    "472": {
        "code": 472,
        "nom": "D\u00e9penses \u00e0 classer et \u00e0 r\u00e9gulariser",
        "parent": 47,
        "position": 2
    },
    "48": {
        "code": 48,
        "nom": "COMPTES DE R\u00c9GULARISATION",
        "parent": 4,
        "position": 3
    },
    "481": {
        "code": 481,
        "nom": "Charges \u00e0 r\u00e9partir sur plusieurs exercices",
        "parent": 48,
        "position": 2
    },
    "486": {
        "code": 486,
        "nom": "Charges constat\u00e9es d'avance",
        "parent": 48,
        "position": 2
    },
    "487": {
        "code": 487,
        "nom": "Produits constat\u00e9s d'avance",
        "parent": 48,
        "position": 1
    },
    "49": {
        "code": 49,
        "nom": "DEPRECIATION DES COMPTES DE TIERS",
        "parent": 4,
        "position": 2
    },
    "491": {
        "code": 491,
        "nom": "D\u00e9pr\u00e9ciation des comptes clients",
        "parent": 49,
        "position": 2
    },
    "496": {
        "code": 496,
        "nom": "D\u00e9pr\u00e9ciation des comptes d\u00e9biteurs divers",
        "parent": 49,
        "position": 2
    },
    "5": {
        "code": 5,
        "nom": "Classe 5 \u2014 Comptes financiers",
        "parent": 0,
        "position": 2
    },
    "50": {
        "code": 50,
        "nom": "VALEURS MOBILI\u00c8RES DE PLACEMENT",
        "parent": 5,
        "position": 2
    },
    "51": {
        "code": 51,
        "nom": "BANQUES, \u00c9TABLISSEMENTS FINANCIERS ET ASSIMIL\u00c9S",
        "parent": 5,
        "position": 2
    },
    "511": {
        "code": 511,
        "nom": "Valeurs à l'encaissement",
        "parent": 51,
        "position": 2
    },
    "5112": {
        "code": 5112,
        "nom": "Chèques à encaisser",
        "parent": 511,
        "position": 2
    },
    "5115": {
        "code": 5115,
        "nom": "Paiements par carte à encaisser",
        "parent": 511,
        "position": 2
    },
    "512": {
        "code": 512,
        "nom": "Banques",
        "parent": 51,
        "position": 2
    },
    "53": {
        "code": 53,
        "nom": "CAISSE",
        "parent": 5,
        "position": 2
    },
    "530": {
        "code": 530,
        "nom": "Caisse",
        "parent": 53,
        "position": 2
    },
    "54": {
        "code": 54,
        "nom": "R\u00c9GIES D'AVANCES ET ACCR\u00c9DITIFS",
        "parent": 5,
        "position": 2
    },
    "58": {
        "code": 58,
        "nom": "VIREMENTS INTERNES",
        "parent": 5,
        "position": 2
    },
    "59": {
        "code": 59,
        "nom": "PROVISIONS POUR D\u00c9PR\u00c9CIATION DES COMPTES FINANCIERS",
        "parent": 5,
        "position": 2
    },
    "6": {
        "code": 6,
        "nom": "Classe 6 \u2014 Comptes de charges",
        "parent": 0,
        "position": 8
    },
    "60": {
        "code": 60,
        "nom": "ACHATS",
        "parent": 6,
        "position": 8
    },
    "601": {
        "code": 601,
        "nom": "Achats stock\u00e9s - Mati\u00e8res premi\u00e8res et fournitures",
        "parent": 60,
        "position": 8
    },
    "602": {
        "code": 602,
        "nom": "Achats stock\u00e9s - Autres approvisionnements",
        "parent": 60,
        "position": 8
    },
    "604": {
        "code": 604,
        "nom": "Achat d'\u00e9tudes et prestations de services",
        "parent": 60,
        "position": 8
    },
    "606": {
        "code": 606,
        "nom": "Achats non stock\u00e9s de mati\u00e8res et fournitures",
        "parent": 60,
        "position": 8
    },
    "6061": {
        "code": 6061,
        "nom": "Fournitures non stockables (eau, \u00e9nergie...)",
        "parent": 606,
        "position": 8
    },
    "6063": {
        "code": 6063,
        "nom": "Fournitures d'entretien et de petit \u00e9quipement",
        "parent": 606,
        "position": 8
    },
    "6064": {
        "code": 6064,
        "nom": "Fournitures administratives",
        "parent": 606,
        "position": 8
    },
    "6068": {
        "code": 6068,
        "nom": "Autres mati\u00e8res et fournitures",
        "parent": 606,
        "position": 8
    },
    "607": {
        "code": 607,
        "nom": "Achats de marchandises",
        "parent": 60,
        "position": 8
    },
    "61": {
        "code": 61,
        "nom": "SERVICES EXT\u00c9RIEURS",
        "parent": 6,
        "position": 8
    },
    "611": {
        "code": 611,
        "nom": "Sous-traitance g\u00e9n\u00e9rale",
        "parent": 61,
        "position": 8
    },
    "612": {
        "code": 612,
        "nom": "Redevances de cr\u00e9dit-bail",
        "parent": 61,
        "position": 8
    },
    "613": {
        "code": 613,
        "nom": "Locations",
        "parent": 61,
        "position": 8
    },
    "614": {
        "code": 614,
        "nom": "Charges locatives et de co-propri\u00e9t\u00e9",
        "parent": 61,
        "position": 8
    },
    "615": {
        "code": 615,
        "nom": "Entretiens et r\u00e9parations",
        "parent": 61,
        "position": 8
    },
    "616": {
        "code": 616,
        "nom": "Primes d'assurance",
        "parent": 61,
        "position": 8
    },
    "618": {
        "code": 618,
        "nom": "Divers",
        "parent": 61,
        "position": 8
    },
    "62": {
        "code": 62,
        "nom": "AUTRES SERVICES EXT\u00c9RIEURS",
        "parent": 6,
        "position": 8
    },
    "621": {
        "code": 621,
        "nom": "Personnel ext\u00e9rieur \u00e0 l'association",
        "parent": 62,
        "position": 8
    },
    "622": {
        "code": 622,
        "nom": "R\u00e9mun\u00e9rations d'interm\u00e9diaires et honoraires",
        "parent": 62,
        "position": 8
    },
    "6226": {
        "code": 6226,
        "nom": "Honoraires",
        "parent": 622,
        "position": 8
    },
    "6227": {
        "code": 6227,
        "nom": "Frais d'actes et de contentieux",
        "parent": 622,
        "position": 8
    },
    "6228": {
        "code": 6228,
        "nom": "Divers",
        "parent": 622,
        "position": 8
    },
    "623": {
        "code": 623,
        "nom": "Publicit\u00e9, publications, relations publiques",
        "parent": 62,
        "position": 8
    },
    "624": {
        "code": 624,
        "nom": "Transports de biens et transports collectifs du personnel",
        "parent": 62,
        "position": 8
    },
    "625": {
        "code": 625,
        "nom": "D\u00e9placements, missions et r\u00e9ceptions",
        "parent": 62,
        "position": 8
    },
    "626": {
        "code": 626,
        "nom": "Frais postaux et de t\u00e9l\u00e9communications",
        "parent": 62,
        "position": 8
    },
    "627": {
        "code": 627,
        "nom": "Services bancaires et assimil\u00e9s",
        "parent": 62,
        "position": 8
    },
    "628": {
        "code": 628,
        "nom": "Divers",
        "parent": 62,
        "position": 8
    },
    "63": {
        "code": 63,
        "nom": "IMP\u00d4TS, TAXES ET VERSEMENTS ASSIMIL\u00c9S",
        "parent": 6,
        "position": 8
    },
    "631": {
        "code": 631,
        "nom": "Imp\u00f4ts, taxes et versements assimil\u00e9s sur r\u00e9mun\u00e9rations (Administration des imp\u00f4ts)",
        "parent": 63,
        "position": 8
    },
    "6311": {
        "code": 6311,
        "nom": "Taxes sur les salaires",
        "parent": 631,
        "position": 8
    },
    "6313": {
        "code": 6313,
        "nom": "Participations des employeurs \u00e0 la formation professionnelle continue",
        "parent": 631,
        "position": 8
    },
    "635": {
        "code": 635,
        "nom": "Autres imp\u00f4ts, taxes et versements assimil\u00e9s (Administration des imp\u00f4ts)",
        "parent": 63,
        "position": 8
    },
    "6351": {
        "code": 6351,
        "nom": "Imp\u00f4ts directs (sauf imp\u00f4ts sur les b\u00e9n\u00e9fices)",
        "parent": 635,
        "position": 8
    },
    "6353": {
        "code": 6353,
        "nom": "Imp\u00f4ts indirects",
        "parent": 635,
        "position": 8
    },
    "637": {
        "code": 637,
        "nom": "Autres imp\u00f4ts, taxes et versements assimil\u00e9s (Autres organismes)",
        "parent": 63,
        "position": 8
    },
    "64": {
        "code": 64,
        "nom": "CHARGES DE PERSONNEL",
        "parent": 6,
        "position": 8
    },
    "641": {
        "code": 641,
        "nom": "R\u00e9mun\u00e9rations du personnel",
        "parent": 64,
        "position": 8
    },
    "643": {
        "code": 643,
        "nom": "R\u00e9mun\u00e9rations du personnel artistique et assimil\u00e9s",
        "parent": 64,
        "position": 8
    },
    "645": {
        "code": 645,
        "nom": "Charges de s\u00e9curit\u00e9 sociale et de pr\u00e9voyance",
        "parent": 64,
        "position": 8
    },
    "647": {
        "code": 647,
        "nom": "Autres charges sociales",
        "parent": 64,
        "position": 8
    },
    "648": {
        "code": 648,
        "nom": "Autres charges de personnel",
        "parent": 64,
        "position": 8
    },
    "65": {
        "code": 65,
        "nom": "AUTRES CHARGES DE GESTION COURANTE",
        "parent": 6,
        "position": 8
    },
    "652": {
        "code": 652,
        "nom": "Licences fédérales",
        "parent": 652,
        "position": 8
    },
    "658": {
        "code": 658,
        "nom": "Charges diverses de gestion courante",
        "parent": 65,
        "position": 8
    },
    "66": {
        "code": 66,
        "nom": "CHARGES FINANCI\u00c8RES",
        "parent": 6,
        "position": 8
    },
    "661": {
        "code": 661,
        "nom": "Charges d'int\u00e9r\u00eats",
        "parent": 66,
        "position": 8
    },
    "67": {
        "code": 67,
        "nom": "CHARGES EXCEPTIONNELLES",
        "parent": 6,
        "position": 8
    },
    "671": {
        "code": 671,
        "nom": "Charges exceptionnelles sur op\u00e9rations de gestion",
        "parent": 67,
        "position": 8
    },
    "6713": {
        "code": 6713,
        "nom": "Dons, lib\u00e9ralit\u00e9s",
        "parent": 671,
        "position": 8
    },
    "678": {
        "code": 678,
        "nom": "Autres charges exceptionnelles",
        "parent": 67,
        "position": 8
    },
    "6788": {
        "code": 6788,
        "nom": "Charges exceptionnelles diverses",
        "parent": 678,
        "position": 8
    },
    "68": {
        "code": 68,
        "nom": "DOTATIONS AUX AMORTISSEMENTS, D\u00c9PR\u00c9CIATIONS, PROVISIONS ET ENGAGEMENTS",
        "parent": 6,
        "position": 8
    },
    "681": {
        "code": 681,
        "nom": "Dotations aux amortissements, d\u00e9pr\u00e9ciations et provisions - Charges d'exploitation",
        "parent": 68,
        "position": 8
    },
    "6811": {
        "code": 6811,
        "nom": "Dotations aux amortissements des immobilisations incorporelles et corporelles",
        "parent": 681,
        "position": 8
    },
    "68111": {
        "code": 68111,
        "nom": "Immobilisations incorporelles",
        "parent": 6811,
        "position": 8
    },
    "68112": {
        "code": 68112,
        "nom": "Immobilisations corporelles",
        "parent": 6811,
        "position": 8
    },
    "686": {
        "code": 686,
        "nom": "Dotations aux amortissements, d\u00e9pr\u00e9ciations et provisions - Charges financi\u00e8res",
        "parent": 68,
        "position": 8
    },
    "69": {
        "code": 69,
        "nom": "PARTICIPATION DES SALARI\u00c9S - IMP\u00d4TS SUR LES B\u00c9N\u00c9FICES ET ASSIMIL\u00c9S",
        "parent": 6,
        "position": 8
    },
    "695": {
        "code": 695,
        "nom": "Imp\u00f4ts sur les soci\u00e9t\u00e9s (y compris imp\u00f4ts sur les soci\u00e9t\u00e9s des personnes morales non lucratives)",
        "parent": 69,
        "position": 8
    },
    "7": {
        "code": 7,
        "nom": "Classe 7 \u2014 Comptes de produits",
        "parent": 0,
        "position": 4
    },
    "70": {
        "code": 70,
        "nom": "VENTES DE PRODUITS FINIS, PRESTATIONS DE SERVICES, MARCHANDISES",
        "parent": 7,
        "position": 4
    },
    "701": {
        "code": 701,
        "nom": "Ventes de produits finis",
        "parent": 70,
        "position": 4
    },
    "706": {
        "code": 706,
        "nom": "Prestations de services",
        "parent": 70,
        "position": 4
    },
    "707": {
        "code": 707,
        "nom": "Ventes de marchandises",
        "parent": 70,
        "position": 4
    },
    "708": {
        "code": 708,
        "nom": "Produits des activit\u00e9s annexes",
        "parent": 70,
        "position": 4
    },
    "71": {
        "code": 71,
        "nom": "PRODUCTION STOCK\u00c9E (OU D\u00c9STOCKAGE)",
        "parent": 7,
        "position": 4
    },
    "72": {
        "code": 72,
        "nom": "PRODUCTION IMMOBILIS\u00c9E",
        "parent": 7,
        "position": 4
    },
    "74": {
        "code": 74,
        "nom": "SUBVENTIONS D'EXPLOITATION",
        "parent": 7,
        "position": 4
    },
    "740": {
        "code": 740,
        "nom": "Subventions re\u00e7ues",
        "parent": 74,
        "position": 4
    },
    "75": {
        "code": 75,
        "nom": "AUTRES PRODUITS DE GESTION COURANTE",
        "parent": 7,
        "position": 4
    },
    "754": {
        "code": 754,
        "nom": "Collectes",
        "parent": 75,
        "position": 4
    },
    "756": {
        "code": 756,
        "nom": "Cotisations",
        "parent": 75,
        "position": 4
    },
    "758": {
        "code": 758,
        "nom": "Produits divers de gestion courante",
        "parent": 75,
        "position": 4
    },
    "7587": {
        "code": 7587,
        "nom": "Ventes de dons en nature",
        "parent": 758,
        "position": 4
    },
    "7588": {
        "code": 7588,
        "nom": "Autres produits de la g\u00e9n\u00e9rosit\u00e9 du public",
        "parent": 758,
        "position": 4
    },
    "76": {
        "code": 76,
        "nom": "PRODUITS FINANCIERS",
        "parent": 7,
        "position": 4
    },
    "760": {
        "code": 760,
        "nom": "Produits financiers",
        "parent": 76,
        "position": 4
    },
    "77": {
        "code": 77,
        "nom": "PRODUITS EXCEPTIONNELS",
        "parent": 7,
        "position": 4
    },
    "771": {
        "code": 771,
        "nom": "Produits exceptionnels sur op\u00e9rations de gestion",
        "parent": 77,
        "position": 4
    },
    "7713": {
        "code": 7713,
        "nom": "Lib\u00e9ralit\u00e9s re\u00e7ues",
        "parent": 771,
        "position": 4
    },
    "7715": {
        "code": 7715,
        "nom": "Subventions d'\u00e9quilibre",
        "parent": 771,
        "position": 4
    },
    "775": {
        "code": 775,
        "nom": "Produits des cessions d'\u00e9l\u00e9ments d'actifs",
        "parent": 77,
        "position": 4
    },
    "778": {
        "code": 778,
        "nom": "Autres produits exceptionnels",
        "parent": 77,
        "position": 4
    },
    "7780": {
        "code": 7780,
        "nom": "Manifestations diverses",
        "parent": 778,
        "position": 4
    },
    "7788": {
        "code": 7788,
        "nom": "Produits exceptionnels divers",
        "parent": 778,
        "position": 4
    },
    "78": {
        "code": 78,
        "nom": "REPRISES SUR AMORTISSEMENTS ET PROVISIONS",
        "parent": 7,
        "position": 4
    },
    "79": {
        "code": 79,
        "nom": "TRANSFERT DE CHARGES",
        "parent": 7,
        "position": 4
    },
    "791": {
        "code": 791,
        "nom": "Transferts de charges d'exploitation",
        "parent": 79,
        "position": 4
    },
    "796": {
        "code": 796,
        "nom": "Transferts de charges financi\u00e8res",
        "parent": 79,
        "position": 4
    },
    "797": {
        "code": 797,
        "nom": "Transferts de charges exceptionnels",
        "parent": 79,
        "position": 4
    },
    "8": {
        "code": 8,
        "nom": "Classe 8 \u00ad\u2014 Comptes sp\u00e9ciaux",
        "parent": 0,
        "position": 12
    },
    "86": {
        "code": 86,
        "nom": "R\u00c9PARTITION PAR NATURE DE CHARGES",
        "parent": 8,
        "position": 8
    },
    "861": {
        "code": 861,
        "nom": "Mise \u00e0 dispositions gratuites de biens",
        "parent": 86,
        "position": 8
    },
    "862": {
        "code": 862,
        "nom": "Prestations",
        "parent": 86,
        "position": 8
    },
    "864": {
        "code": 864,
        "nom": "Personnel b\u00e9n\u00e9vole",
        "parent": 86,
        "position": 8
    },
    "87": {
        "code": 87,
        "nom": "R\u00c9PARTITION PAR NATURE DE RESSOURCES",
        "parent": 8,
        "position": 4
    },
    "870": {
        "code": 870,
        "nom": "B\u00e9n\u00e9volat",
        "parent": 87,
        "position": 4
    },
    "871": {
        "code": 871,
        "nom": "Prestations en nature",
        "parent": 87,
        "position": 4
    },
    "875": {
        "code": 875,
        "nom": "Dons en nature",
        "parent": 87,
        "position": 4
    },
    "89": {
        "code": 89,
        "nom": "BILAN",
        "parent": 8,
        "position": 3
    },
    "890": {
        "code": 890,
        "nom": "Bilan d'ouverture",
        "parent": 89,
        "position": 3
    },
    "891": {
        "code": 891,
        "nom": "Bilan de clôture",
        "parent": 89,
        "position": 3
    },
    "9": {
        "code": 9,
        "nom": "Classe 9 \u2014 Comptes analytiques",
        "parent": 0,
        "position": 12
    }
}

Modified debian/config.debian.php from [2a98e1b5ea] to [1cd45bbd87].

12
13
14
15
16
17
18




19
20
21
22
23
24
25
26
27
28
29
30

31

32
33
34
35
36
37
38
39
40
41
42
43

44
45


46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66





67


68


69
70


71
72



73
74
75

76


77
		$_ENV['XDG_CONFIG_HOME'] = $home . '/.config';
	}

	if (!file_exists($_ENV['XDG_CONFIG_HOME'] . '/garradin'))
	{
		mkdir($_ENV['XDG_CONFIG_HOME'] . '/garradin', 0700, true);
	}





	// Data directory: where the data will go
	if (empty($_ENV['XDG_DATA_HOME']))
	{
		$_ENV['XDG_DATA_HOME'] = $home . '/.local/share';
	}

	if (!file_exists($_ENV['XDG_DATA_HOME'] . '/garradin'))
	{
		mkdir($_ENV['XDG_DATA_HOME'] . '/garradin', 0700, true);
	}


	define('Garradin\DATA_ROOT', $_ENV['XDG_DATA_HOME'] . '/garradin');


	// Cache directory: temporary stuff
	if (empty($_ENV['XDG_CACHE_HOME']))
	{
		$_ENV['XDG_CACHE_HOME'] = $home . '/.cache';
	}

	if (!file_exists($_ENV['XDG_CACHE_HOME'] . '/garradin'))
	{
		mkdir($_ENV['XDG_CACHE_HOME'] . '/garradin', 0700, true);
	}


	define('Garradin\CACHE_ROOT', $_ENV['XDG_CACHE_HOME'] . '/garradin');



	$last_file = $_ENV['XDG_CONFIG_HOME'] . '/garradin/last';

	if ($_ENV['GARRADIN_STANDALONE'] != 1)
	{
		$last_sqlite = trim($_ENV['GARRADIN_STANDALONE']);
	}
	else if (file_exists($last_file))
	{
		$last_sqlite = trim(file_get_contents($last_file));
	}
	else
	{
		$last_sqlite = $_ENV['XDG_DATA_HOME'] . '/garradin/association.sqlite';
	}

	file_put_contents($last_file, $last_sqlite);

	$secret_file = $_ENV['XDG_CONFIG_HOME'] . '/garradin/secret';

	if (!file_exists($secret_file))
	{





		$random = function_exists('random_bytes') ? random_bytes(64) : mt_rand();


		$random = sha1($random . $secret_file);



		file_put_contents($secret_file, $random);


	}




	define('Garradin\SECRET_KEY', trim(file_get_contents($secret_file)));

	define('Garradin\DB_FILE', $last_sqlite);

	define('Garradin\LOCAL_LOGIN', 1);


}







>
>
>
>












>
|
>












>
|
|
>
>
|

|
|
|
|
|
|
|
|
|
|
|
|

|

|
|
<
|
>
>
>
>
>
|
>
>
|
>
>
|
|
>
>

|
>
>
>
|
|
<
>
|
>
>

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

97
98
99
100
101
		$_ENV['XDG_CONFIG_HOME'] = $home . '/.config';
	}

	if (!file_exists($_ENV['XDG_CONFIG_HOME'] . '/garradin'))
	{
		mkdir($_ENV['XDG_CONFIG_HOME'] . '/garradin', 0700, true);
	}

	if (file_exists($_ENV['XDG_CONFIG_HOME'] . '/garradin/config.local.php')) {
		require_once $_ENV['XDG_CONFIG_HOME'] . '/garradin/config.local.php';
	}

	// Data directory: where the data will go
	if (empty($_ENV['XDG_DATA_HOME']))
	{
		$_ENV['XDG_DATA_HOME'] = $home . '/.local/share';
	}

	if (!file_exists($_ENV['XDG_DATA_HOME'] . '/garradin'))
	{
		mkdir($_ENV['XDG_DATA_HOME'] . '/garradin', 0700, true);
	}

	if (!defined('Garradin\DATA_ROOT')) {
		define('Garradin\DATA_ROOT', $_ENV['XDG_DATA_HOME'] . '/garradin');
	}

	// Cache directory: temporary stuff
	if (empty($_ENV['XDG_CACHE_HOME']))
	{
		$_ENV['XDG_CACHE_HOME'] = $home . '/.cache';
	}

	if (!file_exists($_ENV['XDG_CACHE_HOME'] . '/garradin'))
	{
		mkdir($_ENV['XDG_CACHE_HOME'] . '/garradin', 0700, true);
	}

	if (!defined('Garradin\CACHE_ROOT')) {
		define('Garradin\CACHE_ROOT', $_ENV['XDG_CACHE_HOME'] . '/garradin');
	}

	if (!defined('Garradin\DB_FILE')) {
		$last_file = $_ENV['XDG_CONFIG_HOME'] . '/garradin/last';

		if ($_ENV['GARRADIN_STANDALONE'] != 1)
		{
			$last_sqlite = trim($_ENV['GARRADIN_STANDALONE']);
		}
		else if (file_exists($last_file))
		{
			$last_sqlite = trim(file_get_contents($last_file));
		}
		else
		{
			$last_sqlite = $_ENV['XDG_DATA_HOME'] . '/garradin/association.sqlite';
		}

		file_put_contents($last_file, $last_sqlite);

		define('Garradin\DB_FILE', $last_sqlite);
	}


	if (!defined('Garradin\LOCAL_LOGIN')) {
		define('Garradin\LOCAL_LOGIN', true);
	}
}
elseif (isset($_SERVER['SERVER_NAME'])) {
	if (file_exists('/etc/garradin/config.php')) {
		require_once '/etc/garradin/config.php';
	}

	if (!defined('Garradin\DATA_ROOT')) {
		define('Garradin\DATA_ROOT', '/var/lib/garradin');
	}

	if (!defined('Garradin\CACHE_ROOT')) {
		define('Garradin\CACHE_ROOT', '/var/cache/garradin');
	}
}

if (!defined('Garradin\SECRET_KEY')) {
	if (file_exists(CACHE_ROOT . '/key')) {
		define('Garradin\SECRET_KEY', trim(file_get_contents(CACHE_ROOT . '/key')));
	}

	else {
		define('Garradin\SECRET_KEY', base64_encode(random_bytes(64)));
		file_put_contents(CACHE_ROOT . '/key', SECRET_KEY);
	}
}

Modified debian/makedeb.sh from [242f467b69] to [00b4e03f70].

36
37
38
39
40
41
42
43




44
45
46
47
48
49
50
51
52

CODEDIR=${DEBLOCALPREFIX}/share/${PACKAGE_DEBNAME}
mkdir -p ${CODEDIR}
cp -r ${SRCDIR}/* ${CODEDIR}
cp ${THISDIR}/config.debian.php ${CODEDIR}/config.local.php
rm -rf ${CODEDIR}/*.sqlite ${CODEDIR}/cache ${CODEDIR}/www/squelettes
cp ${THISDIR}/garradin.png "${CODEDIR}"





# Cleaning files that will be copied to /usr/share/doc
rm -f ${CODEDIR}/{README,COPYING}

cd $DEBROOT || {
    echo "Debian dest dir [$DEBROOT] not found. :("
    exit 2
}

rm -fr DEBIAN








>
>
>
>

|







36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

CODEDIR=${DEBLOCALPREFIX}/share/${PACKAGE_DEBNAME}
mkdir -p ${CODEDIR}
cp -r ${SRCDIR}/* ${CODEDIR}
cp ${THISDIR}/config.debian.php ${CODEDIR}/config.local.php
rm -rf ${CODEDIR}/*.sqlite ${CODEDIR}/cache ${CODEDIR}/www/squelettes
cp ${THISDIR}/garradin.png "${CODEDIR}"

mkdir -p "${DEBROOT}/var/lib/${PACKAGE_DEBNAME}"
mkdir -p "${DEBROOT}/var/cache/${PACKAGE_DEBNAME}"
mkdir -p "${DEBROOT}/etc/${PACKAGE_DEBNAME}"

# Cleaning files that will be copied to /usr/share/doc
#rm -f ${CODEDIR}/../{README.md,COPYING}

cd $DEBROOT || {
    echo "Debian dest dir [$DEBROOT] not found. :("
    exit 2
}

rm -fr DEBIAN
60
61
62
63
64
65
66
67
68
69
70














71
72
73
74
75
76
77
echo "Creating .deb package [${DEBFILE}]..."

echo "Generating md5 sums..."
find ${DEBLOCALPREFIX} -type f -exec md5sum {} \; > DEBIAN/md5sums

true && {
    echo "Generating Debian-specific files..."
    cp ${SRCDIR}/COPYING ${DEBLOCALPREFIX}/share/doc/${PACKAGE_DEBNAME}/copyright
} || {
	echo "Fail."
	exit 1














}

true && {
    CHANGELOG=${DEBLOCALPREFIX}/share/doc/${PACKAGE_DEBNAME}/changelog.gz
    cat <<EOF | gzip -c > ${CHANGELOG}
${PACKAGE_DEBNAME} ${PACKAGE_DEB_VERSION}; urgency=low








|



>
>
>
>
>
>
>
>
>
>
>
>
>
>







64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
echo "Creating .deb package [${DEBFILE}]..."

echo "Generating md5 sums..."
find ${DEBLOCALPREFIX} -type f -exec md5sum {} \; > DEBIAN/md5sums

true && {
    echo "Generating Debian-specific files..."
    cp ${THISDIR}/../COPYING ${DEBLOCALPREFIX}/share/doc/${PACKAGE_DEBNAME}/copyright
} || {
	echo "Fail."
	exit 1
}

true && {
    cat <<EOF > DEBIAN/postinst
#!/bin/sh

chown www-data:www-data /var/lib/garradin /var/cache/garradin
chown root:www-data /etc/garradin
chmod g=rX,o= /etc/garradin
chmod ug=rwX,o= /var/lib/garradin /var/cache/garradin
EOF

    chmod +x DEBIAN/postinst

}

true && {
    CHANGELOG=${DEBLOCALPREFIX}/share/doc/${PACKAGE_DEBNAME}/changelog.gz
    cat <<EOF | gzip -c > ${CHANGELOG}
${PACKAGE_DEBNAME} ${PACKAGE_DEB_VERSION}; urgency=low

86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
}

# doc.
DOCDIR=${DEBLOCALPREFIX}/share/doc/${PACKAGE_DEBNAME}

true && {
    echo "Generating doc..."
    cp ${SRCDIR}/README ${DOCDIR}
    a2x --doctype manpage --format manpage ${THISDIR}/manpage.txt
    mkdir -p ${DEBLOCALPREFIX}/share/man/man1
    gzip -c ${THISDIR}/garradin.1 > ${DEBLOCALPREFIX}/share/man/man1/${PACKAGE_DEBNAME}.1.gz
    rm -f ${THISDIR}/garradin.1
} || {
    echo "Fail."
    exit 1
}

true && {
    CONTROL=DEBIAN/control
    echo "Generating ${CONTROL}..."
    cat <<EOF > ${CONTROL}
Package: ${PACKAGE_DEBNAME}
Section: web
Priority: optional
Maintainer: Garradin <garradin@kd2.org>
Architecture: ${DEB_ARCH_NAME}
Depends: dash | bash, php5-cli (>=5.6) | php-cli (>=7.0), php5-sqlite | php-sqlite3
Version: ${PACKAGE_DEB_VERSION}
Suggests: www-browser, php-gd
Homepage: http://dev.kd2.org/garradin/
Description: Garradin is a tool to manage non-profit organizations.
 It's only available in french.
Description-fr: Gestionnaire d'association en interface web ou CLI.
 Garradin est un gestionnaire d'association à but non lucratif.







|


















|







104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
}

# doc.
DOCDIR=${DEBLOCALPREFIX}/share/doc/${PACKAGE_DEBNAME}

true && {
    echo "Generating doc..."
    cp ${THISDIR}/../README.md ${DOCDIR}
    a2x --doctype manpage --format manpage ${THISDIR}/manpage.txt
    mkdir -p ${DEBLOCALPREFIX}/share/man/man1
    gzip -c ${THISDIR}/garradin.1 > ${DEBLOCALPREFIX}/share/man/man1/${PACKAGE_DEBNAME}.1.gz
    rm -f ${THISDIR}/garradin.1
} || {
    echo "Fail."
    exit 1
}

true && {
    CONTROL=DEBIAN/control
    echo "Generating ${CONTROL}..."
    cat <<EOF > ${CONTROL}
Package: ${PACKAGE_DEBNAME}
Section: web
Priority: optional
Maintainer: Garradin <garradin@kd2.org>
Architecture: ${DEB_ARCH_NAME}
Depends: dash | bash, php-cli (>=7.2), php-sqlite3
Version: ${PACKAGE_DEB_VERSION}
Suggests: www-browser, php-gd
Homepage: http://dev.kd2.org/garradin/
Description: Garradin is a tool to manage non-profit organizations.
 It's only available in french.
Description-fr: Gestionnaire d'association en interface web ou CLI.
 Garradin est un gestionnaire d'association à but non lucratif.

Added doc/dev/odoo_accounts.sql version [6c994995cd].















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
-- Schéma Odoo (PgSQL) pour info sur la compta
-- Pour les écritures, deux tables : move et move_line
-- Utilisation de deux colonnes "debit" et "credit"

-- https://github.com/odoo/odoo/blob/11.0/addons/account/data/data_account_type.xml
-- https://www.odoo.com/documentation/11.0/webservices/localization.html
CREATE TABLE public.account_account_type (
    id integer NOT NULL,
    name character varying NOT NULL,
    include_initial_balance boolean,
    type character varying NOT NULL,
    note text,
    create_uid integer,
    create_date timestamp without time zone,
    write_uid integer,
    write_date timestamp without time zone
);

COPY public.account_account_type (id, name, include_initial_balance, type, note, create_uid, create_date, write_uid, write_date) FROM stdin;
1	Receivable	t	receivable	\N	1	2019-02-14 15:05:35.697512	1	2019-02-14 15:05:35.697512
2	Payable	t	payable	\N	1	2019-02-14 15:05:35.697512	1	2019-02-14 15:05:35.697512
3	Bank and Cash	t	liquidity	\N	1	2019-02-14 15:05:35.697512	1	2019-02-14 15:05:35.697512
4	Credit Card	t	liquidity	\N	1	2019-02-14 15:05:35.697512	1	2019-02-14 15:05:35.697512
5	Current Assets	t	other	\N	1	2019-02-14 15:05:35.697512	1	2019-02-14 15:05:35.697512
6	Non-current Assets	t	other	\N	1	2019-02-14 15:05:35.697512	1	2019-02-14 15:05:35.697512
7	Prepayments	t	other	\N	1	2019-02-14 15:05:35.697512	1	2019-02-14 15:05:35.697512
8	Fixed Assets	t	other	\N	1	2019-02-14 15:05:35.697512	1	2019-02-14 15:05:35.697512
9	Current Liabilities	t	other	\N	1	2019-02-14 15:05:35.697512	1	2019-02-14 15:05:35.697512
10	Non-current Liabilities	t	other	\N	1	2019-02-14 15:05:35.697512	1	2019-02-14 15:05:35.697512
11	Equity	t	other	\N	1	2019-02-14 15:05:35.697512	1	2019-02-14 15:05:35.697512
12	Current Year Earnings	t	other	\N	1	2019-02-14 15:05:35.697512	1	2019-02-14 15:05:35.697512
13	Other Income	f	other	\N	1	2019-02-14 15:05:35.697512	1	2019-02-14 15:05:35.697512
14	Income	f	other	\N	1	2019-02-14 15:05:35.697512	1	2019-02-14 15:05:35.697512
15	Depreciation	f	other	\N	1	2019-02-14 15:05:35.697512	1	2019-02-14 15:05:35.697512
16	Expenses	f	other	\N	1	2019-02-14 15:05:35.697512	1	2019-02-14 15:05:35.697512
17	Cost of Revenue	f	other	\N	1	2019-02-14 15:05:35.697512	1	2019-02-14 15:05:35.697512
\.


COPY public.account_account (id, name, currency_id, code, deprecated, user_type_id, internal_type, last_time_entries_checked, reconcile, note, company_id, group_id, create_uid, create_date, write_uid, write_date) FROM stdin;
1	Virements Internes	\N	580000	f	5	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
2	Capital souscrit - non appelé	\N	101100	f	11	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
3	Capital souscrit - appelé non versé	\N	101200	f	11	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
4	Capital non amorti	\N	101310	f	11	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
5	Capital amorti	\N	101320	f	11	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
6	Capital souscrit soumis à des réglementations particulières	\N	101800	f	11	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
7	Primes d'émission	\N	104100	f	11	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
8	Primes de fusion	\N	104200	f	11	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
10	Primes de conversion d'obligations en actions	\N	104400	f	11	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
11	Bons de souscription d'actions	\N	104500	f	11	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
12	Réserve spéciale de réévaluation	\N	105100	f	11	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
13	Écart de réévaluation libre	\N	105200	f	11	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
15	Écarts de réévaluation (autres opérations légales)	\N	105500	f	11	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
16	Autres écarts de réévaluation en France	\N	105700	f	11	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
17	Autres écarts de réévaluation à l'étranger	\N	105800	f	11	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
18	Réserve légale proprement dite	\N	106110	f	11	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
19	Plus-values nettes à long terme	\N	106120	f	11	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
20	Réserves indisponibles	\N	106200	f	11	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
22	Plus-values nettes à long terme	\N	106410	f	11	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
23	Réserves consécutives à l'octroi de subventions d'investissement	\N	106430	f	11	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
24	Autres réserves réglementées	\N	106480	f	11	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
25	Réserve de propre assureur	\N	106810	f	11	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
26	Réserves diverses	\N	106880	f	11	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
27	Écarts d'équivalence	\N	107000	f	11	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
28	Compte de l'exploitant	\N	108000	f	11	other	\N	f	Capital pour une Entreprise Individuelle	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
29	Actionnaires : capital souscrit - non appelé	\N	109000	f	11	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
31	Report à nouveau (solde débiteur)	\N	119000	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
30	Report à nouveau (solde créditeur)	\N	110000	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
9	Primes d'apport	\N	104300	f	11	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
14	Réserve de réévaluation	\N	105300	f	11	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
21	Réserves statutaires ou contractuelles	\N	106300	f	11	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
32	Résultat de l'exercice (bénéfice)	\N	120000	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
33	Résultat de l'exercice (perte)	\N	129000	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
34	Subventions d'équipement - État	\N	131100	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
35	Subventions d'équipement - Régions	\N	131200	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
37	Subventions d'équipement - Communes	\N	131400	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
38	Subventions d'équipement - Collectivités publiques	\N	131500	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
39	Subventions d'équipement - Entreprises publiques	\N	131600	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
40	Subventions d'équipement - Entreprises et organismes privés	\N	131700	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
41	Subventions d'équipement - Autres	\N	131800	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
42	Autres subventions d'investissement (même ventilation que celle du compte 131)	\N	138000	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
43	Subventions d'équipement inscrites au compte de résultat - État	\N	139110	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
44	Subventions d'équipement inscrites au compte de résultat - Régions	\N	139120	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
45	Subventions d'équipement inscrites au compte de résultat - Départements	\N	139130	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
46	Subventions d'équipement inscrites au compte de résultat - Communes	\N	139140	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
47	Subventions d'équipement inscrites au compte de résultat - Collectivités publiques	\N	139150	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
48	Subventions d'équipement inscrites au compte de résultat - Entreprises publiques	\N	139160	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
49	Subventions d'équipement inscrites au compte de résultat - Entreprises et organismes privés	\N	139170	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
50	Subventions d'équipement inscrites au compte de résultat - Autres	\N	139180	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
51	Autres subventions d'investissement (même ventilation que celle du compte 1391)	\N	139800	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
53	Provisions pour investissement (participation des salariés)	\N	142400	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
54	Provisions réglementées relatives aux stocks - Hausse de prix	\N	143100	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
55	Provisions réglementées relatives aux stocks - Fluctuation des cours	\N	143200	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
56	Provisions réglementées relatives aux autres éléments de l'actif	\N	144000	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
57	Amortissements dérogatoires	\N	145000	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
58	Provision spéciale de réévaluation	\N	146000	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
36	Subventions d'équipement - Départements	\N	131300	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
52	Provisions reconstitution des gisements miniers et pétroliers	\N	142300	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
719	Bla bla	\N	512002	f	3	liquidity	\N	f	\N	1	\N	1	2019-02-14 15:11:18.063543	1	2019-02-14 15:11:18.063543
59	Plus-values réinvesties	\N	147000	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
60	Autres provisions réglementées	\N	148000	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
61	Provisions pour litiges	\N	151100	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
62	Provisions pour garanties données aux clients	\N	151200	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
64	Provisions pour amendes et pénalités	\N	151400	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
65	Provisions pour pertes de change	\N	151500	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
66	Provisions pour pertes sur contrats	\N	151600	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
67	Autres provisions pour risques	\N	151800	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
69	Provisions pour restructurations	\N	154000	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
70	Provisions pour impôts	\N	155000	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
71	Provisions pour renouvellement des immobilisations (entreprises concessionnaires)	\N	156000	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
72	Provisions pour charges à répartir sur plusieurs exercices - Gros entretien ou grandes révisions	\N	157200	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
73	Provisions pour remises en état	\N	158100	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
76	Emprunts auprès des établissements de crédit	\N	164000	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
77	Dépôts	\N	165100	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
78	Cautionnements	\N	165500	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
79	Participation des salariés aux résultats - Comptes bloqués	\N	166100	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
80	Participation des salariés aux résultats - Fonds de participation	\N	166200	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
81	Emprunts et dettes assortis de conditions particulières - Emissions de titres participatifs	\N	167100	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
82	Emprunts et dettes assortis de conditions particulières - Avances conditionnées de l'État	\N	167400	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
83	Emprunts et dettes assortis de conditions particulières - Emprunts participatifs	\N	167500	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
84	Autres emprunts et dettes assimilées - Autres emprunts	\N	168100	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
85	Autres emprunts et dettes assimilées - Rentes viagères capitalisées	\N	168500	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
86	Autres emprunts et dettes assimilées - Autres dettes	\N	168700	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
74	Emprunts obligataires convertibles	\N	161000	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
63	Provisions pour pertes sur marchés à terme	\N	151300	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
68	Provisions pour pensions et obligations similaires	\N	153000	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
75	Autres emprunts obligataires	\N	163000	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
87	Intérêts courus sur emprunts obligataires convertibles	\N	168810	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
88	Intérêts courus sur autres emprunts obligataires	\N	168830	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
89	Intérêts courus sur emprunts auprès des établissements de crédit	\N	168840	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
90	Intérêts courus sur dépôts et cautionnements reçus	\N	168850	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
91	Intérêts courus sur participation des salariés aux résultats	\N	168860	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
92	Intérêts courus sur emprunts et dettes assortis de conditions particulières	\N	168870	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
93	Intérêts courus sur autres emprunts et dettes assimilées	\N	168880	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
94	Primes de remboursement des obligations	\N	169000	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
96	Dettes rattachées à des participations (hors groupe)	\N	174000	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
97	Dettes rattachées à des sociétés en participation - Principal	\N	178100	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
98	Dettes rattachées à des sociétés en participation - Intérêts courus	\N	178800	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
100	Biens et prestations de services échangés entre établissements (charges)	\N	186000	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
101	Biens et prestations de services échangés entre établissements (produits)	\N	187000	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
102	Comptes de liaison des sociétés en participation	\N	188000	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
103	Immobilisations incorporelles - Frais d'établissement - Frais de constitution	\N	201100	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
104	Immobilisations incorporelles - Frais d'établissement - Frais de prospection	\N	201210	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
105	Immobilisations incorporelles - Frais d'établissement - Frais de publicité	\N	201220	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
108	Immobilisations incorporelles - Concessions et droits similaires, brevets, licences, marques, procédés, logiciels, droits et valeurs similaires	\N	205000	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
109	Immobilisations incorporelles - Droit au bail	\N	206000	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
110	Immobilisations incorporelles - Fonds commercial	\N	207000	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
111	Autres immobilisations incorporelles	\N	208000	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
95	Dettes rattachées à des participations (groupe)	\N	171000	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
237	Études en cours E 1	\N	341100	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
99	Comptes de liaison des établissements	\N	181000	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
106	Immobilisations incorporelles - Frais d'augmentation de capital et d'opérations diverses (fusions, scissions, transformations)	\N	201300	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
107	Immobilisations incorporelles - Frais de recherche et de développement	\N	203000	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
112	Immobilisations corporelles - Terrains nus	\N	211100	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
113	Immobilisations corporelles - Terrains aménagés	\N	211200	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
115	Immobilisations corporelles - Carrières	\N	211410	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
116	Immobilisations corporelles - Terrains bâtis - Ensembles immobiliers industriels	\N	211510	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
117	Immobilisations corporelles - Terrains bâtis - Ensembles immobiliers administratifs et commerciaux	\N	211550	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
118	Immobilisations corporelles - Terrains bâtis affectés aux opérations professionnelles	\N	211581	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
119	Immobilisations corporelles - Terrains bâtis affectés aux opérations non professionnelles	\N	211588	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
120	Immobilisations corporelles - Compte d'ordre sur immobilisations	\N	211600	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
121	Immobilisations corporelles - Agencements et aménagements de terrains (même ventilation que celle du compte 211)	\N	212000	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
122	Immobilisations corporelles - Bâtiments - Ensembles immobiliers industriels	\N	213110	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
123	Immobilisations corporelles - Bâtiments - Ensembles immobiliers administratifs et commerciaux	\N	213150	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
124	Immobilisations corporelles - Bâtiments affectés aux opérations professionnelles	\N	213181	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
125	Immobilisations corporelles - Bâtiments affectés aux opérations non professionnelles	\N	213188	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
126	Immobilisations corporelles - Installations générales, agencements, aménagements des constructions (même ventilation que celle du compte 2131)	\N	213500	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
127	Immobilisations corporelles - Ouvrages d'infrastructure - Voies de terre	\N	213810	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
128	Immobilisations corporelles - Ouvrages d'infrastructure - Voies de fer	\N	213820	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
129	Immobilisations corporelles - Ouvrages d'infrastructure - Voies d'eau	\N	213830	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
130	Immobilisations corporelles - Ouvrages d'infrastructure - Barrages	\N	213840	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
131	Immobilisations corporelles - Ouvrages d'infrastructure - Pistes d'aérodromes	\N	213850	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
132	Immobilisations corporelles - Constructions sur sol d'autrui (même ventilation que celle du compte 213)	\N	214000	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
133	Immobilisations corporelles - Installations complexes spécialisées sur sol propre	\N	215110	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
134	Immobilisations corporelles - Installations complexes spécialisées sur sol d'autrui	\N	215140	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
114	Immobilisations corporelles - Sous-sols et sur-sols	\N	211300	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
135	Immobilisations corporelles - Installations à caractère spécifique sur sol propre	\N	215310	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
136	Immobilisations corporelles - Installations à caractère spécifique sur sol d'autrui	\N	215340	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
137	Immobilisations corporelles - Matériels industriels	\N	215400	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
138	Immobilisations corporelles - Outillage industriel	\N	215500	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
139	Immobilisations corporelles - Agencements et aménagements des matériels et outillage industriels	\N	215700	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
140	Immobilisations corporelles - Installations générales agencements aménagements divers	\N	218100	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
141	Immobilisations corporelles - Matériel de transport	\N	218200	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
143	Immobilisations corporelles - Mobilier	\N	218400	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
144	Immobilisations corporelles - Cheptel	\N	218500	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
145	Immobilisations corporelles - Emballages récupérables	\N	218600	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
146	Immobilisations mises en concession	\N	220000	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
147	Immobilisations corporelles en cours - Terrains	\N	231200	f	5	other	\N	f	Pas d'amortissement sur les terrains	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
149	Immobilisations corporelles en cours - Installations techniques matériel et outillage industriels	\N	231500	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
150	Autres immobilisations corporelles en cours	\N	231800	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
151	Immobilisations incorporelles en cours	\N	232000	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
152	Avances et acomptes versés sur commandes d'immobilisations incorporelles	\N	237000	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
153	Avances et acomptes versés sur commandes d'immobilisations corporelles - Terrains	\N	238200	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
155	Avances et acomptes versés sur commandes d'immobilisations corporelles - Installations techniques matériel et outillage industriels	\N	238500	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
156	Avances et acomptes versés sur commandes d'immobilisations corporelles - Autres immobilisations corporelles	\N	238800	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
157	Parts dans des entreprises liées et créances sur des entreprises liées	\N	250000	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
158	Titres de participation - Actions	\N	261100	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
159	Autres titres de participation	\N	261800	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
142	Immobilisations corporelles - Matériel de bureau et matériel informatique	\N	218300	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
148	Immobilisations corporelles en cours - Constructions	\N	231300	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
154	Avances et acomptes versés sur commandes d'immobilisations corporelles - Constructions	\N	238300	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
160	Titres évalués par équivalence	\N	262000	f	5	other	\N	f	Pas d'amortissement sur les titres évalués par équivalence	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
161	Autres formes de participation	\N	266000	f	5	other	\N	f	Pas d'amortissement sur les titres évalués par équivalence	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
162	Créances rattachées à des participations (groupe)	\N	267100	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
163	Créances rattachées à des participations (hors groupe)	\N	267400	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
164	Versements représentatifs d'apports non capitalisés (appel de fonds)	\N	267500	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
166	Autres créances rattachées à des participations	\N	267700	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
167	Créances rattachées à des participations - Intérêts courus	\N	267800	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
168	Créances rattachées à des sociétés en participation - Principal	\N	268100	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
169	Créances rattachées à des sociétés en participation - Intérêts courus	\N	268800	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
170	Versements restant à effectuer sur titres de participation non libérés	\N	269000	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
171	Titres immobilisés autres que les titres immobilisés de l'activité de portefeuille - Actions	\N	271100	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
172	Titres immobilisés autres que les titres immobilisés de l'activité de portefeuille - Autres titres	\N	271800	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
173	Titres immobilisés - Obligations	\N	272100	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
174	Titres immobilisés - Bons	\N	272200	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
176	Prêts participatifs	\N	274100	f	5	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
177	Prêts aux associés	\N	274200	f	5	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
179	Autres prêts	\N	274800	f	5	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
180	Dépôts	\N	275100	f	5	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
181	Cautionnements	\N	275500	f	5	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
182	Autres créances immobilisées - Créances diverses	\N	276100	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
183	Autres créances immobilisées - Intérêts courus sur titres immobilisés (droits de créance)	\N	276820	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
184	Autres créances immobilisées - Intérêts courus sur prêts	\N	276840	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
185	Autres créances immobilisées - Intérêts courus sur dépôts et cautionnements	\N	276850	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
186	Autres créances immobilisées - Intérêts courus sur créances diverses	\N	276880	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
187	Actions propres ou parts propres	\N	277100	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
175	Titres immobilisés de l'activité de portefeuille	\N	273000	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
178	Prêts au personnel	\N	274300	f	5	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
165	Avances consolidables	\N	267600	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
188	Actions propres ou parts propres en voie d'annulation	\N	277200	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
189	Versements restant à effectuer sur titres immobilisés non libérés	\N	279000	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
190	Amortissements des immobilisations incorporelles - Frais d'établissement (même ventilation que celle du compte 201)	\N	280100	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
192	Amortissements des immobilisations incorporelles - Concessions et droits similaires, brevets, licences, logiciels, droits et valeurs similaires	\N	280500	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
193	Amortissements des immobilisations incorporelles - Fonds commercial	\N	280700	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
194	Amortissements des autres immobilisations incorporelles	\N	280800	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
195	Amortissements des immobilisations corporelles - Terrains de gisement	\N	281100	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
196	Amortissements des immobilisations corporelles - Agencements aménagements de terrains (même ventilation que celle du compte 212)	\N	281200	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
198	Amortissements des immobilisations corporelles - Constructions sur sol d'autrui (même ventilation que celle du compte 214)	\N	281400	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
199	Amortissements des immobilisations corporelles - Installations matériel et outillage industriels (même ventilation que celle du compte 215)	\N	281500	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
200	Amortissements des autres immobilisations corporelles (même ventilation que celle du compte 218)	\N	281800	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
201	Amortissements des immobilisations mises en concession	\N	282000	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
202	Dépréciations des immobilisations incorporelles - Marques, procédés, droits et valeurs similaires	\N	290500	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
203	Dépréciations des immobilisations incorporelles - Droit au bail	\N	290600	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
204	Dépréciations des immobilisations incorporelles - Fonds commercial	\N	290700	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
205	Dépréciations des autres immobilisations incorporelles	\N	290800	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
206	Dépréciations des immobilisations corporelles - Terrains (autres que terrains de gisement)	\N	291100	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
207	Dépréciations des immobilisations mises en concession	\N	292000	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
208	Dépréciations des immobilisations corporelles en cours	\N	293100	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
209	Dépréciations des immobilisations incorporelles en cours	\N	293200	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
191	Amortissements des immobilisations incorporelles - Frais de recherche et de développement	\N	280300	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
197	Amortissements des immobilisations corporelles - Constructions (même ventilation que celle du compte 213)	\N	281300	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
210	Provisions pour dépréciation des titres de participation	\N	296100	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
211	Provisions pour dépréciation des autres formes de participation	\N	296600	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
212	Provisions pour dépréciation des créances rattachées à des participations (même ventilation que celle du compte 267)	\N	296700	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
213	Provisions pour dépréciation des créances rattachées à des sociétés en participation (même ventilation que celle du compte 268)	\N	296800	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
214	Provisions pour dépréciation des titres immobilisés autres que les titres immobilisés de l'activité de portefeuille - droit de propriété (ventilation : 271)	\N	297100	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
215	Provisions pour dépréciation des titres immobilisés - droit de créance (même ventilation que celle du compte 272)	\N	297200	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
217	Provisions pour dépréciation des prêts (même ventilation que celle du compte 274)	\N	297400	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
218	Provisions pour dépréciation des dépôts et cautionnements versés (même ventilation que celle du compte 275)	\N	297500	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
221	Matières premières (ou groupe) B	\N	312000	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
222	Fournitures A, B, C, ..	\N	317000	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
223	Matières consommables (ou groupe) C	\N	321100	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
224	Matières consommables (ou groupe) D	\N	321200	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
225	Combustibles	\N	322100	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
226	Produits d'entretien	\N	322200	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
228	Fournitures de magasin	\N	322400	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
229	Fournitures de bureau	\N	322500	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
230	Emballages perdus	\N	326100	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
231	Emballages récupérables non identifiables	\N	326500	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
232	Emballages à usage mixte	\N	326700	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
233	Produit en cours P 1	\N	331100	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
234	Produit en cours P 2	\N	331200	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
235	Travaux en cours T 1	\N	335100	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
236	Travaux en cours T 2	\N	335200	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
220	Matières premières (ou groupe) A	\N	311000	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
216	Provisions pour dépréciation des titres immobilisés de l'activité de portefeuille	\N	297300	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
227	Fournitures d'atelier et d usine	\N	322300	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
219	Provisions pour dépréciation des autres créances immobilisées (même ventilation que celle du compte 276)	\N	297600	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
238	Études en cours E 2	\N	341200	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
239	Prestations de services en cours S 1	\N	345100	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
240	Prestations de services en cours S 2	\N	345200	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
241	Stocks produits intermédiaires (ou groupe) A	\N	351100	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
242	Stocks produits intermédiaires (ou groupe) B	\N	351200	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
243	Stocks produits finis (ou groupe) A	\N	355100	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
244	Stocks produits finis (ou groupe) B	\N	355200	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
245	Stocks produits résiduels - Déchets	\N	358100	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
246	Stocks produits résiduels - Rebuts	\N	358500	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
247	Stocks produits résiduels - Matières de récupération	\N	358600	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
248	Stocks provenant d'immobilisations	\N	360000	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
250	Stocks de marchandises (ou groupe) B	\N	372000	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
251	Stocks en voie d'acheminement	\N	380000	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
252	Provisions pour dépréciation des matières premières (ou groupe) A	\N	391100	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
253	Provisions pour dépréciation des matières premières (ou groupe) B	\N	391200	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
254	Provisions pour dépréciation des fournitures A, B, C, ..	\N	391700	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
255	Provisions pour dépréciation des matières consommables (même ventilation que celle du compte 321)	\N	392100	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
256	Provisions pour dépréciation des fournitures consommables (même ventilation que celle du compte 322)	\N	392200	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
257	Provisions pour dépréciation des emballages (même ventilation que celle du compte 326)	\N	392600	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
258	Provisions pour dépréciation des produits en cours (même ventilation que celle du compte 331)	\N	393100	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
259	Provisions pour dépréciation des travaux en cours (même ventilation que celle du compte 335)	\N	393500	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
260	Provisions pour dépréciation des études en cours (même ventilation que celle du compte 341)	\N	394100	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
261	Provisions pour dépréciation des prestations de services en cours (même ventilation que celle du compte 345)	\N	394500	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
262	Provisions pour dépréciation des produits intermédiaires (même ventilation que celle du compte 351)	\N	395100	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
263	Provisions pour dépréciation des produits finis (même ventilation que celle du compte 355)	\N	395500	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
249	Stocks de marchandises (ou groupe) A	\N	371000	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
264	Provisions pour dépréciation des stocks de marchandises (ou groupe) A	\N	397100	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
265	Provisions pour dépréciation des stocks de marchandises (ou groupe) B	\N	397200	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
266	Fournisseurs et comptes rattachés	\N	400000	f	2	payable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
267	Fournisseurs - Achats de biens et prestations de services	\N	401100	f	2	payable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
268	Fournisseurs - Retenues de garantie	\N	401700	f	2	payable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
270	Fournisseurs - Achats d'immobilisations	\N	404100	f	2	payable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
271	Fournisseurs d'immobilisations - Retenues de garantie	\N	404700	f	2	payable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
272	Fournisseurs d'immobilisations - Effets à payer	\N	405000	f	2	payable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
273	Factures non parvenues - Fournisseurs	\N	408100	f	2	payable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
274	Factures non parvenues - Fournisseurs d'immobilisations	\N	408400	f	2	payable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
275	Factures non parvenues - Fournisseurs - Intérêts courus	\N	408800	f	2	payable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
276	Fournisseurs débiteurs - Créances pour emballages et matériel à rendre	\N	409600	f	5	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
277	Fournisseurs débiteurs - Autres avoirs des fournisseurs d'exploitation	\N	409710	f	5	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
278	Fournisseurs débiteurs - Autres avoirs des fournisseurs d'immobilisations	\N	409740	f	5	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
279	Fournisseurs débiteurs - Rabais, remises, ristournes à obtenir et autres avoirs non encore reçus	\N	409800	f	5	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
281	Clients - Ventes de biens ou de prestations de services	\N	411100	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
282	Clients - Retenues de garantie	\N	411700	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
284	Clients douteux ou litigieux	\N	416000	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
285	Clients - Factures à établir	\N	418100	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
286	Clients - Intérêts courus non encore facturés	\N	418800	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
287	Clients créditeurs - Avances et acomptes reçus sur commandes	\N	419100	f	5	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
288	Clients créditeurs - Dettes pour emballages et matériels consignés	\N	419600	f	5	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
289	Clients créditeurs - Autres avoirs	\N	419700	f	5	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
290	Clients créditeurs - Rabais, remises, ristournes à accorder et autres avoirs à établir	\N	419800	f	5	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
280	Clients et comptes rattachés	\N	410000	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
269	Fournisseurs - Effets à payer	\N	403000	f	2	payable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
283	Clients - Effets à recevoir	\N	413000	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
292	Comités d'entreprise, d'établissement	\N	422000	f	9	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
293	Participation des salariés aux résultats - Réserve spéciale	\N	424600	f	9	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
294	Participation des salariés aux résultats - Comptes courants	\N	424800	f	9	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
295	Personnel - Avances et acomptes	\N	425000	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
296	Personnel - Dépôts	\N	426000	f	9	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
297	Personnel - Oppositions	\N	427000	f	9	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
298	Personnel - Dettes provisionnées pour congés à payer	\N	428200	f	9	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
299	Personnel - Dettes provisionnées pour participation des salariés aux résultats	\N	428400	f	9	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
300	Personnel - Autres charges à payer	\N	428600	f	9	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
301	Personnel - Produits à recevoir	\N	428700	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
303	Autres organismes sociaux	\N	437000	f	9	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
304	Charges sociales sur congés à payer	\N	438200	f	9	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
305	Organismes sociaux - Autres charges à payer	\N	438600	f	9	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
306	Organismes sociaux - Produits à recevoir	\N	438700	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
307	État - Subventions à recevoir - Subventions d'investissement	\N	441100	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
308	État - Subventions à recevoir - Subventions d'exploitation	\N	441700	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
309	État - Subventions à recevoir - Subventions d'équilibre	\N	441800	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
310	État - Subventions à recevoir - Avances sur subventions	\N	441900	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
311	État - Impôts et taxes recouvrables sur des tiers - Obligataires	\N	442400	f	5	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
312	État - Impôts et taxes recouvrables sur des tiers - Associés	\N	442500	f	5	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
313	Créances sur l'État résultant de la suppression de la règle du décalage d'un mois en matière de TVA	\N	443100	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
314	État - Intérêts courus sur créances figurant au compte 4431	\N	443800	f	5	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
315	État - Impôts sur les bénéfices	\N	444000	f	9	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
316	TVA due intracommunautaire (Taux Normal)	\N	445201	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
317	TVA due intracommunautaire (Taux Intermédiaire)	\N	445202	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
318	TVA due intracommunautaire (Autre taux)	\N	445203	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
319	TVA due imports	\N	445204	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
291	Personnel - Rémunérations dues	\N	421000	f	2	payable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
302	Sécurité Sociale	\N	431000	f	9	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
320	TVA à décaisser	\N	445510	f	9	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
321	Taxes assimilées à la TVA	\N	445580	f	9	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
322	TVA déductible sur immobilisations	\N	445620	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
323	TVA déductible transférée par d'autres entreprises	\N	445630	f	5	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
324	TVA déductible sur autres biens et services	\N	445660	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
325	TVA déductible intracommunautaire	\N	445662	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
326	TVA déductible imports	\N	445663	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
327	Crédit de TVA à reporter	\N	445670	f	5	other	\N	t	Si le remboursement n'a pas été demandé	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
328	Taxes déductibles assimilées à la TVA	\N	445680	f	5	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
329	TVA collectée (Taux Normal)	\N	445711	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
330	TVA collectée (Taux Intermédiaire)	\N	445712	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
331	TVA collectée (Autre taux)	\N	445713	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
332	Taxes collectées assimilées à la TVA	\N	445780	f	9	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
333	Taxes sur le chiffre d'affaires à régulariser ou en attente	\N	445800	f	9	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
334	Acomptes - Régime simplifié d'imposition	\N	445810	f	5	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
335	Acomptes - Régime du forfait	\N	445820	f	5	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
336	Remboursement de taxes sur le chiffre d'affaires demandé	\N	445830	f	5	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
337	TVA récupérée d'avance	\N	445840	f	9	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
338	Taxes sur le chiffre d'affaires sur factures non parvenues	\N	445860	f	5	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
339	Taxes sur le chiffre d'affaires sur factures à établir	\N	445870	f	9	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
340	Obligations cautionnées	\N	446000	f	9	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
341	Autres impôts, taxes et versements assimilés	\N	447000	f	9	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
342	État - Charges fiscales sur congés à payer	\N	448200	f	9	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
343	État - Charges à payer	\N	448600	f	9	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
344	État - Produits à recevoir	\N	448700	f	5	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
345	Quotas d'émission à restituer à l'État	\N	449000	f	9	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
347	Associés - Comptes courants - Principal	\N	455100	f	2	payable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
348	Associés - Comptes courants - Intérêts courus	\N	455800	f	2	payable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
349	Associés - Comptes d'apport en société - Apports en nature	\N	456110	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
346	Groupe	\N	451000	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
350	Associés - Comptes d'apport en société - Apports en numéraire	\N	456150	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
351	Actionnaires - Capital souscrit et appelé, non versé	\N	456210	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
352	Associés - Capital appelé, non versé	\N	456250	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
354	Associés - Versements anticipés	\N	456400	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
355	Actionnaires défaillants	\N	456600	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
356	Associés - Capital à rembourser	\N	456700	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
357	Associés - Dividendes à payer	\N	457000	f	9	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
358	Associés - Opérations faites en commun et en GIE - Opérations courantes	\N	458100	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
359	Associés - Opérations faites en commun et en GIE - Intérêts courus	\N	458800	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
360	Créances sur cessions d'immobilisations	\N	462000	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
361	Dettes sur acquisitions de valeurs mobilières de placement	\N	464000	f	9	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
362	Créances sur cessions de valeurs mobilières de placement	\N	465000	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
363	Autres comptes débiteurs ou créditeurs	\N	467000	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
364	Charges à payer	\N	468600	f	9	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
365	Produits à recevoir	\N	468700	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
367	Différence de conversion - Actif - Diminution des créances	\N	476100	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
368	Différence de conversion - Actif - Augmentation des dettes	\N	476200	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
369	Différence de conversion - Actif - Différences compensées par couverture de change	\N	476800	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
370	Différences de conversion - Passif - Augmentation des créances	\N	477100	f	9	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
371	Différences de conversion - Passif - Diminution des dettes	\N	477200	f	9	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
372	Différences de conversion - Passif - Différences compensées par couverture de change	\N	477800	f	9	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
373	Autres comptes transitoires	\N	478000	f	9	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
374	Charges à répartir sur plusieurs exercices - Frais d'émission des emprunts	\N	481600	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
375	Charges constatées d'avance	\N	486000	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
376	Produits constatés d'avance	\N	487000	f	9	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
377	Comptes de répartition périodique des charges	\N	488600	f	9	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
366	Compte d'attente	\N	471000	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
353	Associés - Versements reçus sur augmentation de capital	\N	456300	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
378	Comptes de répartition périodique des produits	\N	488700	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
379	Quotas d'émission alloués par l'État	\N	489000	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
381	Provisions pour dépréciation des comptes du groupe	\N	495100	f	9	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
382	Provisions pour dépréciation des comptes courants des associés	\N	495500	f	9	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
383	Provisions pour dépréciation des opérations faites en commun et en GIE	\N	495800	f	9	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
384	Provisions pour dépréciation des créances sur cessions d'immobilisations	\N	496200	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
385	Provisions pour dépréciation des créances sur cessions de valeurs mobilières de placement	\N	496500	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
386	Provisions pour dépréciation - Autres comptes débiteurs	\N	496700	f	1	receivable	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
388	Valeurs mobilières de placement - Actions propres	\N	502000	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
389	Valeurs mobilières de placement - Titres cotés	\N	503100	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
390	Valeurs mobilières de placement - Titres non cotés	\N	503500	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
391	Valeurs mobilières de placement - Autres titres conférant un droit de propriété	\N	504000	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
392	Obligations et bons émis par la société et rachetés par elle	\N	505000	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
393	Obligations cotés	\N	506100	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
394	Obligations non cotés	\N	506500	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
395	Bons du Trésor et bons de caisse à court terme	\N	507000	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
396	Autres valeurs mobilières de placement	\N	508100	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
397	Bons de souscription	\N	508200	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
398	Intérêts courus sur obligations, bons et valeurs assimilées	\N	508800	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
399	Versements restant à effectuer sur valeurs mobilières de placement non libérées	\N	509000	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
400	Coupons échus à l'encaissement	\N	511100	f	5	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
401	Chèques à encaisser	\N	511200	f	5	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
403	Effets à l'escompte	\N	511400	f	5	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
404	Banques - Comptes en devises	\N	512400	f	3	liquidity	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
405	Chèques postaux	\N	514000	f	3	liquidity	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
380	Provisions pour dépréciation des comptes de clients	\N	491000	f	9	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
387	Valeurs mobilières de placement - Parts dans entreprises liées	\N	501000	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
402	Effets à l'encaissement	\N	511300	f	5	other	\N	t	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
406	Caisses du Trésor et des établissements publics	\N	515000	f	3	liquidity	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
407	Sociétés de bourse	\N	516000	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
408	Autres organismes financiers	\N	517000	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
409	Intérêts courus à payer	\N	518100	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
410	Intérêts courus à recevoir	\N	518800	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
411	Concours bancaires courants - Crédit de mobilisation de créances commerciales (CMCC)	\N	519100	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
413	Concours bancaires courants - Intérêts courus sur concours bancaires courants	\N	519800	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
414	Instruments de trésorerie	\N	520000	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
415	Caisse en monnaie nationale	\N	531100	f	3	liquidity	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
416	Caisse en devises	\N	531400	f	3	liquidity	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
417	Caisse succursale (ou usine) A	\N	532000	f	3	liquidity	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
419	Régies d'avances et accréditifs	\N	540000	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
421	Provisions pour dépréciation des autres titres conférant un droit de propriété	\N	590400	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
422	Provisions pour dépréciation des obligations	\N	590600	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
423	Provisions pour dépréciation des autres valeurs mobilières de placement et créances assimilées (provisions)	\N	590800	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
424	Achats stockés - Matières premières (ou groupe) A	\N	601100	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
425	Achats stockés - matières premières (ou groupe) B	\N	601200	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
426	Achats stockés - Fournitures A, B, C, ..	\N	601700	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
427	Achats stockés - Matières consommables (ou groupe) C	\N	602110	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
428	Achats stockés - Matières consommables (ou groupe) D	\N	602120	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
429	Achats stockés - Combustibles	\N	602210	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
430	Achats stockés - Produits d'entretien	\N	602220	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
431	Achats stockés - Fournitures d'atelier et d'usine	\N	602230	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
432	Achats stockés - Fournitures de magasin	\N	602240	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
433	Achats stockés - Fournitures de bureau	\N	602250	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
434	Achats stockés - Emballages perdus	\N	602610	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
412	Concours bancaires courants - Mobilisation de créances nées à l'étranger	\N	519300	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
418	Caisse succursale (ou usine) B	\N	533000	f	3	liquidity	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
420	Provisions pour dépréciation des actions	\N	590300	f	5	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
435	Achats stockés - Emballages récupérables non identifiables	\N	602650	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
436	Achats stockés - Emballages à usage mixte	\N	602670	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
437	Variation des stocks de matières premières (et fournitures)	\N	603100	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
438	Variation des stocks des autres approvisionnements	\N	603200	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
439	Variation des stocks de marchandises	\N	603700	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
440	Achats d'études et prestations de services	\N	604000	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
441	Achats de matériel équipements et travaux	\N	605000	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
442	Fournitures non stockables (eau, énergie...)	\N	606100	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
444	Fournitures administratives	\N	606400	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
445	Achats autres matières et fournitures	\N	606800	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
446	Achats de marchandises (ou groupe) A	\N	607100	f	16	other	\N	f	Pour achats France	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
447	Achats de marchandises (ou groupe) B	\N	607200	f	16	other	\N	f	Pour déclaration TVA intracommunautaire	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
448	Frais accessoires incorporés aux achats	\N	608000	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
449	Rabais, remises et ristournes obtenus sur achats de matières premières (et fournitures)	\N	609100	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
450	Rabais, remises et ristournes obtenus sur achats d'autres approvisionnements stockés	\N	609200	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
451	Rabais, remises et ristournes obtenus sur achats d'études et prestations de services	\N	609400	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
452	Rabais, remises et ristournes obtenus sur achats de matériel, équipements et travaux	\N	609500	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
453	Rabais, remises et ristournes obtenus sur achats d'approvisionnements non stockés	\N	609600	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
454	Rabais, remises et ristournes obtenus sur achats de marchandises	\N	609700	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
455	Rabais, remises et ristournes non affectés	\N	609800	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
457	Redevances de crédit-bail mobilier	\N	612200	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
458	Redevances de crédit-bail immobilier	\N	612500	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
459	Locations immobilières	\N	613200	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
460	Locations mobilières	\N	613500	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
461	Locations malis sur emballages	\N	613600	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
462	Charges locatives et de copropriété	\N	614000	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
456	Sous-traitance générale	\N	611000	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
443	Fournitures d'entretien et de petit équipement	\N	606300	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
463	Entretien et réparations sur biens immobiliers	\N	615200	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
464	Entretien et réparations sur biens mobiliers	\N	615500	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
465	Maintenance	\N	615600	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
466	Assurance multirisques	\N	616100	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
467	Assurance obligatoire dommage construction	\N	616200	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
468	Assurance transport sur achats	\N	616360	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
469	Assurance transport sur ventes	\N	616370	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
470	Assurance transport sur autres biens	\N	616380	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
471	Assurance risques d'exploitation	\N	616400	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
472	Assurance insolvabilité clients	\N	616500	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
473	Études et recherches	\N	617000	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
474	Documentation générale	\N	618100	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
476	Frais de colloques, séminaires, conférences	\N	618500	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
477	Rabais, remises et ristournes obtenus sur services extérieurs	\N	619000	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
478	Personnel intérimaire	\N	621100	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
479	Personnel détaché ou prêté à l'entreprise	\N	621400	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
480	Commissions et courtages sur achats	\N	622100	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
481	Commissions et courtages sur ventes	\N	622200	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
482	Rémunérations des transitaires	\N	622400	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
483	Rémunérations d'affacturage	\N	622500	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
484	Honoraires	\N	622600	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
485	Frais d'actes et de contentieux	\N	622700	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
486	Rémunérations d'intermédiaires et honoraires - Divers	\N	622800	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
487	Annonces et insertions	\N	623100	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
488	Échantillons	\N	623200	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
490	Cadeaux à la clientèle	\N	623400	f	16	other	\N	f	Attention déclaration DAS fin d'année	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
491	Primes	\N	623500	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
492	Catalogues et imprimés	\N	623600	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
493	Publications	\N	623700	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
494	Publicité, publications, relations publiques - Divers (pourboires, dons courants...)	\N	623800	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
475	Documentation technique	\N	618300	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
489	Foires et expositions	\N	623300	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
495	Transports sur achats	\N	624100	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
496	Transports sur ventes	\N	624200	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
498	Transports administratifs	\N	624400	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
499	Transports collectifs du personnel	\N	624700	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
500	Transports divers	\N	624800	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
501	Voyages et déplacements	\N	625100	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
502	Frais de déménagement	\N	625500	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
503	Missions	\N	625600	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
504	Réceptions	\N	625700	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
505	Frais postaux et frais de télécommunications	\N	626000	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
506	Frais sur titres (achat, vente, garde)	\N	627100	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
507	Commissions et frais sur émission d'emprunts	\N	627200	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
508	Frais sur effets	\N	627500	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
510	Autres frais et commissions sur prestations de services	\N	627800	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
511	Concours divers (cotisations...)	\N	628100	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
512	Frais de recrutement de personnel	\N	628400	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
513	Rabais, remises et ristournes obtenus sur autres services extérieurs	\N	629000	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
514	Taxe sur les salaires	\N	631100	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
515	Taxe d'apprentissage	\N	631200	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
517	Cotisation pour défaut d'investissement obligatoire dans la construction	\N	631400	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
518	Autres impôts, taxes et versements assimilés sur rémunérations (administrations des impôts)	\N	631800	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
519	Versement de transport	\N	633100	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
520	Allocation logement	\N	633200	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
522	Participation des employeurs à l'effort de construction	\N	633400	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
523	Versements libératoires ouvrant droit à l'exonération de la taxe d'apprentissage	\N	633500	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
524	Autres impôts, taxes et versements assimilés sur rémunérations (autres organismes)	\N	633800	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
497	Transports entre établissements ou chantiers	\N	624300	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
516	Participation des employeurs à la formation professionnelle continue	\N	631300	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
521	Participation des employeurs à la formation professionnelle continue	\N	633300	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
509	Location de coffres	\N	627600	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
525	Cotisation foncière des entreprises	\N	635111	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
526	Cotisation sur la valeur ajoutée des entreprises	\N	635112	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
527	Taxes foncières	\N	635120	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
528	Autres impôts locaux	\N	635130	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
529	Taxe sur les véhicules des sociétés	\N	635140	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
530	Taxes sur le chiffre d'affaires non récupérables	\N	635200	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
532	Droits de mutation	\N	635410	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
533	Autres droits	\N	635800	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
534	Contribution sociale de solidarité à la charge des sociétés	\N	637100	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
535	Taxes perçues par les organismes publics internationaux	\N	637200	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
536	Impôts et taxes exigibles à l'étranger	\N	637400	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
537	Taxes diverses (autres organismes)	\N	637800	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
538	Salaires et appointements	\N	641100	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
539	Congés payés	\N	641200	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
541	Indemnités et avantages divers	\N	641400	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
542	Supplément familial	\N	641500	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
543	Rémunération du travail de l'exploitant	\N	644000	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
544	Cotisations à l'URSSAF	\N	645100	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
545	Cotisations aux mutuelles	\N	645200	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
547	Cotisations aux ASSEDIC	\N	645400	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
548	Cotisations aux autres organismes sociaux	\N	645800	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
549	Cotisations sociales personnelles de l'exploitant	\N	646000	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
550	Prestations directes	\N	647100	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
551	Versements aux comités d'entreprise et d'établissement	\N	647200	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
553	Versements aux autres oeuvres sociales	\N	647400	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
554	Médecine du travail, pharmacie	\N	647500	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
555	Autres charges de personnel	\N	648000	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
556	Crédit d’Impôt Compétitivité Emploi (CICE)	\N	649000	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
531	Impôts indirects	\N	635300	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
540	Primes et gratifications	\N	641300	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
546	Cotisations aux caisses de retraites	\N	645300	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
552	Versements aux comités d'hygiène et de sécurité	\N	647300	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
557	Redevances pour concessions brevets, licences, marques, procédés, logiciels	\N	651100	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
558	Droits d'auteur et de reproduction	\N	651600	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
559	Autres droits et valeurs similaires	\N	651800	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
561	Créances de l'exercice	\N	654100	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
562	Créances des exercices antérieurs	\N	654400	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
563	Quote-part de bénéfice transférée (comptabilité du gérant)	\N	655100	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
564	Quote-part de perte supportée (comptabilité des associés non gérants)	\N	655500	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
565	Charges diverses de gestion courante	\N	658000	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
566	Intérêts des emprunts et dettes assimilées	\N	661160	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
567	Intérêts des dettes rattachées à des participations	\N	661170	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
568	Intérêts des comptes courants et des dépôts créditeurs	\N	661500	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
569	Intérêts bancaires et sur opérations de financement (escompte, ...)	\N	661600	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
570	Intérêts des obligations cautionnées	\N	661700	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
571	Intérêts des dettes commerciales	\N	661810	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
572	Intérêts des dettes diverses	\N	661880	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
573	Pertes sur créances liées à des participations	\N	664000	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
574	Escomptes accordés	\N	665000	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
575	Pertes de change	\N	666000	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
576	Charges nettes sur cessions de valeurs mobilières de placement	\N	667000	f	16	other	\N	f	(contrepartie 767)	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
577	Autres charges financières	\N	668000	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
578	Charges exceptionnelles - Pénalités sur marchés (et dédits payés sur achats et ventes)	\N	671100	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
579	Charges exceptionnelles - Pénalités, amendes fiscales et pénales	\N	671200	f	16	other	\N	f	PV code de la route non déductibles	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
581	Charges exceptionnelles - Créances devenues irrécouvrables dans l'exercice	\N	671400	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
582	Charges exceptionnelles - Subventions accordées	\N	671500	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
583	Charges exceptionnelles - Rappels d'impôts (autres qu'impôts sur les bénéfices)	\N	671700	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
584	Autres charges exceptionnelles sur opération de gestion	\N	671800	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
560	Jetons de présence	\N	653000	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
580	Charges exceptionnelles - Dons, libéralités	\N	671300	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
585	Charges exceptionnelles sur exercices antérieurs (en cours d'exercice seulement)	\N	672000	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
586	Valeurs comptables des éléments d'actif cédés - Immobilisations incorporelles	\N	675100	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
587	Valeurs comptables des éléments d'actif cédés - Immobilisations corporelles	\N	675200	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
588	Valeurs comptables des éléments d'actif cédés - Immobilisations financières	\N	675600	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
589	Valeurs comptables des éléments d'actif cédés - Autres éléments d'actif	\N	675800	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
590	Charges exceptionnelles - Malis provenant de clauses d'indexation	\N	678100	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
591	Charges exceptionnelles - Lots	\N	678200	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
593	Charges exceptionnelles diverses	\N	678800	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
594	Dotations aux amortissements sur immobilisations incorporelles	\N	681110	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
595	Dotations aux amortissements sur immobilisations corporelles	\N	681120	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
596	Dotations aux amortissements des charges d'exploitation à répartir	\N	681200	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
597	Dotations aux provisions pour risques et charges d'exploitation	\N	681500	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
598	Dotations aux dépréciations des immobilisations incorporelles	\N	681610	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
599	Dotations aux dépréciations des immobilisations corporelles	\N	681620	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
600	Dotations aux dépréciations des stocks et en-cours	\N	681730	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
601	Dotations aux dépréciations des créances	\N	681740	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
602	Dotations aux amortissements des primes de remboursement des obligations	\N	686100	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
603	Dotations aux provisions pour risques et charges financiers	\N	686500	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
604	Dotations aux dépréciations des immobilisations financières	\N	686620	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
605	Dotations aux dépréciations des valeurs mobilières de placement	\N	686650	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
606	Autres dotations aux amortissements, dépréciations et provisions - Charges financières	\N	686800	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
607	Dotations aux amortissements exceptionnels des immobilisations	\N	687100	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
608	Dotations aux provisions réglementées exceptionnelles (immobilisations) - Amortissements dérogatoires	\N	687250	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
592	Charges exceptionnelles - Malis provenant du rachat par l'entreprise d'actions et obligations émises par elle-même	\N	678300	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
609	Dotations aux provisions réglementées exceptionnelles (stocks)	\N	687300	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
610	Dotations aux autres provisions réglementées exceptionnelles	\N	687400	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
611	Dotations aux provisions exceptionnelles	\N	687500	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
614	Impôts sur les bénéfices dus en France	\N	695100	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
615	Contribution additionnelle à l'impôt sur les bénéfices	\N	695200	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
616	Impôts sur les bénéfices dus à l'étranger	\N	695400	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
617	Supplément d'impôt sur les sociétés lié aux distributions	\N	696000	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
618	Imposition forfaitaire annuelle des sociétés	\N	697000	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
619	Intégration fiscale - Charges	\N	698100	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
620	Intégration fiscale - Produits	\N	698900	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
621	Produits, Reports en arrière des déficits	\N	699000	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
622	Ventes de produits finis (ou groupe) A	\N	701100	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
623	Ventes de produits finis (ou groupe) B	\N	701200	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
624	Ventes de produits intermédiaires	\N	702000	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
626	Ventes de travaux de catégorie (ou activité) A	\N	704100	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
627	Ventes de travaux de catégorie (ou activité) B	\N	704200	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
628	Ventes d'études	\N	705000	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
629	Ventes de prestations de services	\N	706000	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
630	Ventes de marchandises (ou groupe) A	\N	707100	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
631	Ventes de marchandises (ou groupe) B	\N	707200	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
633	Produits des services exploités dans l'intérêt du personnel	\N	708100	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
634	Commissions et courtages	\N	708200	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
636	Mise à disposition de personnel facturée	\N	708400	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
637	Ports et frais accessoires facturés	\N	708500	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
638	Bonis sur reprises d'emballages consignés	\N	708600	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
639	Bonifications obtenues des clients et primes sur ventes	\N	708700	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
613	Participation des salariés aux résultats	\N	691000	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
625	Ventes de produits résiduels	\N	703000	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
632	Ventes de marchandises à l'exportation	\N	707300	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
635	Locations diverses	\N	708300	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
612	Dotations aux dépréciations exceptionnelles	\N	687600	f	16	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
640	Autres produits d'activités annexes (cessions d'approvisionnements...)	\N	708800	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
641	Rabais, remises et ristournes sur ventes de produits finis	\N	709100	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
642	Rabais, remises et ristournes sur ventes de produits intermédiaires	\N	709200	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
643	Rabais, remises et ristournes sur travaux	\N	709400	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
644	Rabais, remises et ristournes sur études	\N	709500	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
645	Rabais, remises et ristournes sur prestations de services	\N	709600	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
646	Rabais, remises et ristournes sur ventes de marchandises	\N	709700	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
647	Rabais, remises et ristournes sur produits des activités annexes	\N	709800	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
648	Variation des en-cours de production de biens - Produits en cours	\N	713310	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
649	Variation des en-cours de production de biens - Travaux en cours	\N	713350	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
650	Variation des en-cours de production de services - Études en cours	\N	713410	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
651	Variation des en-cours de production de services - Prestations de services en cours	\N	713450	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
652	Variation des stocks de produits intermédiaires	\N	713510	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
653	Variation des stocks de produits finis	\N	713550	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
654	Variation des stocks de produits résiduels	\N	713580	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
656	Production immobilisée - Immobilisations corporelles	\N	722000	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
657	Subventions d'exploitation	\N	740000	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
658	Redevances pour concessions, brevets, licences, marques, procédés, logiciels	\N	751100	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
659	Droits d'auteur et de reproduction	\N	751600	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
660	Redevances pour autres droits et valeurs similaires	\N	751800	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
661	Revenus des immeubles non affectés aux activités professionnelles	\N	752000	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
663	Ristournes perçues des coopératives (provenant des excédents)	\N	754000	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
664	Quote-part de perte transférée (comptabilité du gérant)	\N	755100	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
665	Quote-part de bénéfice attribuée (comptabilité des associés non-gérants)	\N	755500	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
666	Produits divers de gestion courante	\N	758000	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
655	Production immobilisée - Immobilisations incorporelles	\N	721000	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
662	Jetons de présence et rémunérations d'administrateurs, gérants..	\N	753000	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
667	Revenus des titres de participation	\N	761100	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
668	Revenus sur autres formes de participation	\N	761600	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
669	Revenus des titres immobilisés	\N	762100	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
670	Revenus des prêts	\N	762600	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
671	Revenus des créances immobilisées	\N	762700	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
672	Revenus des créances commerciales	\N	763100	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
673	Revenus des créances diverses	\N	763800	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
674	Revenus des valeurs mobilières de placement	\N	764000	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
675	Escomptes obtenus	\N	765000	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
676	Gains de change	\N	766000	f	13	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
677	Produits nets sur cessions de valeurs mobilières de placement	\N	767000	f	14	other	\N	f	(contrepartie 667)	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
678	Autres produits financiers	\N	768000	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
679	Produits exceptionnels - Dédits et pénalités perçus sur achats et sur ventes	\N	771100	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
681	Produits exceptionnels - Rentrées sur créances amorties	\N	771400	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
682	Produits exceptionnels - Subventions d'équilibre	\N	771500	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
683	Produits exceptionnels - Dégrèvements d'impôts autres qu'impôts sur les bénéfices	\N	771700	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
684	Autres produits exceptionnels sur opérations de gestion	\N	771800	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
685	Produits exceptionnels sur exercices antérieurs (en cours d'exercice seulement)	\N	772000	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
686	Produits exceptionnels des cessions d'éléments d'actif - Immobilisations incorporelles	\N	775100	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
687	Produits exceptionnels des cessions d'éléments d'actif - Immobilisations corporelles	\N	775200	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
688	Produits exceptionnels des cessions d'éléments d'actif - Immobilisations financières	\N	775600	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
689	Produits exceptionnels des cessions d'éléments d'actif - Autres éléments d'actif	\N	775800	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
690	Produits exceptionnels - Quote-part des subventions d'investissement virée au résultat de l'exercice	\N	777000	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
691	Produits exceptionnels - Bonis provenant de clauses d'indexation	\N	778100	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
692	Produits exceptionnels - Lots	\N	778200	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
680	Produits exceptionnels - Libéralités reçues	\N	771300	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
693	Produits exceptionnels - Bonis provenant du rachat par l'entreprise d'actions et d'obligations émises par elle-même	\N	778300	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
694	Produits exceptionnels divers	\N	778800	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
695	Reprises sur amortissements des immobilisations incorporelles	\N	781110	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
696	Reprises sur amortissements des immobilisations corporelles	\N	781120	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
697	Reprises sur provisions d'exploitation	\N	781500	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
698	Reprises sur dépréciations des immobilisations incorporelles	\N	781610	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
699	Reprises sur dépréciations des immobilisations corporelles	\N	781620	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
700	Reprises sur dépréciations des actifs circulants - Stocks et en-cours	\N	781730	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
701	Reprises sur dépréciations des actifs circulants - Créances	\N	781740	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
702	Reprises sur provisions financières	\N	786500	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
703	Reprises sur dépréciations des immobilisations financières	\N	786620	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
704	Reprises sur dépréciations des valeurs mobilières de placement	\N	786650	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
705	Reprises sur provisions réglementées (immobilisations) - Amortissements dérogatoires	\N	787250	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
706	Reprises sur provisions réglementées (immobilisations) - Provision spéciale de réévaluation	\N	787260	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
707	Reprises sur provisions réglementées (immobilisations) - Plus-values réinvesties	\N	787270	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
709	Reprises sur autres provisions réglementées	\N	787400	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
710	Reprises sur provisions exceptionnelles	\N	787500	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
713	Transferts de charges financières	\N	796000	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
714	Transferts de charges exceptionnelles	\N	797000	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
716	Banque	\N	512001	f	3	liquidity	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
717	Profits/pertes non distribués	\N	999999	f	12	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:06:53.166234
712	Transferts de charges d'exploitation	\N	791000	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
708	Reprises sur provisions réglementées (stocks)	\N	787300	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
715	Espèces	\N	530001	f	3	liquidity	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
711	Reprises sur dépréciations exceptionnelles	\N	787600	f	14	other	\N	f	\N	1	\N	1	2019-02-14 15:06:53.166234	1	2019-02-14 15:09:48.936423
\.

Added doc/manuel/Comptabilité avancée (partie double).md version [4caaa3768c].















>
>
>
>
>
>
>
1
2
3
4
5
6
7
# Comptabilité avancée (partie double)

## Fonctionnement général

Par défaut les opérations sont enregistrées en tant que brouillon (dans le *brouillard*) et peuvent être modifiées ou supprimées.

Il faut valider les opérations pour les rendre définitivées. Une opération validée ne peut plus être modifiée ou supprimée. En cas d'erreur il faudra créer une nouvelle écriture corrective.

Added doc/manuel/Sauvegarde et restauration.md version [a2332341db].

































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Sauvegarde et restauration



## Messages d'erreur

### Le fichier fourni est corrompu. Certaines clés étrangères référencent des lignes qui n'existent pas.

Ce message indiquent que certaines lignes dans une table font référence à des lignes d'une autre table qui n'existent pas.

Cette erreur se produit lorsque des modifications manuelles ont été apportées à une base de données.

Pour trouver les lignes qui sont invalides, utiliser un outil de gestion de base de données SQLite et lancer la commande suivante :

	PRAGMA schema.integrity_check;

Deleted src/COPYING version [78e50e186b].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
                    GNU AFFERO GENERAL PUBLIC LICENSE
                       Version 3, 19 November 2007

 Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

                            Preamble

  The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.

  The licenses for most software and other practical works are designed
to take away your freedom to share and change the works.  By contrast,
our General Public Licenses are intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.

  Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.

  A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate.  Many developers of free software are heartened and
encouraged by the resulting cooperation.  However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.

  The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community.  It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server.  Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.

  An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals.  This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.

  The precise terms and conditions for copying, distribution and
modification follow.

                       TERMS AND CONDITIONS

  0. Definitions.

  "This License" refers to version 3 of the GNU Affero General Public License.

  "Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.

  "The Program" refers to any copyrightable work licensed under this
License.  Each licensee is addressed as "you".  "Licensees" and
"recipients" may be individuals or organizations.

  To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy.  The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.

  A "covered work" means either the unmodified Program or a work based
on the Program.

  To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy.  Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.

  To "convey" a work means any kind of propagation that enables other
parties to make or receive copies.  Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.

  An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License.  If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.

  1. Source Code.

  The "source code" for a work means the preferred form of the work
for making modifications to it.  "Object code" means any non-source
form of a work.

  A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.

  The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form.  A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.

  The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities.  However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work.  For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.

  The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.

  The Corresponding Source for a work in source code form is that
same work.

  2. Basic Permissions.

  All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met.  This License explicitly affirms your unlimited
permission to run the unmodified Program.  The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work.  This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.

  You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force.  You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright.  Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.

  Conveying under any other circumstances is permitted solely under
the conditions stated below.  Sublicensing is not allowed; section 10
makes it unnecessary.

  3. Protecting Users' Legal Rights From Anti-Circumvention Law.

  No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.

  When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.

  4. Conveying Verbatim Copies.

  You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.

  You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.

  5. Conveying Modified Source Versions.

  You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:

    a) The work must carry prominent notices stating that you modified
    it, and giving a relevant date.

    b) The work must carry prominent notices stating that it is
    released under this License and any conditions added under section
    7.  This requirement modifies the requirement in section 4 to
    "keep intact all notices".

    c) You must license the entire work, as a whole, under this
    License to anyone who comes into possession of a copy.  This
    License will therefore apply, along with any applicable section 7
    additional terms, to the whole of the work, and all its parts,
    regardless of how they are packaged.  This License gives no
    permission to license the work in any other way, but it does not
    invalidate such permission if you have separately received it.

    d) If the work has interactive user interfaces, each must display
    Appropriate Legal Notices; however, if the Program has interactive
    interfaces that do not display Appropriate Legal Notices, your
    work need not make them do so.

  A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit.  Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.

  6. Conveying Non-Source Forms.

  You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:

    a) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by the
    Corresponding Source fixed on a durable physical medium
    customarily used for software interchange.

    b) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by a
    written offer, valid for at least three years and valid for as
    long as you offer spare parts or customer support for that product
    model, to give anyone who possesses the object code either (1) a
    copy of the Corresponding Source for all the software in the
    product that is covered by this License, on a durable physical
    medium customarily used for software interchange, for a price no
    more than your reasonable cost of physically performing this
    conveying of source, or (2) access to copy the
    Corresponding Source from a network server at no charge.

    c) Convey individual copies of the object code with a copy of the
    written offer to provide the Corresponding Source.  This
    alternative is allowed only occasionally and noncommercially, and
    only if you received the object code with such an offer, in accord
    with subsection 6b.

    d) Convey the object code by offering access from a designated
    place (gratis or for a charge), and offer equivalent access to the
    Corresponding Source in the same way through the same place at no
    further charge.  You need not require recipients to copy the
    Corresponding Source along with the object code.  If the place to
    copy the object code is a network server, the Corresponding Source
    may be on a different server (operated by you or a third party)
    that supports equivalent copying facilities, provided you maintain
    clear directions next to the object code saying where to find the
    Corresponding Source.  Regardless of what server hosts the
    Corresponding Source, you remain obligated to ensure that it is
    available for as long as needed to satisfy these requirements.

    e) Convey the object code using peer-to-peer transmission, provided
    you inform other peers where the object code and Corresponding
    Source of the work are being offered to the general public at no
    charge under subsection 6d.

  A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.

  A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling.  In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage.  For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product.  A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.

  "Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source.  The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.

  If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information.  But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).

  The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed.  Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.

  Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.

  7. Additional Terms.

  "Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law.  If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.

  When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it.  (Additional permissions may be written to require their own
removal in certain cases when you modify the work.)  You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.

  Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:

    a) Disclaiming warranty or limiting liability differently from the
    terms of sections 15 and 16 of this License; or

    b) Requiring preservation of specified reasonable legal notices or
    author attributions in that material or in the Appropriate Legal
    Notices displayed by works containing it; or

    c) Prohibiting misrepresentation of the origin of that material, or
    requiring that modified versions of such material be marked in
    reasonable ways as different from the original version; or

    d) Limiting the use for publicity purposes of names of licensors or
    authors of the material; or

    e) Declining to grant rights under trademark law for use of some
    trade names, trademarks, or service marks; or

    f) Requiring indemnification of licensors and authors of that
    material by anyone who conveys the material (or modified versions of
    it) with contractual assumptions of liability to the recipient, for
    any liability that these contractual assumptions directly impose on
    those licensors and authors.

  All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10.  If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term.  If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.

  If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.

  Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.

  8. Termination.

  You may not propagate or modify a covered work except as expressly
provided under this License.  Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).

  However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.

  Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.

  Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License.  If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.

  9. Acceptance Not Required for Having Copies.

  You are not required to accept this License in order to receive or
run a copy of the Program.  Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance.  However,
nothing other than this License grants you permission to propagate or
modify any covered work.  These actions infringe copyright if you do
not accept this License.  Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.

  10. Automatic Licensing of Downstream Recipients.

  Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License.  You are not responsible
for enforcing compliance by third parties with this License.

  An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations.  If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.

  You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License.  For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.

  11. Patents.

  A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based.  The
work thus licensed is called the contributor's "contributor version".

  A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version.  For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.

  Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.

  In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement).  To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.

  If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients.  "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.

  If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.

  A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License.  You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.

  Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.

  12. No Surrender of Others' Freedom.

  If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all.  For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.

  13. Remote Network Interaction; Use with the GNU General Public License.

  Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software.  This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.

  Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU General Public License into a single
combined work, and to convey the resulting work.  The terms of this
License will continue to apply to the part which is the covered work,
but the work with which it is combined will remain governed by version
3 of the GNU General Public License.

  14. Revised Versions of this License.

  The Free Software Foundation may publish revised and/or new versions of
the GNU Affero General Public License from time to time.  Such new versions
will be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

  Each version is given a distinguishing version number.  If the
Program specifies that a certain numbered version of the GNU Affero General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation.  If the Program does not specify a version number of the
GNU Affero General Public License, you may choose any version ever published
by the Free Software Foundation.

  If the Program specifies that a proxy can decide which future
versions of the GNU Affero General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.

  Later license versions may give you additional or different
permissions.  However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.

  15. Disclaimer of Warranty.

  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

  16. Limitation of Liability.

  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.

  17. Interpretation of Sections 15 and 16.

  If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.

                     END OF TERMS AND CONDITIONS

            How to Apply These Terms to Your New Programs

  If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

  To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

Also add information on how to contact you by electronic and paper mail.

  If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source.  For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code.  There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for the
specific requirements.

  You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see
<http://www.gnu.org/licenses/>.
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Modified src/Makefile from [cf4731ac96] to [530c679c07].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

27






28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45




.PHONY: dev-server release deps publish check-dependencies test
KD2_FILE := https://fossil.kd2.org/kd2fw/uv/KD2-5.6.zip

deps:
	$(eval TMP_KD2=$(shell mktemp -d))
	#cd ${TMP_KD2}

	wget ${KD2_FILE} -O ${TMP_KD2}/kd2.zip

	rm -rf "include/lib/KD2"
	unzip "${TMP_KD2}/kd2.zip" -d include/lib

	rm -rf ${TMP_KD2}

dev-server:
	php -S localhost:8082 -t www www/_route.php

test:
	find . -name '*.php' -print0 | xargs -0 -n1 php -l > /dev/null

release: test
	$(eval VERSION=$(shell cat VERSION))
	rm -rf /tmp/garradin-build
	mkdir -p /tmp/garradin-build
	fossil zip ${VERSION} /tmp/garradin-build/src.zip --name garradin
	unzip -d /tmp/garradin-build /tmp/garradin-build/src.zip

	cd include/lib; rsync --files-from=dependencies.list -r ./ /tmp/garradin-build/garradin/src/include/lib/






	mv /tmp/garradin-build/garradin/src /tmp/garradin-build/garradin-${VERSION}
	@#cd /tmp/garradin-build/; zip -r -9 garradin-${VERSION}.zip garradin-${VERSION};
	@#mv -f /tmp/garradin-build/garradin-${VERSION}.zip ./
	tar cjvfh garradin-${VERSION}.tar.bz2 -C /tmp/garradin-build garradin-${VERSION}

deb:
	cd ../debian; ./makedeb.sh

publish: release deb
	$(eval VERSION=$(shell cat VERSION))
	fossil uv sync
	#fossil uv ls | fgrep -v 'garradin-0.8.5' | grep '^garradin-.*\.(tar\.bz2|deb)' | xargs fossil uv rm
	fossil uv add garradin-${VERSION}.tar.bz2
	cd ../debian && fossil uv add garradin-${VERSION}-*.deb
	fossil uv sync

check-dependencies:
	grep -hEo '^use \\?KD2\\\w+|\\KD2\\\w+' -R include/lib/Garradin www | sed -r 's/^use \\?KD2\\|^\\KD2\\//' | sort | uniq




|
|


















|





>
|
>
>
>
>
>
>

















|
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
.PHONY: dev-server release deps publish check-dependencies test minify
KD2_FILE := https://fossil.kd2.org/kd2fw/uv/KD2-7.2.zip

deps:
	$(eval TMP_KD2=$(shell mktemp -d))
	#cd ${TMP_KD2}

	wget ${KD2_FILE} -O ${TMP_KD2}/kd2.zip

	rm -rf "include/lib/KD2"
	unzip "${TMP_KD2}/kd2.zip" -d include/lib

	rm -rf ${TMP_KD2}

dev-server:
	php -S localhost:8082 -t www www/_route.php

test:
	find . -name '*.php' -print0 | xargs -0 -n1 php -l > /dev/null

release: test minify
	$(eval VERSION=$(shell cat VERSION))
	rm -rf /tmp/garradin-build
	mkdir -p /tmp/garradin-build
	fossil zip ${VERSION} /tmp/garradin-build/src.zip --name garradin
	unzip -d /tmp/garradin-build /tmp/garradin-build/src.zip
	cd include/lib; \
		rsync --files-from=dependencies.list -r ./ /tmp/garradin-build/garradin/src/include/lib/
	mv www/admin/static/mini.css /tmp/garradin-build/garradin/src/www/admin/static/admin.css
	cd /tmp/garradin-build/garradin/src/www/admin/static; \
		rm -f styles/[0-9]*.css; \
		rm -f font/*.css font/*.json
	cd /tmp/garradin-build/garradin/src; \
		rm -f Makefile include/lib/KD2/data/countries.en.json
	mv /tmp/garradin-build/garradin/src /tmp/garradin-build/garradin-${VERSION}
	@#cd /tmp/garradin-build/; zip -r -9 garradin-${VERSION}.zip garradin-${VERSION};
	@#mv -f /tmp/garradin-build/garradin-${VERSION}.zip ./
	tar cjvfh garradin-${VERSION}.tar.bz2 -C /tmp/garradin-build garradin-${VERSION}

deb:
	cd ../debian; ./makedeb.sh

publish: release deb
	$(eval VERSION=$(shell cat VERSION))
	fossil uv sync
	#fossil uv ls | fgrep -v 'garradin-0.8.5' | grep '^garradin-.*\.(tar\.bz2|deb)' | xargs fossil uv rm
	fossil uv add garradin-${VERSION}.tar.bz2
	cd ../debian && fossil uv add garradin-${VERSION}-*.deb
	fossil uv sync

check-dependencies:
	grep -hEo '^use \\?KD2\\[^; ]+|\\KD2\\[^\(:; ]+' -R include/lib/Garradin www | sed -r 's/^use \\?KD2\\|^\\KD2\\//' | sort | uniq

minify:
	cat `ls www/admin/static/styles/[0-9]*.css` | sed 's/\.\.\///' > www/admin/static/mini.css
	yui-compressor --nomunge www/admin/static/mini.css -o www/admin/static/mini.css

Deleted src/README version [b24af5ed67].

1
2
3
4
5
6
7
8
9
10
11
12
13
Garradin - Gestionnaire d'association libre
===========================================

Inclus les bibliothèques suivantes :

- Gibberish AES
  https://github.com/mdp/gibberish-aes
  Copyright : Mark Percival 2008 - http://markpercival.us
  Licence : MIT

- KD2fw
  Copyright : 2001-2018 BohwaZ
  Licence : GNU AGPL v3
<
<
<
<
<
<
<
<
<
<
<
<
<


























Modified src/VERSION from [bef1ccc9e8] to [e1f4423d2c].

1
0.9.8.1
|
1
1.0.0-rc4

Modified src/config.dist.php from [7d9b8d58eb] to [870f095e02].

15
16
17
18
19
20
21



22
23
24

25
26
27
28
29
30
31
32
33
34
35
36
37

38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

53
54
55
56
57
58
59
60
61
62
63
64
65

66
67
68
69
70
71
72

73
74
75
76
77
78
79
80

81








82
83
84
85
86
87

88
89
90
91
92
93
94

95
96
97
98
99
100
101
102
103
104
105
106
107

108
109
110
111
112
113
114
115

/**
 * Clé secrète, doit être unique à chaque instance de Garradin
 *
 * Ceci est utilisé afin de sécuriser l'envoi de formulaires
 * (protection anti-CSRF).
 *



 * Si aucune valeur n'est définie, Garradin ajoutera automatiquement
 * une valeur au hasard dans le fichier config.local.php.
 */

const SECRET_KEY = '3xUhIgGwuovRKOjVsVPQ5yUMfXUSIOX2GKzcebsz5OINrYC50r';

/**
 * Se connecter automatiquement avec l'ID de membre indiqué
 * Exemple: LOCAL_LOGIN = 42 connectera automatiquement le membre n°42
 * Attention à ne pas utiliser en production !
 *
 * Il est aussi possible de mettre "LOCAL_LOGIN = -1" pour se connecter
 * avec le premier membre trouvé qui peut gérer la configuration (et donc
 * modifier les droits des membres).
 *
 * Défault : false (connexion automatique désactivée)
 */

const LOCAL_LOGIN = false;

/**
 * Autoriser (ou non) l'import de sauvegarde qui a été modifiée ?
 * 
 * Si mis à true, un avertissement et une confirmation seront demandés
 * Si mis à false, tout fichier SQLite importé qui ne comporte pas une signature
 * valide (hash SHA1) sera refusé.
 * 
 * Ceci ne s'applique qu'à la page "Sauvegarde et restauration" de l'admin,
 * il est toujours possible de restaurer une base de données non signée en
 * la recopiant à la place du fichier association.sqlite
 *
 * Défaut : true
 */

const ALLOW_MODIFIED_IMPORT = true;

/**
 * Doit-on suggérer à l'utilisateur d'utiliser la version chiffrée du site ?
 * 
 * 1 ou true = affiche un message de suggestion sur l'écran de connexion invitant à utiliser le site chiffré
 * (conseillé si vous avez un certificat auto-signé ou peu connu type CACert)
 * 2 = rediriger automatiquement sur la version chiffrée pour l'administration (mais pas le site public)
 * 3 = rediriger automatiquement sur la version chiffrée pour administration et site public
 * false ou 0 = aucune version chiffrée disponible, donc ne rien proposer ni rediriger
 *
 * Défaut : false
 */

const PREFER_HTTPS = false;

/**
 * Répertoire où se situe le code source de Garradin
 *
 * Défaut : répertoire racine de Garradin (__DIR__)
 */

const ROOT = __DIR__;

/**
 * Répertoire où sont situées les données de Garradin
 * (incluant la base de données SQLite, le cache et les fichiers locaux)
 *
 * Défaut : identique à ROOT
 */

const DATA_ROOT = ROOT;









/**
 * Emplacement du fichier de base de données de Garradin
 *
 * Défaut : ROOT . '/association.sqlite'
 */

const DB_FILE = ROOT . '/association.sqlite';

/**
 * Emplacement de stockage des plugins
 *
 * Défaut : DATA_ROOT . '/plugins'
 */

const PLUGINS_ROOT = DATA_ROOT . '/plugins';

/**
 * Plugins fixes qui ne peuvent être désinstallés par l'utilisateur
 * (séparés par une virgule)
 *
 * Ils seront aussi réinstallés en cas de restauration de sauvegarde,
 * s'ils ne sont pas dans la sauvegarde.
 *
 * Exemple : PLUGINS_SYSTEM = 'gestion_emails,factures'
 *
 * Défaut : aucun (chaîne vide)
 */

const PLUGINS_SYSTEM = '';

/**
 * Adresse URI de la racine du site Garradin
 * (doit se terminer par un slash)
 *
 * Défaut : découverte automatique à partir de SCRIPT_NAME
 */







>
>
>
|
|

>
|












>
|



|



|






>
|



|








>
|






>
|



|



>
|
>
>
>
>
>
>
>
>




|

>
|






>
|












>
|







15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

/**
 * Clé secrète, doit être unique à chaque instance de Garradin
 *
 * Ceci est utilisé afin de sécuriser l'envoi de formulaires
 * (protection anti-CSRF).
 *
 * Cette valeur peut être modifiée sans autre impact que la déconnexion des utilisateurs
 * actuellement connectés.
 *
 * Si cette constante n'est définie, Garradin ajoutera automatiquement
 * une valeur aatoire dans le fichier config.local.php.
 */

//const SECRET_KEY = '3xUhIgGwuovRKOjVsVPQ5yUMfXUSIOX2GKzcebsz5OINrYC50r';

/**
 * Se connecter automatiquement avec l'ID de membre indiqué
 * Exemple: LOCAL_LOGIN = 42 connectera automatiquement le membre n°42
 * Attention à ne pas utiliser en production !
 *
 * Il est aussi possible de mettre "LOCAL_LOGIN = -1" pour se connecter
 * avec le premier membre trouvé qui peut gérer la configuration (et donc
 * modifier les droits des membres).
 *
 * Défault : false (connexion automatique désactivée)
 */

//const LOCAL_LOGIN = false;

/**
 * Autoriser (ou non) l'import de sauvegarde qui a été modifiée ?
 *
 * Si mis à true, un avertissement et une confirmation seront demandés
 * Si mis à false, tout fichier SQLite importé qui ne comporte pas une signature
 * valide (hash SHA1) sera refusé.
 *
 * Ceci ne s'applique qu'à la page "Sauvegarde et restauration" de l'admin,
 * il est toujours possible de restaurer une base de données non signée en
 * la recopiant à la place du fichier association.sqlite
 *
 * Défaut : true
 */

//const ALLOW_MODIFIED_IMPORT = true;

/**
 * Doit-on suggérer à l'utilisateur d'utiliser la version chiffrée du site ?
 *
 * 1 ou true = affiche un message de suggestion sur l'écran de connexion invitant à utiliser le site chiffré
 * (conseillé si vous avez un certificat auto-signé ou peu connu type CACert)
 * 2 = rediriger automatiquement sur la version chiffrée pour l'administration (mais pas le site public)
 * 3 = rediriger automatiquement sur la version chiffrée pour administration et site public
 * false ou 0 = aucune version chiffrée disponible, donc ne rien proposer ni rediriger
 *
 * Défaut : false
 */

//const PREFER_HTTPS = false;

/**
 * Répertoire où se situe le code source de Garradin
 *
 * Défaut : répertoire racine de Garradin (__DIR__)
 */

//const ROOT = __DIR__;

/**
 * Répertoire où sont situées les données de Garradin
 * (incluant la base de données SQLite, les sauvegardes, le cache et les fichiers locaux)
 *
 * Défaut : identique à ROOT
 */

//const DATA_ROOT = ROOT;

/**
 * Répertoire où est situé le cache (fichiers temporaires utilisés pour accélérer le chargement des pages)
 *
 * Défaut : sous-répertoire 'cache' de DATA_ROOT
 */

//const CACHE_ROOT = ROOT . '/cache';

/**
 * Emplacement du fichier de base de données de Garradin
 *
 * Défaut : DATA_ROOT . '/association.sqlite'
 */

//const DB_FILE = DATA_ROOT . '/association.sqlite';

/**
 * Emplacement de stockage des plugins
 *
 * Défaut : DATA_ROOT . '/plugins'
 */

//const PLUGINS_ROOT = DATA_ROOT . '/plugins';

/**
 * Plugins fixes qui ne peuvent être désinstallés par l'utilisateur
 * (séparés par une virgule)
 *
 * Ils seront aussi réinstallés en cas de restauration de sauvegarde,
 * s'ils ne sont pas dans la sauvegarde.
 *
 * Exemple : PLUGINS_SYSTEM = 'gestion_emails,factures'
 *
 * Défaut : aucun (chaîne vide)
 */

//const PLUGINS_SYSTEM = '';

/**
 * Adresse URI de la racine du site Garradin
 * (doit se terminer par un slash)
 *
 * Défaut : découverte automatique à partir de SCRIPT_NAME
 */
125
126
127
128
129
130
131

132
133
134
135
136
137
138
139
140
141
142

143
144
145
146
147
148
149
150
151
152
153
154

155
156
157
158
159
160
161
162
163
164
165
166

167
168
169
170
171
172
173
174
175
176
177
178

179
180
181
182
183
184
185
186
187
188
189
190

191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216

217
218
219
220
221
222
223
224
225
226

227
228
229
230
231
232
233
234

235
236
237
238
239
240
241
242
243
244

245
246
247
248
249
250
251
252
//const WWW_URL = 'http://garradin.chezmoi.tld' . WWW_URI;

/**
 * Adresse URL HTTP(S) de l'admin Garradin
 *
 * Défaut : WWW_URL + 'admin/'
 */

//const ADMIN_URL = 'https://admin.garradin.chezmoi.tld/';

/**
 * Affichage des erreurs
 * Si "true" alors un message expliquant l'erreur et comment rapporter le bug s'affiche
 * en cas d'erreur. Sinon rien ne sera affiché.
 *
 * Défaut : false
 *
 * Il est fortement conseillé de mettre cette valeur à false en production !
 */

const SHOW_ERRORS = false;

/**
 * Envoi des erreurs par e-mail
 *
 * Si renseigné, un email sera envoyé à l'adresse indiquée à chaque fois qu'une erreur
 * d'exécution sera rencontrée.
 * Si "false" alors aucun email ne sera envoyé.
 * Note : les erreurs sont déjà toutes loguées dans error.log à la racine de DATA_ROOT
 *
 * Défaut : false
 */

const MAIL_ERRORS = false;

/**
 * Envoi des erreurs à une API compatible AirBrake/Errbit
 *
 * Si renseigné avec une URL HTTP(S) valide, chaque erreur système sera envoyée
 * automatiquement à cette URL.
 *
 * Si laissé à null, aucun rapport ne sera envoyé.
 *
 * Défaut : null
 */

const ERRORS_REPORT_URL = null;

/**
 * Activation de la page permettant de visualiser et rapporter les erreurs présentes
 * dans le error.log.
 *
 * Conseillé de mettre à false si vous ne voulez pas que les administrateurs de votre
 * instance puissent voir les erreurs système.
 *
 * Défaut : true
 * (Afin d'aider au rapport de bugs des instances auto-hébergées)
 */

const ERRORS_ENABLE_LOG_VIEW = true;

/**
 * Utilisation de cron pour les tâches automatiques
 *
 * Si "true" on s'attend à ce qu'une tâche automatisée appelle
 * le script cron.php à la racine toutes les 24 heures. Sinon Garradin
 * effectuera les actions automatiques quand quelqu'un se connecte à
 * l'administration ou visite le site.
 *
 * Défaut : false
 */

const USE_CRON = false;

/**
 * Activation de l'envoi de fichier directement par le serveur web.
 * (X-SendFile)
 *
 * Permet d'améliorer la rapidité d'envoi des fichiers.
 * Supporte les serveurs web suivants :
 * - Apache avec mod_xsendfile (paquet libapache2-mod-xsendfile)
 * - Lighttpd
 *
 * N'activer que si vous êtes sûr que le module est installé et activé (sinon 
 * les fichiers ne pourront être vus ou téléchargés).
 * Nginx n'est PAS supporté, car X-Accel-Redirect ne peut gérer que des fichiers
 * qui sont *dans* le document root du vhost, ce qui n'est pas le cas ici.
 *
 * Pour activer X-SendFile mettre dans la config du virtualhost de Garradin:
 * XSendFile On
 * XSendFilePath /var/www/garradin
 *
 * (remplacer le chemin par le répertoire racine de Garradin)
 *
 * Détails : https://tn123.org/mod_xsendfile/
 *
 * Défaut : false
 */

const ENABLE_XSENDFILE = false;

/**
 * Serveur NTP utilisé pour les connexions avec TOTP
 * (utilisé seulement si le code OTP fourni est faux)
 *
 * Désactiver (false) si vous êtes sûr que votre serveur est toujours à l'heure.
 *
 * Défaut : fr.pool.ntp.org
 */

const NTP_SERVER = 'fr.pool.ntp.org';

/**
 * Hôte du serveur SMTP, mettre à false (défaut) pour utiliser la fonction
 * mail() de PHP
 *
 * Défaut : false
 */

const SMTP_HOST = false;

/**
 * Port du serveur SMTP
 *
 * 25 = port standard pour connexion non chiffrée (465 pour Gmail)
 * 587 = port standard pour connexion SSL
 *
 * Défaut : 587
 */

const SMTP_PORT = 587;

/**
 * Login utilisateur pour le server SMTP
 *
 * mettre à null pour utiliser un serveur local ou anonyme
 *
 * Défaut : null







>











>
|











>
|











>
|











>
|











>
|










|














>
|









>
|







>
|









>
|







145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
//const WWW_URL = 'http://garradin.chezmoi.tld' . WWW_URI;

/**
 * Adresse URL HTTP(S) de l'admin Garradin
 *
 * Défaut : WWW_URL + 'admin/'
 */

//const ADMIN_URL = 'https://admin.garradin.chezmoi.tld/';

/**
 * Affichage des erreurs
 * Si "true" alors un message expliquant l'erreur et comment rapporter le bug s'affiche
 * en cas d'erreur. Sinon rien ne sera affiché.
 *
 * Défaut : false
 *
 * Il est fortement conseillé de mettre cette valeur à false en production !
 */

//const SHOW_ERRORS = false;

/**
 * Envoi des erreurs par e-mail
 *
 * Si renseigné, un email sera envoyé à l'adresse indiquée à chaque fois qu'une erreur
 * d'exécution sera rencontrée.
 * Si "false" alors aucun email ne sera envoyé.
 * Note : les erreurs sont déjà toutes loguées dans error.log à la racine de DATA_ROOT
 *
 * Défaut : false
 */

//const MAIL_ERRORS = false;

/**
 * Envoi des erreurs à une API compatible AirBrake/Errbit
 *
 * Si renseigné avec une URL HTTP(S) valide, chaque erreur système sera envoyée
 * automatiquement à cette URL.
 *
 * Si laissé à null, aucun rapport ne sera envoyé.
 *
 * Défaut : null
 */

//const ERRORS_REPORT_URL = null;

/**
 * Activation de la page permettant de visualiser et rapporter les erreurs présentes
 * dans le error.log.
 *
 * Conseillé de mettre à false si vous ne voulez pas que les administrateurs de votre
 * instance puissent voir les erreurs système.
 *
 * Défaut : true
 * (Afin d'aider au rapport de bugs des instances auto-hébergées)
 */

//const ERRORS_ENABLE_LOG_VIEW = true;

/**
 * Utilisation de cron pour les tâches automatiques
 *
 * Si "true" on s'attend à ce qu'une tâche automatisée appelle
 * le script cron.php à la racine toutes les 24 heures. Sinon Garradin
 * effectuera les actions automatiques quand quelqu'un se connecte à
 * l'administration ou visite le site.
 *
 * Défaut : false
 */

//const USE_CRON = false;

/**
 * Activation de l'envoi de fichier directement par le serveur web.
 * (X-SendFile)
 *
 * Permet d'améliorer la rapidité d'envoi des fichiers.
 * Supporte les serveurs web suivants :
 * - Apache avec mod_xsendfile (paquet libapache2-mod-xsendfile)
 * - Lighttpd
 *
 * N'activer que si vous êtes sûr que le module est installé et activé (sinon
 * les fichiers ne pourront être vus ou téléchargés).
 * Nginx n'est PAS supporté, car X-Accel-Redirect ne peut gérer que des fichiers
 * qui sont *dans* le document root du vhost, ce qui n'est pas le cas ici.
 *
 * Pour activer X-SendFile mettre dans la config du virtualhost de Garradin:
 * XSendFile On
 * XSendFilePath /var/www/garradin
 *
 * (remplacer le chemin par le répertoire racine de Garradin)
 *
 * Détails : https://tn123.org/mod_xsendfile/
 *
 * Défaut : false
 */

//const ENABLE_XSENDFILE = false;

/**
 * Serveur NTP utilisé pour les connexions avec TOTP
 * (utilisé seulement si le code OTP fourni est faux)
 *
 * Désactiver (false) si vous êtes sûr que votre serveur est toujours à l'heure.
 *
 * Défaut : fr.pool.ntp.org
 */

//const NTP_SERVER = 'fr.pool.ntp.org';

/**
 * Hôte du serveur SMTP, mettre à false (défaut) pour utiliser la fonction
 * mail() de PHP
 *
 * Défaut : false
 */

//const SMTP_HOST = false;

/**
 * Port du serveur SMTP
 *
 * 25 = port standard pour connexion non chiffrée (465 pour Gmail)
 * 587 = port standard pour connexion SSL
 *
 * Défaut : 587
 */

//const SMTP_PORT = 587;

/**
 * Login utilisateur pour le server SMTP
 *
 * mettre à null pour utiliser un serveur local ou anonyme
 *
 * Défaut : null
270
271
272
273
274
275
276

277
278
279
280
281
282
283
284
285
286
287
288
289
290
291

292
293
294
295
296
297
298
299
300

301
302
303
304
305
306

307
308
309
310
311
312
313
314
315
316
317
318
319
320

321
 * NONE = pas de chiffrement
 * SSL = connexion SSL native
 * TLS = connexion TLS native (le plus sécurisé)
 * STARTTLS = utilisation de STARTTLS (moyennement sécurisé)
 *
 * Défaut : STARTTLS
 */

const SMTP_SECURITY = 'STARTTLS';

/**
 * Activer les sauvegardes automatiques
 *
 * Utile à désactiver si vous avez déjà des sauvegardes effectuées
 * automatiquement au niveau du système.
 *
 * Sinon les sauvegardes seront effectuées soit par la tâche cron
 * soit à l'affichage de la page d'accueil (si nécessaire).
 *
 * Voir paramètre USE_CRON aussi
 *
 * Défaut : true
 */

const ENABLE_AUTOMATIC_BACKUPS = true;


/**
 * Couleur primaire de l'interface admin par défaut
 * (peut être personnalisée dans la configuration)
 *
 * Défaut : #9c4f15
 */

//const ADMIN_COLOR1 = '#20787a';

/**
 * Couleur secondaire de l'interface admin
 * Défaut : #d98628
 */

//const ADMIN_COLOR2 = '#85b9ba';

/**
 * Image de fond par défaut de l'interface admin
 *
 * Cette URL doit être absolue (http://...) ou relative à l'admin (/admin/static...)
 *
 * Attention si l'image est sur un domaine différent vous devrez activer l'entête CORS:
 * Access-Control-Allow-Origin "*"
 *
 * sinon la personnalisation des couleurs ne fonctionnera pas
 *
 * Défaut : [ADMIN_URL]static/gdin_bg.png
 */

//const ADMIN_BACKGROUND_IMAGE = 'http://mon-asso.fr/fond_garradin.png';







>
|














>
|








>






>














>

300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
 * NONE = pas de chiffrement
 * SSL = connexion SSL native
 * TLS = connexion TLS native (le plus sécurisé)
 * STARTTLS = utilisation de STARTTLS (moyennement sécurisé)
 *
 * Défaut : STARTTLS
 */

//const SMTP_SECURITY = 'STARTTLS';

/**
 * Activer les sauvegardes automatiques
 *
 * Utile à désactiver si vous avez déjà des sauvegardes effectuées
 * automatiquement au niveau du système.
 *
 * Sinon les sauvegardes seront effectuées soit par la tâche cron
 * soit à l'affichage de la page d'accueil (si nécessaire).
 *
 * Voir paramètre USE_CRON aussi
 *
 * Défaut : true
 */

//const ENABLE_AUTOMATIC_BACKUPS = true;


/**
 * Couleur primaire de l'interface admin par défaut
 * (peut être personnalisée dans la configuration)
 *
 * Défaut : #9c4f15
 */

//const ADMIN_COLOR1 = '#20787a';

/**
 * Couleur secondaire de l'interface admin
 * Défaut : #d98628
 */

//const ADMIN_COLOR2 = '#85b9ba';

/**
 * Image de fond par défaut de l'interface admin
 *
 * Cette URL doit être absolue (http://...) ou relative à l'admin (/admin/static...)
 *
 * Attention si l'image est sur un domaine différent vous devrez activer l'entête CORS:
 * Access-Control-Allow-Origin "*"
 *
 * sinon la personnalisation des couleurs ne fonctionnera pas
 *
 * Défaut : [ADMIN_URL]static/gdin_bg.png
 */

//const ADMIN_BACKGROUND_IMAGE = 'http://mon-asso.fr/fond_garradin.png';

Modified src/cron.php from [8c598487d9] to [d355372705].

1
2
3


4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php

namespace Garradin;



require_once __DIR__ . '/include/init.php';

// Exécution des tâches automatiques

if (ENABLE_AUTOMATIC_BACKUPS && $config->get('frequence_sauvegardes') && $config->get('nombre_sauvegardes'))
{
	$s = new Sauvegarde;
	$s->auto();
}

// Exécution des rappels automatiques
$rappels = new Rappels;

if ($rappels->countAll())
{
	$rappels->sendPending();
}



>
>












<
<
<
<
|
<
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17




18

<?php

namespace Garradin;

use Garradin\Services\Reminders;

require_once __DIR__ . '/include/init.php';

// Exécution des tâches automatiques

if (ENABLE_AUTOMATIC_BACKUPS && $config->get('frequence_sauvegardes') && $config->get('nombre_sauvegardes'))
{
	$s = new Sauvegarde;
	$s->auto();
}

// Exécution des rappels automatiques




Reminders::sendPending();

Deleted src/include/data/0.7.0.sql version [acaa57e895].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
CREATE TABLE plugins_signaux
-- Association entre plugins et signaux (hooks)
(
    signal TEXT NOT NULL,
    plugin TEXT NOT NULL REFERENCES plugins (id),
    callback TEXT NOT NULL,
    PRIMARY KEY (signal, plugin)
);

CREATE TABLE compta_rapprochement
-- Rapprochement entre compta et relevés de comptes
(
    operation INTEGER NOT NULL PRIMARY KEY REFERENCES compta_journal (id),
    date TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
    auteur INTEGER NOT NULL REFERENCES membres (id)
);

CREATE TABLE fichiers
-- Données sur les fichiers
(
    id INTEGER NOT NULL PRIMARY KEY,
    nom TEXT NOT NULL, -- nom de fichier (par exemple image1234.jpeg)
    type TEXT NULL, -- Type MIME
    image INTEGER NOT NULL DEFAULT 0, -- 1 = image reconnue
    datetime TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP, -- Date d'ajout ou mise à jour du fichier
    id_contenu INTEGER NOT NULL REFERENCES fichiers_contenu (id)
);

CREATE INDEX fichiers_date ON fichiers (datetime);

CREATE TABLE fichiers_contenu
-- Contenu des fichiers
(
    id INTEGER NOT NULL PRIMARY KEY,
    hash TEXT NOT NULL, -- Hash SHA1 du contenu du fichier
    taille INTEGER NOT NULL, -- Taille en octets
    contenu BLOB NULL
);

CREATE UNIQUE INDEX fichiers_hash ON fichiers_contenu (hash);

CREATE TABLE fichiers_membres
-- Associations entre fichiers et membres (photo de profil par exemple)
(
    fichier INTEGER NOT NULL REFERENCES fichiers (id),
    id INTEGER NOT NULL REFERENCES membres (id),
    PRIMARY KEY(fichier, id)
);

CREATE TABLE fichiers_wiki_pages
-- Associations entre fichiers et pages du wiki
(
    fichier INTEGER NOT NULL REFERENCES fichiers (id),
    id INTEGER NOT NULL REFERENCES wiki_pages (id),
    PRIMARY KEY(fichier, id)
);

CREATE TABLE fichiers_compta_journal
-- Associations entre fichiers et journal de compta (pièce comptable par exemple)
(
    fichier INTEGER NOT NULL REFERENCES fichiers (id),
    id INTEGER NOT NULL REFERENCES compta_journal (id),
    PRIMARY KEY(fichier, id)
);
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































Deleted src/include/data/0.7.2.sql version [ba4b5fbcc7].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
-- Colonne manquante
ALTER TABLE rappels_envoyes ADD COLUMN id_rappel INTEGER NULL REFERENCES rappels (id);

-- Un bug a permis d'insérer des comptes avec des lettres minuscules, créant des problèmes
-- corrigeons donc les comptes pour les mettre en majuscules.

UPDATE compta_comptes SET id = UPPER(id);

-- Le champ id_auteur était à NOT NULL, il faut corriger ça pour pouvoir avoir un rapprochement anonyme
-- une fois que le membre a été supprimé

CREATE TABLE compta_rapprochement2
-- Rapprochement entre compta et relevés de comptes
(
    id_operation INTEGER NOT NULL PRIMARY KEY REFERENCES compta_journal (id),
    date TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
    id_auteur INTEGER NULL REFERENCES membres (id)
);

INSERT INTO compta_rapprochement2 SELECT operation, date, auteur FROM compta_rapprochement;

DROP TABLE compta_rapprochement;

ALTER TABLE compta_rapprochement2 RENAME TO compta_rapprochement;
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































Deleted src/include/data/0.8.0.sql version [34e1625504].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
-- Ajouter champ pour OTP
ALTER TABLE membres ADD COLUMN secret_otp TEXT NULL;

-- Ajouter champ clé PGP
ALTER TABLE membres ADD COLUMN clef_pgp TEXT NULL;

--------------------------------------------------------------------------------
-- Mise à jour des tables contenant un champ date pour ajouter la contrainte  --
-- Ceci afin de forcer les champs à contenir un format de date correct        --
-- On en profite pour ajouter les ON DELETE nécessaires                       --
--------------------------------------------------------------------------------

-- Convertir les dates UNIX en date Y-m-d, apparemment il y en a encore parfois ?
UPDATE wiki_pages SET date_creation = datetime(date_creation, "unixepoch") WHERE CAST(date_creation AS INT) = date_creation;
UPDATE wiki_pages SET date_creation = datetime(date_creation) WHERE datetime(date_creation) != date_creation;

-- Renommage des tables qu'il faut mettre à jour
ALTER TABLE cotisations_membres RENAME TO cotisations_membres_old;
ALTER TABLE rappels RENAME TO rappels_old;
ALTER TABLE rappels_envoyes RENAME TO rappels_envoyes_old;
ALTER TABLE wiki_pages RENAME TO wiki_pages_old;
ALTER TABLE wiki_revisions RENAME TO wiki_revisions_old;
ALTER TABLE compta_categories RENAME TO compta_categories_old;
ALTER TABLE compta_comptes_bancaires RENAME TO compta_comptes_bancaires_old;
ALTER TABLE compta_exercices RENAME TO compta_exercices_old;
ALTER TABLE compta_journal RENAME TO compta_journal_old;
ALTER TABLE compta_rapprochement RENAME TO compta_rapprochement_old;
ALTER TABLE fichiers RENAME TO fichiers_old;
ALTER TABLE membres_operations RENAME TO membres_operations_old;
ALTER TABLE membres_categories RENAME TO membres_categories_old;

-- Suppression des index pour que les nouveaux soient liés aux nouvelles tables
DROP INDEX cm_unique;
DROP INDEX wiki_uri;
DROP INDEX wiki_revisions_id_page;
DROP INDEX wiki_revisions_id_auteur;
DROP INDEX compta_operations_exercice;
DROP INDEX compta_operations_date;
DROP INDEX compta_operations_comptes;
DROP INDEX compta_operations_auteur;
DROP INDEX fichiers_date;

-- Suppression ancienne table recherche
DROP TABLE wiki_recherche;

-- Suppression des triggers
-- Sinon les nouveaux ne seront pas créés sur la nouvelle table
DROP TRIGGER wiki_recherche_delete;
DROP TRIGGER wiki_recherche_update;
DROP TRIGGER wiki_recherche_contenu_insert;
DROP TRIGGER wiki_recherche_contenu_chiffre;

-- Création des tables mises à jour (et de leurs index)
.read schema.sql

-- Copie des données
INSERT INTO cotisations_membres SELECT * FROM cotisations_membres_old;
INSERT INTO rappels SELECT * FROM rappels_old;
INSERT INTO rappels_envoyes SELECT id, id_membre, id_cotisation, id_rappel, date, media FROM rappels_envoyes_old;
INSERT INTO wiki_pages SELECT * FROM wiki_pages_old;
INSERT INTO wiki_revisions SELECT * FROM wiki_revisions_old;
INSERT INTO compta_categories SELECT * FROM compta_categories_old;
INSERT INTO compta_comptes_bancaires SELECT * FROM compta_comptes_bancaires_old;
INSERT INTO compta_exercices SELECT * FROM compta_exercices_old;
INSERT INTO compta_journal SELECT *, NULL FROM compta_journal_old;
INSERT INTO compta_rapprochement SELECT * FROM compta_rapprochement_old;
INSERT INTO fichiers SELECT * FROM fichiers_old;
INSERT INTO membres_operations SELECT * FROM membres_operations_old;
INSERT INTO membres_categories SELECT id, nom, droit_wiki, droit_membres, droit_compta,
	droit_inscription, droit_connexion, droit_config, cacher, id_cotisation_obligatoire FROM membres_categories_old;

-- Suppression des anciennes tables
DROP TABLE cotisations_membres_old;
DROP TABLE rappels_old;
DROP TABLE rappels_envoyes_old;
DROP TABLE wiki_pages_old;
DROP TABLE wiki_revisions_old;
DROP TABLE compta_categories_old;
DROP TABLE compta_comptes_bancaires_old;
DROP TABLE compta_exercices_old;
DROP TABLE compta_journal_old;
DROP TABLE compta_rapprochement_old;
DROP TABLE fichiers_old;
DROP TABLE membres_operations_old;
DROP TABLE membres_categories_old;
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































Deleted src/include/data/0.8.3.sql version [68c67cd1a9].

1
2
3
4
5
6
7
8
9
10
11
-- Ajout d'une clause ON DELETE SET NULL sur la table cotisations
ALTER TABLE cotisations_membres RENAME TO cotisations_membres_old;

-- Création des tables mises à jour (et de leurs index)
.read schema.sql

-- Copie des données
INSERT INTO cotisations_membres SELECT * FROM cotisations_membres_old;

-- Suppression des anciennes tables
DROP TABLE cotisations_membres_old;
<
<
<
<
<
<
<
<
<
<
<






















Deleted src/include/data/0.8.4.sql version [107bec2b2d].

1
2
3
-- Mise à jour des URI du wiki pour ne pas inclure les tirets en début et fin de chaîne
-- (problème de concordance entre API PHP et données SQLite)
UPDATE wiki_pages SET uri = trim(uri, '-') WHERE uri != trim(uri, '-');
<
<
<






Deleted src/include/data/0.9.0.sql version [9f23495ff4].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
-- Désactivation de l'accès aux membres, pour les groupes qui n'avaient que le droit de lecture
-- car maintenant ce droit permet de voir les fiches de membres complètes
UPDATE membres_categories SET droit_membres = 0 WHERE droit_membres = 1;

-- Suppression de la colonne description des catégories
ALTER TABLE membres_categories RENAME TO membres_categories_old;

-- Mise à jour table compta_rapprochement: la foreign key sur membres est passée
-- à ON DELETE SET NULL
ALTER TABLE compta_rapprochement RENAME TO compta_rapprochement_old;

-- Re-créer la table
-- Créer également les nouvelles tables email
.read schema.sql

-- Copie des données, sauf la colonne description
INSERT INTO membres_categories SELECT id, nom, droit_wiki,
	droit_membres, droit_compta, droit_inscription,
	droit_connexion, droit_config, cacher,
	id_cotisation_obligatoire FROM membres_categories_old;

-- Suppression des anciennes tables
DROP TABLE membres_categories_old;

-- Migration des données
INSERT INTO compta_rapprochement SELECT * FROM compta_rapprochement_old;
DROP TABLE compta_rapprochement_old;

-- Cette variable n'est plus utilisée
DELETE FROM config WHERE cle = 'email_envoi_automatique';

ALTER TABLE plugins ADD COLUMN menu_condition TEXT NULL;

-- Supprimer le début dans le nom des plugins
UPDATE plugins_signaux SET callback = replace(callback, 'Garradin\Plugin\', '');
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































Deleted src/include/data/0.9.1.sql version [8d911832a5].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
-- Il manquait une clause ON DELETE SET NULL sur la foreign key
-- de cotisations quand on faisait une mise à jour depuis une
-- ancienne version
ALTER TABLE cotisations RENAME TO cotisations_old;

.read schema.sql

INSERT INTO cotisations SELECT * FROM cotisations_old;

DROP TABLE cotisations_old;

-- Changer le compte des reports automatiques
UPDATE compta_journal SET compte_debit = '890' WHERE compte_debit IS NULL;
UPDATE compta_journal SET compte_credit = '890' WHERE compte_credit IS NULL;
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























Added src/include/data/1.0.0-beta6_migration.sql version [13c95a32fe].



























>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
ALTER TABLE fichiers_membres RENAME TO fichiers_membres_old;
ALTER TABLE fichiers_wiki_pages RENAME TO fichiers_wiki_pages_old;
ALTER TABLE fichiers_acc_transactions RENAME TO fichiers_acc_transactions_old;

.read 1.0.0_schema.sql

INSERT INTO fichiers_membres SELECT * FROM fichiers_membres_old;
INSERT INTO fichiers_wiki_pages SELECT * FROM fichiers_wiki_pages_old;
INSERT INTO fichiers_acc_transactions SELECT * FROM fichiers_acc_transactions_old;

DROP TABLE fichiers_membres_old;
DROP TABLE fichiers_wiki_pages_old;
DROP TABLE fichiers_acc_transactions_old;

Added src/include/data/1.0.0-beta8_migration.sql version [ff1b70a076].





>
>
1
2
UPDATE acc_accounts SET type = 11 WHERE code = '120';
UPDATE acc_accounts SET type = 12 WHERE code = '129';

Added src/include/data/1.0.0-rc3_migration.sql version [46b4d521e5].



>
1
UPDATE acc_transactions SET type = 0 WHERE type = 6;

Added src/include/data/1.0.0_migration.sql version [ee5739a872].

























































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
ALTER TABLE membres_operations RENAME TO membres_operations_old;
ALTER TABLE membres_categories RENAME TO membres_categories_old;

DROP TABLE fichiers_compta_journal; -- Inutilisé à ce jour

-- Fix: comptes de clôture et fermeture
UPDATE compta_comptes SET libelle = 'Bilan d''ouverture' WHERE id = '890' AND libelle = 'Bilan de clôture';
INSERT OR REPLACE INTO compta_comptes (id, parent, libelle, position) VALUES ('891', '89', 'Bilan de clôture', 0);

-- N'est pas utilisé
DELETE FROM config WHERE cle = 'categorie_dons' OR cle = 'categorie_cotisations';

.read 1.0.0_schema.sql

-------- MIGRATION COMPTA ---------
INSERT INTO acc_charts (id, country, code, label) VALUES (1, 'FR', 'PCGA1999', 'Plan comptable associatif 1999');

-- Migration comptes de code comme identifiant à ID unique
-- Inversement valeurs actif/passif et produit/charge
INSERT INTO acc_accounts (id, id_chart, code, label, position, user)
	SELECT NULL, 1, id, libelle,
	CASE position
		WHEN 1 THEN 2
		WHEN 2 THEN 1
		WHEN 3 THEN 3
		WHEN 4 THEN 5
		WHEN 8 THEN 4
		-- Suppression de la position "charge ou produit" qui n'a aucun sens
		WHEN 12 THEN 0
		ELSE 0
	END,
	CASE WHEN plan_comptable = 1 THEN 0 ELSE 1 END
	FROM compta_comptes;

-- Migrations projets vers comptes analytiques
INSERT INTO acc_accounts (id_chart, code, label, position, user, type)
	VALUES (1, '99', 'Projets', 0, 1, 0);

INSERT INTO acc_accounts (id_chart, code, label, position, user, type)
	SELECT 1, '99' || substr('0000' || id, -4), libelle, 0, 1, 7 FROM compta_projets;

-- Mise à jour de la position pour les comptes de tiers qui peuvent varier actif ou passif
UPDATE acc_accounts SET position = 3 WHERE code IN (4010, 4110, 4210, 428, 438);

-- Mise à jour position comptes bancaires, qui peuvent être à découvert et donc changer de côté au bilan
UPDATE acc_accounts SET position = 3 WHERE code LIKE '512%';

-- Migration comptes bancaires
UPDATE acc_accounts SET type = 1 WHERE code IN (SELECT id FROM compta_comptes_bancaires);

-- Caisse
UPDATE acc_accounts SET type = 2 WHERE code = '530';

-- Chèques et carte à encaisser
UPDATE acc_accounts SET type = 3 WHERE code = '5112' OR code = '5113';

-- Comptes d'ouverture et de clôture
UPDATE acc_accounts SET type = 9, position = 0 WHERE code = '890';
UPDATE acc_accounts SET type = 10, position = 0 WHERE code = '891';

-- Comptes de tiers
UPDATE acc_accounts SET type = 4 WHERE code IN (SELECT id FROM compta_comptes WHERE id LIKE '4%' AND plan_comptable = 0 AND desactive = 0);

-- Recopie des mouvements
INSERT INTO acc_transactions (id, label, notes, reference, date, id_year, id_creator)
	SELECT id, libelle, remarques, numero_piece, date, id_exercice, id_auteur
	FROM compta_journal;

-- Recettes
UPDATE acc_transactions SET type = 1 WHERE id IN (SELECT id FROM compta_journal WHERE id_categorie IN (SELECT id FROM compta_categories WHERE type = 1));

-- Dépenses
UPDATE acc_transactions SET type = 2 WHERE id IN (SELECT id FROM compta_journal WHERE id_categorie IN (SELECT id FROM compta_categories WHERE type = -1));

-- Virements
UPDATE acc_transactions SET type = 3 WHERE id IN (SELECT id FROM compta_journal
	WHERE (compte_credit IN ('530', '5112', '5115') OR compte_credit LIKE '512%')
	AND (compte_debit IN ('530', '5112', '5115') OR compte_debit LIKE '512%'));

-- Dettes
UPDATE acc_transactions SET type = 4 WHERE id IN (SELECT id FROM compta_journal WHERE compte_debit LIKE '6%' AND compte_credit LIKE '4%');

-- Créances
UPDATE acc_transactions SET type = 5 WHERE id IN (SELECT id FROM compta_journal WHERE compte_credit LIKE '7%' AND compte_debit LIKE '4%');

-- Création des lignes associées aux mouvements
INSERT INTO acc_transactions_lines (id_transaction, id_account, debit, credit, reference, id_analytical)
	SELECT id, (SELECT id FROM acc_accounts WHERE code = compte_credit), 0, CAST(REPLACE(montant * 100, '.0', '') AS INT), numero_cheque,
	CASE WHEN id_projet IS NOT NULL THEN (SELECT id FROM acc_accounts WHERE code = '99' || substr('0000' || id_projet, -4)) ELSE NULL END
	FROM compta_journal;

INSERT INTO acc_transactions_lines (id_transaction, id_account, debit, credit, reference, id_analytical)
	SELECT id, (SELECT id FROM acc_accounts WHERE code = compte_debit), CAST(REPLACE(montant * 100, '.0', '') AS INT), 0, numero_cheque,
	CASE WHEN id_projet IS NOT NULL THEN (SELECT id FROM acc_accounts WHERE code = '99' || substr('0000' || id_projet, -4)) ELSE NULL END
	FROM compta_journal;

-- Recopie des descriptions de catégories dans la table des comptes, et mise des comptes en signets
-- +Fix éventuels types qui ne correspondent pas à leur type… (@Fred C.) (... a.position = X)
-- Revenus
UPDATE acc_accounts SET type = 6, description = (SELECT description FROM compta_categories WHERE compte = acc_accounts.code)
	WHERE id IN (SELECT a.id FROM acc_accounts a INNER JOIN compta_categories c ON c.compte = a.code AND c.type = 1 AND a.position = 5);

-- Dépenses
UPDATE acc_accounts SET type = 5, description = (SELECT description FROM compta_categories WHERE compte = acc_accounts.code)
	WHERE id IN (SELECT a.id FROM acc_accounts a INNER JOIN compta_categories c ON c.compte = a.code AND c.type = -1 AND c.compte NOT LIKE '4%' AND a.position = 4);

-- Tiers
UPDATE acc_accounts SET type = 4, description = (SELECT description FROM compta_categories WHERE compte = acc_accounts.code)
	WHERE id IN (SELECT a.id FROM acc_accounts a INNER JOIN compta_categories c ON c.compte = a.code AND c.type = -1 AND c.compte LIKE '4%');

-- Recopie des opérations, mais le nom a changé pour acc_transactions_users
INSERT INTO acc_transactions_users
	SELECT * FROM membres_operations_old;

-- Recopie des exercices, mais la date de fin ne peut être nulle
INSERT INTO acc_years (id, label, start_date, end_date, closed, id_chart)
	SELECT id, libelle, debut, CASE WHEN fin IS NULL THEN date(debut, '+1 year') ELSE fin END, cloture, 1 FROM compta_exercices;

-- Recopie des catégories, on supprime la colonne id_cotisation_obligatoire
INSERT INTO membres_categories
	SELECT id, nom, droit_wiki, droit_membres, droit_compta, droit_inscription, droit_connexion, droit_config, cacher FROM membres_categories_old;

DROP TABLE membres_categories_old;

-- Transfert des rapprochements
UPDATE acc_transactions_lines SET reconciled = 1 WHERE id_transaction IN (SELECT id_operation FROM compta_rapprochement);

--------- MIGRATION COTISATIONS ----------

INSERT INTO services SELECT id, intitule, description, duree, debut, fin FROM cotisations;

INSERT INTO services_fees (id, label, amount, id_service, id_account, id_year)
	SELECT id, intitule, CASE WHEN montant IS NOT NULL THEN CAST(montant*100 AS integer) ELSE NULL END, id,
		(SELECT id FROM acc_accounts WHERE code = (SELECT compte FROM compta_categories WHERE id = id_categorie_compta)),
		(SELECT MAX(id) FROM acc_years WHERE closed = 0)
	FROM cotisations;

INSERT INTO services_users SELECT cm.id, cm.id_membre, cm.id_cotisation,
	cm.id_cotisation,
	1,
	NULL,
	cm.date,
	CASE
		WHEN c.duree IS NOT NULL THEN date(cm.date, '+'||c.duree||' days')
		WHEN c.fin IS NOT NULL THEN c.fin
		ELSE NULL
	END
	FROM cotisations_membres cm
	INNER JOIN cotisations c ON c.id = cm.id_cotisation;

INSERT INTO services_reminders SELECT * FROM rappels;
INSERT INTO services_reminders_sent SELECT id, id_membre, id_cotisation,
	CASE WHEN id_rappel IS NULL THEN (SELECT MAX(id) FROM rappels) ELSE id_rappel END, date
	FROM rappels_envoyes
	GROUP BY id_membre, id_cotisation, id_rappel;

DROP TABLE cotisations;
DROP TABLE cotisations_membres;
DROP TABLE rappels;
DROP TABLE rappels_envoyes;

-- Suppression inutilisées
DROP TABLE compta_rapprochement;
DROP TABLE compta_journal;
DROP TABLE compta_categories;
DROP TABLE compta_comptes;
DROP TABLE compta_exercices;
DROP TABLE membres_operations_old;

DROP TABLE compta_projets;
DROP TABLE compta_comptes_bancaires;
DROP TABLE compta_moyens_paiement;

Added src/include/data/1.0.0_schema.sql version [2cb870482b].



































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
CREATE TABLE IF NOT EXISTS config (
-- Configuration de Garradin
    cle TEXT PRIMARY KEY NOT NULL,
    valeur TEXT
);

CREATE TABLE IF NOT EXISTS membres_categories
-- Catégories de membres
(
    id INTEGER PRIMARY KEY NOT NULL,
    nom TEXT NOT NULL,

    droit_wiki INTEGER NOT NULL DEFAULT 1,
    droit_membres INTEGER NOT NULL DEFAULT 1,
    droit_compta INTEGER NOT NULL DEFAULT 1,
    droit_inscription INTEGER NOT NULL DEFAULT 0,
    droit_connexion INTEGER NOT NULL DEFAULT 1,
    droit_config INTEGER NOT NULL DEFAULT 0,
    cacher INTEGER NOT NULL DEFAULT 0
);

-- Membres de l'asso
-- Table dynamique générée par l'application
-- voir Garradin\Membres\Champs.php

CREATE TABLE IF NOT EXISTS membres_sessions
-- Sessions
(
    selecteur TEXT NOT NULL,
    hash TEXT NOT NULL,
    id_membre INTEGER NOT NULL REFERENCES membres (id) ON DELETE CASCADE,
    expire INT NOT NULL,

    PRIMARY KEY (selecteur, id_membre)
);

CREATE TABLE IF NOT EXISTS services
-- Types de services (cotisations)
(
    id INTEGER PRIMARY KEY NOT NULL,

    label TEXT NOT NULL,
    description TEXT NULL,

    duration INTEGER NULL CHECK (duration IS NULL OR duration > 0), -- En jours
    start_date TEXT NULL CHECK (start_date IS NULL OR date(start_date) = start_date),
    end_date TEXT NULL CHECK (end_date IS NULL OR (date(end_date) = end_date AND date(end_date) >= date(start_date)))
);

CREATE TABLE IF NOT EXISTS services_fees
(
    id INTEGER PRIMARY KEY NOT NULL,

    label TEXT NOT NULL,
    description TEXT NULL,

    amount INTEGER NULL,
    formula TEXT NULL, -- Formule de calcul du montant de la cotisation, si cotisation dynamique (exemple : membres.revenu_imposable * 0.01)

    id_service INTEGER NOT NULL REFERENCES services (id) ON DELETE CASCADE,
    id_account INTEGER NULL REFERENCES acc_accounts (id) ON DELETE SET NULL CHECK (id_account IS NULL OR id_year IS NOT NULL), -- NULL si le type n'est pas associé automatiquement à la compta
    id_year INTEGER NULL REFERENCES acc_years (id) ON DELETE SET NULL -- NULL si le type n'est pas associé automatiquement à la compta
);

CREATE TABLE IF NOT EXISTS services_users
-- Enregistrement des cotisations et activités
(
    id INTEGER NOT NULL PRIMARY KEY,
    id_user INTEGER NOT NULL REFERENCES membres (id) ON DELETE CASCADE,
    id_service INTEGER NOT NULL REFERENCES services (id) ON DELETE CASCADE,
    id_fee INTEGER NULL REFERENCES services_fees (id) ON DELETE CASCADE,

    paid INTEGER NOT NULL DEFAULT 0,
    expected_amount INTEGER NULL,

    date TEXT NOT NULL DEFAULT CURRENT_DATE CHECK (date(date) IS NOT NULL AND date(date) = date),
    expiry_date TEXT NULL CHECK (date(expiry_date) IS NULL OR date(expiry_date) = expiry_date)
);

CREATE UNIQUE INDEX IF NOT EXISTS su_unique ON services_users (id_user, id_service, date);

CREATE INDEX IF NOT EXISTS su_service ON services_users (id_service);
CREATE INDEX IF NOT EXISTS su_fee ON services_users (id_fee);
CREATE INDEX IF NOT EXISTS su_paid ON services_users (paid);
CREATE INDEX IF NOT EXISTS su_expiry ON services_users (expiry_date);

CREATE TABLE IF NOT EXISTS services_reminders
-- Rappels de devoir renouveller une cotisation
(
    id INTEGER NOT NULL PRIMARY KEY,
    id_service INTEGER NOT NULL REFERENCES services (id) ON DELETE CASCADE,

    delay INTEGER NOT NULL, -- Délai en jours pour envoyer le rappel

    subject TEXT NOT NULL,
    body TEXT NOT NULL
);

CREATE TABLE IF NOT EXISTS services_reminders_sent
-- Enregistrement des rappels envoyés à qui et quand
(
    id INTEGER NOT NULL PRIMARY KEY,

    id_user INTEGER NOT NULL REFERENCES membres (id) ON DELETE CASCADE,
    id_service INTEGER NOT NULL REFERENCES services (id) ON DELETE CASCADE,
    id_reminder INTEGER NOT NULL REFERENCES services_reminders (id) ON DELETE CASCADE,

    date TEXT NOT NULL DEFAULT CURRENT_DATE CHECK (date(date) IS NOT NULL AND date(date) = date)
);

CREATE UNIQUE INDEX IF NOT EXISTS srs_index ON services_reminders_sent (id_user, id_service, id_reminder, date);

CREATE INDEX IF NOT EXISTS srs_reminder ON services_reminders_sent (id_reminder);
CREATE INDEX IF NOT EXISTS srs_user ON services_reminders_sent (id_user);

--
-- WIKI
--

CREATE TABLE IF NOT EXISTS wiki_pages
-- Pages du wiki
(
    id INTEGER PRIMARY KEY NOT NULL,
    uri TEXT NOT NULL, -- URI unique (équivalent NomPageWiki)
    titre TEXT NOT NULL,
    date_creation TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP CHECK (datetime(date_creation) IS NOT NULL AND datetime(date_creation) = date_creation),
    date_modification TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP CHECK (datetime(date_modification) IS NOT NULL AND datetime(date_modification) = date_modification),
    parent INTEGER NOT NULL DEFAULT 0, -- ID de la page parent
    revision INTEGER NOT NULL DEFAULT 0, -- Numéro de révision (commence à 0 si pas de texte, +1 à chaque changement du texte)
    droit_lecture INTEGER NOT NULL DEFAULT 0, -- Accès en lecture (-1 = public [site web], 0 = tous ceux qui ont accès en lecture au wiki, 1+ = ID de groupe)
    droit_ecriture INTEGER NOT NULL DEFAULT 0 -- Accès en écriture (0 = tous ceux qui ont droit d'écriture sur le wiki, 1+ = ID de groupe)
);

CREATE UNIQUE INDEX IF NOT EXISTS wiki_uri ON wiki_pages (uri);

CREATE VIRTUAL TABLE IF NOT EXISTS wiki_recherche USING fts4
-- Table dupliquée pour chercher une page
(
    id INT PRIMARY KEY NOT NULL, -- Clé externe obligatoire
    titre TEXT NOT NULL,
    contenu TEXT NULL, -- Contenu de la dernière révision
    FOREIGN KEY (id) REFERENCES wiki_pages(id)
);

CREATE TABLE IF NOT EXISTS wiki_revisions
-- Révisions du contenu des pages
(
    id_page INTEGER NOT NULL REFERENCES wiki_pages (id) ON DELETE CASCADE,
    revision INTEGER NULL,

    id_auteur INTEGER NULL REFERENCES membres (id) ON DELETE SET NULL,

    contenu TEXT NOT NULL,
    modification TEXT NULL, -- Description des modifications effectuées
    chiffrement INTEGER NOT NULL DEFAULT 0, -- 1 si le contenu est chiffré, 0 sinon
    date TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP CHECK (datetime(date) IS NOT NULL AND datetime(date) = date),

    PRIMARY KEY(id_page, revision)
);

CREATE INDEX IF NOT EXISTS wiki_revisions_id_page ON wiki_revisions (id_page);
CREATE INDEX IF NOT EXISTS wiki_revisions_id_auteur ON wiki_revisions (id_auteur);

-- Triggers pour synchro avec table wiki_pages
CREATE TRIGGER IF NOT EXISTS wiki_recherche_delete AFTER DELETE ON wiki_pages
    BEGIN
        DELETE FROM wiki_recherche WHERE id = old.id;
    END;

CREATE TRIGGER IF NOT EXISTS wiki_recherche_update AFTER UPDATE OF id, titre ON wiki_pages
    BEGIN
        UPDATE wiki_recherche SET id = new.id, titre = new.titre WHERE id = old.id;
    END;

-- Trigger pour mettre à jour le contenu de la table de recherche lors d'une nouvelle révision
CREATE TRIGGER IF NOT EXISTS wiki_recherche_contenu_insert AFTER INSERT ON wiki_revisions WHEN new.chiffrement != 1
    BEGIN
        UPDATE wiki_recherche SET contenu = new.contenu WHERE id = new.id_page;
    END;

-- Si le contenu est chiffré, la recherche n'affiche pas de contenu
CREATE TRIGGER IF NOT EXISTS wiki_recherche_contenu_chiffre AFTER INSERT ON wiki_revisions WHEN new.chiffrement = 1
    BEGIN
        UPDATE wiki_recherche SET contenu = '' WHERE id = new.id_page;
    END;

--
-- COMPTA
--

CREATE TABLE IF NOT EXISTS acc_charts
-- Plans comptables : il peut y en avoir plusieurs
(
    id INTEGER NOT NULL PRIMARY KEY,
    country TEXT NOT NULL,
    code TEXT NULL, -- NULL = plan comptable créé par l'utilisateur
    label TEXT NOT NULL,
    archived INTEGER NOT NULL DEFAULT 0 -- 1 = archivé, non-modifiable
);

CREATE TABLE IF NOT EXISTS acc_accounts
-- Comptes des plans comptables
(
    id INTEGER NOT NULL PRIMARY KEY,
    id_chart INTEGER NOT NULL REFERENCES acc_charts ON DELETE CASCADE,

    code TEXT NOT NULL, -- peut contenir des lettres, eg. 53A, 53B, etc.

    label TEXT NOT NULL,
    description TEXT NULL,

    position INTEGER NOT NULL, -- position actif/passif/charge/produit
    type INTEGER NOT NULL DEFAULT 0, -- Type de compte spécial : banque, caisse, en attente d'encaissement, etc.
    user INTEGER NOT NULL DEFAULT 1 -- 1 = fait partie du plan comptable original, 0 = a été ajouté par l'utilisateur
);

CREATE UNIQUE INDEX IF NOT EXISTS acc_accounts_codes ON acc_accounts (code, id_chart);
CREATE INDEX IF NOT EXISTS acc_accounts_type ON acc_accounts (type);
CREATE INDEX IF NOT EXISTS acc_accounts_position ON acc_accounts (position);

CREATE TABLE IF NOT EXISTS acc_years
-- Exercices
(
    id INTEGER NOT NULL PRIMARY KEY,

    label TEXT NOT NULL,

    start_date TEXT NOT NULL CHECK (date(start_date) IS NOT NULL AND date(start_date) = start_date),
    end_date TEXT NOT NULL CHECK (date(end_date) IS NOT NULL AND date(end_date) = end_date),

    closed INTEGER NOT NULL DEFAULT 0,

    id_chart INTEGER NOT NULL REFERENCES acc_charts (id)
);

CREATE INDEX IF NOT EXISTS acc_years_closed ON acc_years (closed);

CREATE TABLE IF NOT EXISTS acc_transactions
-- Opérations comptables
(
    id INTEGER PRIMARY KEY NOT NULL,

    type INTEGER NOT NULL DEFAULT 0, -- Type d'écriture, 0 = avancée (normale)
    status INTEGER NOT NULL DEFAULT 0, -- Statut (bitmask)

    label TEXT NOT NULL,
    notes TEXT NULL,
    reference TEXT NULL, -- N° de pièce comptable

    date TEXT NOT NULL DEFAULT CURRENT_DATE CHECK (date(date) IS NOT NULL AND date(date) = date),

    validated INTEGER NOT NULL DEFAULT 0, -- 1 = écriture validée, non modifiable

    hash TEXT NULL,
    prev_hash TEXT NULL,

    id_year INTEGER NOT NULL REFERENCES acc_years(id),
    id_creator INTEGER NULL REFERENCES membres(id) ON DELETE SET NULL,
    id_related INTEGER NULL REFERENCES acc_transactions(id) ON DELETE SET NULL -- écriture liée (par ex. remboursement d'une dette)
);

CREATE INDEX IF NOT EXISTS acc_transactions_year ON acc_transactions (id_year);
CREATE INDEX IF NOT EXISTS acc_transactions_date ON acc_transactions (date);
CREATE INDEX IF NOT EXISTS acc_transactions_related ON acc_transactions (id_related);
CREATE INDEX IF NOT EXISTS acc_transactions_type ON acc_transactions (type);
CREATE INDEX IF NOT EXISTS acc_transactions_status ON acc_transactions (status);

CREATE TABLE IF NOT EXISTS acc_transactions_lines
-- Lignes d'écritures d'une opération
(
    id INTEGER PRIMARY KEY NOT NULL,

    id_transaction INTEGER NOT NULL REFERENCES acc_transactions (id) ON DELETE CASCADE,
    id_account INTEGER NOT NULL REFERENCES acc_accounts (id), -- N° du compte dans le plan comptable

    credit INTEGER NOT NULL,
    debit INTEGER NOT NULL,

    reference TEXT NULL, -- Référence de paiement, eg. numéro de chèque
    label TEXT NULL,

    reconciled INTEGER NOT NULL DEFAULT 0,

    id_analytical INTEGER NULL REFERENCES acc_accounts(id) ON DELETE SET NULL,

    CONSTRAINT line_check1 CHECK ((credit * debit) = 0),
    CONSTRAINT line_check2 CHECK ((credit + debit) > 0)
);

CREATE INDEX IF NOT EXISTS acc_transactions_lines_account ON acc_transactions_lines (id_account);
CREATE INDEX IF NOT EXISTS acc_transactions_lines_analytical ON acc_transactions_lines (id_analytical);
CREATE INDEX IF NOT EXISTS acc_transactions_lines_reconciled ON acc_transactions_lines (reconciled);

CREATE TABLE IF NOT EXISTS acc_transactions_users
-- Liaison des écritures et des membres
(
    id_user INTEGER NOT NULL REFERENCES membres (id) ON DELETE CASCADE,
    id_transaction INTEGER NOT NULL REFERENCES acc_transactions (id) ON DELETE CASCADE,
    id_service_user INTEGER NULL REFERENCES services_users (id) ON DELETE SET NULL,

    PRIMARY KEY (id_user, id_transaction)
);

CREATE INDEX IF NOT EXISTS acc_transactions_users_service ON acc_transactions_users (id_service_user);

CREATE TABLE IF NOT EXISTS plugins
(
    id TEXT NOT NULL PRIMARY KEY,
    officiel INTEGER NOT NULL DEFAULT 0,
    nom TEXT NOT NULL,
    description TEXT NULL,
    auteur TEXT NULL,
    url TEXT NULL,
    version TEXT NOT NULL,
    menu INTEGER NOT NULL DEFAULT 0,
    menu_condition TEXT NULL,
    config TEXT NULL
);

CREATE TABLE IF NOT EXISTS plugins_signaux
-- Association entre plugins et signaux (hooks)
(
    signal TEXT NOT NULL,
    plugin TEXT NOT NULL REFERENCES plugins (id),
    callback TEXT NOT NULL,
    PRIMARY KEY (signal, plugin)
);

CREATE TABLE IF NOT EXISTS fichiers
-- Données sur les fichiers
(
    id INTEGER NOT NULL PRIMARY KEY,
    nom TEXT NOT NULL, -- nom de fichier (par exemple image1234.jpeg)
    type TEXT NULL, -- Type MIME
    image INTEGER NOT NULL DEFAULT 0, -- 1 = image reconnue
    datetime TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP CHECK (datetime(datetime) IS NOT NULL AND datetime(datetime) = datetime), -- Date d'ajout ou mise à jour du fichier
    id_contenu INTEGER NOT NULL REFERENCES fichiers_contenu (id) ON DELETE CASCADE
);

CREATE INDEX IF NOT EXISTS fichiers_date ON fichiers (datetime);

CREATE TABLE IF NOT EXISTS fichiers_contenu
-- Contenu des fichiers
(
    id INTEGER NOT NULL PRIMARY KEY,
    hash TEXT NOT NULL, -- Hash SHA1 du contenu du fichier
    taille INTEGER NOT NULL, -- Taille en octets
    contenu BLOB NULL
);

CREATE UNIQUE INDEX IF NOT EXISTS fichiers_hash ON fichiers_contenu (hash);

CREATE TABLE IF NOT EXISTS fichiers_membres
-- Associations entre fichiers et membres (photo de profil par exemple)
(
    fichier INTEGER NOT NULL REFERENCES fichiers (id) ON DELETE CASCADE,
    id INTEGER NOT NULL REFERENCES membres (id) ON DELETE CASCADE,
    PRIMARY KEY(fichier, id)
);

CREATE TABLE IF NOT EXISTS fichiers_wiki_pages
-- Associations entre fichiers et pages du wiki
(
    fichier INTEGER NOT NULL REFERENCES fichiers (id) ON DELETE CASCADE,
    id INTEGER NOT NULL REFERENCES wiki_pages (id) ON DELETE CASCADE,
    PRIMARY KEY(fichier, id)
);

CREATE TABLE IF NOT EXISTS fichiers_acc_transactions
-- Associations entre fichiers et journal de compta (pièce comptable par exemple)
(
    fichier INTEGER NOT NULL REFERENCES fichiers (id) ON DELETE CASCADE,
    id INTEGER NOT NULL REFERENCES acc_transactions (id) ON DELETE CASCADE,
    PRIMARY KEY(fichier, id)
);

CREATE TABLE IF NOT EXISTS recherches
-- Recherches enregistrées
(
    id INTEGER NOT NULL PRIMARY KEY,
    id_membre INTEGER NULL REFERENCES membres (id) ON DELETE CASCADE, -- Si non NULL, alors la recherche ne sera visible que par le membre associé
    intitule TEXT NOT NULL,
    creation TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP CHECK (datetime(creation) IS NOT NULL AND datetime(creation) = creation),
    cible TEXT NOT NULL, -- "membres" ou "compta"
    type TEXT NOT NULL, -- "json" ou "sql"
    contenu TEXT NOT NULL
);


CREATE TABLE IF NOT EXISTS compromised_passwords_cache
-- Cache des hash de mots de passe compromis
(
    hash TEXT NOT NULL PRIMARY KEY
);

CREATE TABLE IF NOT EXISTS compromised_passwords_cache_ranges
-- Cache des préfixes de mots de passe compromis
(
    prefix TEXT NOT NULL PRIMARY KEY,
    date INTEGER NOT NULL
);

Deleted src/include/data/categories_comptables.sql version [7430a75c4a].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
INSERT INTO "compta_categories" VALUES(NULL,-1,'Prestations de service','','604');
INSERT INTO "compta_categories" VALUES(NULL,-1,'Achat de marchandises à vendre','Marchandises destinées à être revendues en l''état.','607');
INSERT INTO "compta_categories" VALUES(NULL,-1,'Achat de fournitures consommables','','6068');
INSERT INTO "compta_categories" VALUES(NULL,-1,'Publicité et relations publiques','','623');
INSERT INTO "compta_categories" VALUES(NULL,-1,'Frais de déplacement des membres','Billet SNCF, remboursement de frais kilométrique, etc.','625');
INSERT INTO "compta_categories" VALUES(NULL,-1,'Locations','Locations versées pour un local ou du matériel.','613');
INSERT INTO "compta_categories" VALUES(NULL,-1,'Fournitures non stockables : eau, électricité...','Facture d''eau, d''opérateur électrique, etc.','6061');
INSERT INTO "compta_categories" VALUES(NULL,-1,'Fournitures administratives','Cartouches d''encre, papier, matériel bureautique, etc.','6064');
INSERT INTO "compta_categories" VALUES(NULL,-1,'Frais d''actes et de contentieux','Insertion au Journal Officiel, frais de justice, etc.','6227');
INSERT INTO "compta_categories" VALUES(NULL,-1,'Frais postaux et télécommunications','Facture d''accès à Internet, timbres, etc.','626');
INSERT INTO "compta_categories" VALUES(NULL,-1,'Licences fédérales','Licences payées pour les adhérents (par exemple fédération sportive etc.)','652');
INSERT INTO "compta_categories" VALUES(NULL,-1,'Prime d''assurance','','616');
INSERT INTO "compta_categories" VALUES(NULL,-1,'Services bancaires','','627');
INSERT INTO "compta_categories" VALUES(NULL,-1,'Divers','','658');

INSERT INTO "compta_categories" VALUES(NULL,1,'Vente de produits finis','Vente de produits fabriqués par l''association.','701');
INSERT INTO "compta_categories" VALUES(NULL,1,'Prestation de service','','706');
INSERT INTO "compta_categories" VALUES(NULL,1,'Revente de marchandises','','707');
INSERT INTO "compta_categories" VALUES(NULL,1,'Manifestations diverses','Revenus provenant de manifestations au profit de l''association : droit d''entrée, location d''emplacement en vide grenier, ventes, etc.','7780');
INSERT INTO "compta_categories" VALUES(NULL,1,'Cotisations','','756');
INSERT INTO "compta_categories" VALUES(NULL,1,'Dons et collectes','','754');
INSERT INTO "compta_categories" VALUES(NULL,1,'Subventions','','740');
INSERT INTO "compta_categories" VALUES(NULL,1,'Divers','','758');
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































Added src/include/data/charts/fr_1999.csv version [38d9f67e8d].



















































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
code,label,description,position,type
1,"Classe 1 — Comptes de capitaux (Fonds propres, emprunts et dettes assimilés)",,Passif,
10,FONDS ASSOCIATIFS ET RÉSERVES,,Passif,
102,Fonds associatif sans droit de reprise,,Passif,
1021,Valeur du patrimoine intégré,,Passif,
1022,Fonds statutaire,,Passif,
1024,Apports sans droit de reprise,,Passif,
103,Fonds associatif avec droit de reprise,,Passif,
1034,Apports avec droit de reprise,,Passif,
105,Écarts de réévaluation,,Passif,
106,Réserves,,Passif,
1063,Réserves statutaires ou contractuelles,,Passif,
1064,Réserves réglementées,,Passif,
1068,Autres réserves (dont réserves pour projet associatif),,Passif,
11,REPORT À NOUVEAU,,Passif,
110,Report à nouveau (Solde créditeur),,Passif,
119,Report à nouveau (Solde débiteur),,Passif,
12,RÉSULTAT NET DE L'EXERCICE,,Passif,
120,Résultat de l'exercice (excédent),,Passif,Résultat excédentaire
129,Résultat de l'exercice (déficit),,Passif,Résultat déficitaire
13,SUBVENTIONS D'INVESTISSEMENT AFFECTÉES A DES BIENS NON RENOUVELABLES,,Passif,
131,Subventions d'investissement (renouvelables),,Passif,
139,Subventions d'investissement inscrites au compte de résultat,,Passif,
14,PROVISIONS REGLEMENTÉES,,Passif,
15,PROVISIONS,,Passif,
151,Provisions pour risques,,Passif,
157,Provisions pour charges à répartir sur plusieurs exercices,,Passif,
158,Autres provisions pour charges,,Passif,
16,EMPRUNTS ET DETTES ASSIMILÉES,,Passif,
164,Emprunts auprès des établissements de crédits,,Passif,
165,Dépôts et cautionnements reçus,,Passif,
167,Emprunts et dettes assorties de conditions particulières,,Passif,
168,Autres emprunts et dettes assimilés,,Passif,
17,DETTES RATTACHÉES À DES PARTICIPATIONS,,Passif,
18,COMPTES DE LIAISON DES ÉTABLISSEMENTS,,Passif,
181,Apports permanents entre siège social et établissements,,Passif,
185,Biens et prestations de services échangés entre établissements et siège social,,Passif,
186,Biens et prestations de services échangés entre établissements (charges),,Passif,
187,Biens et prestations de services échangés entre établissements (produits),,Passif,
19,FONDS DÉDIÉS,,Passif,
194,Fonds dédiés sur subventions de fonctionnement,,Passif,
195,Fonds dédiés sur dons manuels affectés,,Passif,
197,Fonds dédiés sur legs et donations affectés,,Passif,
198,Excédent disponible après affectation au projet associatif,,Passif,
199,Reprise des fonds affectés au projet associatif,,Passif,
2,Classe 2 — Comptes d'immobilisations,,Actif,
20,IMMOBILISATIONS INCORPORELLES,,Actif,
200,Immobilisations incorporelles,,Actif,
21,IMMOBILISATIONS CORPORELLES,,Actif,
210,Investissements,,Actif,
22,IMMOBILISATIONS GREVÉES DE DROITS,,Actif,
228,Immobilisations grevées de droits,,Actif,
229,Droits des propriétaires,,Actif,
23,IMMOBILISATIONS EN COURS,,Actif,
231,Immobilisations corporelles en cours,,Actif,
238,Avances et acomptes versés sur commande d'immobilisations corporelles,,Actif,
26,PARTICIPATIONS ET CRÉANCES RATTACHÉES A DES PARTICIPATIONS,,Actif,
261,Titres de participation,,Actif,
27,AUTRES IMMOBILISATIONS FINANCIÈRES,,Actif,
270,Participations financières,,Actif,
275,Dépôts et cautionnements versés,,Actif,
28,AMORTISSEMENTS DES IMMOBILISATIONS,,Actif,
280,Amortissements des immobilisations incorporelles,,Actif,
281,Amortissements des immobilisations corporelles,,Actif,
29,DÉPRÉCIATION DES IMMOBILISATIONS,,Actif,
290,Dépréciation des immobilisations incorporelles,,Actif,
291,Dépréciation des immobilisations corporelles,,Actif,
3,Classe 3 — Comptes de stocks,,Actif,
31,MATIERES PREMIERES ET FOURNITURES,,Actif,
311,Matières,,Actif,
317,Fournitures,,Actif,
32,AUTRES APPROVISIONNEMENTS,,Actif,
321,Matières consommables,,Actif,
322,Fournitures consommables,,Actif,
33,EN-COURS DE PRODUCTION DE BIENS,,Actif,
331,Produits en cours,,Actif,
335,Travaux en cours,,Actif,
34,EN-COURS DE PRODUCTION DE SERVICES,,Actif,
35,STOCKS DE PRODUITS,,Actif,
351,Produits intermédiaires,,Actif,
355,Produits finis,,Actif,
358,Produits résiduels,,Actif,
3581,Déchets,,Actif,
3585,Rebuts,,Actif,
3586,Matière de récupération,,Actif,
37,STOCKS DE MARCHANDISES,,Actif,
370,Autres stocks de marchandises,,Actif,
39,PROVISIONS POUR DEPRECIATION DES STOCKS ET EN-COURS,,Actif,
391,Provisions pour dépréciation des matières premières et fournitures,,Actif,
4,Classe 4 — Comptes de tiers,,Actif ou passif,
40,FOURNISSEURS ET COMPTES RATTACHÉS,,Passif,
401,Fournisseurs,,Passif,
4010,Autres fournisseurs,,Actif ou passif,Tiers
408,Fournisseurs - Factures non parvenues,,Passif,
409,Avances aux fournisseurs,,Actif,
41,USAGERS ET COMPTES RATTACHÉS,,Actif,
411,Usagers,,Actif,
4110,Autres usagers,,Actif ou passif,Tiers
419,Avances aux usagers,,Passif,
42,PERSONNEL ET COMPTES RATTACHÉS,,Passif,
421,Personnel - Rémunérations dues,,Passif,
4210,Autres membres du personnel,,Actif ou passif,
425,Personnel - Avances et acomptes,,Actif,
428,Personnel - Charges à payer et produits à recevoir,,Actif ou passif,
43,SÉCURITÉ SOCIALE ET AUTRES ORGANISMES SOCIAUX,,Passif,
430,Dettes et crédits envers les organismes sociaux,,Passif,
431,Sécurité sociale,,Passif,
437,Autres organismes sociaux,,Passif,
4372,Mutuelles,,Passif,
4373,Caisse de retraite et de prévoyance,,Passif,
4374,Caisse d'allocations de chômage - Pôle emploi,,Passif,
4375,AGESSA,,Passif,
4378,Autres organismes sociaux - Divers,,Passif,
438,Organismes sociaux - Charges à payer et produits à recevoir,,Actif ou passif,
4382,Charges sociales sur congés à payer,,Passif,
4386,Autres charges à payer,,Passif,
4387,Produits à recevoir,,Actif,
439,Avances auprès des organismes sociaux,,Passif,
44,ÉTAT ET AUTRES COLLECTIVITÉS PUBLIQUES,,Actif,
441,État - Subventions à recevoir,,Actif,
4411,Subventions d'investissement,,Actif,
4417,Subventions d'exploitation,,Actif,
4418,Subventions d'équilibre,,Actif,
4419,Avances sur subventions,,Actif,
442,État - Impôts et taxes recouvrables sur des tiers,,Passif,
444,État - Impôts sur les bénéfices,,Actif,
445,État - Taxes sur le chiffre d'affaires,,Actif,
4455,Taxes sur le chiffre d'affaires à décaisser,,Actif,
44551,TVA à décaisser,,Actif,
44558,Taxes assimilées à la TVA,,Actif,
4456,Taxes sur le chiffre d'affaires déductibles,,Actif,
44562,TVA sur immobilisations,,Actif,
44566,TVA sur autres biens et services,,Actif,
4457,Taxes sur le chiffre d'affaires collectées par l'association,,Actif,
4458,Taxes sur le chiffre d'affaires à régulariser ou en attente,,Actif,
44581,Acomptes - Régime simplifié d'imposition,,Actif,
44582,Acomptes - Régime du forfait,,Actif,
44583,Remboursement de taxes sur le chiffre d'affaires demandé,,Actif,
44584,TVA récupérée d'avance,,Actif,
44586,Taxes sur le chiffre d'affaires sur factures non parvenues,,Actif,
44587,Taxes sur le chiffre d'affaires sur factures à établir,,Actif,
447,"Autres impôts, taxes et versements assimilés",,Passif,
4471,"Autres impôts, taxes et versements assimilés sur rémunérations (Administration des impôts)",,Passif,
44711,Taxe sur les salaires,,Passif,
44713,Participation des employeurs à la formation professionnelle continue,,Passif,
44714,Cotisation par défaut d'investissement obligatoire dans la construction,,Passif,
44718,"Autres impôts, taxes et versements assimilés",,Passif,
4473,"Autres impôts, taxes et versements assimilés sur rémunérations (Autres organismes)",,Passif,
44733,Participation des employeurs à la formation professionnelle continue,,Passif,
44734,Participation des employeurs à l'effort de construction (versements à fonds perdus),,Passif,
4475,"Autres impôts, taxes et versements assimilés (Administration des impôts)",,Passif,
4477,"Autres impôts, taxes et versements assimilés (Autres organismes)",,Passif,
448,État - Charges à payer et produits à recevoir,,Passif,
4482,Charges fiscales sur congés à payer,,Passif,
4486,Autres charges à payer,,Passif,
4487,Produits à recevoir,,Actif,
449,Avances auprès de l'état et des collectivités publiques,,Passif,
45,"CONFÉDÉRATION, FÉDÉRATION, UNIONS ET ASSOCIATIONS AFFILIÉES",,Actif ou passif,
451,"Confédération, fédération et associations affiliées - Compte courant",,Actif ou passif,
455,Sociétaires - Comptes courants,,Actif ou passif,
46,DÉBITEURS DIVERS ET CRÉDITEURS DIVERS,,Actif ou passif,
467,Autres comptes débiteurs et créditeurs,,Actif ou passif,
468,Divers - Charges à payer et produits à recevoir,,Actif ou passif,
4686,Charges à payer,,Passif,
4687,Produits à recevoir,,Actif,
47,COMPTES TRANSITOIRES OU D'ATTENTE,,Actif ou passif,
471,Recettes à classer,,Passif,
472,Dépenses à classer et à régulariser,,Actif,
48,COMPTES DE RÉGULARISATION,,Actif ou passif,
481,Charges à répartir sur plusieurs exercices,,Actif,
486,Charges constatées d'avance,,Actif,
487,Produits constatés d'avance,,Passif,
49,DEPRECIATION DES COMPTES DE TIERS,,Actif,
491,Dépréciation des comptes clients,,Actif,
496,Dépréciation des comptes débiteurs divers,,Actif,
5,Classe 5 — Comptes financiers,,Actif,
50,VALEURS MOBILIÈRES DE PLACEMENT,,Actif,
51,"BANQUES, ÉTABLISSEMENTS FINANCIERS ET ASSIMILÉS",,Actif,
511,Valeurs à l'encaissement,,Actif,
5112,Chèques à encaisser,,Actif,Attente d'encaissement
5115,Paiements par carte à encaisser,,Actif,
512,Banques,,Actif ou passif,
53,CAISSE,,Actif,
530,Caisse,,Actif,Caisse
54,RÉGIES D'AVANCES ET ACCRÉDITIFS,,Actif,
58,VIREMENTS INTERNES,,Actif,
59,PROVISIONS POUR DÉPRÉCIATION DES COMPTES FINANCIERS,,Actif,
6,Classe 6 — Comptes de charges,,Charge,
60,ACHATS,,Charge,
601,Achats stockés - Matières premières et fournitures,,Charge,
602,Achats stockés - Autres approvisionnements,,Charge,
604,Achat d'études et prestations de services,,Charge,Dépenses
606,Achats non stockés de matières et fournitures,,Charge,
6061,"Fournitures non stockables (eau, énergie...)","Facture d'eau, d'opérateur électrique, etc.",Charge,Dépenses
6063,Fournitures d'entretien et de petit équipement,,Charge,Dépenses
6064,Fournitures administratives,"Cartouches d'encre, papier, matériel bureautique, etc.",Charge,Dépenses
6068,Autres matières et fournitures,,Charge,Dépenses
607,Achats de marchandises,Marchandises destinées à être revendues en l'état.,Charge,Dépenses
61,SERVICES EXTÉRIEURS,,Charge,
611,Sous-traitance générale,,Charge,
612,Redevances de crédit-bail,,Charge,
613,Locations,Locations versées pour un local ou du matériel.,Charge,Dépenses
614,Charges locatives et de co-propriété,,Charge,
615,Entretiens et réparations,,Charge,
616,Primes d'assurance,,Charge,Dépenses
618,Divers,,Charge,
62,AUTRES SERVICES EXTÉRIEURS,,Charge,
621,Personnel extérieur à l'association,,Charge,
62141,Mises à disposition de personnel salarié,,Charge,Dépenses
622,Rémunérations d'intermédiaires et honoraires,,Charge,
6226,Honoraires,,Charge,
6227,Frais d'actes et de contentieux,"Insertion au Journal Officiel, frais de justice, etc.",Charge,Dépenses
6228,Divers,,Charge,
623,"Publicité, publications, relations publiques","Bulletins, affiches, communication, etc.",Charge,Dépenses
624,Transports de biens et transports collectifs du personnel,,Charge,
625,"Déplacements, missions et réceptions","Billet SNCF, remboursement de frais kilométrique, etc.",Charge,Dépenses
626,Frais postaux et de télécommunications,"Facture d'accès à Internet, timbres, etc.",Charge,Dépenses
627,Services bancaires et assimilés,Frais bancaires,Charge,Dépenses
628,Divers,,Charge,Dépenses
63,"IMPÔTS, TAXES ET VERSEMENTS ASSIMILÉS",,Charge,
631,"Impôts, taxes et versements assimilés sur rémunérations (Administration des impôts)",,Charge,
6311,Taxes sur les salaires,,Charge,
6313,Participations des employeurs à la formation professionnelle continue,,Charge,
635,"Autres impôts, taxes et versements assimilés (Administration des impôts)",,Charge,
6351,Impôts directs (sauf impôts sur les bénéfices),,Charge,
6353,Impôts indirects,,Charge,
637,"Autres impôts, taxes et versements assimilés (Autres organismes)",,Charge,
64,CHARGES DE PERSONNEL,,Charge,
641,Rémunérations du personnel,,Charge,
643,Rémunérations du personnel artistique et assimilés,,Charge,
645,Charges de sécurité sociale et de prévoyance,,Charge,
647,Autres charges sociales,,Charge,
648,Autres charges de personnel,,Charge,
65,AUTRES CHARGES DE GESTION COURANTE,,Charge,
652,Licences fédérales,Licences payées pour les adhérents (par exemple fédération sportive etc.),Charge,Dépenses
658,Charges diverses de gestion courante,,Charge,Dépenses
66,CHARGES FINANCIÈRES,,Charge,
661,Charges d'intérêts,,Charge,
67,CHARGES EXCEPTIONNELLES,,Charge,
670,Charges exceptionnelles,Autres dépenses exceptionnelles,Charge,Dépenses
671,Charges exceptionnelles sur opérations de gestion,,Charge,
6713,"Dons, libéralités",,Charge,
678,Autres charges exceptionnelles,,Charge,
6788,Charges exceptionnelles diverses,,Charge,
68,"DOTATIONS AUX AMORTISSEMENTS, DÉPRÉCIATIONS, PROVISIONS ET ENGAGEMENTS",,Charge,
681,"Dotations aux amortissements, dépréciations et provisions - Charges d'exploitation",,Charge,
6811,Dotations aux amortissements des immobilisations incorporelles et corporelles,,Charge,
68111,Immobilisations incorporelles,,Charge,
68112,Immobilisations corporelles,,Charge,
686,"Dotations aux amortissements, dépréciations et provisions - Charges financières",,Charge,
69,PARTICIPATION DES SALARIÉS - IMPÔTS SUR LES BÉNÉFICES ET ASSIMILÉS,,Charge,
695,Impôts sur les sociétés (y compris impôts sur les sociétés des personnes morales non lucratives),,Charge,
7,Classe 7 — Comptes de produits,,Produit,
70,"VENTES DE PRODUITS FINIS, PRESTATIONS DE SERVICES, MARCHANDISES",,Produit,
701,Ventes de produits finis,Vente de produits fabriqués par l'association.,Produit,Recettes
706,Prestations de services,,Produit,Recettes
707,Ventes de marchandises,,Produit,Recettes
708,Produits des activités annexes,,Produit,
71,PRODUCTION STOCKÉE (OU DÉSTOCKAGE),,Produit,
72,PRODUCTION IMMOBILISÉE,,Produit,
74,SUBVENTIONS D'EXPLOITATION,,Produit,
740,Subventions reçues,,Produit,Recettes
75,AUTRES PRODUITS DE GESTION COURANTE,,Produit,
754,Collectes,,Produit,Recettes
756,Cotisations,,Produit,Recettes
758,Produits divers de gestion courante,,Produit,
7587,Ventes de dons en nature,,Produit,
7588,Autres produits de la générosité du public,,Produit,
76,PRODUITS FINANCIERS,,Produit,
760,Produits financiers,,Produit,
77,PRODUITS EXCEPTIONNELS,,Produit,
771,Produits exceptionnels sur opérations de gestion,,Produit,
7713,Libéralités reçues,,Produit,
7715,Subventions d'équilibre,,Produit,
775,Produits des cessions d'éléments d'actifs,,Produit,
778,Autres produits exceptionnels,,Produit,
7780,Manifestations diverses,"Revenus provenant de manifestations au profit de l'association : droit d'entrée, location d'emplacement en vide grenier, ventes, etc.",Produit,Recettes
7788,Produits exceptionnels divers,,Produit,
78,REPRISES SUR AMORTISSEMENTS ET PROVISIONS,,Produit,
79,TRANSFERT DE CHARGES,,Produit,
791,Transferts de charges d'exploitation,,Produit,
796,Transferts de charges financières,,Produit,
797,Transferts de charges exceptionnels,,Produit,
8,Classe 8 ­— Comptes spéciaux,,,
86,RÉPARTITION PAR NATURE DE CHARGES,,Charge,
861,Mise à dispositions gratuites de biens,,Charge,
862,Prestations,,Charge,
864,Personnel bénévole,,Charge,
87,RÉPARTITION PAR NATURE DE RESSOURCES,,Produit,
870,Bénévolat,,Produit,
871,Prestations en nature,,Produit,
875,Dons en nature,,Produit,
89,BILAN,,,
890,Bilan d'ouverture,,,Ouverture
891,Bilan de clôture,,,Clôture
9,Classe 9 — Comptes analytiques,,,
99,Projets,,,Analytique

Added src/include/data/charts/fr_2018.csv version [7724166e91].

















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
code,label,description,position,type
1,"Classe 1 — Comptes de capitaux (Fonds propres, emprunts et dettes assimilés)",,Passif,
10,FONDS ASSOCIATIFS ET RÉSERVES,,Passif,
102,Fonds associatifs sans droit de reprise,,Passif,
1021,Première situation nette établie,,Passif,
1022,Fonds statutaires,,Passif,
1023,Dotations non consomptibles,,Passif,
10231,Dotations non consomptibles initiales,,Passif,
10232,Dotations non consomptibles complémentaires,,Passif,
1024,Autres fonds propres sans droit de reprise,,Passif,
103,Fonds associatif avec droit de reprise,,Passif,
1032,Fonds statutaires,,Passif,
1034,Autres fonds propres avec droit de reprise,,Passif,
105,Ecarts de réévaluation,,Passif,
1051,Ecarts réévaluation sur biens sans dt reprise,,Passif,
1052,Ecarts réévaluation sur biens avec dt reprise,,Passif,
106,Réserves,,Passif,
1062,Réserves indisponibles,,Passif,
1063,Réserves statutaires,,Passif,
1064,Réserves réglementées,,Passif,
1068,Réserves pour projet de l’entité,,Passif,
108,Dotations consomptibles,,Passif,
1081,Dotations consomptibles,,Passif,
1089,Dot. consomptibles inscrites au cpte de résul,,Passif,
11,REPORT à NOUVEAU,,Passif,
110,Report à nouveau (Solde créditeur),,Passif,
119,Report à nouveau (Solde débiteur),,Passif,
12,RÉSULTAT NET DE L'EXERCICE,,Passif,
120,Résultat de l'exercice (excédent),,Passif,Résultat excédentaire
129,Résultat de l'exercice (déficit),,Passif,Résultat déficitaire
13,SUBVENTIONS D'INVESTISSEMENTS,,Passif,
131,Subventions d'équipement,,Passif,
139,Subventions inscrites au compte de résultat,,Passif,
14,PROVISIONS RÉGLEMENTÉES,,Passif,
148,Autres provisions réglementées,,Passif,
15,PROVISIONS POUR RISQUES ET CHARGES,,Passif,
151,Provisions pour risques,,Passif,
152,Provisions pour charges sur legs ou donations,,Passif,
153,Provisions pour pensions et obligations simil,,Passif,
155,Provisions pour impôts,,Passif,
157,Provisions pour charges à répartir,,Passif,
158,Autres provisions pour charges,,Passif,
16,EMPRUNTS ET DETTES ASSIMILÉES,,Passif,
163,Autres emprunts obligataires,,Passif,
1631,Titres associatifs et assimilés,,Passif,
164,Emprunts auprès des établissements de crédit,,Passif,
165,Dépôts et cautionnements reçus,,Passif,
1651,Dépôts,,Passif,
1655,Cautionnements,,Passif,
167,Emprunts et dettes sous conditions particulières,,Passif,
168,Autres emprunts et dettes assimilées,,Passif,
18,COMPTES DE LIAISONS,,Passif,
181,Apports permanents siège-établissements,,Passif,
185,Biens & PS échangés siège-établissements,,Passif,
186,Biens & PS entre établissements - Charges,,Passif,
187,Biens & PS entre établissements - Produits,,Passif,
19,FONDS DÉDIÉS OU REPORTÉS,,Passif,
191,Fonds reportés liés aux legs ou donations,,Passif,
1911,Legs ou donations,,Passif,
1912,Donations temporaires d’usufruit,,Passif,
194,Fonds dédiés sur subventions fonctionnement,,Passif,
195,F.d. / contributions financières autres org.,,Passif,
196,F.d. / ressources liées à la générosité,,Passif,
2,Classe 2 — Comptes d'immobilisations,,Actif,
20,IMMOBILISATIONS INCORPORELLES,,Actif,
201,Frais d'établissement,,Actif,
203,Frais de recherche et de développement,,Actif,
204,Donations temporaires d’usufruit,,Actif,
205,"Brevets, licences, marques...",,Actif,
206,Droit au bail,,Actif,
208,Autres immobilisations incorporelles,,Actif,
21,IMMOBILISATIONS CORPORELLES,,Actif,
211,Terrains,,Actif,
212,Agencements / aménagements de terrains,,Actif,
2131,Bâtiments,,Actif,
2135,"Installations, agencements...de constructions",,Actif,
214,Constructions sur sol d'autrui,,Actif,
215,"Installations techniques, matériel, outillage",,Actif,
2154,Matériel industriel,,Actif,
2155,Outillage industriel,,Actif,
218,Autres immobilisations corporelles,,Actif,
2181,"Installations, agencements, aménagem. divers",,Actif,
2182,Matériel de transport,,Actif,
2183,Matériel bureau et informatique,,Actif,
2184,Mobilier,,Actif,
23,IMMOBILISATIONS EN COURS,,Actif,
231,Immobilisations corporelles en cours,,Actif,
238,"Avances, acomptes sur immobilis. corporelles",,Actif,
24,BIEN DESTINÉS À ÊTRE CÉDÉS,,Actif,
240,Biens reçus par legs ou donations à céder,,Actif,
26,PARTICIPATIONS ET CRÉANCES RATTACHÉES,,Actif,
261,Titres de participation,,Actif,
266,Autres formes de participation,,Actif,
267,Créances rattachées à des participations,,Actif,
269,Versements restants sur participations,,Actif,
27,IMMOBILISATIONS FINANCIERES,,Actif,
271,Titres immobilisés (droit de propriété),,Actif,
272,Titres immobilisés (droit de créance),,Actif,
274,Prêts,,Actif,
2742,Prêts aux partenaires,,Actif,
275,Dépôts et cautionnements versés,,Actif,
276,Autres créances immobilisées,,Actif,
28,AMORTISSEMENTS DES IMMOBILISAT,,Actif,
2801,Amt. frais d'établissement,,Actif,
2804,Amt. donations temporaires d’usufruit,,Actif,
2805,"Amt brevets, licences, marques...",,Actif,
2806,Amt. droit au bail,,Actif,
2808,Amt. autres immo.incorporelles,,Actif,
2812,"Amt.agencements, aménagements de terrains",,Actif,
28131,Amortissements bâtiments,,Actif,
28135,"Amt. installations, agencements...",,Actif,
2814,Amt.constructions sur sol d'autrui,,Actif,
2815,"Amt instal. techniques, matériel, outillage",,Actif,
28181,"Amt. intallations, agencements, aménagements",,Actif,
28182,Amt. matériel de transport,,Actif,
28183,"Amortiss.matériel de bureau, informatique",,Actif,
28184,Amortissements du mobilier,,Actif,
29,DÉPRÉCIATIONS DES IMMOBILISATIONS,,Actif,
2904,Donations temporaires d'usufruit,,Actif,
2905,"Brevets, licences, marques...",,Actif,
2906,Droit au bail,,Actif,
2908,Autres immobilisations incorporelles,,Actif,
2911,Terrains,,Actif,
2931,Immobilisations corporelles en cours,,Actif,
294,Biens reçus par legs ou donations à céder,,Actif,
2961,Titres de participations,,Actif,
2966,Autres formes de participations,,Actif,
2967,Créances rattachées à des participations,,Actif,
2971,Titres immobilisés (droit de propriété),,Actif,
2972,Titres immobilisés (droit de créance),,Actif,
2974,Prêts,,Actif,
2975,Dépôts et cautionnements versés,,Actif,
2976,Autres créances immobilisées,,Actif,
3,Classe 3 — Comptes de stocks,,Actif,
31,MATIÈRES PREMIÈRES ET FOURNITURES,,Actif,
318,Matières premières et fournitures,,Actif,
32,AUTRES APPROVISIONNEMENTS,,Actif,
321,Matières consommables,,Actif,
322,Fournitures consommables,,Actif,
326,Emballages,,Actif,
33,EN-COURS DE PRODUCTION DE BIENS,,Actif,
331,Produits en cours,,Actif,
335,Travaux en cours,,Actif,
34,EN-COURS DE PROUCTION DE SERVICES,,Actif,
341,Etudes en cours,,Actif,
345,Prestations de services en cours,,Actif,
35,STOCKS DE PRODUITS,,Actif,
351,Produits intermédiaires,,Actif,
355,Produits finis,,Actif,
358,Produits résiduels,,Actif,
37,STOCKS DE MARCHANDISES,,Actif,
370,Stocks de marchandises,,Actif,
39,PROVISIONS PR DÉPRECIATIONS STOCKS & EN-COURS,,Actif,
391,Matières premières et fournitures,,Actif,
392,Autres approvisionnements,,Actif,
393,En-cours de production de biens,,Actif,
394,En-cours de production de services,,Actif,
395,Stocks de produits,,Actif,
397,Stocks de marchandises,,Actif,
4,Classe 4 — Comptes de tiers,,Actif ou passif,
40,FOURNISSEURS ET COMPTES RATTACHÉS,,Actif ou passif,
401,Fournisseurs,,Actif ou passif,
4010,Autres fournisseurs,,Actif ou passif,Tiers
403,Fournisseurs - Effets à payer,,Passif,
404,Fournisseurs d'immobilisations,,Actif ou passif,
405,Fournisseurs d'immos - Effets à payer,,Passif,
408,Fournisseurs - Factures non parvenues,,Passif,
4091,Fournisseurs - Avances & acomptes,,Actif,
41,USAGERS ET COMPTES RATTACHÉS,,Actif ou passif,
411,Usagers,,Actif ou passif,
4110,Autres usagers,Pour les dettes ou créances des membres,Actif ou passif,Tiers
413,Usagers - Effets à recevoir,,Actif,
416,Usagers douteux ou litigieux,,Actif,
418,Usagers non encore facturés,,Actif,
4191,Usagers créditeurs : Avances et acomptes,,Passif,
42,PERSONNEL ET COMPTES RATTACHÉS,,Actif ou passif,
421,Personnel : Rémunérations dues,,Passif,
4210,Autres membres du personnel,Dettes dûes aux salarié⋅e⋅s,Actif ou passif,Tiers
422,"Comités d'entreprise, d'établissement",,Actif ou passif,
425,Personnel : Avances & acomptes,,Actif,
427,Personnel - Oppositions,,Passif,
4286,Personnel- Charges à payer,,Passif,
4287,Personnel- Produits à recevoir,,Actif,
43,SÉCURITÉ SOCIALE &  AUTRES ORGANISMES SOCIAUX,,Passif,
431,Sécurité sociale,,Passif,
4372,Mutuelles,,Passif,
4373,Caisses de retraites et de prévoyance,,Passif,
4378,Autres organismes sociaux,,Passif,
44,ETAT ET AUTRES COLLECTIVITÉS PUBLIQUES,,Actif,
441,Etat - Subventions à recevoir,,Actif,
4421,Prélèvements à la source- Impôt sur le revenu,,Actif ou passif,
444,Etat - Impôts sur les bénéfices,,Actif ou passif,
4452,TVA due intracommunautaire,,Actif ou passif,
4455,Taxes sur CA à décaisser,,Actif,
44562,TVA déductible sur immobilisations,,Actif,
44566,TVA déductible sur autres biens et services,,Actif,
44571,TVA normale collectée,,Actif,
445711,TVA réduite collectée,,Actif,
445712,TVA super-réduite collectée,,Actif,
445713,TVA intermédiaire collectée,,Actif,
4458,Taxe sur CA à régulariser ou en attente,,Actif,
447,"Autres impôts, taxes et versements assimilés",,Actif,
4486,Etat - Charges à payer,,Passif,
4487,Etat - Produits à recevoir,,Actif,
45,"CONFÉDÉRATION, FEDERATION, UNIONS...AFFILIÉES",,Actif ou passif,
451,"Confédération, fédération at assoc. affiliées",,Actif ou passif,
455,Partenaires - comptes courants,,Actif ou passif,
46,DEBITEURS DIVERS ET CREDIT.DVS,,Actif ou passif,
461,Créances reçues par legs ou donations,,Actif,
466,Dettes des legs ou donations,,Passif,
4671,Débiteurs divers,,Actif ou passif,
4672,Créditeurs divers,,Actif ou passif,
4681,Frais des bénévoles,,Actif ou passif,
4686,Divers - Charges à payer,,Passif,
4687,Divers - Produits à recevoir,,Actif,
47,COMPTES D'ATTENTE,,Actif ou passif,
4715,Compte de transit,,Actif ou passif,
4718,Compte d'attente,,Actif ou passif,
48,COMPTES DE REGULARISATION,,Actif ou passif,
481,Charges à répartir,,Passif,
486,Charges constatées d'avance,,Passif,
487,Produits constatés d'avance,,Actif,
49,DÉPRECIATIONS DES COMPTES DE TIERS,,Actif ou passif,
491,Prov. pour dépreciation des comptes d'usagers,,Passif,
496,Prov. pour dépreci. cptes débiteurs divers,,Passif,
5,Classe 5 — Comptes financiers,,Actif,
50,VALEURS MOBILIERES DE PLACEMENT,,Actif,
503,Actions,,Actif,
506,Obligations,,Actif,
508,Autres VMP et créances assimilées,,Actif,
51,"BANQUES, ETABLISSEMENTS FINANCIERS",,Actif,
5112,Chèques à encaisser,,Actif,Attente d'encaissement
5115,Paiements par carte à encaisser,,Actif,
512,Banques,,Actif ou passif,
5186,Intérêts courus à payer,,Passif,
5187,Intérêts courus à recevoir,,Actif,
53,Caisses,,Actif ou passif,
530,Caisse,,Actif,Caisse
58,VIREMENTS INTERNES,,Actif ou passif,
580,Virements internes,,Actif ou passif,
59,DEPRECIATIONS DES COMPTES FINANCIERS,,Actif ou passif,
5903,Actions,,Actif ou passif,
5906,Obligations,,Actif ou passif,
5908,Autres VMP et créances assimilées,,Actif ou passif,
6,Classe 6 — Comptes de charges,,Charge,
60,ACHATS (SAUF 603),,Charge,
601,Achats stockés - Matières premières et fournitures,,Charge,
6010,Achats stockés de matières et fournitures,,Charge,
6011,Achats stockés - Matières premières,,Charge,
6017,Achats stockés - Fournitures,,Charge,
602,Achats stockés - Autres approvisionnements,,Charge,
6021,Achats stockés - Matières consommables,,Charge,
60221,Achats stockés - Combustibles,,Charge,
60222,Achats stockés - Produits d'entretien,,Charge,
60223,Achats stockés - Fournitures d'atelier,,Charge,
60224,Achats stockés - Fournitures de magasin,,Charge,
60225,Fournitures de bureau,,Charge,
6026,Achats stockés - Emballages,,Charge,
603,Variations de stocks,,Charge,
6031,Variations de stocks matières & fournitures,,Charge,
6032,Variations stocks autres approvisionnements,,Charge,
6037,Variations de stocks de marchandises,,Charge,
604,Achats d'études et prestations de services,,Charge,
605,"Achats matériel, équipements & travaux",,Charge,
606,Achats non stockés de matières et fournitures,,Charge,
6061,"Fournitures non stockables (eau, énergie...)","Facture d'eau, d’électricité, etc.",Charge,Dépenses
60611,Eau,,Charge,
60612,Electricité,,Charge,
60613,Chauffage,,Charge,
6063,Fournitures d'entretien et petit équipement,"Vis, et matériel de bricolage (sauf outils) par exemple",Charge,Dépenses
6064,Fournitures administratives,"Cartouches d'encre, papier, matériel bureautique, etc.",Charge,Dépenses
6065,Petits logiciels,Par exemple contribution à un logiciel de gestion associative génial :-),Charge,Dépenses
6068,Autres fournitures & matières,,Charge,Dépenses
607,Achats de marchandises,Marchandises destinées à être revendues en l'état.,Charge,Dépenses
608,Frais accessoires d'achats,,Charge,
60811,Frais accessoires d'achats sur matières,,Charge,
60817,Frais accessoires d'achats sur fournitures,,Charge,
609,"Rabais, remises et ristournes sur achats",,Charge,
6091,RRR sur achats matières et fournitures,,Charge,
6092,RRR sur achats et autres approvisionnements,,Charge,
6097,RRR sur achats de marchandises,,Charge,
61,SERVICES EXTERIEURS,,Charge,
611,Sous-traitance générale,,Charge,
6122,Redevance crédit-bail mobilier,,Charge,
6125,Redevances crédit-bail immobilier,,Charge,
6132,Locations immobilières,Locations versées pour un local ou du matériel.,Charge,Dépenses
6135,Locations mobilières,,Charge,
6136,Malis sur emballages,,Charge,
614,Charges locatives et de copropriété,,Charge,
6152,Entretien sur biens immobiliers,,Charge,
6155,Entretien sur biens mobiliers,,Charge,
6156,Maintenance,,Charge,
616,Primes d'assurance,"Frais d’assurance local, activité, etc.",Charge,Dépenses
6161,Primes d'assurances mutirisques,,Charge,
6164,Primes d'assurances / risques d'exploitation,,Charge,
6165,Primes d'assurances / insolvabilité usagers,,Charge,
6168,Autres assurances,,Charge,
617,Etudes et recherches,,Charge,
6181,Documentation générale,,Charge,
6183,Documentation technique,,Charge,
6185,"Frais de colloques, séminaires, conférences",,Charge,
6187,Prestations administratives,,Charge,
62,AUTRES SERVICES EXTERIEURS,,Charge,
621,Personnel extérieur à l'association,,Charge,
6211,Personnel intérimaire,,Charge,
6214,Personnel détaché ou prêté à l'association,,Charge,
62141,Mises à disposition de personnel salarié,Frais de mise à disposition via un groupement d’employeurs,Charge,Dépenses
622,Rémunérations d'intermédiaires et honoraires,,Charge,
6221,Commissions ... sur achats,,Charge,
6222,Commissions... sur ventes,,Charge,
6226,Honoraires,,Charge,
62264,Honoraires sur legs ou donations à céder,,Charge,
6227,Frais d'actes et de contentieux,,Charge,
6228,Rémunérations div .intermédiaires & honor.,,Charge,
623,"Publicité, publications, relations publiques","Bulletins, affiches, communication, etc.",Charge,Dépenses
6231,Annonces et insertions,,Charge,
6232,Fêtes et cérémonies,,Charge,
6233,Foires et expositions,,Charge,
6234,Cadeaux,,Charge,
6236,Catalogues et imprimés,,Charge,
6237,Publications,,Charge,
6238,"Divers : pourboires, dons courants",,Charge,
624,Transports de biens...,,Charge,
6241,Transports sur achats,,Charge,
6242,Transports sur ventes,,Charge,
6243,Transports entre établissements,,Charge,
6244,Transports administratifs,,Charge,
6247,Transports collectifs du personnel,,Charge,
6248,Transports divers,,Charge,
625,"Déplacements, missions et réceptions","Billet de train, remboursement de frais kilométrique, etc.",Charge,Dépenses
6251,Voyages et déplacements,,Charge,
6255,Frais de déménagement,,Charge,
6256,Frais de missions,,Charge,
6257,"Frais de réceptions, représentations",,Charge,
626,Frais postaux et de télécommunications,"Facture d'accès à Internet, timbres, etc.",Charge,Dépenses
6261,Liaisons spécialisées,,Charge,
6263,"Affranchissements, frais postaux",,Charge,
6265,Téléphone,,Charge,
627,Services bancaires et assimilés,Frais bancaires,Charge,Dépenses
628,Divers,,Charge,Dépenses
6281,Cotisations (liées à l'activité économique),,Charge,
6284,Frais de recrutement du personnel,,Charge,
63,"IMPÔTS, TAXES ET VERSEMENTS ASSIMILÉS",,Charge,
631,Sur rémunérations - administration des impôts,,Charge,
6311,Taxe sur les salaires,,Charge,
633,Sur rémunérations - autres organismes,,Charge,
6331,Versement de transport,,Charge,
6332,Allocation logement,,Charge,
6333,Formation professionnelle continue,,Charge,
6334,Participations employeurs à l'effort de const,,Charge,
635,Autres - Administration des impôts,,Charge,
63512,Taxes foncières,,Charge,
63513,Autres impôts locaux,,Charge,
6354,Droits d'enregistrement et de timbre,,Charge,
637,Autres - Autres organismes,,Charge,
64,CHARGES DE PERSONNEL,,Charge,
641,Rémunérations du personnel,,Charge,
6411,"Salaires, appointements",,Charge,
6412,Congés payés,,Charge,
6413,Primes et gratifications,,Charge,
6414,Indemnités et avantages divers,,Charge,
6415,Supplément familial,,Charge,
645,Charges de sécurité sociale et de prévoyance,,Charge,
6451,Cotisations à l'URSSAF,,Charge,
6452,Cotisations aux mutuelles,,Charge,
6453,Cotisations caisses de retraites et de prévoy,,Charge,
6458,Cotisations aux autres organismes sociaux,,Charge,
647,Autres charges sociales,,Charge,
6472,Versements aux comités d'entreprise et d'étab,,Charge,
6473,Versement aux comités d'hygiène et de sécurit,,Charge,
6474,Versements aux autres oeuvres sociales,,Charge,
6475,"Médecine du travail, pharmacie",,Charge,
648,Autres charges de personnel,,Charge,
6481,Indemnités du personnel de culte,,Charge,
6485,Charges sociales sur indemnités de culte,,Charge,
6488,Autres charges de personnel,,Charge,
65,AUTRES CHARGES DE GESTION COURANTE,,Charge,
6511,"Redevances pour concessions, brevets, licenc.",,Charge,
6516,Droits d'auteur et de reproduction,,Charge,
6518,Autres droits et valeurs similaires,,Charge,
652,Licences fédérales,Licences payées pour les adhérents (par exemple fédération sportive etc.),Charge,Dépenses
653,Charges de la générosité du public,,Charge,
6531,Autres charges sur legs ou donations,,Charge,
654,Pertes sur créances irrécouvrables,,Charge,
655,Quotes-parts sur opérations faites en commun,,Charge,
657,Aides financières,,Charge,
6571,Aides financières octroyées,,Charge,
6572,Quotes-parts de générosité reversée,,Charge,
658,Charges diverses de gestion courante,,Charge,Dépenses
6586,Cotisations (vie statutaire),,Charge,
6588,Charges diverses de gestion courante,,Charge,
66,CHARGES FINANCIERES,,Charge,
661,Charges d'intérêts,,Charge,
665,Escomptes accordés,,Charge,
666,Pertes de changes,,Charge,
667,Charges nettes sur cessions de VMP,,Charge,
668,Autres charges financières,,Charge,
67,CHARGES EXEPTIONNELLES,,Charge,
670,Charges exceptionnelles,Autres dépenses exceptionnelles,Charge,Dépenses
6712,"Pénalités, amendes fiscales at pénales",,Charge,
6713,"Dons, libéralités",,Charge,
6714,Créances devenues irrécouvrables,,Charge,
6718,Autres charges exceptionnelles de gestion,,Charge,
673,Apports ou affectations en numéraire,,Charge,
675,Valeurs comptables des éléments d'actifs cédés,,Charge,
6750,Valeurs comptables des actifs cédés,,Charge,
6754,Immobilisations reçues par legs ou donations,,Charge,
678,Autres charges exceptionnelles sur opération en capital,,Charge,
68,"DOT. AUX AMORTISS., DÉPRÉC. ET ENGAGEMENTS",,Charge,
6811,Dot. aux amortissements des immobilisations,,Charge,
6812,Dot. aux amortissements charges à répartir,,Charge,
6815,Dot. aux provisions d'exploitation,,Charge,
6816,Dot. provisions pour dépréciations des immos,,Charge,
68164,Dot. pr dépréc. d’actifs reçus par legs ou donations,,Charge,
6817,Dot. aux dépréciations des actifs circulants,,Charge,
68173,Dotations dépréciations stocks et en-cours,,Charge,
68174,Dotations dépréciations créances,,Charge,
686,Dot. aux amort. & prov. - Charges financières,,Charge,
68662,Dot. aux amort. & prov immos financières,,Charge,
68665,Dot. aux amort. & prov VMP,,Charge,
687,Dot. aux amort. & prov. - Charges exceptionn.,,Charge,
689,Reports en fonds dédiés,,Charge,
6891,Reports en fonds reportés,,Charge,
6894,Reports en fonds dédiés / subventions d’exploitation,,Charge,
6895,Reports en fds dédiés / contributions financières d'autres organismes,,Charge,
6896,Reports en fds dédiés / ressources générosité,,Charge,
69,IMPÔTS SUR LES BENEFICES,,Charge,
695,IS sur personnes non lucratives,,Charge,
7,Classe 7 — Comptes de produits,,Produit,
70,"VENTES PROD.FINIS, MARCHANDISES, PRESTATIONS",,Produit,
701,Ventes de produits finis,Vente de produits fabriqués par l'association.,Produit,Recettes
702,Ventes de produits intermédiaires,,Produit,
703,Ventes de produits résiduels,,Produit,
704,Travaux,,Produit,
705,Etudes,,Produit,
706,Prestations de services,,Produit,Recettes
7063,Parrainages,,Produit,
707,Ventes de marchandises,Ventes de produits achetés et revendus en l’état,Produit,Recettes
7073,Ventes de dons en nature,,Produit,
708,Produits des activités annexes,,Produit,
7081,Produits des prestations fournies au personne,,Produit,
7083,Locations diverses,,Produit,
7085,Ports et frais accessoires facturés,,Produit,
7088,Autres produits d'activités annexes,,Produit,
709,RRR accordés,,Produit,
7091,RRR sur ventes de produits finis,,Produit,
7092,RRR sur ventes de produits intermédiaires,,Produit,
7094,RRR sur travaux,,Produit,
7095,RRR sur études,,Produit,
7096,RRR sur prest.de services,,Produit,
7097,RRR sur ventes marchandises,,Produit,
71,PRODUCTION STOCKEE,,Produit,
713,"Variation de stocks (en-cours, productions)",,Produit,
7133,Variation des en-cours de production de biens,,Produit,
7134,Variation des en-cours de production services,,Produit,
7135,Variations de stocks de produits,,Produit,
72,PRODUCTION IMMOBILISEE,,Produit,
721,Production immobilisée incorporelle,,Produit,
722,Production immobilisée corporelle,,Produit,
73,CONCOURS PUBLICS,,Produit,
730,Concours publics,,Produit,
74,SUBVENTION D'EXPLOITATION,,Produit,
740,Subventions reçues,,Produit,Recettes
748,Subventions d'exploitation diverses,,Produit,
75,AUTRES PRODUITS DE GESTION COURANTE,,Produit,
751,"Redevances pour concessions, licences...",,Produit,
753,Versements des fondateurs ou consommation dot,,Produit,
7531,Versements des fondateurs,,Produit,
7532,Quotes-parts de dotation consomptible virée a,,Produit,
754,Ressources liées à la générosité du public,Dons reçus,Produit,Recettes
7541,Dons manuels,,Produit,
75411,Dons manuels,,Produit,
75412,Abandons de frais par les bénévoles,,Produit,
7542,Mécénats,,Produit,
7543,"Legs, donations et assurances-vie",,Produit,
75431,Assurances-vie,,Produit,
75432,Legs ou donations,,Produit,
75433,Autres produits sur legs ou donations,,Produit,
755,Contributions financières,,Produit,
7551,Contributions financières d’autres organismes,,Produit,
7552,Quotes-parts de générosité reçues,,Produit,
756,Cotisations,Cotisations des adherent⋅e⋅s,Produit,Recettes
7561,Cotisations sans contrepartie,,Produit,
7562,Cotisations avec contrepartie,,Produit,
757,Gains de change / créances et dettes d’exploitation,,Produit,
758,Produits divers de gestion courante,,Produit,
7588,Autres produits divers de gestion courante,,Produit,
76,PRODUITS FINANCIERS,,Produit,
761,Produits des participations,,Produit,
762,Produits des autres immobilisat. financières,,Produit,
763,Revenus des autres créances,,Produit,
764,Revenus des VMP,,Produit,
765,Escomptes obtenus,,Produit,
766,Gains de change,,Produit,
767,Produits nets sur cession VMP,,Produit,
768,Autres produits financiers,,Produit,
77,PRODUITS EXCEPTIONNELS,,Produit,
771,Produits exception. sur opération de gestion,,Produit,
7713,Libéralités perçues,,Produit,
7718,Autres produits exception. sur op. de gestion,,Produit,
775,Produits des cessions d'actif,,Produit,
7754,Immos reçues en legs ou donations à céder,,Produit,
777,QP subvention d'investissement virée au résul,,Produit,
778,Autres produits exceptionnels,,Produit,
7780,Manifestations diverses,"Revenus provenant de manifestations au profit de l'association : droit d'entrée, location d'emplacement en vide grenier, ventes, etc.",Produit,Recettes
78,"REPRISES SUR AMORT., DÉPRÉC., ENGAGEMENTS",,Produit,
781,Reprises / amt & prov. d'exploitation,,Produit,
7811,Amt immos corporelles & incorporelles,,Produit,
7815,Reprises sur provisions d'exploitation,,Produit,
7816,Déprec. immos corporelles & incorporelles,,Produit,
78164,Reprises dépréc. d’actifs reçus par legs ou donations destinés à être cédés,,Produit,
7817,Dépréciations actifs circulant,,Produit,
786,Reprises / amt & prov. financiers,,Produit,
7865,Risques & charges financiers,,Produit,
7866,Déprec.des éléments financiers,,Produit,
787,Reprises sur amt & prov. exceptionnelles,,Produit,
7872,Provisions réglementées - Immobilisations,,Produit,
7873,Provisions réglementées - stocks,,Produit,
7874,Autres provisions réglementées,,Produit,
7875,Risques et charges,,Produit,
7876,Dépréciations exceptionnelles,,Produit,
789,Utilisations fds reportés et de fds dédiés,,Produit,
7891,Utilisations de fonds reportés,,Produit,
7894,Utilisations des fonds dédiés / subventions,,Produit,
7895,Utilisations des fds dédiés / contributions,,Produit,
7896,Utilisations des fds dédiés / générosité,,Produit,
79,TRANSFERT DE CHARGES,,Produit,
791,Transferts de charges d'exploitation,,Produit,
796,Transferts de charges financières,,Produit,
797,Transferts de charges exceptionnelles,,Produit,
8,Classe 8 ­— Comptes spéciaux,,,
86,EMPLOIS CONTRIBUTIONS VOLONTAIRES EN NATURE,,,
860,Secours en nature,,,
8601,Alimentaires,,,
8602,Vestimentaires,,,
861,Mise à dispositions gratuites de biens,,,
8611,Locaux,,,
8612,Matériels,,,
862,Prestations,,,
864,Personnel bénévole,,,
87,CONTRIBUTIONS VOLONTAIRES EN NATURE,,,
870,Dons en nature,,,
871,Prestations en nature,,,
875,Bénévolat,,,Bénévolat
89,COMPTES DE BILAN,,,
890,Bilan d'ouverture,,,Ouverture
891,Bilan de clôture,,,Clôture
9,Classe 9 — Comptes analytiques,,,
90,COMPTES RÉFLÉCHIS,,,
906,Charges réfléchies,,,
907,Produits réfléchis,,,
99,Projets,,,Analytique

Deleted src/include/data/plan_comptable.json version [4d7e33a414].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
{
    "1": {
        "code": 1,
        "nom": "Classe 1 \u2014 Comptes de capitaux (Fonds propres, emprunts et dettes assimil\u00e9s)",
        "parent": 0,
        "position": 1
    },
    "10": {
        "code": 10,
        "nom": "FONDS ASSOCIATIFS ET R\u00c9SERVES",
        "parent": 1,
        "position": 1
    },
    "102": {
        "code": 102,
        "nom": "Fonds associatif sans droit de reprise",
        "parent": 10,
        "position": 1
    },
    "1021": {
        "code": 1021,
        "nom": "Valeur du patrimoine int\u00e9gr\u00e9",
        "parent": 102,
        "position": 1
    },
    "1022": {
        "code": 1022,
        "nom": "Fonds statutaire",
        "parent": 102,
        "position": 1
    },
    "1024": {
        "code": 1024,
        "nom": "Apports sans droit de reprise",
        "parent": 102,
        "position": 1
    },
    "103": {
        "code": 103,
        "nom": "Fonds associatif avec droit de reprise",
        "parent": 10,
        "position": 1
    },
    "1034": {
        "code": 1034,
        "nom": "Apports avec droit de reprise",
        "parent": 103,
        "position": 1
    },
    "105": {
        "code": 105,
        "nom": "\u00c9carts de r\u00e9\u00e9valuation",
        "parent": 10,
        "position": 1
    },
    "106": {
        "code": 106,
        "nom": "R\u00e9serves",
        "parent": 10,
        "position": 1
    },
    "1063": {
        "code": 1063,
        "nom": "R\u00e9serves statutaires ou contractuelles",
        "parent": 106,
        "position": 1
    },
    "1064": {
        "code": 1064,
        "nom": "R\u00e9serves r\u00e9glement\u00e9es",
        "parent": 106,
        "position": 1
    },
    "1068": {
        "code": 1068,
        "nom": "Autres r\u00e9serves (dont r\u00e9serves pour projet associatif)",
        "parent": 106,
        "position": 1
    },
    "11": {
        "code": 11,
        "nom": "REPORT \u00c0 NOUVEAU",
        "parent": 1,
        "position": 1
    },
    "110": {
        "code": 110,
        "nom": "Report \u00e0 nouveau (Solde cr\u00e9diteur)",
        "parent": 11,
        "position": 1
    },
    "119": {
        "code": 119,
        "nom": "Report \u00e0 nouveau (Solde d\u00e9biteur)",
        "parent": 11,
        "position": 1
    },
    "12": {
        "code": 12,
        "nom": "R\u00c9SULTAT NET DE L'EXERCICE",
        "parent": 1,
        "position": 1
    },
    "120": {
        "code": 120,
        "nom": "R\u00e9sultat de l'exercice (exc\u00e9dent)",
        "parent": 12,
        "position": 1
    },
    "129": {
        "code": 129,
        "nom": "R\u00e9sultat de l'exercice (d\u00e9ficit)",
        "parent": 12,
        "position": 1
    },
    "13": {
        "code": 13,
        "nom": "SUBVENTIONS D'INVESTISSEMENT AFFECT\u00c9ES A DES BIENS NON RENOUVELABLES",
        "parent": 1,
        "position": 1
    },
    "131": {
        "code": 131,
        "nom": "Subventions d'investissement (renouvelables)",
        "parent": 13,
        "position": 1
    },
    "139": {
        "code": 139,
        "nom": "Subventions d'investissement inscrites au compte de r\u00e9sultat",
        "parent": 13,
        "position": 1
    },
    "14": {
        "code": 14,
        "nom": "PROVISIONS REGLEMENT\u00c9ES",
        "parent": 1,
        "position": 1
    },
    "15": {
        "code": 15,
        "nom": "PROVISIONS",
        "parent": 1,
        "position": 1
    },
    "151": {
        "code": 151,
        "nom": "Provisions pour risques",
        "parent": 15,
        "position": 1
    },
    "157": {
        "code": 157,
        "nom": "Provisions pour charges \u00e0 r\u00e9partir sur plusieurs exercices",
        "parent": 15,
        "position": 1
    },
    "158": {
        "code": 158,
        "nom": "Autres provisions pour charges",
        "parent": 15,
        "position": 1
    },
    "16": {
        "code": 16,
        "nom": "EMPRUNTS ET DETTES ASSIMIL\u00c9ES",
        "parent": 1,
        "position": 1
    },
    "164": {
        "code": 164,
        "nom": "Emprunts aupr\u00e8s des \u00e9tablissements de cr\u00e9dits",
        "parent": 16,
        "position": 1
    },
    "165": {
        "code": 165,
        "nom": "D\u00e9p\u00f4ts et cautionnements re\u00e7us",
        "parent": 16,
        "position": 1
    },
    "167": {
        "code": 167,
        "nom": "Emprunts et dettes assorties de conditions particuli\u00e8res",
        "parent": 16,
        "position": 1
    },
    "168": {
        "code": 168,
        "nom": "Autres emprunts et dettes assimil\u00e9s",
        "parent": 16,
        "position": 1
    },
    "17": {
        "code": 17,
        "nom": "DETTES RATTACH\u00c9ES \u00c0 DES PARTICIPATIONS",
        "parent": 1,
        "position": 1
    },
    "18": {
        "code": 18,
        "nom": "COMPTES DE LIAISON DES \u00c9TABLISSEMENTS",
        "parent": 1,
        "position": 1
    },
    "181": {
        "code": 181,
        "nom": "Apports permanents entre si\u00e8ge social et \u00e9tablissements",
        "parent": 18,
        "position": 1
    },
    "185": {
        "code": 185,
        "nom": "Biens et prestations de services \u00e9chang\u00e9s entre \u00e9tablissements et si\u00e8ge social",
        "parent": 18,
        "position": 1
    },
    "186": {
        "code": 186,
        "nom": "Biens et prestations de services \u00e9chang\u00e9s entre \u00e9tablissements (charges)",
        "parent": 18,
        "position": 1
    },
    "187": {
        "code": 187,
        "nom": "Biens et prestations de services \u00e9chang\u00e9s entre \u00e9tablissements (produits)",
        "parent": 18,
        "position": 1
    },
    "19": {
        "code": 19,
        "nom": "FONDS D\u00c9DI\u00c9S",
        "parent": 1,
        "position": 1
    },
    "194": {
        "code": 194,
        "nom": "Fonds d\u00e9di\u00e9s sur subventions de fonctionnement",
        "parent": 19,
        "position": 1
    },
    "195": {
        "code": 195,
        "nom": "Fonds d\u00e9di\u00e9s sur dons manuels affect\u00e9s",
        "parent": 19,
        "position": 1
    },
    "197": {
        "code": 197,
        "nom": "Fonds d\u00e9di\u00e9s sur legs et donations affect\u00e9s",
        "parent": 19,
        "position": 1
    },
    "198": {
        "code": 198,
        "nom": "Exc\u00e9dent disponible apr\u00e8s affectation au projet associatif",
        "parent": 19,
        "position": 1
    },
    "199": {
        "code": 199,
        "nom": "Reprise des fonds affect\u00e9s au projet associatif",
        "parent": 19,
        "position": 1
    },
    "2": {
        "code": 2,
        "nom": "Classe 2 \u2014 Comptes d'immobilisations",
        "parent": 0,
        "position": 2
    },
    "20": {
        "code": 20,
        "nom": "IMMOBILISATIONS INCORPORELLES",
        "parent": 2,
        "position": 2
    },
    "200": {
        "code": 200,
        "nom": "Immobilisations incorporelles",
        "parent": 20,
        "position": 2
    },
    "21": {
        "code": 21,
        "nom": "IMMOBILISATIONS CORPORELLES",
        "parent": 2,
        "position": 2
    },
    "210": {
        "code": 210,
        "nom": "Investissements",
        "parent": 21,
        "position": 2
    },
    "22": {
        "code": 22,
        "nom": "IMMOBILISATIONS GREV\u00c9ES DE DROITS",
        "parent": 2,
        "position": 2
    },
    "228": {
        "code": 228,
        "nom": "Immobilisations grev\u00e9es de droits",
        "parent": 22,
        "position": 2
    },
    "229": {
        "code": 229,
        "nom": "Droits des propri\u00e9taires",
        "parent": 22,
        "position": 2
    },
    "23": {
        "code": 23,
        "nom": "IMMOBILISATIONS EN COURS",
        "parent": 2,
        "position": 2
    },
    "231": {
        "code": 231,
        "nom": "Immobilisations corporelles en cours",
        "parent": 23,
        "position": 2
    },
    "238": {
        "code": 238,
        "nom": "Avances et acomptes vers\u00e9s sur commande d'immobilisations corporelles",
        "parent": 23,
        "position": 2
    },
    "26": {
        "code": 26,
        "nom": "PARTICIPATIONS ET CR\u00c9ANCES RATTACH\u00c9ES A DES PARTICIPATIONS",
        "parent": 2,
        "position": 2
    },
    "261": {
        "code": 261,
        "nom": "Titres de participation",
        "parent": 26,
        "position": 2
    },
    "27": {
        "code": 27,
        "nom": "AUTRES IMMOBILISATIONS FINANCI\u00c8RES",
        "parent": 2,
        "position": 2
    },
    "270": {
        "code": 270,
        "nom": "Participations financi\u00e8res",
        "parent": 27,
        "position": 2
    },
    "275": {
        "code": 275,
        "nom": "D\u00e9p\u00f4ts et cautionnements vers\u00e9s",
        "parent": 27,
        "position": 2
    },
    "28": {
        "code": 28,
        "nom": "AMORTISSEMENTS DES IMMOBILISATIONS",
        "parent": 2,
        "position": 2
    },
    "280": {
        "code": 280,
        "nom": "Amortissements des immobilisations incorporelles",
        "parent": 28,
        "position": 2
    },
    "281": {
        "code": 281,
        "nom": "Amortissements des immobilisations corporelles",
        "parent": 28,
        "position": 2
    },
    "29": {
        "code": 29,
        "nom": "D\u00c9PR\u00c9CIATION DES IMMOBILISATIONS",
        "parent": 2,
        "position": 2
    },
    "290": {
        "code": 290,
        "nom": "D\u00e9pr\u00e9ciation des immobilisations incorporelles",
        "parent": 29,
        "position": 2
    },
    "291": {
        "code": 291,
        "nom": "D\u00e9pr\u00e9ciation des immobilisations corporelles",
        "parent": 29,
        "position": 2
    },
    "3": {
        "code": 3,
        "nom": "Classe 3 \u2014 Comptes de stocks",
        "parent": 0,
        "position": 2
    },
    "31": {
        "code": 31,
        "nom": "MATIERES PREMIERES ET FOURNITURES",
        "parent": 3,
        "position": 2
    },
    "311": {
        "code": 311,
        "nom": "Mati\u00e8res",
        "parent": 31,
        "position": 2
    },
    "317": {
        "code": 317,
        "nom": "Fournitures",
        "parent": 31,
        "position": 2
    },
    "32": {
        "code": 32,
        "nom": "AUTRES APPROVISIONNEMENTS",
        "parent": 3,
        "position": 2
    },
    "321": {
        "code": 321,
        "nom": "Mati\u00e8res consommables",
        "parent": 32,
        "position": 2
    },
    "322": {
        "code": 322,
        "nom": "Fournitures consommables",
        "parent": 32,
        "position": 2
    },
    "33": {
        "code": 33,
        "nom": "EN-COURS DE PRODUCTION DE BIENS",
        "parent": 3,
        "position": 2
    },
    "331": {
        "code": 331,
        "nom": "Produits en cours",
        "parent": 33,
        "position": 2
    },
    "335": {
        "code": 335,
        "nom": "Travaux en cours",
        "parent": 33,
        "position": 2
    },
    "34": {
        "code": 34,
        "nom": "EN-COURS DE PRODUCTION DE SERVICES",
        "parent": 3,
        "position": 2
    },
    "35": {
        "code": 35,
        "nom": "STOCKS DE PRODUITS",
        "parent": 3,
        "position": 2
    },
    "351": {
        "code": 351,
        "nom": "Produits interm\u00e9diaires",
        "parent": 35,
        "position": 2
    },
    "355": {
        "code": 355,
        "nom": "Produits finis",
        "parent": 35,
        "position": 2
    },
    "358": {
        "code": 358,
        "nom": "Produits r\u00e9siduels",
        "parent": 35,
        "position": 2
    },
    "3581": {
        "code": 3581,
        "nom": "D\u00e9chets",
        "parent": 358,
        "position": 2
    },
    "3585": {
        "code": 3585,
        "nom": "Rebuts",
        "parent": 358,
        "position": 2
    },
    "3586": {
        "code": 3586,
        "nom": "Mati\u00e8re de r\u00e9cup\u00e9ration",
        "parent": 358,
        "position": 2
    },
    "37": {
        "code": 37,
        "nom": "STOCKS DE MARCHANDISES",
        "parent": 3,
        "position": 2
    },
    "370": {
        "code": 370,
        "nom": "Autres stocks de marchandises",
        "parent": 37,
        "position": 2
    },
    "39": {
        "code": 39,
        "nom": "PROVISIONS POUR DEPRECIATION DES STOCKS ET EN-COURS",
        "parent": 3,
        "position": 2
    },
    "391": {
        "code": 391,
        "nom": "Provisions pour d\u00e9pr\u00e9ciation des mati\u00e8res premi\u00e8res et fournitures",
        "parent": 39,
        "position": 2
    },
    "4": {
        "code": 4,
        "nom": "Classe 4 \u2014 Comptes de tiers",
        "parent": 0,
        "position": 3
    },
    "40": {
        "code": 40,
        "nom": "FOURNISSEURS ET COMPTES RATTACH\u00c9S",
        "parent": 4,
        "position": 1
    },
    "401": {
        "code": 401,
        "nom": "Fournisseurs",
        "parent": 40,
        "position": 1
    },
    "4010": {
        "code": 4010,
        "nom": "Autres fournisseurs",
        "parent": 401,
        "position": 1
    },
    "408": {
        "code": 408,
        "nom": "Fournisseurs - Factures non parvenues",
        "parent": 40,
        "position": 1
    },
    "409": {
        "code": 409,
        "nom": "Avances aux fournisseurs",
        "parent": 40,
        "position": 2
    },
    "41": {
        "code": 41,
        "nom": "USAGERS ET COMPTES RATTACH\u00c9S",
        "parent": 4,
        "position": 2
    },
    "411": {
        "code": 411,
        "nom": "Usagers",
        "parent": 41,
        "position": 2
    },
    "4110": {
        "code": 4110,
        "nom": "Autres usagers",
        "parent": 411,
        "position": 2
    },
    "419": {
        "code": 419,
        "nom": "Avances aux usagers",
        "parent": 41,
        "position": 1
    },
    "42": {
        "code": 42,
        "nom": "PERSONNEL ET COMPTES RATTACH\u00c9S",
        "parent": 4,
        "position": 1
    },
    "421": {
        "code": 421,
        "nom": "Personnel - R\u00e9mun\u00e9rations dues",
        "parent": 42,
        "position": 1
    },
    "4210": {
        "code": 4210,
        "nom": "Autres membres du personnel",
        "parent": 421,
        "position": 1
    },
    "425": {
        "code": 425,
        "nom": "Personnel - Avances et acomptes",
        "parent": 42,
        "position": 2
    },
    "428": {
        "code": 428,
        "nom": "Personnel - Charges \u00e0 payer et produits \u00e0 recevoir",
        "parent": 42,
        "position": 1
    },
    "43": {
        "code": 43,
        "nom": "S\u00c9CURIT\u00c9 SOCIALE ET AUTRES ORGANISMES SOCIAUX",
        "parent": 4,
        "position": 1
    },
    "430": {
        "code": 430,
        "nom": "Dettes et cr\u00e9dits envers les organismes sociaux",
        "parent": 43,
        "position": 1
    },
    "431": {
        "code": 431,
        "nom": "S\u00e9curit\u00e9 sociale",
        "parent": 43,
        "position": 1
    },
    "437": {
        "code": 437,
        "nom": "Autres organismes sociaux",
        "parent": 43,
        "position": 1
    },
    "4372": {
        "code": 4372,
        "nom": "Mutuelles",
        "parent": 437,
        "position": 1
    },
    "4373": {
        "code": 4373,
        "nom": "Caisse de retraite et de pr\u00e9voyance",
        "parent": 437,
        "position": 1
    },
    "4374": {
        "code": 4374,
        "nom": "Caisse d'allocations de ch\u00f4mage - P\u00f4le emploi",
        "parent": 437,
        "position": 1
    },
    "4375": {
        "code": 4375,
        "nom": "AGESSA",
        "parent": 437,
        "position": 1
    },
    "4378": {
        "code": 4378,
        "nom": "Autres organismes sociaux - Divers",
        "parent": 437,
        "position": 1
    },
    "438": {
        "code": 438,
        "nom": "Organismes sociaux - Charges \u00e0 payer et produits \u00e0 recevoir",
        "parent": 43,
        "position": 1
    },
    "4382": {
        "code": 4382,
        "nom": "Charges sociales sur cong\u00e9s \u00e0 payer",
        "parent": 438,
        "position": 1
    },
    "4386": {
        "code": 4386,
        "nom": "Autres charges \u00e0 payer",
        "parent": 438,
        "position": 1
    },
    "4387": {
        "code": 4387,
        "nom": "Produits \u00e0 recevoir",
        "parent": 438,
        "position": 2
    },
    "439": {
        "code": 439,
        "nom": "Avances aupr\u00e8s des organismes sociaux",
        "parent": 43,
        "position": 1
    },
    "44": {
        "code": 44,
        "nom": "\u00c9TAT ET AUTRES COLLECTIVIT\u00c9S PUBLIQUES",
        "parent": 4,
        "position": 2
    },
    "441": {
        "code": 441,
        "nom": "\u00c9tat - Subventions \u00e0 recevoir",
        "parent": 44,
        "position": 2
    },
    "4411": {
        "code": 4411,
        "nom": "Subventions d'investissement",
        "parent": 441,
        "position": 2
    },
    "4417": {
        "code": 4417,
        "nom": "Subventions d'exploitation",
        "parent": 441,
        "position": 2
    },
    "4418": {
        "code": 4418,
        "nom": "Subventions d'\u00e9quilibre",
        "parent": 441,
        "position": 2
    },
    "4419": {
        "code": 4419,
        "nom": "Avances sur subventions",
        "parent": 441,
        "position": 2
    },
    "442": {
        "code": 442,
        "nom": "\u00c9tat - Imp\u00f4ts et taxes recouvrables sur des tiers",
        "parent": 44,
        "position": 1
    },
    "444": {
        "code": 444,
        "nom": "\u00c9tat - Imp\u00f4ts sur les b\u00e9n\u00e9fices",
        "parent": 44,
        "position": 2
    },
    "445": {
        "code": 445,
        "nom": "\u00c9tat - Taxes sur le chiffre d'affaires",
        "parent": 44,
        "position": 2
    },
    "4455": {
        "code": 4455,
        "nom": "Taxes sur le chiffre d'affaires \u00e0 d\u00e9caisser",
        "parent": 445,
        "position": 2
    },
    "44551": {
        "code": 44551,
        "nom": "TVA \u00e0 d\u00e9caisser",
        "parent": 4455,
        "position": 2
    },
    "44558": {
        "code": 44558,
        "nom": "Taxes assimil\u00e9es \u00e0 la TVA",
        "parent": 4455,
        "position": 2
    },
    "4456": {
        "code": 4456,
        "nom": "Taxes sur le chiffre d'affaires d\u00e9ductibles",
        "parent": 445,
        "position": 2
    },
    "44562": {
        "code": 44562,
        "nom": "TVA sur immobilisations",
        "parent": 4456,
        "position": 2
    },
    "44566": {
        "code": 44566,
        "nom": "TVA sur autres biens et services",
        "parent": 4456,
        "position": 2
    },
    "4457": {
        "code": 4457,
        "nom": "Taxes sur le chiffre d'affaires collect\u00e9es par l'association",
        "parent": 445,
        "position": 2
    },
    "4458": {
        "code": 4458,
        "nom": "Taxes sur le chiffre d'affaires \u00e0 r\u00e9gulariser ou en attente",
        "parent": 445,
        "position": 2
    },
    "44581": {
        "code": 44581,
        "nom": "Acomptes - R\u00e9gime simplifi\u00e9 d'imposition",
        "parent": 4458,
        "position": 2
    },
    "44582": {
        "code": 44582,
        "nom": "Acomptes - R\u00e9gime du forfait",
        "parent": 4458,
        "position": 2
    },
    "44583": {
        "code": 44583,
        "nom": "Remboursement de taxes sur le chiffre d'affaires demand\u00e9",
        "parent": 4458,
        "position": 2
    },
    "44584": {
        "code": 44584,
        "nom": "TVA r\u00e9cup\u00e9r\u00e9e d'avance",
        "parent": 4458,
        "position": 2
    },
    "44586": {
        "code": 44586,
        "nom": "Taxes sur le chiffre d'affaires sur factures non parvenues",
        "parent": 4458,
        "position": 2
    },
    "44587": {
        "code": 44587,
        "nom": "Taxes sur le chiffre d'affaires sur factures \u00e0 \u00e9tablir",
        "parent": 4458,
        "position": 2
    },
    "447": {
        "code": 447,
        "nom": "Autres imp\u00f4ts, taxes et versements assimil\u00e9s",
        "parent": 44,
        "position": 1
    },
    "4471": {
        "code": 4471,
        "nom": "Autres imp\u00f4ts, taxes et versements assimil\u00e9s sur r\u00e9mun\u00e9rations (Administration des imp\u00f4ts)",
        "parent": 447,
        "position": 1
    },
    "44711": {
        "code": 44711,
        "nom": "Taxe sur les salaires",
        "parent": 4471,
        "position": 1
    },
    "44713": {
        "code": 44713,
        "nom": "Participation des employeurs \u00e0 la formation professionnelle continue",
        "parent": 4471,
        "position": 1
    },
    "44714": {
        "code": 44714,
        "nom": "Cotisation par d\u00e9faut d'investissement obligatoire dans la construction",
        "parent": 4471,
        "position": 1
    },
    "44718": {
        "code": 44718,
        "nom": "Autres imp\u00f4ts, taxes et versements assimil\u00e9s",
        "parent": 4471,
        "position": 1
    },
    "4473": {
        "code": 4473,
        "nom": "Autres imp\u00f4ts, taxes et versements assimil\u00e9s sur r\u00e9mun\u00e9rations (Autres organismes)",
        "parent": 447,
        "position": 1
    },
    "44733": {
        "code": 44733,
        "nom": "Participation des employeurs \u00e0 la formation professionnelle continue",
        "parent": 4473,
        "position": 1
    },
    "44734": {
        "code": 44734,
        "nom": "Participation des employeurs \u00e0 l'effort de construction (versements \u00e0 fonds perdus)",
        "parent": 4473,
        "position": 1
    },
    "4475": {
        "code": 4475,
        "nom": "Autres imp\u00f4ts, taxes et versements assimil\u00e9s (Administration des imp\u00f4ts)",
        "parent": 447,
        "position": 1
    },
    "4477": {
        "code": 4477,
        "nom": "Autres imp\u00f4ts, taxes et versements assimil\u00e9s (Autres organismes)",
        "parent": 447,
        "position": 1
    },
    "448": {
        "code": 448,
        "nom": "\u00c9tat - Charges \u00e0 payer et produits \u00e0 recevoir",
        "parent": 44,
        "position": 1
    },
    "4482": {
        "code": 4482,
        "nom": "Charges fiscales sur cong\u00e9s \u00e0 payer",
        "parent": 448,
        "position": 1
    },
    "4486": {
        "code": 4486,
        "nom": "Autres charges \u00e0 payer",
        "parent": 448,
        "position": 1
    },
    "4487": {
        "code": 4487,
        "nom": "Produits \u00e0 recevoir",
        "parent": 448,
        "position": 2
    },
    "449": {
        "code": 449,
        "nom": "Avances aupr\u00e8s de l'\u00e9tat et des collectivit\u00e9s publiques",
        "parent": 44,
        "position": 1
    },
    "45": {
        "code": 45,
        "nom": "CONF\u00c9D\u00c9RATION, F\u00c9D\u00c9RATION, UNIONS ET ASSOCIATIONS AFFILI\u00c9ES",
        "parent": 4,
        "position": 3
    },
    "451": {
        "code": 451,
        "nom": "Conf\u00e9d\u00e9ration, f\u00e9d\u00e9ration et associations affili\u00e9es - Compte courant",
        "parent": 45,
        "position": 3
    },
    "455": {
        "code": 455,
        "nom": "Soci\u00e9taires - Comptes courants",
        "parent": 45,
        "position": 3
    },
    "46": {
        "code": 46,
        "nom": "D\u00c9BITEURS DIVERS ET CR\u00c9DITEURS DIVERS",
        "parent": 4,
        "position": 3
    },
    "467": {
        "code": 467,
        "nom": "Autres comptes d\u00e9biteurs et cr\u00e9diteurs",
        "parent": 46,
        "position": 3
    },
    "468": {
        "code": 468,
        "nom": "Divers - Charges \u00e0 payer et produits \u00e0 recevoir",
        "parent": 46,
        "position": 3
    },
    "4686": {
        "code": 4686,
        "nom": "Charges \u00e0 payer",
        "parent": 468,
        "position": 1
    },
    "4687": {
        "code": 4687,
        "nom": "Produits \u00e0 recevoir",
        "parent": 468,
        "position": 2
    },
    "47": {
        "code": 47,
        "nom": "COMPTES TRANSITOIRES OU D'ATTENTE",
        "parent": 4,
        "position": 3
    },
    "471": {
        "code": 471,
        "nom": "Recettes \u00e0 classer",
        "parent": 47,
        "position": 1
    },
    "472": {
        "code": 472,
        "nom": "D\u00e9penses \u00e0 classer et \u00e0 r\u00e9gulariser",
        "parent": 47,
        "position": 2
    },
    "48": {
        "code": 48,
        "nom": "COMPTES DE R\u00c9GULARISATION",
        "parent": 4,
        "position": 3
    },
    "481": {
        "code": 481,
        "nom": "Charges \u00e0 r\u00e9partir sur plusieurs exercices",
        "parent": 48,
        "position": 2
    },
    "486": {
        "code": 486,
        "nom": "Charges constat\u00e9es d'avance",
        "parent": 48,
        "position": 2
    },
    "487": {
        "code": 487,
        "nom": "Produits constat\u00e9s d'avance",
        "parent": 48,
        "position": 1
    },
    "49": {
        "code": 49,
        "nom": "DEPRECIATION DES COMPTES DE TIERS",
        "parent": 4,
        "position": 2
    },
    "491": {
        "code": 491,
        "nom": "D\u00e9pr\u00e9ciation des comptes clients",
        "parent": 49,
        "position": 2
    },
    "496": {
        "code": 496,
        "nom": "D\u00e9pr\u00e9ciation des comptes d\u00e9biteurs divers",
        "parent": 49,
        "position": 2
    },
    "5": {
        "code": 5,
        "nom": "Classe 5 \u2014 Comptes financiers",
        "parent": 0,
        "position": 2
    },
    "50": {
        "code": 50,
        "nom": "VALEURS MOBILI\u00c8RES DE PLACEMENT",
        "parent": 5,
        "position": 2
    },
    "51": {
        "code": 51,
        "nom": "BANQUES, \u00c9TABLISSEMENTS FINANCIERS ET ASSIMIL\u00c9S",
        "parent": 5,
        "position": 2
    },
    "511": {
        "code": 511,
        "nom": "Valeurs à l'encaissement",
        "parent": 51,
        "position": 2
    },
    "5112": {
        "code": 5112,
        "nom": "Chèques à encaisser",
        "parent": 511,
        "position": 2
    },
    "5115": {
        "code": 5115,
        "nom": "Paiements par carte à encaisser",
        "parent": 511,
        "position": 2
    },
    "512": {
        "code": 512,
        "nom": "Banques",
        "parent": 51,
        "position": 2
    },
    "53": {
        "code": 53,
        "nom": "CAISSE",
        "parent": 5,
        "position": 2
    },
    "530": {
        "code": 530,
        "nom": "Caisse",
        "parent": 53,
        "position": 2
    },
    "54": {
        "code": 54,
        "nom": "R\u00c9GIES D'AVANCES ET ACCR\u00c9DITIFS",
        "parent": 5,
        "position": 2
    },
    "58": {
        "code": 58,
        "nom": "VIREMENTS INTERNES",
        "parent": 5,
        "position": 2
    },
    "59": {
        "code": 59,
        "nom": "PROVISIONS POUR D\u00c9PR\u00c9CIATION DES COMPTES FINANCIERS",
        "parent": 5,
        "position": 2
    },
    "6": {
        "code": 6,
        "nom": "Classe 6 \u2014 Comptes de charges",
        "parent": 0,
        "position": 8
    },
    "60": {
        "code": 60,
        "nom": "ACHATS",
        "parent": 6,
        "position": 8
    },
    "601": {
        "code": 601,
        "nom": "Achats stock\u00e9s - Mati\u00e8res premi\u00e8res et fournitures",
        "parent": 60,
        "position": 8
    },
    "602": {
        "code": 602,
        "nom": "Achats stock\u00e9s - Autres approvisionnements",
        "parent": 60,
        "position": 8
    },
    "604": {
        "code": 604,
        "nom": "Achat d'\u00e9tudes et prestations de services",
        "parent": 60,
        "position": 8
    },
    "606": {
        "code": 606,
        "nom": "Achats non stock\u00e9s de mati\u00e8res et fournitures",
        "parent": 60,
        "position": 8
    },
    "6061": {
        "code": 6061,
        "nom": "Fournitures non stockables (eau, \u00e9nergie...)",
        "parent": 606,
        "position": 8
    },
    "6063": {
        "code": 6063,
        "nom": "Fournitures d'entretien et de petit \u00e9quipement",
        "parent": 606,
        "position": 8
    },
    "6064": {
        "code": 6064,
        "nom": "Fournitures administratives",
        "parent": 606,
        "position": 8
    },
    "6068": {
        "code": 6068,
        "nom": "Autres mati\u00e8res et fournitures",
        "parent": 606,
        "position": 8
    },
    "607": {
        "code": 607,
        "nom": "Achats de marchandises",
        "parent": 60,
        "position": 8
    },
    "61": {
        "code": 61,
        "nom": "SERVICES EXT\u00c9RIEURS",
        "parent": 6,
        "position": 8
    },
    "611": {
        "code": 611,
        "nom": "Sous-traitance g\u00e9n\u00e9rale",
        "parent": 61,
        "position": 8
    },
    "612": {
        "code": 612,
        "nom": "Redevances de cr\u00e9dit-bail",
        "parent": 61,
        "position": 8
    },
    "613": {
        "code": 613,
        "nom": "Locations",
        "parent": 61,
        "position": 8
    },
    "614": {
        "code": 614,
        "nom": "Charges locatives et de co-propri\u00e9t\u00e9",
        "parent": 61,
        "position": 8
    },
    "615": {
        "code": 615,
        "nom": "Entretiens et r\u00e9parations",
        "parent": 61,
        "position": 8
    },
    "616": {
        "code": 616,
        "nom": "Primes d'assurance",
        "parent": 61,
        "position": 8
    },
    "618": {
        "code": 618,
        "nom": "Divers",
        "parent": 61,
        "position": 8
    },
    "62": {
        "code": 62,
        "nom": "AUTRES SERVICES EXT\u00c9RIEURS",
        "parent": 6,
        "position": 8
    },
    "621": {
        "code": 621,
        "nom": "Personnel ext\u00e9rieur \u00e0 l'association",
        "parent": 62,
        "position": 8
    },
    "622": {
        "code": 622,
        "nom": "R\u00e9mun\u00e9rations d'interm\u00e9diaires et honoraires",
        "parent": 62,
        "position": 8
    },
    "6226": {
        "code": 6226,
        "nom": "Honoraires",
        "parent": 622,
        "position": 8
    },
    "6227": {
        "code": 6227,
        "nom": "Frais d'actes et de contentieux",
        "parent": 622,
        "position": 8
    },
    "6228": {
        "code": 6228,
        "nom": "Divers",
        "parent": 622,
        "position": 8
    },
    "623": {
        "code": 623,
        "nom": "Publicit\u00e9, publications, relations publiques",
        "parent": 62,
        "position": 8
    },
    "624": {
        "code": 624,
        "nom": "Transports de biens et transports collectifs du personnel",
        "parent": 62,
        "position": 8
    },
    "625": {
        "code": 625,
        "nom": "D\u00e9placements, missions et r\u00e9ceptions",
        "parent": 62,
        "position": 8
    },
    "626": {
        "code": 626,
        "nom": "Frais postaux et de t\u00e9l\u00e9communications",
        "parent": 62,
        "position": 8
    },
    "627": {
        "code": 627,
        "nom": "Services bancaires et assimil\u00e9s",
        "parent": 62,
        "position": 8
    },
    "628": {
        "code": 628,
        "nom": "Divers",
        "parent": 62,
        "position": 8
    },
    "63": {
        "code": 63,
        "nom": "IMP\u00d4TS, TAXES ET VERSEMENTS ASSIMIL\u00c9S",
        "parent": 6,
        "position": 8
    },
    "631": {
        "code": 631,
        "nom": "Imp\u00f4ts, taxes et versements assimil\u00e9s sur r\u00e9mun\u00e9rations (Administration des imp\u00f4ts)",
        "parent": 63,
        "position": 8
    },
    "6311": {
        "code": 6311,
        "nom": "Taxes sur les salaires",
        "parent": 631,
        "position": 8
    },
    "6313": {
        "code": 6313,
        "nom": "Participations des employeurs \u00e0 la formation professionnelle continue",
        "parent": 631,
        "position": 8
    },
    "635": {
        "code": 635,
        "nom": "Autres imp\u00f4ts, taxes et versements assimil\u00e9s (Administration des imp\u00f4ts)",
        "parent": 63,
        "position": 8
    },
    "6351": {
        "code": 6351,
        "nom": "Imp\u00f4ts directs (sauf imp\u00f4ts sur les b\u00e9n\u00e9fices)",
        "parent": 635,
        "position": 8
    },
    "6353": {
        "code": 6353,
        "nom": "Imp\u00f4ts indirects",
        "parent": 635,
        "position": 8
    },
    "637": {
        "code": 637,
        "nom": "Autres imp\u00f4ts, taxes et versements assimil\u00e9s (Autres organismes)",
        "parent": 63,
        "position": 8
    },
    "64": {
        "code": 64,
        "nom": "CHARGES DE PERSONNEL",
        "parent": 6,
        "position": 8
    },
    "641": {
        "code": 641,
        "nom": "R\u00e9mun\u00e9rations du personnel",
        "parent": 64,
        "position": 8
    },
    "643": {
        "code": 643,
        "nom": "R\u00e9mun\u00e9rations du personnel artistique et assimil\u00e9s",
        "parent": 64,
        "position": 8
    },
    "645": {
        "code": 645,
        "nom": "Charges de s\u00e9curit\u00e9 sociale et de pr\u00e9voyance",
        "parent": 64,
        "position": 8
    },
    "647": {
        "code": 647,
        "nom": "Autres charges sociales",
        "parent": 64,
        "position": 8
    },
    "648": {
        "code": 648,
        "nom": "Autres charges de personnel",
        "parent": 64,
        "position": 8
    },
    "65": {
        "code": 65,
        "nom": "AUTRES CHARGES DE GESTION COURANTE",
        "parent": 6,
        "position": 8
    },
    "652": {
        "code": 652,
        "nom": "Licences fédérales",
        "parent": 652,
        "position": 8
    },
    "658": {
        "code": 658,
        "nom": "Charges diverses de gestion courante",
        "parent": 65,
        "position": 8
    },
    "66": {
        "code": 66,
        "nom": "CHARGES FINANCI\u00c8RES",
        "parent": 6,
        "position": 8
    },
    "661": {
        "code": 661,
        "nom": "Charges d'int\u00e9r\u00eats",
        "parent": 66,
        "position": 8
    },
    "67": {
        "code": 67,
        "nom": "CHARGES EXCEPTIONNELLES",
        "parent": 6,
        "position": 8
    },
    "671": {
        "code": 671,
        "nom": "Charges exceptionnelles sur op\u00e9rations de gestion",
        "parent": 67,
        "position": 8
    },
    "6713": {
        "code": 6713,
        "nom": "Dons, lib\u00e9ralit\u00e9s",
        "parent": 671,
        "position": 8
    },
    "678": {
        "code": 678,
        "nom": "Autres charges exceptionnelles",
        "parent": 67,
        "position": 8
    },
    "6788": {
        "code": 6788,
        "nom": "Charges exceptionnelles diverses",
        "parent": 678,
        "position": 8
    },
    "68": {
        "code": 68,
        "nom": "DOTATIONS AUX AMORTISSEMENTS, D\u00c9PR\u00c9CIATIONS, PROVISIONS ET ENGAGEMENTS",
        "parent": 6,
        "position": 8
    },
    "681": {
        "code": 681,
        "nom": "Dotations aux amortissements, d\u00e9pr\u00e9ciations et provisions - Charges d'exploitation",
        "parent": 68,
        "position": 8
    },
    "6811": {
        "code": 6811,
        "nom": "Dotations aux amortissements des immobilisations incorporelles et corporelles",
        "parent": 681,
        "position": 8
    },
    "68111": {
        "code": 68111,
        "nom": "Immobilisations incorporelles",
        "parent": 6811,
        "position": 8
    },
    "68112": {
        "code": 68112,
        "nom": "Immobilisations corporelles",
        "parent": 6811,
        "position": 8
    },
    "686": {
        "code": 686,
        "nom": "Dotations aux amortissements, d\u00e9pr\u00e9ciations et provisions - Charges financi\u00e8res",
        "parent": 68,
        "position": 8
    },
    "69": {
        "code": 69,
        "nom": "PARTICIPATION DES SALARI\u00c9S - IMP\u00d4TS SUR LES B\u00c9N\u00c9FICES ET ASSIMIL\u00c9S",
        "parent": 6,
        "position": 8
    },
    "695": {
        "code": 695,
        "nom": "Imp\u00f4ts sur les soci\u00e9t\u00e9s (y compris imp\u00f4ts sur les soci\u00e9t\u00e9s des personnes morales non lucratives)",
        "parent": 69,
        "position": 8
    },
    "7": {
        "code": 7,
        "nom": "Classe 7 \u2014 Comptes de produits",
        "parent": 0,
        "position": 4
    },
    "70": {
        "code": 70,
        "nom": "VENTES DE PRODUITS FINIS, PRESTATIONS DE SERVICES, MARCHANDISES",
        "parent": 7,
        "position": 4
    },
    "701": {
        "code": 701,
        "nom": "Ventes de produits finis",
        "parent": 70,
        "position": 4
    },
    "706": {
        "code": 706,
        "nom": "Prestations de services",
        "parent": 70,
        "position": 4
    },
    "707": {
        "code": 707,
        "nom": "Ventes de marchandises",
        "parent": 70,
        "position": 4
    },
    "708": {
        "code": 708,
        "nom": "Produits des activit\u00e9s annexes",
        "parent": 70,
        "position": 4
    },
    "71": {
        "code": 71,
        "nom": "PRODUCTION STOCK\u00c9E (OU D\u00c9STOCKAGE)",
        "parent": 7,
        "position": 4
    },
    "72": {
        "code": 72,
        "nom": "PRODUCTION IMMOBILIS\u00c9E",
        "parent": 7,
        "position": 4
    },
    "74": {
        "code": 74,
        "nom": "SUBVENTIONS D'EXPLOITATION",
        "parent": 7,
        "position": 4
    },
    "740": {
        "code": 740,
        "nom": "Subventions re\u00e7ues",
        "parent": 74,
        "position": 4
    },
    "75": {
        "code": 75,
        "nom": "AUTRES PRODUITS DE GESTION COURANTE",
        "parent": 7,
        "position": 4
    },
    "754": {
        "code": 754,
        "nom": "Collectes",
        "parent": 75,
        "position": 4
    },
    "756": {
        "code": 756,
        "nom": "Cotisations",
        "parent": 75,
        "position": 4
    },
    "758": {
        "code": 758,
        "nom": "Produits divers de gestion courante",
        "parent": 75,
        "position": 4
    },
    "7587": {
        "code": 7587,
        "nom": "Ventes de dons en nature",
        "parent": 758,
        "position": 4
    },
    "7588": {
        "code": 7588,
        "nom": "Autres produits de la g\u00e9n\u00e9rosit\u00e9 du public",
        "parent": 758,
        "position": 4
    },
    "76": {
        "code": 76,
        "nom": "PRODUITS FINANCIERS",
        "parent": 7,
        "position": 4
    },
    "760": {
        "code": 760,
        "nom": "Produits financiers",
        "parent": 76,
        "position": 4
    },
    "77": {
        "code": 77,
        "nom": "PRODUITS EXCEPTIONNELS",
        "parent": 7,
        "position": 4
    },
    "771": {
        "code": 771,
        "nom": "Produits exceptionnels sur op\u00e9rations de gestion",
        "parent": 77,
        "position": 4
    },
    "7713": {
        "code": 7713,
        "nom": "Lib\u00e9ralit\u00e9s re\u00e7ues",
        "parent": 771,
        "position": 4
    },
    "7715": {
        "code": 7715,
        "nom": "Subventions d'\u00e9quilibre",
        "parent": 771,
        "position": 4
    },
    "775": {
        "code": 775,
        "nom": "Produits des cessions d'\u00e9l\u00e9ments d'actifs",
        "parent": 77,
        "position": 4
    },
    "778": {
        "code": 778,
        "nom": "Autres produits exceptionnels",
        "parent": 77,
        "position": 4
    },
    "7780": {
        "code": 7780,
        "nom": "Manifestations diverses",
        "parent": 778,
        "position": 4
    },
    "7788": {
        "code": 7788,
        "nom": "Produits exceptionnels divers",
        "parent": 778,
        "position": 4
    },
    "78": {
        "code": 78,
        "nom": "REPRISES SUR AMORTISSEMENTS ET PROVISIONS",
        "parent": 7,
        "position": 4
    },
    "79": {
        "code": 79,
        "nom": "TRANSFERT DE CHARGES",
        "parent": 7,
        "position": 4
    },
    "791": {
        "code": 791,
        "nom": "Transferts de charges d'exploitation",
        "parent": 79,
        "position": 4
    },
    "796": {
        "code": 796,
        "nom": "Transferts de charges financi\u00e8res",
        "parent": 79,
        "position": 4
    },
    "797": {
        "code": 797,
        "nom": "Transferts de charges exceptionnels",
        "parent": 79,
        "position": 4
    },
    "8": {
        "code": 8,
        "nom": "Classe 8 \u00ad\u2014 Comptes sp\u00e9ciaux",
        "parent": 0,
        "position": 12
    },
    "86": {
        "code": 86,
        "nom": "R\u00c9PARTITION PAR NATURE DE CHARGES",
        "parent": 8,
        "position": 8
    },
    "861": {
        "code": 861,
        "nom": "Mise \u00e0 dispositions gratuites de biens",
        "parent": 86,
        "position": 8
    },
    "862": {
        "code": 862,
        "nom": "Prestations",
        "parent": 86,
        "position": 8
    },
    "864": {
        "code": 864,
        "nom": "Personnel b\u00e9n\u00e9vole",
        "parent": 86,
        "position": 8
    },
    "87": {
        "code": 87,
        "nom": "R\u00c9PARTITION PAR NATURE DE RESSOURCES",
        "parent": 8,
        "position": 4
    },
    "870": {
        "code": 870,
        "nom": "B\u00e9n\u00e9volat",
        "parent": 87,
        "position": 4
    },
    "871": {
        "code": 871,
        "nom": "Prestations en nature",
        "parent": 87,
        "position": 4
    },
    "875": {
        "code": 875,
        "nom": "Dons en nature",
        "parent": 87,
        "position": 4
    },
    "89": {
        "code": 89,
        "nom": "BILAN",
        "parent": 8,
        "position": 3
    },
    "890": {
        "code": 890,
        "nom": "Bilan d'ouverture",
        "parent": 89,
        "position": 3
    },
    "890": {
        "code": 891,
        "nom": "Bilan de clôture",
        "parent": 89,
        "position": 3
    },
    "9": {
        "code": 9,
        "nom": "Classe 9 \u2014 Comptes analytiques",
        "parent": 0,
        "position": 12
    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Modified src/include/data/schema.sql from [c8df01c2dd] to [bdddcd8200].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
CREATE TABLE IF NOT EXISTS config (
-- Configuration de Garradin
    cle TEXT PRIMARY KEY NOT NULL,
    valeur TEXT
);

-- On stocke ici les ID de catégorie de compta correspondant aux types spéciaux
-- compta_categorie_cotisations => id_categorie
-- compta_categorie_dons => id_categorie

CREATE TABLE IF NOT EXISTS membres_categories
-- Catégories de membres
(
    id INTEGER PRIMARY KEY NOT NULL,
    nom TEXT NOT NULL,

    droit_wiki INTEGER NOT NULL DEFAULT 1,
    droit_membres INTEGER NOT NULL DEFAULT 1,
    droit_compta INTEGER NOT NULL DEFAULT 1,
    droit_inscription INTEGER NOT NULL DEFAULT 0,
    droit_connexion INTEGER NOT NULL DEFAULT 1,
    droit_config INTEGER NOT NULL DEFAULT 0,
    cacher INTEGER NOT NULL DEFAULT 0,

    id_cotisation_obligatoire INTEGER NULL REFERENCES cotisations (id) ON DELETE SET NULL
);

-- Membres de l'asso
-- Table dynamique générée par l'application
-- voir Garradin\Membres\Champs.php

CREATE TABLE IF NOT EXISTS membres_sessions
-- Sessions
(
    selecteur TEXT NOT NULL,
    hash TEXT NOT NULL,
    id_membre INTEGER NOT NULL REFERENCES membres (id) ON DELETE CASCADE,
    expire INT NOT NULL,

    PRIMARY KEY (selecteur, id_membre)
);

CREATE TABLE IF NOT EXISTS cotisations
-- Types de cotisations et activités
(
    id INTEGER PRIMARY KEY NOT NULL,
    id_categorie_compta INTEGER NULL REFERENCES compta_categories (id) ON DELETE SET NULL, -- NULL si le type n'est pas associé automatiquement à la compta

    intitule TEXT NOT NULL,
    description TEXT NULL,
    montant REAL NOT NULL,

    duree INTEGER NULL, -- En jours
    debut TEXT NULL, -- timestamp
    fin TEXT NULL
);

CREATE TABLE IF NOT EXISTS cotisations_membres
-- Enregistrement des cotisations et activités
(
    id INTEGER NOT NULL PRIMARY KEY,
    id_membre INTEGER NOT NULL REFERENCES membres (id) ON DELETE CASCADE,
    id_cotisation INTEGER NOT NULL REFERENCES cotisations (id) ON DELETE CASCADE,

    date TEXT NOT NULL DEFAULT CURRENT_DATE CHECK (date(date) IS NOT NULL AND date(date) = date)
);

CREATE UNIQUE INDEX IF NOT EXISTS cm_unique ON cotisations_membres (id_membre, id_cotisation, date);

CREATE TABLE IF NOT EXISTS membres_operations
-- Liaison des enregistrement des paiements en compta
(
    id_membre INTEGER NOT NULL REFERENCES membres (id) ON DELETE CASCADE,
    id_operation INTEGER NOT NULL REFERENCES compta_journal (id) ON DELETE CASCADE,
    id_cotisation INTEGER NULL REFERENCES cotisations_membres (id) ON DELETE SET NULL,

    PRIMARY KEY (id_membre, id_operation)
);

CREATE TABLE IF NOT EXISTS rappels
-- Rappels de devoir renouveller une cotisation
(
    id INTEGER NOT NULL PRIMARY KEY,
    id_cotisation INTEGER NOT NULL REFERENCES cotisations (id) ON DELETE CASCADE,

    delai INTEGER NOT NULL, -- Délai en jours pour envoyer le rappel

    sujet TEXT NOT NULL,
    texte TEXT NOT NULL
);

CREATE TABLE IF NOT EXISTS rappels_envoyes
-- Enregistrement des rappels envoyés à qui et quand
(
    id INTEGER NOT NULL PRIMARY KEY,

    id_membre INTEGER NOT NULL REFERENCES membres (id) ON DELETE CASCADE,
    id_cotisation INTEGER NOT NULL REFERENCES cotisations (id) ON DELETE CASCADE,
    id_rappel INTEGER NULL REFERENCES rappels (id) ON DELETE CASCADE,

    date TEXT NOT NULL DEFAULT CURRENT_DATE CHECK (date(date) IS NOT NULL AND date(date) = date),

    media INTEGER NOT NULL -- Média utilisé pour le rappel : 1 = email, 2 = courrier, 3 = autre
);

--
-- WIKI
--

CREATE TABLE IF NOT EXISTS wiki_pages
-- Pages du wiki
(
    id INTEGER PRIMARY KEY NOT NULL,
    uri TEXT NOT NULL, -- URI unique (équivalent NomPageWiki)
    titre TEXT NOT NULL,
    date_creation TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP CHECK (datetime(date_creation) IS NOT NULL AND datetime(date_creation) = date_creation),
    date_modification TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP CHECK (datetime(date_modification) IS NOT NULL AND datetime(date_modification) = date_modification),
    parent INTEGER NOT NULL DEFAULT 0, -- ID de la page parent
    revision INTEGER NOT NULL DEFAULT 0, -- Numéro de révision (commence à 0 si pas de texte, +1 à chaque changement du texte)
    droit_lecture INTEGER NOT NULL DEFAULT 0, -- Accès en lecture (-1 = public [site web], 0 = tous ceux qui ont accès en lecture au wiki, 1+ = ID de groupe)
    droit_ecriture INTEGER NOT NULL DEFAULT 0 -- Accès en écriture (0 = tous ceux qui ont droit d'écriture sur le wiki, 1+ = ID de groupe)
);

CREATE UNIQUE INDEX IF NOT EXISTS wiki_uri ON wiki_pages (uri);

CREATE VIRTUAL TABLE IF NOT EXISTS wiki_recherche USING fts4
-- Table dupliquée pour chercher une page
(
    id INT PRIMARY KEY NOT NULL, -- Clé externe obligatoire
    titre TEXT NOT NULL,
    contenu TEXT NULL, -- Contenu de la dernière révision
    FOREIGN KEY (id) REFERENCES wiki_pages(id)
);

CREATE TABLE IF NOT EXISTS wiki_revisions
-- Révisions du contenu des pages
(
    id_page INTEGER NOT NULL REFERENCES wiki_pages (id) ON DELETE CASCADE,
    revision INTEGER NULL,

    id_auteur INTEGER NULL REFERENCES membres (id) ON DELETE SET NULL,

    contenu TEXT NOT NULL,
    modification TEXT NULL, -- Description des modifications effectuées
    chiffrement INTEGER NOT NULL DEFAULT 0, -- 1 si le contenu est chiffré, 0 sinon
    date TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP CHECK (datetime(date) IS NOT NULL AND datetime(date) = date),

    PRIMARY KEY(id_page, revision)
);

CREATE INDEX IF NOT EXISTS wiki_revisions_id_page ON wiki_revisions (id_page);
CREATE INDEX IF NOT EXISTS wiki_revisions_id_auteur ON wiki_revisions (id_auteur);

-- Triggers pour synchro avec table wiki_pages
CREATE TRIGGER IF NOT EXISTS wiki_recherche_delete AFTER DELETE ON wiki_pages
    BEGIN
        DELETE FROM wiki_recherche WHERE id = old.id;
    END;

CREATE TRIGGER IF NOT EXISTS wiki_recherche_update AFTER UPDATE OF id, titre ON wiki_pages
    BEGIN
        UPDATE wiki_recherche SET id = new.id, titre = new.titre WHERE id = old.id;
    END;

-- Trigger pour mettre à jour le contenu de la table de recherche lors d'une nouvelle révision
CREATE TRIGGER IF NOT EXISTS wiki_recherche_contenu_insert AFTER INSERT ON wiki_revisions WHEN new.chiffrement != 1
    BEGIN
        UPDATE wiki_recherche SET contenu = new.contenu WHERE id = new.id_page;
    END;

-- Si le contenu est chiffré, la recherche n'affiche pas de contenu
CREATE TRIGGER IF NOT EXISTS wiki_recherche_contenu_chiffre AFTER INSERT ON wiki_revisions WHEN new.chiffrement = 1
    BEGIN
        UPDATE wiki_recherche SET contenu = '' WHERE id = new.id_page;
    END;

/*
CREATE TABLE wiki_suivi
-- Suivi des pages
(
    id_membre INTEGER NOT NULL,
    id_page INTEGER NOT NULL,

    PRIMARY KEY (id_membre, id_page),

    FOREIGN KEY (id_page) REFERENCES wiki_pages (id), -- Clé externe obligatoire
    FOREIGN KEY (id_membre) REFERENCES membres (id) -- Clé externe obligatoire
);
*/

--
-- COMPTA
--

CREATE TABLE IF NOT EXISTS compta_exercices
-- Exercices
(
    id INTEGER NOT NULL PRIMARY KEY,

    libelle TEXT NOT NULL,

    debut TEXT NOT NULL DEFAULT CURRENT_DATE CHECK (date(debut) IS NOT NULL AND date(debut) = debut),
    fin TEXT NULL DEFAULT NULL CHECK (fin IS NULL OR (date(fin) IS NOT NULL AND date(fin) = fin)),

    cloture INTEGER NOT NULL DEFAULT 0
);


CREATE TABLE IF NOT EXISTS compta_comptes
-- Plan comptable
(
    id TEXT NOT NULL PRIMARY KEY, -- peut contenir des lettres, eg. 53A, 53B, etc.
    parent TEXT NOT NULL DEFAULT 0,

    libelle TEXT NOT NULL,

    position INTEGER NOT NULL, -- position actif/passif/charge/produit
    plan_comptable INTEGER NOT NULL DEFAULT 1, -- 1 = fait partie du plan comptable, 0 = a été ajouté par l'utilisateur
    desactive INTEGER NOT NULL DEFAULT 0 -- 1 = compte historique désactivé
);

CREATE INDEX IF NOT EXISTS compta_comptes_parent ON compta_comptes (parent);

CREATE TABLE IF NOT EXISTS compta_comptes_bancaires
-- Comptes bancaires
(
    id TEXT NOT NULL PRIMARY KEY,

    banque TEXT NOT NULL,

    iban TEXT NULL,
    bic TEXT NULL,

    FOREIGN KEY(id) REFERENCES compta_comptes(id) ON DELETE CASCADE
);

CREATE TABLE IF NOT EXISTS compta_projets
-- Projets (compta analytique)
(
    id INTEGER PRIMARY KEY NOT NULL,

    libelle TEXT NOT NULL
);

CREATE TABLE IF NOT EXISTS compta_journal
-- Journal des opérations comptables
(
    id INTEGER PRIMARY KEY NOT NULL,

    libelle TEXT NOT NULL,
    remarques TEXT NULL,
    numero_piece TEXT NULL, -- N° de pièce comptable

    montant REAL NOT NULL,

    date TEXT NOT NULL DEFAULT CURRENT_DATE CHECK (date(date) IS NOT NULL AND date(date) = date),
    moyen_paiement TEXT NULL,
    numero_cheque TEXT NULL,

    compte_debit TEXT NULL, -- N° du compte dans le plan, NULL est utilisé pour une opération qui vient d'un exercice précédent
    compte_credit TEXT NULL, -- N° du compte dans le plan

    id_exercice INTEGER NULL DEFAULT NULL, -- En cas de compta simple, l'exercice est permanent (NULL)
    id_auteur INTEGER NULL,
    id_categorie INTEGER NULL, -- Numéro de catégorie (en mode simple)
    id_projet INTEGER NULL,

    FOREIGN KEY(moyen_paiement) REFERENCES compta_moyens_paiement(code),
    FOREIGN KEY(compte_debit) REFERENCES compta_comptes(id),
    FOREIGN KEY(compte_credit) REFERENCES compta_comptes(id),
    FOREIGN KEY(id_exercice) REFERENCES compta_exercices(id),
    FOREIGN KEY(id_auteur) REFERENCES membres(id) ON DELETE SET NULL,
    FOREIGN KEY(id_categorie) REFERENCES compta_categories(id) ON DELETE SET NULL,
    FOREIGN KEY(id_projet) REFERENCES compta_projets(id) ON DELETE SET NULL
);

CREATE INDEX IF NOT EXISTS compta_operations_exercice ON compta_journal (id_exercice);
CREATE INDEX IF NOT EXISTS compta_operations_date ON compta_journal (date);
CREATE INDEX IF NOT EXISTS compta_operations_comptes ON compta_journal (compte_debit, compte_credit);
CREATE INDEX IF NOT EXISTS compta_operations_auteur ON compta_journal (id_auteur);

CREATE TABLE IF NOT EXISTS compta_moyens_paiement
-- Moyens de paiement
(
    code TEXT NOT NULL PRIMARY KEY,
    nom TEXT NOT NULL
);

--INSERT INTO compta_moyens_paiement (code, nom) VALUES ('AU', 'Autre');
INSERT OR IGNORE INTO compta_moyens_paiement (code, nom) VALUES ('CB', 'Carte bleue');
INSERT OR IGNORE INTO compta_moyens_paiement (code, nom) VALUES ('CH', 'Chèque');
INSERT OR IGNORE INTO compta_moyens_paiement (code, nom) VALUES ('ES', 'Espèces');
INSERT OR IGNORE INTO compta_moyens_paiement (code, nom) VALUES ('PR', 'Prélèvement');
INSERT OR IGNORE INTO compta_moyens_paiement (code, nom) VALUES ('TI', 'TIP');
INSERT OR IGNORE INTO compta_moyens_paiement (code, nom) VALUES ('VI', 'Virement');

CREATE TABLE IF NOT EXISTS compta_categories
-- Catégories pour simplifier le plan comptable
(
    id INTEGER NOT NULL PRIMARY KEY,
    type INTEGER NOT NULL DEFAULT 1, -- 1 = recette, -1 = dépense, 0 = autre (utilisé uniquement pour l'interface)

    intitule TEXT NOT NULL,
    description TEXT NULL,

    compte TEXT NOT NULL, -- Compte affecté par cette catégorie

    FOREIGN KEY(compte) REFERENCES compta_comptes(id) ON DELETE CASCADE
);

CREATE TABLE IF NOT EXISTS plugins
(
    id TEXT NOT NULL PRIMARY KEY,
    officiel INTEGER NOT NULL DEFAULT 0,
    nom TEXT NOT NULL,
    description TEXT NULL,
    auteur TEXT NULL,
    url TEXT NULL,
    version TEXT NOT NULL,
    menu INTEGER NOT NULL DEFAULT 0,
    menu_condition TEXT NULL,
    config TEXT NULL
);

CREATE TABLE IF NOT EXISTS plugins_signaux
-- Association entre plugins et signaux (hooks)
(
    signal TEXT NOT NULL,
    plugin TEXT NOT NULL REFERENCES plugins (id),
    callback TEXT NOT NULL,
    PRIMARY KEY (signal, plugin)
);

CREATE TABLE IF NOT EXISTS compta_rapprochement
-- Rapprochement entre compta et relevés de comptes
(
    id_operation INTEGER NOT NULL PRIMARY KEY REFERENCES compta_journal (id) ON DELETE CASCADE,
    date TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP CHECK (datetime(date) IS NOT NULL AND datetime(date) = date),
    id_auteur INTEGER NULL REFERENCES membres (id) ON DELETE SET NULL
);

CREATE TABLE IF NOT EXISTS fichiers
-- Données sur les fichiers
(
    id INTEGER NOT NULL PRIMARY KEY,
    nom TEXT NOT NULL, -- nom de fichier (par exemple image1234.jpeg)
    type TEXT NULL, -- Type MIME
    image INTEGER NOT NULL DEFAULT 0, -- 1 = image reconnue
    datetime TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP CHECK (datetime(datetime) IS NOT NULL AND datetime(datetime) = datetime), -- Date d'ajout ou mise à jour du fichier
    id_contenu INTEGER NOT NULL REFERENCES fichiers_contenu (id) ON DELETE CASCADE
);

CREATE INDEX IF NOT EXISTS fichiers_date ON fichiers (datetime);

CREATE TABLE IF NOT EXISTS fichiers_contenu
-- Contenu des fichiers
(
    id INTEGER NOT NULL PRIMARY KEY,
    hash TEXT NOT NULL, -- Hash SHA1 du contenu du fichier
    taille INTEGER NOT NULL, -- Taille en octets
    contenu BLOB NULL
);

CREATE UNIQUE INDEX IF NOT EXISTS fichiers_hash ON fichiers_contenu (hash);

CREATE TABLE IF NOT EXISTS fichiers_membres
-- Associations entre fichiers et membres (photo de profil par exemple)
(
    fichier INTEGER NOT NULL REFERENCES fichiers (id),
    id INTEGER NOT NULL REFERENCES membres (id),
    PRIMARY KEY(fichier, id)
);

CREATE TABLE IF NOT EXISTS fichiers_wiki_pages
-- Associations entre fichiers et pages du wiki
(
    fichier INTEGER NOT NULL REFERENCES fichiers (id),
    id INTEGER NOT NULL REFERENCES wiki_pages (id),
    PRIMARY KEY(fichier, id)
);

CREATE TABLE IF NOT EXISTS fichiers_compta_journal
-- Associations entre fichiers et journal de compta (pièce comptable par exemple)
(
    fichier INTEGER NOT NULL REFERENCES fichiers (id),
    id INTEGER NOT NULL REFERENCES compta_journal (id),
    PRIMARY KEY(fichier, id)
);

CREATE TABLE IF NOT EXISTS recherches
-- Recherches enregistrées
(
    id INTEGER NOT NULL PRIMARY KEY,
    id_membre INTEGER NULL REFERENCES membres (id) ON DELETE CASCADE, -- Si non NULL, alors la recherche ne sera visible que par le membre associé
    intitule TEXT NOT NULL,
    creation TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP CHECK (datetime(creation) IS NOT NULL AND datetime(creation) = creation),
    cible TEXT NOT NULL, -- "membres" ou "compta_journal"
    type TEXT NOT NULL, -- "json" ou "sql"
    contenu TEXT NOT NULL
);


CREATE TABLE IF NOT EXISTS compromised_passwords_cache
-- Cache des hash de mots de passe compromis
(
    hash TEXT NOT NULL PRIMARY KEY
);

CREATE TABLE IF NOT EXISTS compromised_passwords_cache_ranges
-- Cache des préfixes de mots de passe compromis
(
    prefix TEXT NOT NULL PRIMARY KEY,
    date INTEGER NOT NULL
);
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<





1





























































































































































































































































































































































































































1.0.0_schema.sql
























































































































































































































































































































































































































Modified src/include/init.php from [d8b3de9018] to [94cb9d23a4].

1
2
3
4
5
6
7

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46





47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149


150
















151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177

178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221




222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
<?php

namespace Garradin;

use KD2\ErrorManager;
use KD2\Security;
use KD2\Form;


error_reporting(-1);

/*
 * Version de Garradin
 */

function garradin_version()
{
    if (defined('Garradin\VERSION'))
    {
        return VERSION;
    }

    $file = __DIR__ . '/../VERSION';

    if (file_exists($file))
    {
        $version = trim(file_get_contents($file));
    }
    else
    {
        $version = 'unknown';
    }

    define('Garradin\VERSION', $version);
    return $version;
}

function garradin_manifest()
{
    $file = __DIR__ . '/../../manifest.uuid';

    if (@file_exists($file))
    {
        return substr(trim(file_get_contents($file)), 0, 10);
    }

    return false;





}

/*
 * Configuration globale
 */

// Configuration externalisée
if (file_exists(__DIR__ . '/../config.local.php'))
{
    require __DIR__ . '/../config.local.php';
}

// Configuration par défaut, si les constantes ne sont pas définies dans config.local.php
// (fallback)
if (!defined('Garradin\ROOT'))
{
    define('Garradin\ROOT', dirname(__DIR__));
}


/**
 * Auto-chargement des dépendances
 */
class Loader
{
    /**
     * Liste des classes déjà chargées
     * @var array
     */
    static protected $loaded = [];

    /**
     * Inclure un fichier de classe depuis le nom de la classe
     * @param  string $classname
     * @return void
     */
    static public function load($classname)
    {
        $classname = ltrim($classname, '\\');

        if (array_key_exists($classname, self::$loaded))
        {
            return true;
        }

        // Plugins
        if (substr($classname, 0, 16) == 'Garradin\\Plugin\\')
        {
            $classname = substr($classname, 16);
            $plugin_name = substr($classname, 0, strpos($classname, '\\'));
            $filename = str_replace('\\', '/', substr($classname, strpos($classname, '\\')+1));

            $path = Plugin::getPath(strtolower($plugin_name)) . '/lib/' . $filename . '.php';
        }
        else
        {
            // PSR-0 autoload
            $filename = str_replace('\\', '/', $classname);
            $path = ROOT . '/include/lib/' . $filename . '.php';
        }

        if (!file_exists($path))
        {
            throw new \Exception('File '.$path.' doesn\'t exists');
        }

        self::$loaded[$classname] = true;

        require $path;
    }
}

\spl_autoload_register(['Garradin\Loader', 'load'], true);

if (!defined('Garradin\DATA_ROOT'))
{
    define('Garradin\DATA_ROOT', ROOT);
}

if (!defined('Garradin\WWW_URI'))
{
    try {
        $uri = \KD2\HTTP::getRootURI(ROOT);
    }
    catch (\UnexpectedValueException $e) {
        echo "<h2>Impossible de détecter le chemin d'accès web de Garradin.</h2>";
        echo '<p><a href="https://fossil.kd2.org/garradin/wikiedit?name=Installation">Consulter l\'aide pour configurer manuellement le chemin d\'accès</a></p>';
        exit;
    }

    if ($uri == '/www/') {
        $uri = '/';
    }
    else {
        readfile(ROOT . '/sous-domaine.html');
        exit;
    }

    define('Garradin\WWW_URI', $uri);
    unset($uri);
}

if (!defined('Garradin\WWW_URL'))


{
















    define('Garradin\WWW_URL', \KD2\HTTP::getScheme() . '://' . \KD2\HTTP::getHost() . WWW_URI);
}

static $default_config = [
    'CACHE_ROOT'            => DATA_ROOT . '/cache',
    'DB_FILE'               => DATA_ROOT . '/association.sqlite',
    'DB_SCHEMA'             => ROOT . '/include/data/schema.sql',
    'PLUGINS_ROOT'          => DATA_ROOT . '/plugins',
    'PREFER_HTTPS'          => false,
    'ALLOW_MODIFIED_IMPORT' => true,
    'PLUGINS_SYSTEM'        => '',
    'SHOW_ERRORS'           => true,
    'MAIL_ERRORS'           => false,
    'ERRORS_REPORT_URL'     => null,
    'ERRORS_ENABLE_LOG_VIEW'=> true,
    'USE_CRON'              => false,
    'ENABLE_XSENDFILE'      => false,
    'SMTP_HOST'             => false,
    'SMTP_USER'             => null,
    'SMTP_PASSWORD'         => null,
    'SMTP_PORT'             => 587,
    'SMTP_SECURITY'         => 'STARTTLS',
    'ADMIN_URL'             => WWW_URL . 'admin/',
    'NTP_SERVER'            => 'fr.pool.ntp.org',
    'ENABLE_AUTOMATIC_BACKUPS' => true,
    'ADMIN_COLOR1'          => '#9c4f15',
    'ADMIN_COLOR2'          => '#d98628',

];

foreach ($default_config as $const => $value)
{
    $const = sprintf('Garradin\\%s', $const);

    if (!defined($const))
    {
        define($const, $value);
    }
}

if (!defined('Garradin\\ADMIN_BACKGROUND_IMAGE')) {
    define('Garradin\\ADMIN_BACKGROUND_IMAGE', ADMIN_URL . 'static/gdin_bg.png');
}

const WEBSITE = 'https://fossil.kd2.org/garradin/';
const PLUGINS_URL = 'https://garradin.eu/plugins/list.json';
const DEFAULT_REPORT_URL = null;

// PHP devrait être assez intelligent pour chopper la TZ système mais nan
// il sait pas faire (sauf sur Debian qui a le bon patch pour ça), donc pour 
// éviter le message d'erreur à la con on définit une timezone par défaut
// Pour utiliser une autre timezone, il suffit de définir date.timezone dans
// un .htaccess ou dans config.local.php
if (!ini_get('date.timezone'))
{
    if (($tz = @date_default_timezone_get()) && $tz != 'UTC')
    {
        ini_set('date.timezone', $tz);
    }
    else
    {
        ini_set('date.timezone', 'Europe/Paris');
    }
}

/*
 * Gestion des erreurs et exceptions
 */

class UserException extends \LogicException
{
}





// activer le gestionnaire d'erreurs/exceptions
ErrorManager::enable(SHOW_ERRORS ? ErrorManager::DEVELOPMENT : ErrorManager::PRODUCTION);
ErrorManager::setLogFile(DATA_ROOT . '/error.log');

// activer l'envoi de mails si besoin est
if (MAIL_ERRORS)
{
    ErrorManager::setEmail(MAIL_ERRORS);
}

ErrorManager::setContext([
    'rootDirectory'      => ROOT,
    'garradin_data_root' => DATA_ROOT,
    'garradin_version'   => garradin_version(),
]);

if (ERRORS_REPORT_URL)
{
    ErrorManager::setRemoteReporting(ERRORS_REPORT_URL, true);
}
else
{
    ErrorManager::setRemoteReporting(DEFAULT_REPORT_URL, false);
}

ErrorManager::setProductionErrorTemplate('<!DOCTYPE html><html><head><title>Erreur interne</title>
    <style type="text/css">
    body {font-family: sans-serif; }
    code, p, h1 { max-width: 400px; margin: 1em auto; display: block; }
    code { text-align: right; color: #666; }
    a { color: blue; }
    form { text-align: center; }
    </style></head><body><h1>Erreur interne</h1><p>Désolé mais le serveur a rencontré une erreur interne
    et ne peut répondre à votre requête. Merci de ré-essayer plus tard.</p>
    <p>Si vous suspectez un bug dans Garradin, vous pouvez suivre 
    <a href="http://dev.kd2.org/garradin/Rapporter+un+bug">ces instructions</a>
    pour le rapporter.</p>
    <if(sent)><p>Un-e responsable a été notifié-e et cette erreur sera corrigée dès que possible.</p></if>
    <if(logged)><code>L\'erreur a été enregistrée dans les journaux système (error.log) sous la référence : <b>{$ref}</b></code></if>
    <p><a href="' . WWW_URL . '">&larr; Retour à la page d\'accueil</a></p>
    </body></html>');

ErrorManager::setHtmlHeader('<!DOCTYPE html><meta charset="utf-8" /><style type="text/css">
    body { font-family: sans-serif; } * { margin: 0; padding: 0; }
    u, code b, i, h3 { font-style: normal; font-weight: normal; text-decoration: none; }
    #icn { color: #fff; font-size: 2em; float: right; margin: 1em; padding: 1em; background: #900; border-radius: 50%; }
    section header { background: #fdd; padding: 1em; }
    section article { margin: 1em; }
    section article h3, section article h4 { font-size: 1em; font-family: mono; }
    code { border: 1px dotted #ccc; display: block; }
    code b { margin-right: 1em; color: #999; }
    code u { background: #fcc; display: inline-block; width: 100%; }
    table { border-collapse: collapse; margin: 1em; } td, th { border: 1px solid #ccc; padding: .2em .5em; text-align: left; 
    vertical-align: top; }
    input { padding: .3em; margin: .5em; font-size: 1.2em; cursor: pointer; }
</style>
<pre id="icn"> \__/<br /> (xx)<br />//||\\\\</pre>
<section>
    <article>
    <h1>Une erreur s\'est produite</h1>
    <if(report)><form method="post" action="{$report_url}"><p><input type="hidden" name="report" value="{$report_json}" /><input type="submit" value="Rapporter l\'erreur aux développeur⋅euses de Garradin &rarr;" /></p></form></if>
    </article>
</section>
');

function user_error($e)
{
    if (PHP_SAPI == 'cli')
    {
        echo $e->getMessage();
    }
    else
    {
        $tpl = Template::getInstance();

        $tpl->assign('error', $e->getMessage());
        $tpl->assign('admin_url', ADMIN_URL);
        $tpl->display('error.tpl');
    }

    exit;
}

// Message d'erreur simple pour les erreurs de l'utilisateur
ErrorManager::setCustomExceptionHandler('\Garradin\UserException', '\Garradin\user_error');
ErrorManager::setCustomExceptionHandler('\KD2\MiniSkelMarkupException', '\Garradin\user_error');

// Clé secrète utilisée pour chiffrer les tokens CSRF etc.
if (!defined('Garradin\SECRET_KEY'))
{
    $key = base64_encode(Security::random_bytes(64));
    Install::setLocalConfig('SECRET_KEY', $key);
    define('Garradin\SECRET_KEY', $key);
}

// Intégration du secret pour les tokens
Form::tokenSetSecret(SECRET_KEY);

// Fonctions utilitaires bien utiles d'avoir dans le namespace global de Garradin
function obj_has($obj, $pattern)
{
    return \KD2\Helpers::obj_has($obj, $pattern);
}

function obj_get($src, $pattern, $default = null)
{
    return \KD2\Helpers::obj_get($src, $pattern, $default);
}

/*
 * Vérifications pour enclencher le processus d'installation ou de mise à jour
 */

if (!defined('Garradin\INSTALL_PROCESS') && !defined('Garradin\UPGRADE_PROCESS'))
{
    if (!file_exists(DB_FILE))
    {
        Utils::redirect(ADMIN_URL . 'install.php');
    }

    $config = Config::getInstance();

    if (version_compare($config->getVersion(), garradin_version(), '<'))
    {
        Utils::redirect(ADMIN_URL . 'upgrade.php');
    }
}







>









|
|
|
|

|

|
|
|
|
|
|
|
|

|
|




|

|
|
|
|

|
>
>
>
>
>









|






|


|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<

|
|
|
|
|
|

|
|
|
|
|
|
|
|

|
<
<
<
<
<
<
|
|
<
|
<



|




|
|
|
|
<
<
|
|

|
|
|
|
|
|
|

|
|


|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|



|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>




|

|
|
|
|
<
<
<
<




<


|





|
|
|
|
|
|
|
|









>
>
>
>








|



|
|
|




|

<
|
<
<
<

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|


|
|
|
|
|
|
|
|
|
|
|
|



|
|
|
|



|

|
|
|
|
|
|
|

|
|
|
|

|









|
|
|





<
<
<
<
<
|
<
<
<
<







|
|
|
|

|

|
|
|
|

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72


















73





74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91






92
93

94

95
96
97
98
99
100
101
102
103
104
105
106


107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179




180
181
182
183

184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233

234



235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307





308




309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
<?php

namespace Garradin;

use KD2\ErrorManager;
use KD2\Security;
use KD2\Form;
use KD2\DB\EntityManager;

error_reporting(-1);

/*
 * Version de Garradin
 */

function garradin_version()
{
	if (defined('Garradin\VERSION'))
	{
		return VERSION;
	}

	$file = __DIR__ . '/../VERSION';

	if (file_exists($file))
	{
		$version = trim(file_get_contents($file));
	}
	else
	{
		$version = 'unknown';
	}

	define('Garradin\VERSION', $version);
	return $version;
}

function garradin_manifest()
{
	$file = __DIR__ . '/../../manifest.uuid';

	if (@file_exists($file))
	{
		return substr(trim(file_get_contents($file)), 0, 10);
	}

	return false;
}

if (!defined('\SQLITE3_OPEN_READWRITE')) {
	echo 'Le module de base de données SQLite3 n\'est pas disponible.' . PHP_EOL;
	exit(1);
}

/*
 * Configuration globale
 */

// Configuration externalisée
if (file_exists(__DIR__ . '/../config.local.php'))
{
	require __DIR__ . '/../config.local.php';
}

// Configuration par défaut, si les constantes ne sont pas définies dans config.local.php
// (fallback)
if (!defined('Garradin\ROOT'))
{
	define('Garradin\ROOT', dirname(__DIR__));
}

\spl_autoload_register(function (string $classname) {


















	$classname = ltrim($classname, '\\');






	// Plugins
	if (substr($classname, 0, 16) == 'Garradin\\Plugin\\')
	{
		$classname = substr($classname, 16);
		$plugin_name = substr($classname, 0, strpos($classname, '\\'));
		$filename = str_replace('\\', '/', substr($classname, strpos($classname, '\\')+1));

		$path = Plugin::getPath(strtolower($plugin_name)) . '/lib/' . $filename . '.php';
	}
	else
	{
		// PSR-0 autoload
		$filename = str_replace('\\', '/', $classname);
		$path = ROOT . '/include/lib/' . $filename . '.php';
	}

	if (file_exists($path)) {






		require_once $path;
	}

}, true);


if (!defined('Garradin\DATA_ROOT'))
{
	define('Garradin\DATA_ROOT', ROOT);
}

if (!defined('Garradin\WWW_URI'))
{
	try {
		$uri = \KD2\HTTP::getRootURI(ROOT);
	}
	catch (\UnexpectedValueException $e) {


		$uri = null;
	}

	if ($uri == '/www/') {
		$uri = '/';
	}
	elseif ($uri !== null) {
		readfile(ROOT . '/sous-domaine.html');
		exit;
	}

	define('Garradin\WWW_URI', $uri);
	unset($uri);
}

if (!defined('Garradin\WWW_URL')) {
	$host = \KD2\HTTP::getHost();
}

if (WWW_URI === null || (!empty($host) && $host == 'host.unknown')) {
	$title = 'Impossible de détecter automatiquement l\'URL du site web.';
	$info = 'Consulter l\'aide pour configurer manuellement l\'URL avec la directive WWW_URL et WWW_URI.';
	$url ='https://fossil.kd2.org/garradin/wiki?name=Installation';

	if (PHP_SAPI == 'cli') {
		printf("\n/!\\ %s\n%s\n-> %s\n\n", $title, $info, $url);
	}
	else {
		printf('<h2 style="color: red">%s</h2><p><a href="%s">%s</a></p>', $title, $url, $info);
	}

	exit(1);
}

if (!defined('Garradin\WWW_URL')) {
	define('Garradin\WWW_URL', \KD2\HTTP::getScheme() . '://' . $host . WWW_URI);
}

static $default_config = [
	'CACHE_ROOT'            => DATA_ROOT . '/cache',
	'DB_FILE'               => DATA_ROOT . '/association.sqlite',
	'DB_SCHEMA'             => ROOT . '/include/data/schema.sql',
	'PLUGINS_ROOT'          => DATA_ROOT . '/plugins',
	'PREFER_HTTPS'          => false,
	'ALLOW_MODIFIED_IMPORT' => true,
	'PLUGINS_SYSTEM'        => '',
	'SHOW_ERRORS'           => true,
	'MAIL_ERRORS'           => false,
	'ERRORS_REPORT_URL'     => null,
	'ERRORS_ENABLE_LOG_VIEW'=> true,
	'USE_CRON'              => false,
	'ENABLE_XSENDFILE'      => false,
	'SMTP_HOST'             => false,
	'SMTP_USER'             => null,
	'SMTP_PASSWORD'         => null,
	'SMTP_PORT'             => 587,
	'SMTP_SECURITY'         => 'STARTTLS',
	'ADMIN_URL'             => WWW_URL . 'admin/',
	'NTP_SERVER'            => 'fr.pool.ntp.org',
	'ENABLE_AUTOMATIC_BACKUPS' => true,
	'ADMIN_COLOR1'          => '#9c4f15',
	'ADMIN_COLOR2'          => '#d98628',
	'ADMIN_BACKGROUND_IMAGE' => WWW_URL . 'admin/static/gdin_bg.png'
];

foreach ($default_config as $const => $value)
{
	$const = sprintf('Garradin\\%s', $const);

	if (!defined($const))
	{
		define($const, $value);
	}




}

const WEBSITE = 'https://fossil.kd2.org/garradin/';
const PLUGINS_URL = 'https://garradin.eu/plugins/list.json';


// PHP devrait être assez intelligent pour chopper la TZ système mais nan
// il sait pas faire (sauf sur Debian qui a le bon patch pour ça), donc pour
// éviter le message d'erreur à la con on définit une timezone par défaut
// Pour utiliser une autre timezone, il suffit de définir date.timezone dans
// un .htaccess ou dans config.local.php
if (!ini_get('date.timezone'))
{
	if (($tz = @date_default_timezone_get()) && $tz != 'UTC')
	{
		ini_set('date.timezone', $tz);
	}
	else
	{
		ini_set('date.timezone', 'Europe/Paris');
	}
}

/*
 * Gestion des erreurs et exceptions
 */

class UserException extends \LogicException
{
}

class ValidationException extends UserException
{
}

// activer le gestionnaire d'erreurs/exceptions
ErrorManager::enable(SHOW_ERRORS ? ErrorManager::DEVELOPMENT : ErrorManager::PRODUCTION);
ErrorManager::setLogFile(DATA_ROOT . '/error.log');

// activer l'envoi de mails si besoin est
if (MAIL_ERRORS)
{
	ErrorManager::setEmail(MAIL_ERRORS);
}

ErrorManager::setContext([
	'rootDirectory'      => ROOT,
	'garradin_data_root' => DATA_ROOT,
	'garradin_version'   => garradin_version(),
]);

if (ERRORS_REPORT_URL)
{
	ErrorManager::setRemoteReporting(ERRORS_REPORT_URL, true);
}





ErrorManager::setProductionErrorTemplate('<!DOCTYPE html><html><head><title>Erreur interne</title>
	<style type="text/css">
	body {font-family: sans-serif; }
	code, p, h1 { max-width: 400px; margin: 1em auto; display: block; }
	code { text-align: right; color: #666; }
	a { color: blue; }
	form { text-align: center; }
	</style></head><body><h1>Erreur interne</h1><p>Désolé mais le serveur a rencontré une erreur interne
	et ne peut répondre à votre requête. Merci de ré-essayer plus tard.</p>
	<p>Si vous suspectez un bug dans Garradin, vous pouvez suivre 
	<a href="http://dev.kd2.org/garradin/Rapporter+un+bug">ces instructions</a>
	pour le rapporter.</p>
	<if(sent)><p>Un-e responsable a été notifié-e et cette erreur sera corrigée dès que possible.</p></if>
	<if(logged)><code>L\'erreur a été enregistrée dans les journaux système (error.log) sous la référence : <b>{$ref}</b></code></if>
	<p><a href="' . WWW_URL . '">&larr; Retour à la page d\'accueil</a></p>
	</body></html>');

ErrorManager::setHtmlHeader('<!DOCTYPE html><meta charset="utf-8" /><style type="text/css">
	body { font-family: sans-serif; } * { margin: 0; padding: 0; }
	u, code b, i, h3 { font-style: normal; font-weight: normal; text-decoration: none; }
	#icn { color: #fff; font-size: 2em; float: right; margin: 1em; padding: 1em; background: #900; border-radius: 50%; }
	section header { background: #fdd; padding: 1em; }
	section article { margin: 1em; }
	section article h3, section article h4 { font-size: 1em; font-family: mono; }
	code { border: 1px dotted #ccc; display: block; }
	code b { margin-right: 1em; color: #999; }
	code u { background: #fcc; display: inline-block; width: 100%; }
	table { border-collapse: collapse; margin: 1em; } td, th { border: 1px solid #ccc; padding: .2em .5em; text-align: left; 
	vertical-align: top; }
	input { padding: .3em; margin: .5em; font-size: 1.2em; cursor: pointer; }
</style>
<pre id="icn"> \__/<br /> (xx)<br />//||\\\\</pre>
<section>
	<article>
	<h1>Une erreur s\'est produite</h1>
	<if(report)><form method="post" action="{$report_url}"><p><input type="hidden" name="report" value="{$report_json}" /><input type="submit" value="Rapporter l\'erreur aux développeur⋅euses de Garradin &rarr;" /></p></form></if>
	</article>
</section>
');

function user_error(\Exception $e)
{
	if (PHP_SAPI == 'cli')
	{
		echo $e->getMessage();
	}
	else
	{
		$tpl = Template::getInstance();

		$tpl->assign('error', $e->getMessage());
		$tpl->assign('admin_url', ADMIN_URL);
		$tpl->display('error.tpl');
	}

	exit;
}

// Message d'erreur simple pour les erreurs de l'utilisateur
ErrorManager::setCustomExceptionHandler('\Garradin\UserException', '\Garradin\user_error');
ErrorManager::setCustomExceptionHandler('\KD2\MiniSkelMarkupException', '\Garradin\user_error');

// Clé secrète utilisée pour chiffrer les tokens CSRF etc.
if (!defined('Garradin\SECRET_KEY'))
{
	$key = base64_encode(random_bytes(64));
	Install::setLocalConfig('SECRET_KEY', $key);
	define('Garradin\SECRET_KEY', $key);
}

// Intégration du secret pour les tokens
Form::tokenSetSecret(SECRET_KEY);






EntityManager::setGlobalDB(DB::getInstance());





/*
 * Vérifications pour enclencher le processus d'installation ou de mise à jour
 */

if (!defined('Garradin\INSTALL_PROCESS') && !defined('Garradin\UPGRADE_PROCESS'))
{
	if (!file_exists(DB_FILE))
	{
		Utils::redirect(ADMIN_URL . 'install.php');
	}

	$config = Config::getInstance();

	if (version_compare($config->getVersion(), garradin_version(), '<'))
	{
		Utils::redirect(ADMIN_URL . 'upgrade.php');
	}
}

Added src/include/lib/Garradin/Accounting/Accounts.php version [104aa964ca].















































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
<?php

namespace Garradin\Accounting;

use Garradin\Entities\Accounting\Account;
use Garradin\Entities\Accounting\Line;
use Garradin\Entities\Accounting\Transaction;
use Garradin\Entities\Accounting\Year;
use Garradin\CSV;
use Garradin\DB;
use Garradin\Utils;
use KD2\DB\EntityManager;

class Accounts
{
	protected $chart_id;
	protected $em;

	const EXPECTED_CSV_COLUMNS = ['code', 'label', 'description', 'position', 'type'];

	public function __construct(int $chart_id)
	{
		$this->chart_id = $chart_id;
		$this->em = EntityManager::getInstance(Account::class);
	}

	static public function get(int $id)
	{
		return EntityManager::findOneById(Account::class, $id);
	}

	static public function getSelectorLabel(int $id)
	{
		return EntityManager::getInstance(Account::class)->col('SELECT code || \' — \' || label FROM @TABLE WHERE id = ?;', $id);
	}

	public function getIdFromCode(string $code): int
	{
		return $this->em->col('SELECT id FROM @TABLE WHERE code = ? AND id_chart = ?;', $code, $this->chart_id);
	}

	/**
	 * Return common accounting accounts from current chart
	 * (will not return analytical and volunteering accounts)
	 */
	public function listCommonTypes(): array
	{
		return $this->em->all('SELECT * FROM @TABLE WHERE id_chart = ? AND type != 0 AND type NOT IN (?, ?) ORDER BY code COLLATE NOCASE;',
			$this->chart_id, Account::TYPE_ANALYTICAL, Account::TYPE_VOLUNTEERING);
	}

	/**
	 * Return all accounts from current chart
	 */
	public function listAll(): array
	{
		return $this->em->all('SELECT * FROM @TABLE WHERE id_chart = ? ORDER BY code COLLATE NOCASE;',
			$this->chart_id);
	}

	public function listForCodes(array $codes): array
	{
		return DB::getInstance()->getGrouped('SELECT code, id, label FROM acc_accounts WHERE id_chart = ?;', $this->chart_id);
	}

	/**
	 * Return all accounts from current chart
	 */
	public function export(): \Generator
	{
		$res = $this->em->DB()->iterate($this->em->formatQuery('SELECT code, label, description, position, type FROM @TABLE WHERE id_chart = ? ORDER BY code COLLATE NOCASE;'),
			$this->chart_id);

		foreach ($res as $row) {
			$row->type = Account::TYPES_NAMES[$row->type];
			$row->position = Account::POSITIONS_NAMES[$row->position];
			yield $row;
		}
	}

	/**
	 * Return only analytical accounts
	 */
	public function listAnalytical(): array
	{
		return $this->em->DB()->getAssoc($this->em->formatQuery('SELECT id, label FROM @TABLE WHERE id_chart = ? AND type = ? ORDER BY code COLLATE NOCASE;'), $this->chart_id, Account::TYPE_ANALYTICAL);
	}

	/**
	 * Return only analytical accounts
	 */
	public function listVolunteering(): array
	{
		return $this->em->all('SELECT * FROM @TABLE WHERE id_chart = ? AND type = ? ORDER BY code COLLATE NOCASE;',
			$this->chart_id, Account::TYPE_VOLUNTEERING);
	}

	/**
	 * List common accounts, grouped by type
	 * @return array
	 */
	public function listCommonGrouped(array $types = null): array
	{
		if (null === $types) {
			$types = '';
		}
		else {
			$types = array_map('intval', $types);
			$types = ' AND ' . $this->em->DB()->where('type', $types);
		}

		$out = [];
		$query = $this->em->iterate('SELECT * FROM @TABLE WHERE id_chart = ? AND type != 0 ' . $types . ' ORDER BY type, code COLLATE NOCASE;',
			$this->chart_id);

		foreach ($query as $row) {
			if (!isset($out[$row->type])) {
				$out[$row->type] = (object) [
					'label'    => Account::TYPES_NAMES[$row->type],
					'type'     => $row->type,
					'accounts' => [],
				];
			}

			$out[$row->type]->accounts[] = $row;
		}

		return $out;
	}

	public function getNextCodesForTypes(): array
	{
		$db = DB::getInstance();
		$codes = $db->getAssoc(sprintf('SELECT type, MAX(code) FROM %s WHERE id_chart = ? AND type > 0 GROUP BY type;', Account::TABLE), $this->chart_id);

		foreach ($codes as &$code) {
			if (($letter = substr($code, -1)) && !is_numeric($letter)) {
				$code = substr($code, 0, -1);
				$letter = strtoupper($letter);
				$letter = ($letter == 'Z') ? 'AA' : chr(ord($letter)+1);
			}
			else {
				$letter = 'A';
			}

			$code = $code . $letter;
		}

		unset($code);
		return $codes;
	}

	public function copyFrom(int $id)
	{
		$db = DB::getInstance();
		return $db->exec(sprintf('INSERT INTO %s (id_chart, code, label, description, position, type, user)
			SELECT %d, code, label, description, position, type, user FROM %1$s WHERE id_chart = %d;', Account::TABLE, $this->chart_id, $id));
	}

	public function importUpload(array $file)
	{
		if (empty($file['size']) || empty($file['tmp_name'])) {
			throw new UserException('Fichier invalide');
		}

		self::importCSV($file['tmp_name']);
	}

	public function importCSV(string $file): void
	{
		$db = DB::getInstance();
		$positions = array_flip(Account::POSITIONS_NAMES);
		$types = array_flip(Account::TYPES_NAMES);

		$db->begin();

		try {
			foreach (CSV::import($file, self::EXPECTED_CSV_COLUMNS) as $line => $row) {
				$account = new Account;
				$account->id_chart = $this->chart_id;
				try {
					$row['position'] = $positions[$row['position']];
					$row['type'] = $types[$row['type']];
					$account->importForm($row);
					$account->save();
				}
				catch (ValidationException $e) {
					throw new UserException(sprintf('Ligne %d : %s', $line, $e->getMessage()));
				}
			}

			$db->commit();
		}
		catch (\Exception $e) {
			$db->rollback();
			throw $e;
		}
	}

	public function countByType(int $type)
	{
		return DB::getInstance()->count(Account::TABLE, 'id_chart = ? AND type = ?', $this->chart_id, $type);
	}

	public function getSingleAccountForType(int $type)
	{
		return DB::getInstance()->first('SELECT * FROM acc_accounts WHERE type = ? AND id_chart = ? LIMIT 1;', $type, $this->chart_id);
	}

/* FIXME: implement closing of accounts
	public function getClosingAccountId()
	{
		return DB::getInstance()->firstColumn('SELECT id FROM acc_accounts WHERE type = ? AND id_chart = ?;', Account::TYPE_CLOSING, $this->chart_id);
	}

	public function closeRevenueExpenseAccounts(Year $year, int $user_id)
	{
		$closing_id = $this->getClosingAccountId();

		if (!$closing_id) {
			throw new UserException('Aucun compte n\'est indiqué comme compte de clôture dans le plan comptable');
		}

		$transaction = new Transaction;
		$transaction->id_creator = $user_id;
		$transaction->id_year = $year->id();
		$transaction->type = Transaction::TYPE_ADVANCED;
		$transaction->label = 'Clôture de l\'exercice';
		$transaction->date = new \DateTime;
		$debit = 0;
		$credit = 0;

		$sql = 'SELECT a.id, SUM(l.credit - l.debit) AS sum, a.position, a.code
			FROM acc_transactions_lines l
			INNER JOIN acc_transactions t ON t.id = l.id_transaction
			INNER JOIN acc_accounts a ON a.id = l.id_account
			WHERE t.id_year = ? AND a.position IN (?, ?)
			GROUP BY a.id
			ORDER BY a.code;';

		$res = DB::getInstance()->iterate($sql, $year->id(), Account::REVENUE, Account::EXPENSE);

		foreach ($res as $row) {
			$reversed = $row->position == Account::ASSET;

			$line = new Line;
			$line->id_account = $row->id;
			$line->credit = $reversed ? abs($row->sum) : 0;
			$line->debit = !$reversed ? abs($row->sum) : 0;
			$transaction->addLine($line);

			if ($reversed) {
				$debit += abs($row->sum);
			}
			else {
				$credit += abs($row->sum);
			}
		}

		if ($debit) {
			$line = new Line;
			$line->id_account = $closing_id;
			$line->credit = 0;
			$line->debit = $debit;
			$transaction->addLine($line);
		}

		if ($credit) {
			$line = new Line;
			$line->id_account = $closing_id;
			$line->credit = $credit;
			$line->debit = 0;
			$transaction->addLine($line);
		}

		$transaction->save();
	}
*/
}

Added src/include/lib/Garradin/Accounting/Charts.php version [23502d0c8f].





























































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<?php

namespace Garradin\Accounting;

use Garradin\Entities\Accounting\Chart;
use Garradin\Utils;
use Garradin\DB;
use KD2\DB\EntityManager;

class Charts
{
	static public function get(int $id)
	{
		return EntityManager::findOneById(Chart::class, $id);
	}

	static public function list()
	{
		$em = EntityManager::getInstance(Chart::class);
		return $em->all('SELECT * FROM @TABLE ORDER BY country, label;');
	}

	static public function listAssoc()
	{
		return DB::getInstance()->getAssoc(sprintf('SELECT id, country || \' - \' || label FROM %s ORDER BY country, label;', Chart::TABLE));
	}

	static public function listByCountry()
	{
		$sql = sprintf('SELECT id, country, label FROM %s ORDER BY country, label;', Chart::TABLE);
		$list = DB::getInstance()->getGrouped($sql);
		$out = [];

		foreach ($list as $row) {
			$country = Utils::getCountryName($row->country);

			if (!array_key_exists($country, $out)) {
				$out[$country] = [];
			}

			$out[$country][$row->id] = $row->label;
		}

		return $out;
	}
}

Added src/include/lib/Garradin/Accounting/Graph.php version [a1b33675d1].













































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
<?php

namespace Garradin\Accounting;

use Garradin\Entities\Accounting\Account;
use Garradin\Entities\Accounting\Line;
use Garradin\Entities\Accounting\Transaction;
use Garradin\Utils;
use Garradin\Config;
use Garradin\DB;
use const Garradin\ADMIN_COLOR1;
use const Garradin\ADMIN_COLOR2;
use const Garradin\ADMIN_URL;
use KD2\DB\EntityManager;

use KD2\Graphics\SVG\Plot;
use KD2\Graphics\SVG\Plot_Data;

use KD2\Graphics\SVG\Pie;
use KD2\Graphics\SVG\Pie_Data;

class Graph
{
	const URL_LIST = [
		ADMIN_URL . 'acc/reports/graph_plot.php?type=assets&%s' => 'Évolution banques et caisses',
		ADMIN_URL . 'acc/reports/graph_plot.php?type=result&%s' => 'Évolution dépenses et recettes',
		ADMIN_URL . 'acc/reports/graph_plot.php?type=debts&%s' => 'Évolution créances (positif) et dettes (négatif)',
		ADMIN_URL . 'acc/reports/graph_pie.php?type=revenue&%s' => 'Répartition recettes',
		ADMIN_URL . 'acc/reports/graph_pie.php?type=expense&%s' => 'Répartition dépenses',
		ADMIN_URL . 'acc/reports/graph_pie.php?type=assets&%s' => 'Répartition actif',
	];

	const PLOT_TYPES = [
		'assets' => [
			'Total' => ['type' => [Account::TYPE_BANK, Account::TYPE_CASH, Account::TYPE_OUTSTANDING]],
			'Banques' => ['type' => Account::TYPE_BANK],
			'Caisses' => ['type' => Account::TYPE_CASH],
			'En attente' => ['type' => Account::TYPE_OUTSTANDING],
		],
		'result' => [
			'Recettes' => ['position' => Account::REVENUE],
			'Dépenses' => ['position' => Account::EXPENSE],
		],
		'debts' => [
			'Comptes de tiers' => ['type' => Account::TYPE_THIRD_PARTY],
		],
	];

	const PIE_TYPES = [
		'revenue' => ['position' => Account::REVENUE],
		'expense' => ['position' => Account::EXPENSE],
		'assets' => ['type' => [Account::TYPE_BANK, Account::TYPE_CASH, Account::TYPE_OUTSTANDING]],
	];

	const WEEKLY_INTERVAL = 604800; // 7 days
	const MONTHLY_INTERVAL = 2635200; // 1 month

	static public function plot(string $type, array $criterias, int $interval = self::WEEKLY_INTERVAL, int $width = 700)
	{
		if (!array_key_exists($type, self::PLOT_TYPES)) {
			throw new \InvalidArgumentException('Unknown type');
		}

		$plot = new Plot($width, 300);

		$lines = self::PLOT_TYPES[$type];
		$data = [];

		foreach ($lines as $label => $line_criterias) {
			$line_criterias = array_merge($criterias, $line_criterias);
			$sums = Reports::getSumsByInterval($line_criterias, $interval);

			if (count($sums) <= 1) {
				continue;
			}

			// Invert sums for banks, cash, etc.
			if ('assets' === $type || 'debts' === $type || ('result' === $type && $line_criterias['position'] == Account::EXPENSE)) {
				$sums = array_map(function ($v) { return $v * -1; }, $sums);
			}

			$sums = array_map(function ($v) { return (int)$v/100; }, $sums);

			$graph = new Plot_Data($sums);
			$graph->title = $label;
			$data[] = $graph;
		}


		if (count($data))
		{
			$labels = [];

			foreach ($data[0]->get() as $k=>$v)
			{
				$date = new \DateTime('@' . ($k * $interval));
				$labels[] = Utils::date_fr($date, 'M y');
			}

			$plot->setLabels($labels);

			$i = 0;
			$colors = self::getColors();

			foreach ($data as $line)
			{
				$line->color = $colors[$i++];
				$line->width = 3;
				$plot->add($line);

				if ($i >= count($colors))
					$i = 0;
			}
		}

		return $plot->output();
	}

	static public function pie(string $type, array $criterias)
	{
		if (!array_key_exists($type, self::PIE_TYPES)) {
			throw new \InvalidArgumentException('Unknown type');
		}

		$pie = new Pie(700, 300);

		$pie_criterias = self::PIE_TYPES[$type];
		$data = Reports::getClosingSumsWithAccounts(array_merge($criterias, $pie_criterias), 'ABS(sum) DESC');

		$others = 0;
		$colors = self::getColors();
		$max = count($colors);
		$total = 0;
		$count = 0;
		$i = 0;

		foreach ($data as $row) {
			$row->sum = abs($row->sum);
			$total += $row->sum;
		}

		foreach ($data as $row)
		{
			if ($i++ >= $max || $count > $total*0.95)
			{
				$others += $row->sum;
			}
			else
			{
				$label = strlen($row->label) > 40 ? substr($row->label, 0, 38) . '…' : $row->label;
				$pie->add(new Pie_Data(abs($row->sum) / 100, $label, $colors[$i-1]));
			}

			$count += $row->sum;
		}

		if ($others != 0)
		{
			$pie->add(new Pie_Data(abs($others) / 100, 'Autres', '#ccc'));
		}

		$pie->togglePercentage(true);

		return $pie->output();
	}

	static protected function getColors()
	{
		$config = Config::getInstance();
		$c1 = $config->get('couleur1') ?: ADMIN_COLOR1;
		$c2 = $config->get('couleur2') ?: ADMIN_COLOR2;
		list($h, $s, $v) = Utils::rgbToHsv($c1);
		list($h1, $s, $v) = Utils::rgbToHsv($c2);

		$colors = [];

		for ($i = 0; $i < 6; $i++) {
			if ($i % 2 == 0) {
				$s = $v = 50;
				$h =& $h1;
			}
			else {
				$s = $v = 70;
				$h =& $h2;
			}

			$colors[] = sprintf('hsl(%d, %d%%, %d%%)', $h, $s, $v);

			$h += 30;

			if ($h > 360) {
				$h -= 360;
			}
		}

		return $colors;
	}
}

Added src/include/lib/Garradin/Accounting/Reports.php version [bd1f8f1a69].































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
<?php

namespace Garradin\Accounting;

use Garradin\Entities\Accounting\Account;
use Garradin\Entities\Accounting\Line;
use Garradin\Entities\Accounting\Transaction;
use Garradin\Utils;
use Garradin\DB;
use KD2\DB\EntityManager;

class Reports
{
	static public function getWhereClause(array $criterias): string
	{
		$where = [];

		if (!empty($criterias['year'])) {
			$where[] = sprintf('t.id_year = %d', $criterias['year']);
		}

		if (!empty($criterias['position'])) {
			$db = DB::getInstance();
			$where[] = $db->where('position', $criterias['position']);
		}

		if (!empty($criterias['exclude_position'])) {
			$db = DB::getInstance();
			$where[] = $db->where('position', 'NOT IN', $criterias['exclude_position']);
		}

		if (!empty($criterias['type'])) {
			$db = DB::getInstance();
			$criterias['type'] = array_map('intval', (array)$criterias['type']);
			$where[] = sprintf('a.type IN (%s)', implode(',', $criterias['type']));
		}

		if (!empty($criterias['user'])) {
			$where[] = sprintf('t.id IN (SELECT id_transaction FROM acc_transactions_users WHERE id_user = %d)', $criterias['user']);
		}

		if (!empty($criterias['creator'])) {
			$where[] = sprintf('t.id_creator = %d', $criterias['creator']);
		}

		if (!empty($criterias['service_user'])) {
			$where[] = sprintf('t.id IN (SELECT tu.id_transaction FROM acc_transactions_users tu WHERE id_service_user = %d)', $criterias['service_user']);
		}

		if (!empty($criterias['analytical'])) {
			$where[] = sprintf('l.id_analytical = %d', $criterias['analytical']);
		}

		if (!count($where)) {
			throw new \LogicException('Unknown criteria');
		}

		return implode(' AND ', $where);
	}

	/**
	 * Return account sums per year or per account
	 * @param  bool $order_year If true will return accounts grouped by year, if false it will return years grouped by account
	 */
	static public function getAnalyticalSums(bool $by_year = false): \Generator
	{
		$sql = 'SELECT a.label AS account_label, a.id AS id_account, y.id AS id_year, y.label AS year_label, y.start_date, y.end_date,
			SUM(l.credit - l.debit) AS sum, SUM(l.credit) AS credit, SUM(l.debit) AS debit
			FROM acc_transactions_lines l
			INNER JOIN acc_transactions t ON t.id = l.id_transaction
			INNER JOIN acc_accounts a ON a.id = l.id_analytical
			INNER JOIN acc_years y ON y.id = t.id_year
			GROUP BY %s
			ORDER BY %s;';

		if ($by_year) {
			$group = 'y.id, a.id';
			$order = 'y.start_date DESC, a.label COLLATE NOCASE';
		}
		else {
			$group = 'a.id, y.id';
			$order = 'a.label COLLATE NOCASE, y.id';
		}

		$sql = sprintf($sql, $group, $order);

		$current = null;

		foreach (DB::getInstance()->iterate($sql) as $row) {
			$id = $by_year ? $row->id_year : $row->id_account;

			if (null !== $current && $current->id !== $id) {
				$current->items[] = (object) [
					'label' => 'Total',
					'credit' => $current->credit,
					'debit' => $current->debit,
					'sum' => $current->sum,
					'id_account' => $by_year ? null : $current->id,
					'id_year' => $by_year ? $current->id : null,
				];

				yield $current;
				$current = null;
			}

			if (null === $current) {
				$current = (object) [
					'id' => $by_year ? $row->id_year : $row->id_account,
					'label' => $by_year ? $row->year_label : $row->account_label,
					'credit' => 0,
					'debit' => 0,
					'sum' => 0,
					'items' => []
				];
			}

			$row->label = !$by_year ? $row->year_label : $row->account_label;
			$current->items[] = $row;
			$current->credit += $row->credit;
			$current->debit += $row->debit;
			$current->sum += $row->sum;
		}

		if ($current === null) {
			return;
		}

		$current->items[] = (object) [
			'label' => 'Total',
			'credit' => $current->credit,
			'debit' => $current->debit,
			'sum' => $current->sum,
			'id_account' => $by_year ? null : $row->id_account,
			'id_year' => $by_year ? $row->id_year : null,
		];
		yield $current;
	}

	static public function getSumsByInterval(array $criterias, int $interval)
	{
		$where = self::getWhereClause($criterias);
		$where_interval = !empty($criterias['year']) ? sprintf(' WHERE id_year = %d', $criterias['year']) : '';

		$db = DB::getInstance();

		$sql = sprintf('SELECT
			strftime(\'%%s\', MIN(date)) / %d AS start_interval,
			strftime(\'%%s\', MAX(date)) / %1$d AS end_interval
			FROM acc_transactions %s;',
			$interval, $where_interval);

		extract((array)$db->first($sql));

		$out = array_fill_keys(range($start_interval, $end_interval), 0);

		$sql = sprintf('SELECT strftime(\'%%s\', t.date) / %d AS interval, SUM(l.credit) - SUM(l.debit) AS sum, t.id_year
			FROM acc_transactions t
			INNER JOIN acc_transactions_lines l ON l.id_transaction = t.id
			INNER JOIN acc_accounts a ON a.id = l.id_account
			WHERE %s
			GROUP BY %s ORDER BY %3$s;', $interval, $where, isset($criterias['year']) ? 'interval' : 't.id_year, interval');

		$data = $db->getGrouped($sql);
		$sum = 0;
		$year = null;

		foreach ($out as $k => &$v) {
			if (array_key_exists($k, $data)) {
				$row = $data[$k];
				if ($row->id_year != $year) {
					$sum = 0;
					$year = $row->id_year;
				}

				$sum += $data[$k]->sum;
			}

			$v = $sum;
		}

		unset($v);

		return $out;
	}

	static public function getResult(array $criterias): int
	{
		$where = self::getWhereClause($criterias);
		$sql = sprintf('SELECT SUM(l.credit) - SUM(l.debit)
			FROM %s l
			INNER JOIN %s t ON t.id = l.id_transaction
			INNER JOIN %s a ON a.id = l.id_account
			WHERE %s AND a.position = ?;',
			Line::TABLE, Transaction::TABLE, Account::TABLE, $where);

		$db = DB::getInstance();
		$a = $db->firstColumn($sql, Account::REVENUE);
		$b = $db->firstColumn($sql, Account::EXPENSE);

		return (int)$a - abs((int)$b);
	}

	static public function getClosingSumsWithAccounts(array $criterias, ?string $order = null, bool $reverse = false): array
	{
		$where = self::getWhereClause($criterias);

		$order = $order ?: 'a.code COLLATE NOCASE';
		$reverse = $reverse ? '* - 1' : '';

		// Find sums, link them to accounts
		$sql = sprintf('SELECT a.id, a.code, a.label, a.position, SUM(l.credit) AS credit, SUM(l.debit) AS debit,
			SUM(l.credit - l.debit) %s AS sum
			FROM %s l
			INNER JOIN %s t ON t.id = l.id_transaction
			INNER JOIN %s a ON a.id = l.id_account
			WHERE %s
			GROUP BY l.id_account
			HAVING sum != 0
			ORDER BY %s;',
			$reverse, Line::TABLE, Transaction::TABLE, Account::TABLE, $where, $order);
		return DB::getInstance()->getGrouped($sql);
	}

	static public function getBalanceSheet(array $criterias): array
	{
		$out = [
			Account::ASSET => [],
			Account::LIABILITY => [],
			'sums' => [
				Account::ASSET => 0,
				Account::LIABILITY => 0,
			],
		];

		$position_criteria = ['position' => [Account::ASSET, Account::LIABILITY, Account::ASSET_OR_LIABILITY]];
		$list = self::getClosingSumsWithAccounts($criterias + $position_criteria);

		foreach ($list as $row) {
			if ($row->sum == 0) {
				// Ignore empty accounts
				continue;
			}

			$position = $row->position;

			if ($position == Account::ASSET_OR_LIABILITY) {
				$position = $row->sum < 0 ? Account::ASSET : Account::LIABILITY;
				$row->sum = abs($row->sum);
			}
			elseif ($position == Account::ASSET) {
				// reverse number for assets
				$row->sum *= -1;
			}

			$out[$position][] = $row;
		}

		$result = self::getResult($criterias);

		$out[Account::LIABILITY][] = (object) [
			'id' => null,
			'label' => $result > 0 ? 'Résultat de l\'exercice courant (excédent)' : 'Résultat de l\'exercice courant (perte)',
			'sum' => $result,
		];

		// Calculate the total sum for assets and liabilities
		foreach ($out as $position => $rows) {
			if ($position == 'sums') {
				continue;
			}

			$sum = 0;
			foreach ($rows as $row) {
				$sum += $row->sum;
			}

			$out['sums'][$position] = $sum;
		}

		return $out;
	}

	/**
	 * Return list of favorite accounts (accounts with a type), grouped by type, with their current sum
	 * @return \Generator list of accounts grouped by type
	 */
	static public function getClosingSumsFavoriteAccounts(array $criterias): \Generator
	{
		$where = self::getWhereClause($criterias);

		$sql = sprintf('SELECT a.id, a.code, a.label, a.description, a.type,
			SUM(l.credit) - SUM(l.debit) AS sum
			FROM %s a
			INNER JOIN %s t ON t.id = l.id_transaction
			INNER JOIN %s l ON a.id = l.id_account
			WHERE a.type != 0 AND %s
			GROUP BY l.id_account
			ORDER BY a.type, a.code COLLATE NOCASE;', Account::TABLE, Transaction::TABLE, Line::TABLE, $where);

		$group = null;

		foreach (DB::getInstance()->iterate($sql) as $row) {
			if (null !== $group && $row->type !== $group->type) {
				yield $group;
				$group = null;
			}

			if (null === $group) {
				$group = (object) [
					'label'    => Account::TYPES_NAMES[$row->type],
					'type'     => $row->type,
					'accounts' => []
				];
			}

			$reverse = Account::isReversed($row->type) ? -1 : 1;
			$row->sum *= $reverse;

			$group->accounts[] = $row;
		}

		if (null !== $group) {
			yield $group;
		}
	}

	/**
	 * Grand livre
	 */
	static public function getGeneralLedger(array $criterias): \Generator
	{
		$where = self::getWhereClause($criterias);

		$db = DB::getInstance();

		$sql = sprintf('SELECT t.id_year, l.id_account, l.debit, l.credit, t.id, t.date, t.reference, l.reference AS line_reference, t.label, l.label AS line_label
			FROM acc_transactions t
			INNER JOIN acc_transactions_lines l ON l.id_transaction = t.id
			INNER JOIN acc_accounts a ON a.id = l.id_account
			WHERE %s
			ORDER BY a.code COLLATE NOCASE, t.date, t.id;', $where);

		$account = null;
		$debit = $credit = 0;
		$accounts = null;

		foreach ($db->iterate($sql) as $row) {
			if (null === $accounts) {
				$accounts = $db->getGrouped('SELECT id, code, label FROM acc_accounts WHERE id_chart = (SELECT id_chart FROM acc_years WHERE id = ?);', $row->id_year);
			}

			if (null !== $account && $account->id != $row->id_account) {
				yield $account;
				$account = null;
			}

			if (null === $account) {
				$account = (object) [
					'code'  => $accounts[$row->id_account]->code,
					'label' => $accounts[$row->id_account]->label,
					'id'    => $row->id_account,
					'id_year' => $row->id_year,
					'sum'   => 0,
					'debit' => 0,
					'credit'=> 0,
					'lines' => [],
				];
			}

			$row->date = \DateTime::createFromFormat('Y-m-d', $row->date);

			$account->sum += ($row->credit - $row->debit);
			$account->debit += $row->debit;
			$account->credit += $row->credit;
			$debit += $row->debit;
			$credit += $row->credit;
			$row->running_sum = $account->sum;


			$account->lines[] = $row;
		}

		if (null === $account) {
			return;
		}

		$account->all_debit = $debit;
		$account->all_credit = $credit;

		yield $account;
	}

	static public function getJournal(array $criterias): \Generator
	{
		$where = self::getWhereClause($criterias);

		$sql = sprintf('SELECT t.id_year, l.id_account, l.debit, l.credit, t.id, t.date, t.reference, l.reference AS line_reference, t.label, l.label AS line_label FROM acc_transactions t
			INNER JOIN acc_transactions_lines l ON l.id_transaction = t.id
			WHERE %s ORDER BY t.date, t.id;', $where);

		$transaction = null;
		$accounts = null;
		$db = DB::getInstance();

		foreach ($db->iterate($sql) as $row) {
			if (null === $accounts) {
				$accounts = $db->getGrouped('SELECT id, code, label FROM acc_accounts WHERE id_chart = (SELECT id_chart FROM acc_years WHERE id = ?);', $row->id_year);
			}

			if (null !== $transaction && $transaction->id != $row->id) {
				yield $transaction;
				$transaction = null;
			}

			if (null === $transaction) {
				$transaction = (object) [
					'id'        => $row->id,
					'label'     => $row->label,
					'date'      => \DateTime::createFromFormat('Y-m-d', $row->date),
					'reference' => $row->reference,
					'lines'     => [],
				];
			}

			if (!isset($accounts[$row->id_account])) {
				throw new \LogicException(sprintf('Account #%s not found', $row->id_account));
			}

			$transaction->lines[] = (object) [
				'account_label' => $accounts[$row->id_account]->label,
				'account_code'  => $accounts[$row->id_account]->code,
				'label'         => $row->line_label,
				'reference'     => $row->line_reference,
				'id_account'    => $row->id_account,
				'credit'        => $row->credit,
				'debit'         => $row->debit,
				'id_year'       => $row->id_year,
			];
		}

		if (null === $transaction) {
			return;
		}

		yield $transaction;
	}
}

Added src/include/lib/Garradin/Accounting/Transactions.php version [6561462819].







































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
<?php

namespace Garradin\Accounting;

use Garradin\Entities\Accounting\Account;
use Garradin\Entities\Accounting\Line;
use Garradin\Entities\Accounting\Transaction;
use Garradin\Entities\Accounting\Year;
use KD2\DB\EntityManager;
use Garradin\CSV;
use Garradin\CSV_Custom;
use Garradin\DB;
use Garradin\DynamicList;
use Garradin\Utils;
use Garradin\UserException;

class Transactions
{
	const EXPECTED_CSV_COLUMNS_SELF = ['id', 'type', 'status', 'label', 'date', 'notes', 'reference',
		'line_id', 'account', 'credit', 'debit', 'line_reference', 'line_label', 'reconciled'];

	const POSSIBLE_CSV_COLUMNS = [
		'id'             => 'Numéro d\'écriture',
		'label'          => 'Libellé',
		'date'           => 'Date',
		'notes'          => 'Notes',
		'reference'      => 'Numéro pièce comptable',
		'p_reference'    => 'Référence paiement',
		'debit_account'  => 'Compte de débit',
		'credit_account' => 'Compte de crédit',
		'amount'         => 'Montant',
	];

	const MANDATORY_CSV_COLUMNS = ['id', 'label', 'date', 'credit_account', 'debit_account', 'amount'];

	static public function get(int $id)
	{
		return EntityManager::findOneById(Transaction::class, $id);
	}

	static public function saveReconciled(\Generator $journal, ?array $checked)
	{
		if (null === $checked) {
			$checked = [];
		}

		$db = DB::getInstance();
		$db->begin();

		// Synchro des trucs cochés
		$st = $db->prepare('UPDATE acc_transactions_lines SET reconciled = :r WHERE id = :id;');

		foreach ($journal as $row)
		{
			if (!isset($row->id_line)) {
				continue;
			}

			$st->bindValue(':id', (int)$row->id_line, \SQLITE3_INTEGER);
			$st->bindValue(':r', !empty($checked[$row->id_line]) ? 1 : 0, \SQLITE3_INTEGER);
			$st->execute();
		}

		$db->commit();
	}

	static public function saveDeposit(Transaction $transaction, \Generator $journal, array $checked)
	{
		$db = DB::getInstance();
		$db->begin();

		try {
			$ids = [];
			foreach ($journal as $row) {
				if (!array_key_exists($row->id, $checked)) {
					continue;
				}

				$ids[] = (int)$row->id;

				$line = new Line;
				$line->importForm([
					'reference'  => $row->line_reference,
					'id_account' => $row->id_account,
				]);
				$line->credit = $row->debit;

				$transaction->addLine($line);
			}

			$transaction->save();
			$ids = implode(',', $ids);
			$db->exec(sprintf('UPDATE acc_transactions SET status = (status | %d) WHERE id IN (%s);', Transaction::STATUS_DEPOSIT, $ids));
			$db->commit();
		}
		catch (\Exception $e) {
			$db->rollback();
			throw $e;
		}
	}

	static public function countForUser(int $user_id): int
	{
		return DB::getInstance()->count('acc_transactions_users', 'id_user = ?', $user_id);
	}

	static public function countForCreator(int $user_id): int
	{
		return DB::getInstance()->count('acc_transactions', 'id_creator = ?', $user_id);
	}

	/**
	 * Return all transactions from year
	 */
	static public function export(int $year_id): \Generator
	{
		$sql = 'SELECT t.id, t.type, t.status, t.label, t.date, t.notes, t.reference,
			l.id AS line_id, a.code AS account, l.debit AS debit, l.credit AS credit,
			l.reference AS line_reference, l.label AS line_label, l.reconciled,
			a2.code AS analytical
			FROM acc_transactions t
			INNER JOIN acc_transactions_lines l ON l.id_transaction = t.id
			INNER JOIN acc_accounts a ON a.id = l.id_account
			LEFT JOIN acc_accounts a2 ON a2.id = l.id_analytical
			WHERE t.id_year = ? ORDER BY t.date, t.id, l.id;';

		$res = DB::getInstance()->iterate($sql, $year_id);

		$previous_id = null;

		foreach ($res as $row) {
			if ($previous_id === $row->id) {
				$row->id = $row->type = $row->status = $row->label = $row->date = $row->notes = $row->reference = null;
			}
			else {
				$row->type = Transaction::TYPES_NAMES[$row->type];

				$status = [];

				foreach (Transaction::STATUS_NAMES as $k => $v) {
					if ($row->status & $k) {
						$status[] = $v;
					}
				}

				$row->status = implode(', ', $status);
				$row->date = \DateTime::createFromFormat('Y-m-d', $row->date);
				$row->date = $row->date->format('d/m/Y');
			}

			$row->credit = Utils::money_format($row->credit, ',', '');
			$row->debit = Utils::money_format($row->debit, ',', '');

			$previous_id = $row->id;
			yield $row;
		}
	}

	static public function importCSV(Year $year, array $file, int $user_id)
	{
		if ($year->closed) {
			throw new \InvalidArgumentException('Closed year');
		}

		$db = DB::getInstance();
		$db->begin();

		$accounts = $year->accounts();
		$transaction = null;
		$types = array_flip(Transaction::TYPES_NAMES);

		$l = 0;

		try {
			foreach (CSV::importUpload($file, self::EXPECTED_CSV_COLUMNS_SELF) as $l => $row) {
				$row = (object) $row;

				$has_transaction = !empty($row->id) || !empty($row->type) || !empty($row->status) || !empty($row->label) || !empty($row->date) || !empty($row->notes) || !empty($row->reference);

				if (null !== $transaction && $has_transaction) {
					$transaction->save();
					$transaction = null;
				}

				if (null === $transaction) {
					if (!$has_transaction) {
						throw new UserException('cette ligne n\'est reliée à aucune écriture');
					}

					if ($row->id) {
						$transaction = self::get((int)$row->id);

						if (!$transaction) {
							throw new UserException(sprintf('l\'écriture n°%d est introuvable', $row->id));
						}

						if ($transaction->validated) {
							throw new UserException(sprintf('l\'écriture n°%d est validée et ne peut être modifiée', $row->id));
						}
					}
					else {
						$transaction = new Transaction;
						$transaction->id_creator = $user_id;
						$transaction->id_year = $year->id();
					}

					if (!isset($types[$row->type])) {
						throw new UserException(sprintf('le type "%s" est inconnu', $row->type));
					}

					$transaction->type = $types[$row->type];
					$fields = array_intersect_key((array)$row, array_flip(['label', 'date', 'notes', 'reference']));

					$transaction->importForm($fields);
				}

				$id_account = $accounts->getIdFromCode($row->account);

				if (!$id_account) {
					throw new UserException(sprintf('le compte "%s" n\'existe pas dans le plan comptable', $row->account));
				}

				$row->line_id = trim($row->line_id);
				$id_analytical = null;
				$data = [
					'credit'     => $row->credit ?: 0,
					'debit'      => $row->debit ?: 0,
					'id_account' => $id_account,
					'reference'  => $row->line_reference,
					'label'      => $row->line_label,
					'reconciled' => $row->reconciled,
				];

				if (!empty($row->analytical)) {
					$id_analytical = $accounts->getIdFromCode($row->analytical);

					if (!$id_analytical) {
						throw new UserException(sprintf('le compte analytique "%s" n\'existe pas dans le plan comptable', $row->analytical));
					}

					$data['id_analytical'] = $id_analytical;
				}
				elseif (property_exists($row, 'analytical')) {
					$data['id_analytical'] = null;
				}

				if ($row->line_id) {
					$line = $transaction->getLine((int)$row->line_id);

					if (!$line) {
						throw new UserException(sprintf('le numéro de ligne "%s" n\'existe pas dans l\'écriture "%s"', $row->line_id, $transaction->id ?: 'à créer'));
					}
				}
				else {
					$line = new Line;
				}

				$line->importForm($data);

				if (!$row->line_id) {
					$transaction->addLine($line);
				}
			}

			if (null !== $transaction) {
				$transaction->save();
			}
		}
		catch (UserException $e) {
			$db->rollback();
			throw new UserException(sprintf('Erreur sur la ligne %d : %s', $l, $e->getMessage()));
		}

		$db->commit();
	}

	static public function importCustom(Year $year, CSV_Custom $csv, int $user_id)
	{
		if ($year->closed) {
			throw new \InvalidArgumentException('Closed year');
		}

		$db = DB::getInstance();
		$db->begin();

		$accounts = $year->accounts();
		$l = 0;

		try {
			foreach ($csv->iterate() as $l => $row) {
				if (!isset($row->credit_account, $row->debit_account, $row->amount)) {
					throw new UserException('Une des colonnes compte de crédit, compte de débit ou montant est manquante.');
				}

				if (!empty($row->id)) {
					$transaction = self::get((int)$row->id);

					if (!$transaction) {
						throw new UserException(sprintf('Ligne %d : l\'écriture n°%d est introuvable', $l, $row->id));
					}

					if ($transaction->validated) {
						throw new UserException(sprintf('Ligne %d : l\'écriture n°%d est validée et ne peut être modifiée', $l, $row->id));
					}

					$transaction->resetLines();
				}
				else {
					$transaction = new Transaction;
					$transaction->type = Transaction::TYPE_ADVANCED;
					$transaction->id_creator = $user_id;
					$transaction->id_year = $year->id();
				}

				$fields = array_intersect_key((array)$row, array_flip(['label', 'date', 'notes', 'reference']));
				$transaction->importForm($fields);

				$credit_account = $accounts->getIdFromCode($row->credit_account);
				$debit_account = $accounts->getIdFromCode($row->debit_account);

				if (!$credit_account) {
					throw new UserException(sprintf('Compte de crédit "%s" inconnu dans le plan comptable', $row->credit_account));
				}

				if (!$debit_account) {
					throw new UserException(sprintf('Compte de débit "%s" inconnu dans le plan comptable', $row->debit_account));
				}

				$line = new Line;
				$line->importForm([
					'credit'     => $row->amount,
					'debit'      => 0,
					'id_account' => $credit_account,
					'reference'  => isset($row->p_reference) ? $row->p_reference : null,
				]);
				$transaction->addLine($line);

				$line = new Line;
				$line->importForm([
					'credit'     => 0,
					'debit'      => $row->amount,
					'id_account' => $debit_account,
					'reference'  => isset($row->p_reference) ? $row->p_reference : null,
				]);
				$transaction->addLine($line);
				$transaction->save();
			}
		}
		catch (UserException $e) {
			$db->rollback();
			throw new UserException(sprintf('Erreur sur la ligne %d : %s', $l, $e->getMessage()));
		}

		$db->commit();
	}

	static public function setAnalytical(?int $id_analytical, array $lines)
	{
		$db = DB::getInstance();

		if (null !== $id_analytical && !$db->test(Account::TABLE, 'type = 7 AND id = ?', $id_analytical)) {
			throw new \InvalidArgumentException('Chosen account ID is not analytical');
		}

		$lines = array_map('intval', $lines);

		return $db->exec(sprintf('UPDATE acc_transactions_lines SET id_analytical = %s WHERE id IN (%s);',
			(int)$id_analytical ?: 'NULL',
			implode(', ', $lines)));
	}

	static public function listByType(int $year_id, int $type)
	{
		$reverse = 1;

		$columns = Account::LIST_COLUMNS;
		unset($columns['line_label'], $columns['sum'], $columns['debit'], $columns['credit']);
		$columns['line_reference']['label'] = 'Réf. paiement';
		$columns['change']['select'] = sprintf('SUM(l.credit) * %d', $reverse);
		$columns['change']['label'] = 'Montant';

		$tables = 'acc_transactions_lines l
			INNER JOIN acc_transactions t ON t.id = l.id_transaction
			INNER JOIN acc_accounts a ON a.id = l.id_account
			LEFT JOIN acc_accounts b ON b.id = l.id_analytical';
		$conditions = sprintf('t.type = %s AND t.id_year = %d', $type, $year_id);

		$sum = 0;

		$list = new DynamicList($columns, $tables, $conditions);
		$list->orderBy('date', true);
		$list->setCount('COUNT(*)');
		$list->groupBy('t.id');
		$list->setModifier(function (&$row) use (&$sum, $reverse) {
			$row->date = \DateTime::createFromFormat('!Y-m-d', $row->date);
		});
		$list->setExportCallback(function (&$row) {
			$row->change = Utils::money_format($row->change, '.', '', false);
		});

		return $list;
	}
}

Added src/include/lib/Garradin/Accounting/Years.php version [6f97d0273b].















































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
<?php

namespace Garradin\Accounting;

use Garradin\Entities\Accounting\Year;
use Garradin\Utils;
use Garradin\DB;
use KD2\DB\EntityManager;

class Years
{
	static public function get(int $year_id)
	{
		return EntityManager::findOneById(Year::class, $year_id);
	}

	static public function getCurrentOpenYear()
	{
		return EntityManager::findOne(Year::class, 'SELECT * FROM @TABLE WHERE closed = 0 ORDER BY start_date LIMIT 1;');
	}

	static public function listOpen()
	{
		$db = EntityManager::getInstance(Year::class)->DB();
		return $db->get('SELECT *, (SELECT 1 FROM acc_transactions WHERE id_year = acc_years.id LIMIT 1) AS has_transactions
			FROM acc_years WHERE closed = 0 ORDER BY end_date;');
	}

	static public function listAssoc()
	{
		return DB::getInstance()->getAssoc('SELECT id, label FROM acc_years ORDER BY end_date;');
	}

	static public function listClosed()
	{
		$em = EntityManager::getInstance(Year::class);
		return $em->all('SELECT * FROM @TABLE WHERE closed = 1 ORDER BY end_date;');
	}

	static public function countClosed()
	{
		return DB::getInstance()->count(Year::TABLE, 'closed = 1');
	}

	static public function list(bool $reverse = false)
	{
		$desc = $reverse ? 'DESC' : '';
		$em = EntityManager::getInstance(Year::class);
		return $em->all(sprintf('SELECT * FROM @TABLE ORDER BY end_date %s;', $desc));
	}

	static public function getNewYearDates(): array
	{
		$last_year = EntityManager::findOne(Year::class, 'SELECT * FROM @TABLE ORDER BY end_date DESC LIMIT 1;');

		if ($last_year) {
			$start_date = clone $last_year->start_date;
			$start_date->modify('+1 year');

			$end_date = clone $last_year->end_date;
			$end_date->modify('+1 year');
		}
		else {
			$start_date = new \DateTime;
			$end_date = clone $start_date;
			$end_date->modify('+1 year');
		}

		return [$start_date, $end_date];
	}
}

Added src/include/lib/Garradin/CSV.php version [0895323879].

















































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
<?php

namespace Garradin;

use KD2\Office\Calc\Writer as ODSWriter;

class CSV
{
	static public function readAsArray(string $path)
	{
		if (!file_exists($path) || !is_readable($path))
		{
			throw new \RuntimeException('Fichier inconnu : '.$path);
		}

		$fp = self::open($path);

		if (!$fp)
		{
			return false;
		}

		$delim = self::findDelimiter($fp);
		self::skipBOM($fp);

		$line = 0;
		$out = [];
		$nb_columns = null;

		while (!feof($fp))
		{
			$row = fgetcsv($fp, 4096, $delim);
			$line++;

			if (empty($row))
			{
				continue;
			}

			if (null === $nb_columns)
			{
				$nb_columns = count($row);
			}

			if (count($row) != $nb_columns)
			{
				throw new UserException('Erreur sur la ligne ' . $line . ' : incohérence dans le nombre de colonnes avec la première ligne.');
			}

			$out[$line] = $row;
		}

		fclose($fp);

		return $out;
	}

	static public function open(string $file)
	{
		ini_set('auto_detect_line_endings', true);
		return fopen($file, 'r');
	}

	static public function findDelimiter(&$fp)
	{
		$line = '';

		while ($line === '' && !feof($fp))
		{
			$line = fgets($fp, 4096);
		}

		if (strlen($line) >= 4095) {
			throw new UserException('Fichier CSV illisible : la première ligne est trop longue.');
		}

		// Delete the columns content
		$line = preg_replace('/".*?"/', '', $line);

		$delims = [
			';' => substr_count($line, ';'),
			',' => substr_count($line, ','),
			"\t"=> substr_count($line, "\t")
		];

		arsort($delims);
		reset($delims);

		rewind($fp);

		return key($delims);
	}

	static public function skipBOM(&$fp)
	{
		// Skip BOM
		if (fgets($fp, 4) !== chr(0xEF) . chr(0xBB) . chr(0xBF))
		{
			fseek($fp, 0);
		}
	}

	static public function row($row): string
	{
		$row = (array) $row;

		array_walk($row, function (&$field) {
			$field = strtr($field, ['"' => '""', "\r\n" => "\n"]);
		});

		return sprintf("\"%s\"\r\n", implode('","', $row));
	}

	static public function export(string $format, string $name, iterable $iterator, ?array $header = null, ?callable $row_map_callback = null): void
	{
		if ('csv' == $format) {
			self::toCSV(... array_slice(func_get_args(), 1));
		}
		else {
			self::toODS(... array_slice(func_get_args(), 1));
		}
	}

	static protected function rowToArray($row, ?callable $row_map_callback)
	{
		if (null !== $row_map_callback) {
			call_user_func_array($row_map_callback, [&$row]);
		}

		if (is_object($row) && $row instanceof Entity) {
			$row = $row->asArray();
		}
		elseif (is_object($row)) {
			$row = (array) $row;
		}

		foreach ($row as $key => &$v) {
			if ((is_object($v) && !($v instanceof \DateTimeInterface)) || is_array($v)) {
				throw new \UnexpectedValueException(sprintf('Unexpected value for "%s": %s', $key, gettype($v)));
			}
		}

		return $row;
	}

	static public function toCSV(string $name, iterable $iterator, ?array $header = null, ?callable $row_map_callback = null): void
	{
		header('Content-type: application/csv');
		header(sprintf('Content-Disposition: attachment; filename="%s.csv"', $name));

		$fp = fopen('php://output', 'w');

		if ($header)
		{
			fputs($fp, self::row($header));
		}

		foreach ($iterator as $row)
		{
			foreach ($row as $key => &$v) {
				if (is_object($v)&& $v instanceof \DateTimeInterface) {
					$v = $v->format('d/m/Y');
				}
			}

			$row = self::rowToArray($row, $row_map_callback);

			if (!$header)
			{
				fputs($fp, self::row(array_keys($row)));
				$header = true;
			}

			fputs($fp, self::row($row));
		}

		fclose($fp);
	}

	static public function toODS(string $name, iterable $iterator, ?array $header = null, ?callable $row_map_callback = null): void
	{
		header('Content-type: application/vnd.oasis.opendocument.spreadsheet');
		header(sprintf('Content-Disposition: attachment; filename="%s.ods"', $name));

		$ods = new ODSWriter;
		$ods->table_name = $name;

		if ($header)
		{
			$ods->add((array) $header);
		}

		foreach ($iterator as $row)
		{
			$row = self::rowToArray($row, $row_map_callback);

			if (!$header)
			{
				$ods->add(array_keys($row));
				$header = true;
			}

			$ods->add((array) $row);
		}

		$ods->output();
	}

	static public function importUpload(array $file, array $expected_columns): \Generator
	{
		if (empty($file['size']) || empty($file['tmp_name'])) {
			throw new UserException('Fichier invalide');
		}

		return self::import($file['tmp_name'], $expected_columns);
	}

	static public function import(string $file, array $expected_columns): \Generator
	{
		$fp = fopen($file, 'r');

		if (!$fp) {
			throw new UserException('Le fichier ne peut être ouvert');
		}

		// Find the delimiter
		$delim = self::findDelimiter($fp);
		self::skipBOM($fp);

		$line = 1;

		$columns = fgetcsv($fp, 4096, $delim);
		$columns = array_map('trim', $columns);

		// Check for required columns
		foreach ($expected_columns as $column) {
			if (!in_array($column, $columns, true)) {
				throw new UserException(sprintf('La colonne "%s" est absente du fichier importé', $column));
			}
		}

		while (!feof($fp))
		{
			$row = fgetcsv($fp, 4096, $delim);
			$line++;

			// Empty line, skip
			if (empty($row)) {
				continue;
			}

			if (count($row) != count($columns))
			{
				throw new UserException('Erreur sur la ligne ' . $line . ' : le nombre de colonnes est incorrect.');
			}

			$row = array_combine($columns, $row);

			yield $line => $row;
		}

		fclose($fp);
	}
}

Added src/include/lib/Garradin/CSV_Custom.php version [12dd8c64a5].





















































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
<?php

namespace Garradin;

use KD2\UserSession;

class CSV_Custom
{
	protected $session;
	protected $key;
	protected $csv;
	protected $translation;
	protected $columns;
	protected $mandatory_columns = [];
	protected $skip = 1;

	public function __construct(UserSession $session, string $key)
	{
		$this->session = $session;
		$this->key = $key;
		$this->csv = $this->session->get($this->key);
		$this->translation = $this->session->get($this->key . '_translation') ?: [];
		$this->skip = $this->session->get($this->key . '_skip') ?: 1;
	}

	public function load(array $file)
	{
		if (empty($file['size']) || empty($file['tmp_name'])) {
			throw new UserException('Fichier invalide');
		}

		$csv = CSV::readAsArray($file['tmp_name']);

		if (!count($csv)) {
			throw new UserException('Ce fichier est vide (aucune ligne trouvée).');
		}

		$this->session->set($this->key, $csv);
	}

	public function iterate(): \Generator
	{
		if (empty($this->csv)) {
			throw new \LogicException('No file has been loaded');
		}

		if (!$this->columns || !$this->translation) {
			throw new \LogicException('Missing columns or translation table');
		}

		$default = array_map(function ($a) { return null; }, $this->columns);

		$i = 0;

		foreach ($this->csv as $k => $line) {
			if ($i++ < $this->skip) {
				continue;
			}

			$row = $default;

			foreach ($line as $col => $value) {
				if (!isset($this->translation[$col])) {
					continue;
				}

				$row[$this->translation[$col]] = $value;
			}

			$row = (object) $row;
			yield $k => $row;
		}
	}

	public function getFirstLine(): array
	{
		if (empty($this->csv)) {
			throw new \LogicException('No file has been loaded');
		}

		return reset($this->csv);
	}

	public function getSelectedTable(?array $source = null): array
	{
		if (null === $source && isset($_POST['translation_table'])) {
			$source = $_POST['translation_table'];
		}
		elseif (null === $source) {
			$source = [];
		}

		$selected = $this->getFirstLine();

		foreach ($selected as $k => &$v) {
			if (isset($source[$k])) {
				$v = $source[$k];
			}
			elseif (isset($this->translation[$k])) {
				$v = $this->translation[$k];
			}
			elseif (false !== ($pos = array_search($v, $this->columns, true))) {
				$v = $pos;
			}
			else {
				$v = null;
			}
		}

		return $selected;
	}

	public function getTranslationTable(): array
	{
		return $this->translation;
	}

	public function setTranslationTable(array $table): void
	{
		$translation = [];

		foreach ($table as $csv => $target) {
			if (empty($target)) {
				continue;
			}

			if (!array_key_exists($target, $this->columns)) {
				throw new UserException('Colonne inconnue');
			}

			$translation[(int)$csv] = $target;
		}

		foreach ($this->mandatory_columns as $key) {
			if (!in_array($key, $translation, true)) {
				throw new UserException(sprintf('La colonne "%s" est obligatoire mais n\'a pas été sélectionnée ou n\'existe pas.', $this->columns[$key]));
			}
		}

		$this->translation = $translation;

		$this->session->set($this->key . '_translation', $this->translation);
	}

	public function clear(): void
	{
		$this->session->set($this->key, null);
		$this->session->set($this->key . '_translation', null);
		$this->session->set($this->key . '_skip', null);
	}

	public function loaded(): bool
	{
		return null !== $this->csv;
	}

	public function ready(): bool
	{
		return $this->loaded() && !empty($this->translation);
	}

	public function count(): ?int
	{
		return null !== $this->csv ? count($this->csv) : null;
	}

	public function skip(int $count): void
	{
		$this->skip = $count;
		$this->session->set($this->key . '_skip', $count);
	}

	public function setColumns(array $columns): void
	{
		$this->columns = $columns;
	}

	public function setMandatoryColumns(array $columns): void
	{
		$this->mandatory_columns = $columns;
	}

	public function getColumnsString(): string
	{
		return implode(', ', $this->getColumns());
	}

	public function getMandatoryColumnsString(): string
	{
		return implode(', ', $this->getMandatoryColumns());
	}

	public function getColumns(): array
	{
		return $this->columns;
	}

	public function getMandatoryColumns(): array
	{
		return array_intersect_key($this->columns, $this->mandatory_columns);
	}
}

Deleted src/include/lib/Garradin/Compta/Categories.php version [aacf281b4b].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
<?php

namespace Garradin\Compta;

use Garradin\DB;
use Garradin\Utils;
use Garradin\UserException;

/**
 * Catégories comptables
 */
class Categories
{
    const DEPENSES = -1;
    const RECETTES = 1;
    const AUTRES = 0;

    public function importCategories()
    {
        $db = DB::getInstance();
        $db->import(\Garradin\ROOT . '/include/data/categories_comptables.sql');
    }

    public function add($data)
    {
        $this->_checkFields($data);

        $db = DB::getInstance();

        if (empty($data['compte']) || !trim($data['compte']))
        {
            throw new UserException('Le compte associé ne peut rester vide.');
        }

        $data['compte'] = trim($data['compte']);

        if (!$db->test('compta_comptes', $db->where('id', $data['compte'])))
        {
            throw new UserException('Le compte associé n\'existe pas.');
        }

        if (!isset($data['type']) ||
            ($data['type'] != self::DEPENSES && $data['type'] != self::RECETTES))
        {
            // Catégories "autres" pas possibles pour le moment
            throw new UserException('Type de catégorie inconnu.');
        }

        $db->insert('compta_categories', [
            'intitule'  =>  $data['intitule'],
            'description'=> $data['description'],
            'compte'    =>  $data['compte'],
            'type'      =>  (int)$data['type'],
        ]);

        return $db->lastInsertRowId();
    }

    public function edit($id, $data)
    {
        $this->_checkFields($data);

        $db = DB::getInstance();

        $db->update('compta_categories',
            [
                'intitule'  =>  $data['intitule'],
                'description'=> $data['description'],
            ],
            'id = :id_select',
            ['id_select' => (int) $id]
        );

        return true;
    }

    public function delete($id)
    {
        $db = DB::getInstance();

        $id = (int) $id;

        // Ne pas supprimer une catégorie qui est utilisée !
        if ($db->test('compta_journal', $db->where('id_categorie', $id)))
        {
            throw new UserException('Cette catégorie ne peut être supprimée car des opérations comptables y sont liées.');
        }

        $db->delete('compta_categories', 'id = ?', $id);

        return true;
    }

    public function get($id)
    {
        $db = DB::getInstance();
        return $db->first('SELECT * FROM compta_categories WHERE id = ?;', (int)$id);
    }

    public function getList($type = null)
    {
        $db = DB::getInstance();
        $where = is_null($type) ? '1' : 'cat.type = '.(int)$type;

        $query = sprintf('SELECT cat.id, cat.*, cc.libelle AS compte_libelle
            FROM compta_categories AS cat INNER JOIN compta_comptes AS cc
                ON cc.id = cat.compte
            WHERE %s ORDER BY cat.intitule;', $where);

        return $db->getGrouped($query);
    }

    public function listMoyensPaiement($assoc = false)
    {
        $db = DB::getInstance();

        $query = 'SELECT code, nom FROM compta_moyens_paiement ORDER BY nom COLLATE NOCASE;';

        if ($assoc) {
            return $db->getAssoc($query);
        }
        else {
            return $db->getGrouped($query);
        }
    }

    public function getMoyenPaiement($code)
    {
        $db = DB::getInstance();
        return $db->firstColumn('SELECT nom FROM compta_moyens_paiement WHERE code = ?;', $code);
    }

    protected function _checkFields(&$data)
    {
        if (empty($data['intitule']) || !trim($data['intitule']))
        {
            throw new UserException('L\'intitulé ne peut rester vide.');
        }

        $data['intitule'] = trim($data['intitule']);
        $data['description'] = isset($data['description']) ? trim($data['description']) : '';

        return true;
    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































































































































































































Deleted src/include/lib/Garradin/Compta/Comptes.php version [9bf36bdeef].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
<?php

namespace Garradin\Compta;

use \Garradin\DB;
use \Garradin\Utils;
use \Garradin\UserException;

class Comptes
{
    const CAISSE = '530';

    const CHEQUE_A_ENCAISSER = '5112';
    const CARTE_A_ENCAISSER = '5115';

    const PASSIF = 0x01;
    const ACTIF = 0x02;
    const PRODUIT = 0x04;
    const CHARGE = 0x08;

    /**
     * Importe un plan comptable
     * @param  string $source_file Chemin du fichier à importer.
     * @param  boolean $delete_all True active la suppression des tous les anciens comptes (peu importe plan_comptable)
     * @return boolean/array Retourne un array des comptes non-supprimés avec leur raison, s'il y en a. Sinon true.
     *
     * Accepte 0 ou 1 argument : soit un chemin, soit true.
     * Sans arguments : importe le plan par défaut et ne supprime que les comptes
     * plus présent appartenants au plan d'origine (WHERE plan_comptable = 1)
     */
    public function importPlan($source_file = null, $delete_all = false)
    {
        $reset = false;

        if(null == $source_file)
        {
            $reset = true;
            $source_file = \Garradin\ROOT . '/include/data/plan_comptable.json';
        }

        $plan = json_decode(file_get_contents($source_file));

        if(is_null($plan))
        {
            throw new UserException('Le fichier n\'est pas du JSON ou n\'a pas pu être décodé.');
        }

        $db = DB::getInstance();
        $db->begin();
        $ids = [];

        foreach ($plan as $id=>$compte)
        {
            $ids[] = $id;

            if ($db->test('compta_comptes', $db->where('id', $id)))
            {
                $db->update('compta_comptes', [
                    'parent'    =>  $compte->parent,
                    'libelle'   =>  $compte->nom,
                    'position'  =>  $compte->position,
                    'plan_comptable' => $reset || !empty($compte->plan_comptable) ? 1 : 0,
                    'desactive' => !empty($compte->desactive) ? 1 : 0,
                ], $db->where('id', $id));
            }
            else
            {
                $db->insert('compta_comptes', [
                    'id'        =>  $id,
                    'parent'    =>  $compte->parent,
                    'libelle'   =>  $compte->nom,
                    'position'  =>  $compte->position,
                    'plan_comptable' => $reset || !empty($compte->plan_comptable) ? 1 : 0,
                    'desactive' => !empty($compte->desactive) ? 1 : 0,
                ]);
            }
        }

        // Effacer les comptes du plan comptable s'ils ne sont pas utilisés ailleurs
        // et qu'ils ne sont pas dans le nouveau plan comptable qu'on vient d'importer
        $sql = 'DELETE FROM compta_comptes WHERE id NOT IN (
            SELECT id FROM compta_comptes_bancaires
            UNION SELECT compte_credit FROM compta_journal
            UNION SELECT compte_debit FROM compta_journal
            UNION SELECT id FROM compta_categories)
            AND '. $db->where('id', 'NOT IN', $ids);

        // Si on ne fait qu'importer une mise à jour du plan comptable,
        // ne supprimer que les comptes qui n'ont pas été créés par l'usager
        if (!$delete_all) {
            $sql .= ' AND ' . $db->where('plan_comptable', 1);
        }

        $db->commit();

        return true;
    }

    public function exportPlan()
    {
        $name = 'plan_comptable';

        header('Content-type: application/json');
        header(sprintf('Content-Disposition: attachment; filename="%s.json"', $name));

        $liste = $this->listTree(0, true);

        $export = [];

        foreach ($liste as $k => $v)
        {
            $export[$v->id] = [
                'code'           => $v->id,
                'nom'            => $v->libelle,
                'parent'         => $v->parent,
                'position'       => $v->position,
                'plan_comptable' => $v->plan_comptable,
                'desactive'      => $v->desactive,
            ];
        }

        file_put_contents('php://output', json_encode($export, JSON_PRETTY_PRINT));

        return true;
    }

    public function add($data)
    {
        $this->_checkFields($data, true);

        $db = DB::getInstance();

        if (empty($data['id']))
        {
            $new_id = $data['parent'];
            $letters = range('A', 'Z');
            $sub_accounts = $db->getAssoc('SELECT id, id FROM compta_comptes 
                WHERE parent = ? ORDER BY id COLLATE NOCASE ASC;', $data['parent']);

            foreach ($letters as $letter)
            {
                if (!in_array($new_id . $letter, $sub_accounts))
                {
                    $new_id .= $letter;
                    break;
                }
            }

            // On a exaucé le nombre de sous-comptes possibles
            if ($new_id == $data['parent'])
            {
                throw new UserException('Nombre de sous-comptes maximal atteint pour ce compte parent-ci.');
            }
        }
        else
        {
            $new_id = strtoupper($data['id']);

            $parent = false;
            $id = $new_id;

            // Vérification que c'est bien le bon parent !
            // Sinon risque par exemple d'avoir parent = 5 et id = 512A !
            while (!$parent && strlen($id))
            {
                // On enlève un caractère à la fin jusqu'à trouver un compte parent
                $id = substr($id, 0, -1);
                $parent = $db->firstColumn('SELECT id FROM compta_comptes WHERE id = ?;', $id);
            }

            if (!$parent || $parent != $data['parent'])
            {
                throw new UserException('Le compte parent sélectionné est incorrect, par exemple pour créer un compte 512A il faut sélectionner 512 comme compte parent.');
            }
        }

        // Vérification que le compte n'existe pas déjà
        if ($db->test('compta_comptes', 'id = ?', $new_id))
        {
            throw new UserException('Ce numéro de compte existe déjà dans le plan comptable : ' . $new_id);
        }

        if (isset($data['position']))
        {
            $position = (int) $data['position'];
        }
        else
        {
            $position = $db->firstColumn('SELECT position FROM compta_comptes WHERE id = ?;', $data['parent']);
        }

        $db->insert('compta_comptes', [
            'id'        =>  $new_id,
            'libelle'   =>  trim($data['libelle']),
            'parent'    =>  $data['parent'],
            'plan_comptable' => 0,
            'position'  =>  (int)$position,
        ]);

        return $new_id;
    }

    public function edit($id, $data)
    {
        $db = DB::getInstance();

        $id = trim($id);

        // Vérification que l'on peut éditer ce compte
        if ($db->firstColumn('SELECT plan_comptable FROM compta_comptes WHERE id = ?;', $id))
        {
            throw new UserException('Ce compte fait partie du plan comptable et n\'est pas modifiable.');
        }

        if (isset($data['position']) && empty($data['position']))
        {
            throw new UserException('Aucune position du compte n\'a été indiquée.');
        }

        $this->_checkFields($data);

        $update = [
            'libelle'   =>  trim($data['libelle']),
        ];

        if (isset($data['position']))
        {
            $update['position'] = (int) trim($data['position']);
        }

        $db->update('compta_comptes', $update, $db->where('id', $id));

        return true;
    }

    public function delete($id)
    {
        $db = DB::getInstance();

        $id = trim($id);

        // Ne pas supprimer un compte qui est utilisé !
        if ($db->test('compta_journal', 'compte_debit = ? OR compte_credit = ?', $id, $id))
        {
            throw new UserException('Ce compte ne peut être supprimé car des opérations comptables y sont liées.');
        }

        if ($db->test('compta_comptes_bancaires', $db->where('id', $id)))
        {
            throw new UserException('Ce compte ne peut être supprimé car il est lié à un compte bancaire.');
        }

        $db->delete('compta_comptes', $db->where('id', $id));

        return true;
    }

    /**
     * Peut-on supprimer ce compte ? (OUI s'il n'a pas d'écriture liée)
     * @param  string $id Numéro du compte
     * @return boolean TRUE si le compte n'a pas d'écriture liée
     */
    public function canDelete($id)
    {
        $db = DB::getInstance();

        $id = trim($id);

        if ($db->firstColumn('SELECT 1 FROM compta_journal
                WHERE compte_debit = ? OR compte_credit = ? LIMIT 1;', $id, $id))
        {
            return false;
        }

        if ($db->test('compta_categories', $db->where('compte', $id)))
        {
            return false;
        }

        return true;
    }

    /**
     * Peut-on désactiver ce compte ? (OUI s'il n'a pas d'écriture liée dans l'exercice courant)
     * @param  string $id Numéro du compte
     * @return boolean TRUE si le compte n'a pas d'écriture liée dans l'exercice courant
     */
    public function canDisable($id, &$code = 0)
    {
        $db = DB::getInstance();

        $id = trim($id);

        if ($db->firstColumn('SELECT 1 FROM compta_journal
                WHERE id_exercice = (SELECT id FROM compta_exercices WHERE cloture = 0 LIMIT 1) 
                AND (compte_debit = ? OR compte_credit = ?) LIMIT 1;', $id, $id))
        {
            $code = 1;
            return false;
        }

        if ($db->test('compta_categories', $db->where('compte', $id)))
        {
            $code = 2;
            return false;
        }

        return true;
    }

    /**
     * Désactiver un compte
     * Le compte ne sera plus utilisable pour les écritures ou les catégories mais restera en base de données
     * @param  string $id Numéro du compte
     * @return boolean TRUE si la désactivation a fonctionné, une exception utilisateur si
     * la désactivation n'est pas possible.
     */
    public function disable($id)
    {
        $db = DB::getInstance();

        $id = trim($id);

        if (!$this->canDisable($id, $code))
        {
            if ($code === 1)
            {
                throw new UserException('Ce compte ne peut être désactivé car des écritures y sont liées sur l\'exercice courant. '
                    . 'Il faut supprimer ou ré-attribuer ces écritures avant de pouvoir supprimer le compte.');
            }
            else
            {
                throw new UserException('Ce compte ne peut être désactivé car des catégories y sont liées.');
            }
        }

        return $db->update('compta_comptes', ['desactive' => 1], $db->where('id', $id));
    }

    /**
     * Renvoie si un compte existe et n'est pas désactivé
     * @param  string  $id Numéro de compte
     * @return boolean     TRUE si le compte existe et n'est pas désactivé
     */
    public function isActive($id)
    {
        $db = DB::getInstance();
        return $db->test('compta_comptes', $db->where('id', trim($id)) . ' AND ' . $db->where('desactive', '!=', 1));
    }

    public function get($id)
    {
        $db = DB::getInstance();
        return $db->first('SELECT * FROM compta_comptes WHERE id = ?;', trim($id));
    }

    public function getList($parent = 0)
    {
        $db = DB::getInstance();
        return $db->getGrouped('SELECT id, * FROM compta_comptes WHERE parent = ? ORDER BY id;', $parent);
    }

    public function getListAll()
    {
        $db = DB::getInstance();
        return $db->getAssoc('SELECT id, libelle FROM compta_comptes ORDER BY id;');
    }

    public function listTree($parent_id = 0, $include_children = true)
    {
        $db = DB::getInstance();

        if ($include_children && $parent_id)
        {
            $where = $db->where('parent', 'LIKE', $parent_id . '%');
        }
        elseif ($include_children && !$parent_id)
        {
            $where = '1';
        }
        else
        {
            $where = $db->where('parent', !$parent_id ? (int) $parent_id : (string) $parent_id);
        }

        $query = 'SELECT * FROM compta_comptes WHERE %s OR %s ORDER BY id;';
        $query = sprintf($query, $db->where('id', (string) $parent_id), $where);

        return $db->get($query);
    }

    protected function _checkFields(&$data, $force_parent_check = false)
    {
        $db = DB::getInstance();

        if (empty($data['libelle']) || !trim($data['libelle']))
        {
            throw new UserException('Le libellé ne peut rester vide.');
        }

        $data['libelle'] = trim($data['libelle']);

        if (isset($data['id']))
        {
            $force_parent_check = true;
            $data['id'] = trim($data['id']);

            if ($db->test('compta_comptes', $db->where('id', $data['id'])))
            {
                throw new UserException('Le compte numéro '.$data['id'].' existe déjà.');
            }
        }

        if (isset($data['parent']) || $force_parent_check)
        {
            if (empty($data['parent']) && !trim($data['parent']))
            {
                throw new UserException('Le compte ne peut pas ne pas avoir de compte parent.');
            }

            if (!($id = $db->firstColumn('SELECT id FROM compta_comptes WHERE id = ?;', $data['parent'])))
            {
                throw new UserException('Le compte parent indiqué n\'existe pas.');
            }

            $data['parent'] = trim($id);
        }

        if (isset($data['id']))
        {
            if (strncmp($data['id'], $data['parent'], strlen($data['parent'])) !== 0)
            {
                throw new UserException('Le compte '.$data['id'].' n\'est pas un sous-compte de '.$data['parent'].'.');
            }
        }

        return true;
    }

    public function getPositions()
    {
        return [
            self::ACTIF     =>  'Actif',
            self::PASSIF    =>  'Passif',
            self::ACTIF | self::PASSIF      =>  'Actif ou passif (déterminé automatiquement au bilan selon le solde du compte)',
            self::CHARGE    =>  'Charge',
            self::PRODUIT   =>  'Produit',
            self::CHARGE | self::PRODUIT    =>  'Charge et produit',
        ];
    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted src/include/lib/Garradin/Compta/Comptes_Bancaires.php version [c2ddfadd03].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
<?php

namespace Garradin\Compta;

use \Garradin\DB;
use \Garradin\Utils;
use \Garradin\UserException;


class Comptes_Bancaires extends Comptes
{
    const NUMERO_PARENT_COMPTES = 512;

    public function add($data)
    {
        $db = DB::getInstance();

        $data['parent'] = self::NUMERO_PARENT_COMPTES;
        $data['id'] = null;

        $this->_checkBankFields($data);

        $new_id = parent::add($data);

        $db->insert('compta_comptes_bancaires', [
            'id'     =>  $new_id,
            'banque' =>  $data['banque'],
            'iban'   =>  $data['iban'],
            'bic'    =>  $data['bic'],
        ]);

        return $new_id;
    }

    public function edit($id, $data)
    {
        $db = DB::getInstance();
        $id = trim($id);

        if (!$db->test('compta_comptes_bancaires', $db->where('id', $id)))
        {
            throw new UserException('Ce compte n\'est pas un compte bancaire.');
        }

        $this->_checkBankFields($data);
        $result = parent::edit($id, $data);

        if (!$result)
        {
            return $result;
        }

        $db->update('compta_comptes_bancaires', [
            'banque' =>  $data['banque'],
            'iban'   =>  $data['iban'],
            'bic'    =>  $data['bic'],
        ], $db->where('id', $id));

        return true;
    }

    /**
     * Supprime un compte bancaire
     * La suppression sera refusée si le compte est utilisé dans l'exercice en cours
     * ou dans une catégorie.
     * Le compte bancaire sera supprimé et le compte au plan comptable seulement désactivé
     * si le compte est utilisé dans un exercice précédent.
     *
     * La désactivation d'un compte fait qu'il n'est plus utilisable dans l'exercice courant
     * ou les exercices suivants, mais il est possible de le réactiver.
     * @param  string $id  Numéro du compte
     * @return boolean     TRUE si la suppression ou désactivation a été effectuée, une exception ou FALSE sinon
     */
    public function delete($id)
    {
        $db = DB::getInstance();
        $id = trim($id);

        if (!$db->test('compta_comptes_bancaires', $db->where('id', $id)))
        {
            throw new UserException('Ce compte n\'est pas un compte bancaire.');
        }

        // Ne pas supprimer/désactiver un compte qui est utilisé dans l'exercice courant
        if ($db->firstColumn('SELECT 1 FROM compta_journal
                WHERE id_exercice = (SELECT id FROM compta_exercices WHERE cloture = 0 LIMIT 1) 
                AND (compte_debit = ? OR compte_credit = ?) LIMIT 1;', $id, $id))
        {
            throw new UserException('Ce compte ne peut être supprimé car des écritures y sont liées sur l\'exercice courant. '
                . 'Il faut supprimer ou ré-attribuer ces écritures avant de pouvoir supprimer le compte.');
        }

        // Il n'est pas possible de supprimer ou désactiver un compte qui est lié à des catégories
        if ($db->test('compta_categories', $db->where('compte', $id)))
        {
            throw new UserException('Ce compte ne peut être supprimé car des catégories y sont liées. '
                . 'Merci de supprimer ou modifier les catégories liées avant de le supprimer.');
        }

        $db->delete('compta_comptes_bancaires', $db->where('id', $id));

        try {
            $return = parent::delete($id);
        }
        catch (UserException $e) {
            // Impossible de supprimer car des opérations y sont encore liées
            // sur les exercices précédents, alors on le désactive
            $return = parent::disable($id);
        }

        return $return;
    }

    public function get($id)
    {
        $db = DB::getInstance();
        return $db->first('SELECT * FROM compta_comptes AS c
            INNER JOIN compta_comptes_bancaires AS cc
            ON c.id = cc.id
            WHERE c.id = ?;', $id);
    }

    public function getList($parent = false)
    {
        $db = DB::getInstance();
        return $db->getGrouped('SELECT c.id AS id, * FROM compta_comptes AS c
            INNER JOIN compta_comptes_bancaires AS cc ON c.id = cc.id
            WHERE c.parent = ? ORDER BY c.id;', self::NUMERO_PARENT_COMPTES);
    }

    protected function _checkBankFields(&$data)
    {
        if (empty($data['banque']) || !trim($data['banque']))
        {
            throw new UserException('Le nom de la banque ne peut rester vide.');
        }

        if (empty($data['bic']))
        {
            $data['bic'] = '';
        }
        else
        {
            $data['bic'] = trim(strtoupper($data['bic']));
            $data['bic'] = preg_replace('![^\dA-Z]!', '', $data['bic']);

            if (!Utils::checkBIC($data['bic']))
            {
                throw new UserException('Code BIC/SWIFT invalide.');
            }
        }

        if (empty($data['iban']))
        {
            $data['iban'] = '';
        }
        else
        {
            $data['iban'] = trim(strtoupper($data['iban']));
            $data['iban'] = preg_replace('![^\dA-Z]!', '', $data['iban']);

            if (!Utils::checkIBAN($data['iban']))
            {
                throw new UserException('Code IBAN invalide.');
            }
        }

        return true;
    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































































































































































Deleted src/include/lib/Garradin/Compta/Exercices.php version [3bc6667d2a].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
<?php

namespace Garradin\Compta;

use \Garradin\DB;
use \Garradin\Utils;
use \Garradin\UserException;

class Exercices
{
    public function add($data)
    {
        $this->_checkFields($data);

        $db = DB::getInstance();

        if ($db->firstColumn('SELECT 1 FROM compta_exercices WHERE
            (debut <= :debut AND fin >= :debut) OR (debut <= :fin AND fin >= :fin);',
            ['debut' => $data['debut'], 'fin' => $data['fin']]))
        {
            throw new UserException('La date de début ou de fin se recoupe avec un autre exercice.');
        }

        if ($db->firstColumn('SELECT 1 FROM compta_exercices WHERE cloture = 0;'))
        {
            throw new UserException('Il n\'est pas possible de créer un nouvel exercice tant qu\'il existe un exercice non-clôturé.');
        }

        $db->insert('compta_exercices', [
            'libelle'   =>  trim($data['libelle']),
            'debut'     =>  $data['debut'],
            'fin'       =>  $data['fin'],
        ]);

        return $db->lastInsertRowId();
    }

    public function edit($id, $data)
    {
        $db = DB::getInstance();

        $this->_checkFields($data);

        // Evitons que les exercices se croisent
        if ($db->firstColumn('SELECT 1 FROM compta_exercices WHERE id != :id AND
            ((debut <= :debut AND fin >= :debut) OR (debut <= :fin AND fin >= :fin));',
            ['debut' => $data['debut'], 'fin' => $data['fin'], 'id' => (int) $id]))
        {
            throw new UserException('La date de début ou de fin se recoupe avec un autre exercice.');
        }

        // On vérifie qu'on ne va pas mettre des opérations en dehors de tout exercice
        if ($db->firstColumn('SELECT 1 FROM compta_journal WHERE id_exercice = ?
            AND date < ? LIMIT 1;', (int)$id, $data['debut']))
        {
            throw new UserException('Des opérations de cet exercice ont une date antérieure à la date de début de l\'exercice.');
        }

        if ($db->firstColumn('SELECT 1 FROM compta_journal WHERE id_exercice = ?
            AND date > ? LIMIT 1;', (int)$id, $data['fin']))
        {
            throw new UserException('Des opérations de cet exercice ont une date postérieure à la date de fin de l\'exercice.');
        }

        $db->update('compta_exercices', [
            'libelle'   =>  trim($data['libelle']),
            'debut'     =>  $data['debut'],
            'fin'       =>  $data['fin'],
        ], 'id = :id', ['id' => (int)$id]);

        return true;
    }

    /**
     * Clôturer un exercice et en ouvrir un nouveau
     * Le report à nouveau n'est pas effectué automatiquement par cette fonction, voir doReports pour ça.
     * @param  integer  $id     ID de l'exercice à clôturer
     * @param  string   $end    Date de clôture de l'exercice au format Y-m-d
     * @return integer          L'ID du nouvel exercice créé
     */
    public function close($id, $end)
    {
        $db = DB::getInstance();

        if (!Utils::checkDate($end))
        {
            throw new UserException('Date de fin vide ou invalide.');
        }

        $db->begin();

        // Clôture de l'exercice
        $db->update('compta_exercices', [
            'cloture'   =>  1,
            'fin'       =>  $end,
        ], 'id = :id', ['id' => (int)$id]);

        // Date de début du nouvel exercice : lendemain de la clôture du précédent exercice
        $new_begin = Utils::modifyDate($end, '+1 day');

        // Date de fin du nouvel exercice : un an moins un jour après l'ouverture
        $new_end = Utils::modifyDate($new_begin, '+1 year -1 day');

        // Enfin sauf s'il existe déjà des opérations après cette date, auquel cas la date de fin
        // est fixée à la date de la dernière opération, ceci pour ne pas avoir d'opération
        // orpheline d'exercice
        $last = $db->firstColumn('SELECT date FROM compta_journal WHERE id_exercice = ? AND date >= ? ORDER BY date DESC LIMIT 1;', $id, $new_end);
        $new_end = $last ?: $new_end;

        $year_begin = substr($new_begin, 0, 4);
        $year_end = substr($new_end, 0, 4);

        // Nom du nouvel exercice
        if ($year_begin == $year_end) {
            $label = sprintf('Exercice %d', $year_begin);
        }
        else {
            $label = sprintf('Exercice %d-%d', $year_begin, $year_end);
        }

        // Création du nouvel exercice
        $new_id = $this->add([
            'debut'     =>  $new_begin,
            'fin'       =>  $new_end,
            'libelle'   =>  $label,
        ]);

        // Ré-attribution des opérations de l'exercice à clôturer qui ne sont pas dans son
        // intervale au nouvel exercice
        $db->update('compta_journal', ['id_exercice' => $new_id], 'id_exercice = :id AND date >= :date', [
            'id'   => $id,
            'date' => $new_begin,
        ]);

        $db->commit();

        return $new_id;
    }

    /**
     * Créer les reports à nouveau issus de l'exercice $old_id dans le nouvel exercice courant
     * @param  integer $old_id  ID de l'ancien exercice
     * @param  integer $new_id  ID du nouvel exercice
     * @param  string  $date    Date Y-m-d donnée aux opérations créées
     * @return boolean          true si succès
     */
    public function doReports($old_id, $date)
    {
        $db = DB::getInstance();

        $db->begin();

        $report_crediteur = 110;
        $report_debiteur  = 119;

        $comptes = new Comptes;

        if (!$comptes->isActive($report_crediteur))
        {
            throw new UserException('Impossible de faire le report à nouveau : le compte de report créditeur ' . $report_crediteur . ' n\'existe pas ou est désactivé.');
        }
        else if (!$comptes->isActive($report_debiteur))
        {
            throw new UserException('Impossible de faire le report à nouveau : le compte de report débiteur ' . $report_debiteur . ' n\'existe pas ou est désactivé.');
        }

        unset($comptes);

        $this->solderResultat($old_id, $date);

        // Récupérer chacun des comptes de bilan et leurs soldes (uniquement les classes 1 à 5)
        $statement = $db->preparedQuery('SELECT compta_comptes.id AS compte, compta_comptes.position AS position,
            ROUND(COALESCE((SELECT SUM(montant) FROM compta_journal WHERE compte_debit = compta_comptes.id AND id_exercice = :id), 0), 2)
            - ROUND(COALESCE((SELECT SUM(montant) FROM compta_journal WHERE compte_credit = compta_comptes.id AND id_exercice = :id), 0), 2) AS solde
            FROM compta_comptes 
            INNER JOIN compta_journal ON 
                compta_journal.id_exercice = :id AND (
                    (compta_comptes.id = compta_journal.compte_debit AND CAST(substr(compta_journal.compte_debit, 1, 1) AS INTEGER) <= 5)
                    OR (compta_comptes.id = compta_journal.compte_credit AND CAST(substr(compta_journal.compte_credit, 1, 1) AS INTEGER) <= 5)
                )
            WHERE solde != 0
            GROUP BY compta_comptes.id;', ['id' => $old_id]);

        $diff = 0;
        $journal = new Journal;

        while ($row = $statement->fetchArray(SQLITE3_ASSOC))
        {
            $solde = $row['solde'];

            // Solde du compte à zéro : aucun report à faire
            if (empty($solde))
            {
                continue;
            }

            $compte_debit = $solde < 0 ? 890 : $row['compte'];
            $compte_credit = $solde > 0 ? 890 : $row['compte'];

            $diff += $solde;
            $solde = round(abs($solde), 2);

            // Chaque solde de compte est reporté dans le nouvel exercice
            $journal->add([
                'libelle'       =>  'Report à nouveau',
                'date'          =>  $date,
                'montant'       =>  $solde,
                'compte_debit'  =>  $compte_debit,
                'compte_credit' =>  $compte_credit,
                'remarques'     =>  'Report de solde créé automatiquement à la clôture de l\'exercice précédent',
            ]);
        }

        // FIXME utiliser $diff pour équilibrer

        $db->commit();

        return true;
    }

    /**
     * Solder les comptes de charge et de produits de l'exercice N 
     * et les inscrire au résultat de l'exercice N+1
     * @param  integer  $exercice   ID de l'exercice à solder
     * @param  string   $date       Date de début de l'exercice Y-m-d
     * @return boolean              true en cas de succès
     */
    public function solderResultat($exercice, $date)
    {
        $resultat_excedent = 120;
        $resultat_debiteur = 129;

        $comptes = new Comptes;

        if (!$comptes->isActive($resultat_excedent))
        {
            throw new UserException('Impossible de solder l\'exercice : le compte de résultat excédent ' . $resultat_excedent . ' n\'existe pas ou est désactivé.');
        }
        else if (!$comptes->isActive($resultat_debiteur))
        {
            throw new UserException('Impossible de solder l\'exercice : le compte de résultat débiteur ' . $resultat_debiteur . ' n\'existe pas ou est désactivé.');
        }

        unset($comptes);

        $rapports = new Rapports;
        $resultat = $rapports->compteResultat(['id_exercice' => $exercice], [6, 7]);
        $resultat = $resultat['resultat'];

        if ($resultat != 0)
        {
            $journal = new Journal;
            $journal->add([
                'libelle'   =>  'Résultat de l\'exercice précédent',
                'date'      =>  $date,
                'montant'   =>  abs($resultat),
                'compte_debit'  =>  $resultat < 0 ? $resultat_debiteur : 890,
                'compte_credit' =>  $resultat > 0 ? $resultat_excedent : 890,
            ]);
        }

        return true;
    }

    public function delete($id)
    {
        $db = DB::getInstance();

        // Ne pas supprimer un compte qui est utilisé !
        if ($db->test('compta_journal', $db->where('id_exercice', $id)))
        {
            throw new UserException('Cet exercice ne peut être supprimé car des opérations comptables y sont liées.');
        }

        $db->delete('compta_exercices', 'id = ?', (int)$id);

        return true;
    }

    public function get($id, $with_count = false)
    {
        $with_count = $with_count
            ? ', (SELECT COUNT(*) FROM compta_journal WHERE id_exercice = compta_exercices.id) AS nb_operations'
            : '';

        $db = DB::getInstance();
        return $db->first('SELECT *, strftime(\'%s\', debut) AS debut,
            strftime(\'%s\', fin) AS fin ' . $with_count . '
            FROM compta_exercices WHERE id = ?;', (int)$id);
    }

    public function getCurrent()
    {
        $db = DB::getInstance();
        return $db->first('SELECT *, strftime(\'%s\', debut) AS debut, strftime(\'%s\', fin) AS fin FROM compta_exercices
            WHERE cloture = 0 LIMIT 1;');
    }

    public function getCurrentId()
    {
        $db = DB::getInstance();
        return $db->firstColumn('SELECT id FROM compta_exercices WHERE cloture = 0 LIMIT 1;');
    }

    public function getList()
    {
        $db = DB::getInstance();
        return $db->getGrouped('SELECT id, *, strftime(\'%s\', debut) AS debut,
            strftime(\'%s\', fin) AS fin,
            (SELECT COUNT(*) FROM compta_journal WHERE id_exercice = compta_exercices.id) AS nb_operations
            FROM compta_exercices ORDER BY fin DESC;');
    }

    protected function _checkFields(&$data)
    {
        if (empty($data['libelle']) || !trim($data['libelle']))
        {
            throw new UserException('Le libellé ne peut rester vide.');
        }

        $data['libelle'] = trim($data['libelle']);

        if (empty($data['debut']) || !checkdate(substr($data['debut'], 5, 2), substr($data['debut'], 8, 2), substr($data['debut'], 0, 4)))
        {
            throw new UserException('Date de début vide ou invalide.');
        }

        if (empty($data['fin']) || !checkdate(substr($data['fin'], 5, 2), substr($data['fin'], 8, 2), substr($data['fin'], 0, 4)))
        {
            throw new UserException('Date de fin vide ou invalide.');
        }

        return true;
    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































































































































































































































































































































































































































































































































































Deleted src/include/lib/Garradin/Compta/Import.php version [f437eb905d].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
<?php

namespace Garradin\Compta;

use Garradin\DB;
use Garradin\Utils;
use Garradin\UserException;
use Garradin\Config;

class Import
{
	protected $header = [
		'Numéro mouvement',
		'Date',
		'Type de mouvement',
		'Catégorie',
		'Libellé',
		'Montant',
		'Compte de débit - numéro',
		'Compte de débit - libellé',
		'Compte de crédit - numéro',
		'Compte de crédit - libellé',
		'Moyen de paiement',
		'Numéro de chèque',
		'Numéro de pièce',
		'Remarques',
		'Projet'
	];

	protected function export($exercice)
	{
		return DB::getInstance()->iterate('SELECT
			journal.id,
			strftime(\'%d/%m/%Y\', date) AS date,
			(CASE cat.type WHEN 1 THEN \'Recette\' WHEN -1 THEN \'Dépense\' ELSE \'Autre\' END) AS type,
			(CASE cat.intitule WHEN NULL THEN \'\' ELSE cat.intitule END) AS cat,
			journal.libelle,
			montant,
			compte_debit,
			debit.libelle AS libelle_debit,
			compte_credit,
			credit.libelle AS libelle_credit,
			(CASE moyen_paiement WHEN NULL THEN \'\' ELSE moyen.nom END) AS moyen,
			numero_cheque,
			numero_piece,
			remarques,
			projet.libelle AS projet
			FROM compta_journal AS journal
				LEFT JOIN compta_categories AS cat ON cat.id = journal.id_categorie
				LEFT JOIN compta_comptes AS debit ON debit.id = journal.compte_debit
				LEFT JOIN compta_comptes AS credit ON credit.id = journal.compte_credit
				LEFT JOIN compta_moyens_paiement AS moyen ON moyen.code = journal.moyen_paiement
				LEFT JOIN compta_projets AS projet ON projet.id = journal.id_projet
			WHERE id_exercice = '.(int)$exercice.'
			ORDER BY journal.date;
		');
	}

	protected function exportName()
	{
		return sprintf('Export comptabilité - %s - %s', Config::getInstance()->get('nom_asso'), date('Y-m-d'));
	}

	public function toCSV($exercice)
	{
		return Utils::toCSV($this->exportName(), $this->export($exercice), $this->header);
	}

	public function toODS($exercice)
	{
		return Utils::toODS($this->exportName(), $this->export($exercice), $this->header);
	}

	public function fromCSV($path)
	{
		if (!file_exists($path) || !is_readable($path))
		{
			throw new \RuntimeException('Fichier inconnu : '.$path);
		}

		$fp = fopen($path, 'r');

		if (!$fp)
		{
			return false;
		}

		$db = DB::getInstance();
		$db->begin();
		$cats = new Categories;
		$journal = new Journal;

		$liste_cats = $db->getAssoc('SELECT type || intitule, id FROM compta_categories;');
		// Liste des moyens sous la forme nom -> code
		$liste_moyens = array_flip($cats->listMoyensPaiement(true));
		$liste_moyens = array_change_key_case($liste_moyens, \CASE_LOWER);

		// Liste associative des projets
		$liste_projets = $db->getAssoc('SELECT libelle, id FROM compta_projets;');

		$col = function($column) use (&$row, &$columns)
		{
			if (!isset($columns[$column]))
				return null;

			if (!isset($row[$columns[$column]]))
				return null;

			return $row[$columns[$column]];
		};

		$line = 0;
		$delim = Utils::find_csv_delim($fp);
		Utils::skip_bom($fp);

		while (!feof($fp))
		{
			$row = fgetcsv($fp, 4096, $delim);
			$line++;

			if (empty($row))
			{
				continue;
			}

			if ($line === 1)
			{
				if (trim($row[0]) != 'Numéro mouvement')
				{
					throw new UserException('Erreur sur la ligne ' . $line . ' : l\'entête des colonnes est absent ou incorrect.');
				}

				$columns = array_flip($row);

				continue;
			}

			if (count($row) != count($columns))
			{
				$db->rollback();
				throw new UserException('Erreur sur la ligne ' . $line . ' : le nombre de colonnes est incorrect.');
			}

			if (trim($row[0]) !== '' && !is_numeric($row[0]))
			{
				$db->rollback();
				throw new UserException('Erreur sur la ligne ' . $line . ' : la première colonne doit être vide ou contenir le numéro unique d\'opération.');
			}

			$id = $col('Numéro mouvement');
			$date = $col('Date');

			if (!preg_match('!^\d{2}/\d{2}/\d{4}$!', $date))
			{
				$db->rollback();
				throw new UserException('Erreur sur la ligne ' . $line . ' : la date n\'est pas au format jj/mm/aaaa.');
			}

			$date = explode('/', $date);
			$date = $date[2] . '-' . $date[1] . '-' . $date[0];

			// En dehors de l'exercice courant
			if ($db->test('compta_exercices', '(? < debut OR ? > fin) AND cloture = 0', $date, $date))
			{
				continue;
			}

			$debit = $col('Compte de débit - numéro');
			$credit = $col('Compte de crédit - numéro');

			$cat = $col('Catégorie');
			$moyen = strtolower($col('Moyen de paiement'));
			$type = $col('Type de mouvement');

			if ('Recette' === $type) {
				$type = 1;
			}
			elseif ('Dépense' === $type) {
				$type = -1;
			}
			else {
				$type = 0;
			}

			// Association du moyen de paiement par nom
			if ($moyen && array_key_exists($moyen, $liste_moyens))
			{
				$moyen = $liste_moyens[$moyen];
			}
			// Sinon on estime que c'est juste le code qui est fourni
			else
			{
				$moyen = substr(strtoupper($moyen), 0, 2);
			}

			// Vérification de l'existence du moyen de paiement
			// s'il n'est pas valide, on ne peut pas avoir de catégorie non plus
			if (!trim($moyen) || !in_array($moyen, $liste_moyens, true))
			{
				$moyen = false;
				$cat = false;
			}

			if ($cat && array_key_exists($type . $cat, $liste_cats)) {
				$cat = $liste_cats[$type . $cat];
			}
			else {
				$cat = $moyen = false;
			}

			$id_projet = null;

			if (!empty($col('Projet'))) {
				if (!array_key_exists($col('Projet'), $liste_projets)) {
					throw new UserException(sprintf('Erreur sur la ligne %d : le projet "%s" est inconnu', $line, $col('Projet')));
				}

				$id_projet = $liste_projets[$col('Projet')];
			}

			$data = [
				'libelle'       =>  $col('Libellé'),
				'montant'       =>  (float) $col('Montant'),
				'date'          =>  $date,
				'compte_credit' =>  $credit,
				'compte_debit'  =>  $debit,
				'numero_piece'  =>  $col('Numéro de pièce'),
				'remarques'     =>  $col('Remarques'),
				'id_projet'     =>  $id_projet,
			];

			if ($cat)
			{
				$data['moyen_paiement']	=	$moyen;
				$data['numero_cheque']	=	$col('Numéro de chèque');
				$data['id_categorie']	=	$cat;
			}

			try {
				if (empty($id))
				{
					$journal->add($data);
				}
				else
				{
					$journal->edit($id, $data);
				}
			}
			catch (UserException $e)
			{
				throw new UserException(sprintf('Ligne %s: %s', $line, $e->getMessage()));
			}
		}

		$db->commit();

		fclose($fp);
		return true;
	}
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































































































































































































































































































































































Deleted src/include/lib/Garradin/Compta/Journal.php version [88e9a2c624].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
<?php

namespace Garradin\Compta;

use \Garradin\DB;
use \Garradin\Utils;
use \Garradin\UserException;
use \Garradin\Config;

class Journal
{
    protected function _getCurrentExercice()
    {
        $db = DB::getInstance();
        $id = $db->firstColumn('SELECT id FROM compta_exercices WHERE cloture = 0 LIMIT 1;');

        if (!$id)
        {
            throw new UserException('Aucun exercice en cours.');
        }

        return $id;
    }

    public function checkExercice()
    {
        return $this->_getCurrentExercice();
    }

    protected function _checkOpenExercice($id)
    {
        if (is_null($id))
            return true;

        return DB::getInstance()->test('compta_exercices', 'cloture = 0 AND id = ?', (int)$id);
    }

    public function getSolde($id_compte, $inclure_sous_comptes = false, $exercice = null)
    {
        $db = DB::getInstance();
        $exercice = (int) $exercice ?: $this->_getCurrentExercice();
        $compte = $inclure_sous_comptes
            ? 'LIKE \'' . $db->escapeString(trim($id_compte)) . '%\''
            : '= \'' . $db->escapeString(trim($id_compte)) . '\'';

        $debit = 'COALESCE((SELECT SUM(montant) FROM compta_journal WHERE compte_debit '.$compte.' AND id_exercice = '.(int)$exercice.'), 0)';
        $credit = 'COALESCE((SELECT SUM(montant) FROM compta_journal WHERE compte_credit '.$compte.' AND id_exercice = '.(int)$exercice.'), 0)';

        // L'actif augmente au débit, le passif au crédit
        $position = $db->firstColumn('SELECT position FROM compta_comptes WHERE id = ?;', $id_compte);

        if (($position & Comptes::ACTIF) || ($position & Comptes::CHARGE))
        {
            $query = $debit . ' - ' . $credit;
        }
        else
        {
            $query = $credit . ' - ' . $debit;
        }

        return $db->firstColumn('SELECT ' . $query . ';');
    }

    public function getJournalCompte($compte, $inclure_sous_comptes = false, $exercice = null)
    {
        $db = DB::getInstance();

        $position = $db->firstColumn('SELECT position FROM compta_comptes WHERE id = ?;', $compte);

        $exercice = (int) $exercice ?: $this->_getCurrentExercice();
        $compte = $inclure_sous_comptes
            ? 'LIKE \'' . $db->escapeString(trim($compte)) . '%\''
            : '= \'' . $db->escapeString(trim($compte)) . '\'';

        // L'actif et les charges augmentent au débit, le passif et les produits au crédit
        if (($position & Comptes::ACTIF) || ($position & Comptes::CHARGE))
        {
            $d = '';
            $c = '-';
        }
        else
        {
            $d = '-';
            $c = '';
        }

        $query = 'SELECT *, strftime(\'%s\', date) AS date, 
            (CASE WHEN compte_debit '.$compte.' THEN '.$d.'montant ELSE '.$c.'montant END) AS solde
            FROM compta_journal WHERE (compte_debit '.$compte.' OR compte_credit '.$compte.') 
            AND id_exercice = '.(int)$exercice.'
            ORDER BY date ASC;';

        $result = $db->get($query);
        $solde = 0.0;

        foreach ($result as &$row)
        {
            $solde += $row->solde;
            $row->solde = $solde;
        }

        return $result;
    }

    public function add($data)
    {
        $this->_checkFields($data);

        $db = DB::getInstance();

        $data['id_exercice'] = $this->_getCurrentExercice();

        $db->insert('compta_journal', $data);
        $id = $db->lastInsertRowId();

        return $id;
    }

    public function edit($id, $data)
    {
        $db = DB::getInstance();

        // On ne peut éditer une opération qui n'existe pas
        if (!$db->test('compta_journal', 'id = ?', $id))
        {
            throw new UserException(sprintf('L\'opération n°%s n\'existe pas et ne peut donc être modifiée.', (int)$id));
        }

        // Vérification que l'on peut éditer cette opération
        if (!$this->_checkOpenExercice($db->firstColumn('SELECT id_exercice FROM compta_journal WHERE id = ?;', (int)$id)))
        {
            throw new UserException('Cette opération fait partie d\'un exercice qui a été clôturé.');
        }

        $this->_checkFields($data);

        $db->update('compta_journal', $data, $db->where('id', trim($id)));

        return true;
    }

    public function delete($id)
    {
        $db = DB::getInstance();

        // On ne peut supprimer une opération qui n'existe pas
        if (!$db->test('compta_journal', 'id = ?', $id))
        {
            throw new UserException(sprintf('L\'opération n°%s n\'existe pas et ne peut donc être supprimée.', (int)$id));
        }

        // Vérification que l'on peut éditer cette opération
        if (!$this->_checkOpenExercice($db->firstColumn('SELECT id_exercice FROM compta_journal WHERE id = ?;', (int)$id)))
        {
            throw new UserException('Cette opération fait partie d\'un exercice qui a été clôturé.');
        }

        $db->begin();
        $db->delete('membres_operations', $db->where('id_operation', (int)$id));
        $db->delete('compta_rapprochement', $db->where('id_operation', (int)$id));
        $db->delete('compta_journal', $db->where('id', (int)$id));
        $db->commit();

        return true;
    }

    public function get($id)
    {
        $db = DB::getInstance();
        return $db->first('SELECT *, strftime(\'%s\', date) AS date FROM compta_journal WHERE id = ?;', $id);
    }

    /**
     * Compte le nombre d'écritures liées à un membre
     * @param  integer $id Numéro de membre
     * @return integer     Nombre d'écritures liées
     */
    public function countForMember($id)
    {
        $db = DB::getInstance();
        return $db->count('compta_journal', $db->where('id_auteur', $id));
    }

    /**
     * Lister les écritures liées à un membre
     * @param  integer $id       Identifiant de membre
     * @param  integer $exercice Identifiant d'exercice
     * @return array           Liste des écritures liées
     */
    public function listForMember($id, $exercice)
    {
        $db = DB::getInstance();
        return $db->get('SELECT * FROM compta_journal
            WHERE id_auteur = ? AND id_exercice = ?;', (int)$id, (int)$exercice);
    }

    /**
     * Lister les membres liés à cette écriture
     * @param  integer $id Numéro d'écriture
     * @return array     Liste des membres liés
     */
    public function listRelatedMembers($id)
    {
        $db = DB::getInstance();
        $champ_id = Config::getInstance()->get('champ_identite');

        return $db->get('SELECT mo.id_membre, mo.id_cotisation, m.'.$champ_id.' AS identite
            FROM membres_operations AS mo INNER JOIN membres AS m ON mo.id_membre = m.id
            WHERE mo.id_operation = ?;', (int)$id);
    }

    protected function _checkFields(&$data)
    {
        $db = DB::getInstance();

        if (empty($data['libelle']) || !trim($data['libelle']))
        {
            throw new UserException('Le libellé ne peut rester vide.');
        }

        $data['libelle'] = trim($data['libelle']);

        if (!empty($data['moyen_paiement'])
            && !$db->test('compta_moyens_paiement', $db->where('code', $data['moyen_paiement'])))
        {
            throw new UserException('Moyen de paiement invalide.');
        }

        if (empty($data['date']) || !Utils::checkDate($data['date']))
        {
            throw new UserException('Date vide ou invalide.');
        }

        if (!$db->test('compta_exercices', 'cloture = 0 AND debut <= :date AND fin >= :date;', 
            ['date' => $data['date']]))
        {
            throw new UserException('La date ne correspond pas à l\'exercice en cours.');
        }

        if (empty($data['moyen_paiement']))
        {
            $data['moyen_paiement'] = null;
            $data['numero_cheque'] = null;
        }
        else
        {
            $data['moyen_paiement'] = strtoupper($data['moyen_paiement']);

            if ($data['moyen_paiement'] != 'CH')
            {
                $data['numero_cheque'] = null;
            }

            if (!$db->test('compta_moyens_paiement', $db->where('code', $data['moyen_paiement'])))
            {
                throw new UserException('Moyen de paiement invalide.');
            }
        }

        $data['montant'] = str_replace(',', '.', $data['montant']);
        $data['montant'] = (float)$data['montant'];

        if ($data['montant'] <= 0)
        {
            throw new UserException('Le montant ne peut être égal ou inférieur à zéro.');
        }

        foreach (['remarques', 'numero_piece', 'numero_cheque'] as $champ)
        {
            if (empty($data[$champ]) || !trim($data[$champ]))
            {
                $data[$champ] = '';
            }
            else
            {
                $data[$champ] = trim($data[$champ]);
            }
        }

        if (empty($data['compte_debit']) || !$db->test('compta_comptes', $db->where('id', $data['compte_debit'])))
        {
            throw new UserException('Compte débité inconnu.');
        }

        if (empty($data['compte_credit']) || !$db->test('compta_comptes', $db->where('id', $data['compte_credit'])))
        {
            throw new UserException('Compte crédité inconnu.');
        }

        $data['compte_credit'] = strtoupper(trim($data['compte_credit']));
        $data['compte_debit'] = strtoupper(trim($data['compte_debit']));

        if ($data['compte_credit'] == $data['compte_debit'])
        {
            throw new UserException('Compte crédité identique au compte débité.');
        }

        if (isset($data['id_categorie']))
        {
            if (!$db->test('compta_categories', $db->where('id', (int)$data['id_categorie'])))
            {
                throw new UserException('Catégorie inconnue.');
            }

            $data['id_categorie'] = (int)$data['id_categorie'];
        }
        else
        {
            $data['id_categorie'] = NULL;
        }

        if (isset($data['id_auteur']))
        {
            $data['id_auteur'] = (int)$data['id_auteur'];
        }

        if (empty($data['id_projet']))
        {
            $data['id_projet'] = null;
        }
        elseif (isset($data['id_projet']))
        {
            $data['id_projet'] = (int)$data['id_projet'];

            if (!$db->test('compta_projets', $db->where('id', $data['id_projet'])))
            {
                throw new UserException('Projet inconnu.');
            }
        }

        return true;
    }

    public function getListForCategory($type = null, $cat = null)
    {
        $db = DB::getInstance();
        $exercice = $this->_getCurrentExercice();

        $query = 'SELECT compta_journal.*, strftime(\'%s\', compta_journal.date) AS date ';

        if (is_null($cat) && !is_null($type))
        {
            $query.= ', compta_categories.intitule AS categorie
                FROM compta_journal LEFT JOIN compta_categories
                ON compta_journal.id_categorie = compta_categories.id ';
        }
        else
        {
            $query.= ' FROM compta_journal ';
        }

        $query .= ' WHERE ';

        if (!is_null($cat))
        {
            $query .= 'id_categorie = ' . (int)$cat;
        }
        elseif (is_null($type) && is_null($cat))
        {
            $query .= 'id_categorie IS NULL';
        }
        else
        {
            $query.= 'id_categorie IN (SELECT id FROM compta_categories WHERE type = '.(int)$type.')';
        }

        $query .= ' AND id_exercice = ' . (int)$exercice;
        $query .= ' ORDER BY date;';

        return $db->get($query);
    }

    public function searchSQL($query)
    {
        if (!preg_match('/LIMIT\s+/i', $query))
        {
            $query = preg_replace('/;?\s*$/', '', $query);
            $query .= ' LIMIT 100';
        }

        try {
            return DB::getInstance()->userSelectGet($query);
        }
        catch (\Exception $e) {
            throw new UserException('Erreur dans la requête : ' . $e->getMessage());
        }
    }

    public function schemaSQL()
    {
        $db = DB::getInstance();

        $tables = [
            'journal'   =>  $db->firstColumn('SELECT sql FROM sqlite_master WHERE type = \'table\' AND name = \'compta_journal\';'),
        ];

        return $tables;
    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































































































































































































































































































































































































































































































































































































































































































Deleted src/include/lib/Garradin/Compta/Projets.php version [e557763ba3].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<?php

namespace Garradin\Compta;

use \Garradin\DB;
use \Garradin\UserException;

class Projets
{
    public function getAssocList()
    {
        return DB::getInstance()->getAssoc('SELECT id, libelle FROM compta_projets ORDER BY libelle;');
    }

    public function getList()
    {
        return DB::getInstance()->get('SELECT *, 
            (SELECT COUNT(*) FROM compta_journal WHERE id_projet = compta_projets.id) AS nb_operations
            FROM compta_projets ORDER BY libelle;');
    }

    public function get($id)
    {
        return DB::getInstance()->first('SELECT * FROM compta_projets WHERE id = ?;', (int) $id);
    }

    public function add($libelle)
    {
        if (trim($libelle) == '')
        {
            throw new UserException('Le libellé est obligatoire');
        }

        $db = DB::getInstance();

        $db->insert('compta_projets', ['libelle' => trim($libelle)]);

        return $db->lastInsertRowId();
    }

    public function edit($id, $libelle)
    {
        if (trim($libelle) == '')
        {
            throw new UserException('Le libellé est obligatoire');
        }

        $db = DB::getInstance();

        return $db->update('compta_projets', ['libelle' => trim($libelle)], $db->where('id', (int) $id));
    }

    public function remove($id)
    {
        $db = DB::getInstance();

        return $db->delete('compta_projets', $db->where('id', (int) $id));
    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































Deleted src/include/lib/Garradin/Compta/Rapports.php version [9726d24a12].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
<?php

namespace Garradin\Compta;

use \Garradin\DB;
use \Garradin\Utils;
use \Garradin\UserException;

class Rapports
{
    protected function getWhereClause(array $criterias)
    {
        $where = [];
        $db = DB::getInstance();

        foreach ($criterias as $name => $value)
        {
            $where[] = $db->where($name, $value);
        }

        return implode(' AND ', $where);
    }

    public function journal(array $criterias)
    {
        $db = DB::getInstance();
        return $db->get('SELECT *, strftime(\'%s\', date) AS date FROM compta_journal
            WHERE ' . $this->getWhereClause($criterias) . ' ORDER BY date, id;');
    }

    public function grandLivre(array $criterias)
    {
        $db = DB::getInstance();
        $livre = ['classes' => [], 'debit' => 0.0, 'credit' => 0.0];
        $where = $this->getWhereClause($criterias);

        $res = $db->preparedQuery('SELECT compte FROM
            (SELECT compte_debit AS compte FROM compta_journal
                    WHERE ' . $where . ' GROUP BY compte_debit
                UNION
                SELECT compte_credit AS compte FROM compta_journal
                    WHERE ' . $where . ' GROUP BY compte_credit)
            ORDER BY compte ASC;');

        while ($row = $res->fetchArray(SQLITE3_NUM))
        {
            $compte = $row[0];

            if (trim($compte) === '')
            {
                continue;
            }

            $classe = substr($compte, 0, 1);
            $parent = substr($compte, 0, 2);

            if (!array_key_exists($classe, $livre['classes']))
            {
                $livre['classes'][$classe] = [];
            }

            if (!array_key_exists($parent, $livre['classes'][$classe]))
            {
                $livre['classes'][$classe][$parent] = [
                    'total'         =>  0.0,
                    'comptes'       =>  [],
                ];
            }

            $livre['classes'][$classe][$parent]['comptes'][$compte] = ['debit' => 0.0, 'credit' => 0.0, 'journal' => []];

            $livre['classes'][$classe][$parent]['comptes'][$compte]['journal'] = $db->get(
                'SELECT *, strftime(\'%s\', date) AS date FROM (
                    SELECT * FROM compta_journal WHERE compte_debit = :compte AND ' . $where . '
                    UNION
                    SELECT * FROM compta_journal WHERE compte_credit = :compte AND ' . $where . '
                    )
                ORDER BY date, numero_piece, id;', 
                ['compte' => $compte]);

            $solde = 0.0;

            foreach ($livre['classes'][$classe][$parent]['comptes'][$compte]['journal'] as &$ligne)
            {
                if ($ligne->compte_credit == $compte)
                {
                    $solde += $ligne->montant;
                }
                else
                {
                    $solde -= $ligne->montant;
                }

                $ligne->solde = $solde;
            }

            $debit = (float) $db->firstColumn(
                'SELECT SUM(montant) FROM compta_journal WHERE compte_debit = ? AND ' . $where . ';',
                $compte);

            $credit = (float) $db->firstColumn(
                'SELECT SUM(montant) FROM compta_journal WHERE compte_credit = ? AND ' . $where . ';',
                $compte);

            $livre['classes'][$classe][$parent]['comptes'][$compte]['debit'] = $debit;
            $livre['classes'][$classe][$parent]['comptes'][$compte]['credit'] = $credit;
            $livre['classes'][$classe][$parent]['comptes'][$compte]['solde'] = $credit - $debit;

            $livre['classes'][$classe][$parent]['total'] += $debit;
            $livre['classes'][$classe][$parent]['total'] -= $credit;

            $livre['debit'] += $debit;
            $livre['credit'] += $credit;
        }

        $res->finalize();

        return $livre;
    }

    public function compteResultat(array $criterias, array $comptes)
    {
        $db = DB::getInstance();
        $where = $this->getWhereClause($criterias);

        $charges    = ['comptes' => [], 'total' => 0.0];
        $produits   = ['comptes' => [], 'total' => 0.0];
        $resultat   = 0.0;

        $where_comptes = [];

        foreach ($comptes as $compte)
        {
            $where_comptes[] = sprintf('compte LIKE \'%s%%\'', $compte);
        }

        $where_comptes = implode(' OR ', $where_comptes);

        $res = $db->preparedQuery('SELECT compte, SUM(debit), SUM(credit)
            FROM
                (SELECT compte_debit AS compte, SUM(montant) AS debit, 0 AS credit
                    FROM compta_journal WHERE ' . $where . ' GROUP BY compte_debit
                UNION
                SELECT compte_credit AS compte, 0 AS debit, SUM(montant) AS credit
                    FROM compta_journal WHERE ' . $where . ' GROUP BY compte_credit)
            WHERE ' . $where_comptes . '
            GROUP BY compte
            ORDER BY compte ASC;');

        while ($row = $res->fetchArray(SQLITE3_NUM))
        {
            list($compte, $debit, $credit) = $row;
            $classe = substr($compte, 0, 1);
            $sousclasse = substr($compte, 0, 2);
            $parent = substr($compte, 0, 2);

            if ($classe == 6 || $sousclasse == 86)
            {
                if (!isset($charges['comptes'][$parent]))
                {
                    $charges['comptes'][$parent] = ['comptes' => [], 'solde' => 0.0];
                }

                $solde = round($debit - $credit, 2);

                if (empty($solde))
                    continue;

                $charges['comptes'][$parent]['comptes'][$compte] = $solde;
                $charges['total'] += $solde;
                $charges['comptes'][$parent]['solde'] += $solde;
            }
            elseif ($classe == 7 || $sousclasse == 87)
            {
                if (!isset($produits['comptes'][$parent]))
                {
                    $produits['comptes'][$parent] = ['comptes' => [], 'solde' => 0.0];
                }

                $solde = round($credit - $debit, 2);

                if (empty($solde))
                    continue;

                $produits['comptes'][$parent]['comptes'][$compte] = $solde;
                $produits['total'] += $solde;
                $produits['comptes'][$parent]['solde'] += $solde;
            }
        }

        // Suppression des soldes nuls
        $this->removeEmptyAccounts($produits);
        $this->removeEmptyAccounts($charges);

        $res->finalize();

        $resultat = $produits['total'] - $charges['total'];

        return ['charges' => $charges, 'produits' => $produits, 'resultat' => $resultat];
    }

    /**
     * Calculer le bilan comptable 
     * @return array    Un tableau multi-dimensionnel avec deux clés : actif et passif
     */
    public function bilan(array $criterias)
    {
        $db = DB::getInstance();
        $where = $this->getWhereClause($criterias);

        $include = [Comptes::ACTIF, Comptes::PASSIF,
            Comptes::PASSIF | Comptes::ACTIF];

        $actif           = ['comptes' => [], 'total' => 0.0];
        $passif          = ['comptes' => [], 'total' => 0.0];
        $actif_ou_passif = ['comptes' => [], 'total' => 0.0];

        $resultat = $this->compteResultat($criterias, [6, 7]);

        if ($resultat['resultat'] >= 0)
        {
            $passif['comptes']['12'] = [
                'comptes'   =>  ['120' => $resultat['resultat']],
                'solde'     =>  $resultat['resultat']
            ];

            $passif['total'] = $resultat['resultat'];
        }
        else
        {
            $passif['comptes']['12'] = [
                'comptes'   =>  ['129' => $resultat['resultat']],
                'solde'     =>  $resultat['resultat']
            ];

            $passif['total'] = $resultat['resultat'];
        }

        // Y'a sûrement moyen d'améliorer tout ça pour que le maximum de travail
        // soit fait au niveau du SQL, mais pour le moment ça marche
        $res = $db->preparedQuery('SELECT compte, debit, credit, (SELECT position FROM compta_comptes WHERE id = compte) AS position
            FROM
                (SELECT compte_debit AS compte, SUM(montant) AS debit, NULL AS credit
                    FROM compta_journal WHERE ' . $where . ' GROUP BY compte_debit
                UNION
                SELECT compte_credit AS compte, NULL AS debit, SUM(montant) AS credit
                    FROM compta_journal WHERE ' . $where . ' GROUP BY compte_credit)
            WHERE compte IN (SELECT id FROM compta_comptes WHERE position IN ('.implode(', ', $include).'))
            ORDER BY compte ASC;');

        while ($row = $res->fetchArray(SQLITE3_NUM))
        {
            list($compte, $debit, $credit, $position) = $row;
            $parent = substr($compte, 0, 2);

            if (($position & Comptes::ACTIF) && ($position & Comptes::PASSIF))
            {
                $position = 'actif_ou_passif';
                $solde = $debit - $credit;
            }
            else if ($position & Comptes::ACTIF)
            {
                $position = 'actif';
                $solde = $debit - $credit;
            }
            else if ($position & Comptes::PASSIF)
            {
                $position = 'passif';
                $solde = $credit - $debit;
            }
            else
            {
                continue;
            }

            if (!isset(${$position}['comptes'][$parent]))
            {
                ${$position}['comptes'][$parent] = ['comptes' => [], 'solde' => 0];
            }

            if (!isset(${$position}['comptes'][$parent]['comptes'][$compte]))
            {
                ${$position}['comptes'][$parent]['comptes'][$compte] = 0;
            }

            $solde = round($solde, 2);
            ${$position}['comptes'][$parent]['comptes'][$compte] += $solde;
            ${$position}['total'] += $solde;
            ${$position}['comptes'][$parent]['solde'] += $solde;
        }

        $res->finalize();

        foreach ($actif_ou_passif['comptes'] as $parent=>$p)
        {
            foreach ($p['comptes'] as $compte=>$solde)
            {
                if ($solde > 0)
                {
                    $position = 'actif';
                }
                else if ($solde < 0)
                {
                    $position = 'passif';
                    $solde = -$solde;
                }
                else
                {
                    continue;
                }

                if (!isset(${$position}['comptes'][$parent]))
                {
                    ${$position}['comptes'][$parent] = ['comptes' => [], 'solde' => 0];
                }

                if (!isset(${$position}['comptes'][$parent]['comptes'][$compte]))
                {
                    ${$position}['comptes'][$parent]['comptes'][$compte] = 0;
                }

                ${$position}['comptes'][$parent]['comptes'][$compte] += $solde;
                ${$position}['total'] += $solde;
                ${$position}['comptes'][$parent]['solde'] += $solde;
            }
        }

        // Suppression des soldes nuls
        $this->removeEmptyAccounts($passif);
        $this->removeEmptyAccounts($actif);

        return ['actif' => $actif, 'passif' => $passif];
    }

    protected function removeEmptyAccounts(&$source)
    {
        // Suppression des soldes nuls
        foreach ($source['comptes'] as $parent=>$p)
        {
            if ($p['solde'] == 0)
            {
                unset($source['comptes'][$parent]);
                continue;
            }

            foreach ($p['comptes'] as $id=>$solde)
            {
                if ($solde == 0)
                {
                    unset($source['comptes'][$parent]['comptes'][$id]);
                }
            }
        }
    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































































































































































































































































































































































































































































































Deleted src/include/lib/Garradin/Compta/Rapprochement.php version [21098b9dae].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
<?php

namespace Garradin\Compta;

use \Garradin\DB;
use \Garradin\Utils;
use \Garradin\UserException;
use \Garradin\Compta\Journal;
use \Garradin\Compta\Comptes_Bancaires;

class Rapprochement
{
    public function getJournal($compte, $debut, $fin, &$solde_initial, &$solde_final, $sauf_deja_rapprochees = false)
    {
        $db = DB::getInstance();

        $query = 'SELECT 
            COALESCE((SELECT SUM(montant) FROM compta_journal WHERE compte_debit = :compte AND compte_credit NOT LIKE \'8%\'  AND date < :date), 0)
            - COALESCE((SELECT SUM(montant) FROM compta_journal WHERE compte_credit = :compte AND compte_debit NOT LIKE \'8%\'  AND date < :date), 0)';

        $solde_initial = $solde = $db->firstColumn($query, [
            'compte'    =>  $compte,
            'date'      =>  $debut,
        ]);

        $query = '
            SELECT j.*, strftime(\'%s\', j.date) AS date,
                (CASE WHEN j.compte_debit = :compte THEN j.montant ELSE -(j.montant) END) AS solde,
                r.date AS date_rapprochement
            FROM compta_journal AS j
                LEFT JOIN compta_rapprochement AS r ON r.id_operation = j.id
            WHERE (compte_debit = :compte OR compte_credit = :compte)
                AND j.date >= :debut AND j.date <= :fin
                AND compte_debit NOT LIKE \'8%\' AND compte_credit NOT LIKE \'8%\'
                ' . ($sauf_deja_rapprochees ? 'AND r.id_operation IS NULL' : '') . '
            ORDER BY date ASC;';

        $result = $db->get($query, [
            'compte'    =>  $compte,
            'debut'     =>  $debut,
            'fin'       =>  $fin,
        ]);

        foreach ($result as &$row)
        {
            $solde += $row->solde;
            $row->solde = $solde;
        }

        $solde_final = $solde;

        return $result;
    }

    public function record(array $journal, array $cases = null, $id_auteur)
    {
        if (!is_array($cases) && empty($cases))
        {
            $cases = [];
        }

        $db = DB::getInstance();
        $db->begin();

        // Synchro des trucs cochés
        $st = $db->prepare('INSERT OR REPLACE INTO compta_rapprochement (id_operation, id_auteur) 
            VALUES (:operation, :auteur);');
        $st->bindValue(':auteur', (int)$id_auteur, \SQLITE3_INTEGER);

        foreach ($journal as $row)
        {
            if (!array_key_exists($row->id, $cases))
                continue;

            $st->bindValue(':operation', (int)$row->id, \SQLITE3_INTEGER);
            $st->execute();
        }

        // Synchro des trucs NON cochés
        $st = $db->prepare('DELETE FROM compta_rapprochement WHERE id_operation = :id;');

        foreach ($journal as $row)
        {
            if (array_key_exists($row->id, $cases))
                continue;

            $st->bindValue(':id', (int)$row->id, \SQLITE3_INTEGER);
            $st->execute();
        }

        $db->commit();
        return true;
    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































Deleted src/include/lib/Garradin/Compta/Stats.php version [5104b17973].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
<?php

namespace Garradin\Compta;

use \Garradin\DB;
use \Garradin\Utils;
use \Garradin\UserException;

class Stats
{
	protected function _parRepartitionCategorie($type)
	{
		return DB::getInstance()->get('SELECT SUM(montant) AS somme, id_categorie
			FROM compta_journal
			WHERE id_categorie IN (SELECT id FROM compta_categories WHERE type = ?)
			AND id_exercice = (SELECT id FROM compta_exercices WHERE cloture = 0)
			GROUP BY id_categorie ORDER BY somme DESC;', $type);
	}

	public function repartitionRecettes()
	{
		return $this->_parRepartitionCategorie(Categories::RECETTES);
	}

	public function repartitionDepenses()
	{
		return $this->_parRepartitionCategorie(Categories::DEPENSES);
	}

	protected function _parType($type)
	{
		return $this->getStats('SELECT strftime(\'%Y%m\', date) AS date,
			SUM(montant) FROM compta_journal
			WHERE id_categorie IN (SELECT id FROM compta_categories WHERE type = :type)
			AND id_exercice = (SELECT id FROM compta_exercices WHERE cloture = 0)
			GROUP BY strftime(\'%Y-%m\', date) ORDER BY date;',
			['type' => $type]);
	}

	public function recettes()
	{
		return $this->_parType(Categories::RECETTES);
	}

	public function depenses()
	{
		return $this->_parType(Categories::DEPENSES);
	}

	public function soldeCompte($compte, $augmente = 'debit', $diminue = 'credit')
	{
		$db = DB::getInstance();

		if (strpos($compte, '%') !== false)
		{
			$compte = 'LIKE \''. $db->escapeString($compte) . '\'';
		}
		else
		{
			$compte = '= \''. $db->escapeString($compte) . '\'';
		}

		$stats = $this->getStats('SELECT strftime(\'%Y%m\', date) AS date,
			(COALESCE((SELECT SUM(montant) FROM compta_journal
				WHERE compte_'.$augmente.' '.$compte.' AND id_exercice = cj.id_exercice
				AND date >= strftime(\'%Y-%m-01\', cj.date)
				AND date <= strftime(\'%Y-%m-31\', cj.date)), 0)
			- COALESCE((SELECT SUM(montant) FROM compta_journal
				WHERE compte_'.$diminue.' '.$compte.' AND id_exercice = cj.id_exercice
				AND date >= strftime(\'%Y-%m-01\', cj.date)
				AND date <= strftime(\'%Y-%m-31\', cj.date)), 0)
			) AS solde
			FROM compta_journal AS cj
			WHERE (compte_debit '.$compte.' OR compte_credit '.$compte.')
			AND id_exercice = (SELECT id FROM compta_exercices WHERE cloture = 0)
			GROUP BY strftime(\'%Y-%m\', date) ORDER BY date;');

		$c = 0;
		foreach ($stats as $k=>$v)
		{
			$c += $v;
			$stats[$k] = $c;
		}

		return $stats;
	}

	public function getStats($query, Array $args = [])
	{
		$db = DB::getInstance();

		$data = $db->getAssoc($query, $args);

		$e = $db->first('SELECT *, strftime(\'%s\', debut) AS debut,
			strftime(\'%s\', fin) AS fin FROM compta_exercices
			WHERE cloture = 0 LIMIT 1;');

		if (!$e)
		{
			return [];
		}

		$y = date('Y', $e->debut);
		$m = date('m', $e->debut);
		$max = date('Ym', $e->fin);

		while ($y . $m <= $max)
		{
			if (!isset($data[$y . $m]))
			{
				$data[$y . $m] = 0;
			}

			if ($m == 12)
			{
				$m = '01';
				$y++;
			}
			else
			{
				$m++;
				$m = str_pad((int)$m, 2, '0', STR_PAD_LEFT);
			}
		}

		ksort($data);

		return $data;
	}
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































































Modified src/include/lib/Garradin/Config.php from [c889a0eda3] to [06d32e37da].

45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72

73
74
75
76
77
78
79
80
81
82
83
84
85
        $object = new \stdClass;

        $this->fields_types = [
            'nom_asso'                =>  $string,
            'adresse_asso'            =>  $string,
            'email_asso'              =>  $string,
            'site_asso'               =>  $string,
            
            'monnaie'                 =>  $string,
            'pays'                    =>  $string,
            
            'champs_membres'          =>  $object,
            
            'categorie_membres'       =>  $int,
            
            'categorie_dons'          =>  $int,
            'categorie_cotisations'   =>  $int,
            
            'accueil_wiki'            =>  $string,
            'accueil_connexion'       =>  $string,
            
            'frequence_sauvegardes'   =>  $int,
            'nombre_sauvegardes'      =>  $int,
            
            'champ_identifiant'       =>  $string,
            'champ_identite'          =>  $string,
            
            'version'                 =>  $string,

            
            'couleur1'                =>  $string,
            'couleur2'                =>  $string,
            'image_fond'              =>  $string,

            'desactiver_site'         => $bool,
        ];

        $db = DB::getInstance();

        $this->config = $db->getAssoc('SELECT cle, valeur FROM config ORDER BY cle;');

        foreach ($this->config as $key=>&$value)







|


|

|

|
<
<
<


|


|


|

>
|




|







45
46
47
48
49
50
51
52
53
54
55
56
57
58
59



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
        $object = new \stdClass;

        $this->fields_types = [
            'nom_asso'                =>  $string,
            'adresse_asso'            =>  $string,
            'email_asso'              =>  $string,
            'site_asso'               =>  $string,

            'monnaie'                 =>  $string,
            'pays'                    =>  $string,

            'champs_membres'          =>  $object,

            'categorie_membres'       =>  $int,




            'accueil_wiki'            =>  $string,
            'accueil_connexion'       =>  $string,

            'frequence_sauvegardes'   =>  $int,
            'nombre_sauvegardes'      =>  $int,

            'champ_identifiant'       =>  $string,
            'champ_identite'          =>  $string,

            'version'                 =>  $string,
            'last_chart_change'       =>  $int,

            'couleur1'                =>  $string,
            'couleur2'                =>  $string,
            'image_fond'              =>  $string,

            'desactiver_site'         =>  $bool,
        ];

        $db = DB::getInstance();

        $this->config = $db->getAssoc('SELECT cle, valeur FROM config ORDER BY cle;');

        foreach ($this->config as $key=>&$value)
118
119
120
121
122
123
124

125


126
127
128
129
130
131
132
133
134
135
136
137
138
139


140
141
142
143
144


145
146
147
148
149
150
151
    {
        if (empty($this->modified))
            return true;

        $values = [];
        $db = DB::getInstance();


        if (isset($this->modified['image_fond']))


        {
            if ($current = $db->firstColumn('SELECT valeur FROM config WHERE cle = \'image_fond\';'))
            {
                try {
                    $f = new Fichiers($current);
                    $f->remove();
                }
                catch (\InvalidArgumentException $e) {
                    // Ignore: the file has already been deleted
                }
            }

            if (strlen($this->config['image_fond']) > 0)
            {


                $f = Fichiers::storeFromBase64('Image_fond_admin.png', $this->config['image_fond']);
                $this->config['image_fond'] = $f->id;
                unset($f);
            }
        }



        $db->begin();

        foreach ($this->modified as $key=>$modified)
        {
            $value = $this->config[$key];








>
|
>
>
|
|










|

>
>
|
|



>
>







116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
    {
        if (empty($this->modified))
            return true;

        $values = [];
        $db = DB::getInstance();

        // Image files
        if (isset($this->modified['image_fond'])) {
            $key = 'image_fond';
            $value =& $this->config[$key];

            if ($current = $db->firstColumn('SELECT valeur FROM config WHERE cle = ?;', $key))
            {
                try {
                    $f = new Fichiers($current);
                    $f->remove();
                }
                catch (\InvalidArgumentException $e) {
                    // Ignore: the file has already been deleted
                }
            }

            if (strlen($value) > 0)
            {
                $content = $value;
                $value = null;
                $f = Fichiers::storeFromBase64($key . '.png', $content);
                $value = $f->id;
                unset($f);
            }
        }

        unset($value, $key);

        $db->begin();

        foreach ($this->modified as $key=>$modified)
        {
            $value = $this->config[$key];

161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
            $db->preparedQuery('INSERT OR REPLACE INTO config (cle, valeur) VALUES (?, ?);',
                [$key, $value]);
        }

        if (!empty($this->modified['champ_identifiant']))
        {
            // Mettre les champs identifiant vides à NULL pour pouvoir créer un index unique
            $db->exec('UPDATE membres SET '.$this->get('champ_identifiant').' = NULL 
                WHERE '.$this->get('champ_identifiant').' = "";');

            // Création de l'index unique
            $db->exec('DROP INDEX IF EXISTS membres_identifiant;');
            $db->exec('CREATE UNIQUE INDEX membres_identifiant ON membres ('.$this->get('champ_identifiant').');');
        }








|







166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
            $db->preparedQuery('INSERT OR REPLACE INTO config (cle, valeur) VALUES (?, ?);',
                [$key, $value]);
        }

        if (!empty($this->modified['champ_identifiant']))
        {
            // Mettre les champs identifiant vides à NULL pour pouvoir créer un index unique
            $db->exec('UPDATE membres SET '.$this->get('champ_identifiant').' = NULL
                WHERE '.$this->get('champ_identifiant').' = "";');

            // Création de l'index unique
            $db->exec('DROP INDEX IF EXISTS membres_identifiant;');
            $db->exec('CREATE UNIQUE INDEX membres_identifiant ON membres ('.$this->get('champ_identifiant').');');
        }

187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
            throw new \OutOfBoundsException('Ce champ est inconnu.');
        }

        if (!array_key_exists($key, $this->config))
        {
            return null;
        }
        
        return $this->config[$key];
    }

    public function getVersion()
    {
        if (!array_key_exists('version', $this->config))
        {







|







192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
            throw new \OutOfBoundsException('Ce champ est inconnu.');
        }

        if (!array_key_exists($key, $this->config))
        {
            return null;
        }

        return $this->config[$key];
    }

    public function getVersion()
    {
        if (!array_key_exists('version', $this->config))
        {
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
                // Vérification que le champ existe bien
                if (!$champs->get($value))
                {
                    throw new UserException('Le champ '.$value.' n\'existe pas pour la configuration de '.$key);
                }

                // Vérification que le champ est unique pour l'identifiant
                if ($key == 'champ_identifiant' 
                    && !$db->firstColumn('SELECT (COUNT(DISTINCT lower('.$value.')) = COUNT(*)) 
                        FROM membres WHERE '.$value.' IS NOT NULL AND '.$value.' != \'\';'))
                {
                    throw new UserException('Le champ '.$value.' comporte des doublons et ne peut donc pas servir comme identifiant pour la connexion.');
                }
                break;
            }
            case 'categorie_cotisations':
            case 'categorie_dons':
            {
                return false;
                $db = DB::getInstance();
                if (!$db->firstColumn('SELECT 1 FROM compta_categories WHERE id = ?;', $value))
                {
                    throw new UserException('Champ '.$key.' : La catégorie comptable numéro \''.$value.'\' ne semble pas exister.');
                }
                break;
            }
            case 'categorie_membres':
            {
                $db = DB::getInstance();
                if (!$db->firstColumn('SELECT 1 FROM membres_categories WHERE id = ?;', $value))
                {







|
|




<
<
<
<
<
<
<
<
<
<
<







302
303
304
305
306
307
308
309
310
311
312
313
314











315
316
317
318
319
320
321
                // Vérification que le champ existe bien
                if (!$champs->get($value))
                {
                    throw new UserException('Le champ '.$value.' n\'existe pas pour la configuration de '.$key);
                }

                // Vérification que le champ est unique pour l'identifiant
                if ($key == 'champ_identifiant'
                    && !$db->firstColumn('SELECT (COUNT(DISTINCT lower('.$value.')) = COUNT(*))
                        FROM membres WHERE '.$value.' IS NOT NULL AND '.$value.' != \'\';'))
                {
                    throw new UserException('Le champ '.$value.' comporte des doublons et ne peut donc pas servir comme identifiant pour la connexion.');
                }











                break;
            }
            case 'categorie_membres':
            {
                $db = DB::getInstance();
                if (!$db->firstColumn('SELECT 1 FROM membres_categories WHERE id = ?;', $value))
                {

Deleted src/include/lib/Garradin/Cotisations.php version [895e912baf].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
<?php

namespace Garradin;

class Cotisations
{
	/**
	 * Vérification des champs fournis pour la modification de donnée
	 * @param  array $data Tableau contenant les champs à ajouter/modifier
	 * @return void
	 */
	protected function _checkFiel