initial commit

This commit is contained in:
Matthieu Bessat 2024-01-19 16:39:49 +01:00
commit 5ebc506921
975 changed files with 154341 additions and 0 deletions

10
.editorconfig Normal file
View file

@ -0,0 +1,10 @@
root = true
[*]
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
charset = utf-8
indent_style = tab
indent_size = tab
tab_width = 4

View file

@ -0,0 +1 @@
on

View file

@ -0,0 +1,14 @@
src/data/*
src/*.tar.gz
src/*.asc
src/*.log
src/include/lib/KD2
src/debug_sql.sqlite
src/modules/*
src/config.local.php
build/windows/*.exe
build/windows/php.zip
build/windows/install_dir
build/*.tar.gz*
build/debian/*.deb
src/psalm.phar

View file

@ -0,0 +1 @@
on

BIN
.fslckout Normal file

Binary file not shown.

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
src/data

1
.php-version Normal file
View file

@ -0,0 +1 @@
8.1.26

21
.travis.yml Normal file
View file

@ -0,0 +1,21 @@
language: php
php:
- '7.2'
- '7.3'
- '7.4'
install:
- make -C src deps
script:
- php tests/run.php
notifications:
irc:
channels:
- "chat.freenode.net#garradin"
template:
- "%{build_number} by %{author} on %{branch}: %{message} "
- "Build details: %{build_url}"
use_notice: false
skip_join: true

661
COPYING Normal file
View file

@ -0,0 +1,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/>.

32
README.md Normal file
View file

@ -0,0 +1,32 @@
# Paheko - Le gestionnaire d'association
Paheko est un logiciel de gestion d'association.
Plus d'infos sur le site de développement ici : [fossil.kd2.org/paheko](https://fossil.kd2.org/paheko/)
[Documentation développeuse⋅développeur](https://fossil.kd2.org/paheko/wiki?name=Documentation+d%C3%A9veloppeur)
Il est possible d'essayer gratuitement sur la plateforme [Paheko.cloud](https://paheko.cloud/).
Le code sur Github n'est qu'un miroir, le développement principal se passe sur Fossil, mais les PR sont quand même possibles sur Github.
**PR/Patch :** sauf si c'est une correction de bug, le mieux est de discuter de la modification sur dev(arobase)paheko.cloud avant de proposer le patch, pour qu'il ait plus de chances d'être accepté.
## 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-2022+ BohwaZ - Licence : GNU AGPL v3
* [Gibberish AES](https://github.com/mdp/gibberish-aes) - Copyright : Mark Percival 2008 - http://markpercival.us - Licence : MIT
* [Parsedown](https://github.com/erusev/parsedown) - Copyright Emanuil Rusev - License MIT
* [Unzipit.js](https://github.com/greggman/unzipit) - Copyright (c) 2019 Gregg Tavares 2014 Josh Wolfe - License MIT

15
SECURITY.md Normal file
View file

@ -0,0 +1,15 @@
# Security Policy
We take the security of Garradin very seriously.
Nous prenons la sécurité de Garradin au sérieux.
## Supported Versions
Only the latest stable branch is supported.
## Reporting a Vulnerability
If you find a security issue, please contact us: security@garradin.eu
Vous pouvez nous contacter à l'adresse e-mail ci-dessus si vous trouvez un problème de sécurité.

View file

@ -0,0 +1,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)
);

View file

@ -0,0 +1,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;

View file

@ -0,0 +1,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;

390
archives/0.8.0_schema.sql Normal file
View file

@ -0,0 +1,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)
);

View file

@ -0,0 +1,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;

388
archives/0.8.3_schema.sql Normal file
View file

@ -0,0 +1,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)
);

View file

@ -0,0 +1,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, '-');

View file

@ -0,0 +1,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\', '');

35
archives/0.9.0_schema.sql Normal file
View file

@ -0,0 +1,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\', '');

View file

@ -0,0 +1,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;

400
archives/0.9.1_schema.sql Normal file
View file

@ -0,0 +1,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
);

414
archives/0.9.5_schema.sql Normal file
View file

@ -0,0 +1,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
);

406
archives/1.0.0_schema.sql Normal file
View file

@ -0,0 +1,406 @@
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 TRIGGER IF NOT EXISTS acc_years_delete BEFORE DELETE ON acc_years BEGIN
UPDATE services_fees SET id_account = NULL, id_year = NULL WHERE id_year = OLD.id;
END;
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, id_year);
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_transaction ON acc_transactions_lines (id_transaction);
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
);

1760
archives/plan_comptable.json Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,141 @@
<?php
namespace Paheko;
const SQLITE_JOURNAL_MODE = 'WAL';
const ENABLE_UPGRADES = false;
if (shell_exec('which pdftotext')) {
define('Paheko\PDFTOTEXT_COMMAND', 'pdftotext');
}
if (shell_exec('which ssconvert')) {
define('Paheko\CALC_CONVERT_COMMAND', 'ssconvert');
}
elseif (shell_exec('which unoconv')) {
define('Paheko\CALC_CONVERT_COMMAND', 'unoconv');
}
if (!empty($_ENV['PAHEKO_STANDALONE']))
{
$home = $_ENV['HOME'];
// Config directory
if (empty($_ENV['XDG_CONFIG_HOME']))
{
$_ENV['XDG_CONFIG_HOME'] = $home . '/.config';
}
// Rename Garradin to Paheko
if (file_exists($_ENV['XDG_CONFIG_HOME'] . '/garradin')) {
rename($_ENV['XDG_CONFIG_HOME'] . '/garradin', $_ENV['XDG_CONFIG_HOME'] . '/paheko');
}
if (!file_exists($_ENV['XDG_CONFIG_HOME'] . '/paheko'))
{
mkdir($_ENV['XDG_CONFIG_HOME'] . '/paheko', 0700, true);
}
if (file_exists($_ENV['XDG_CONFIG_HOME'] . '/paheko/config.local.php')) {
require_once $_ENV['XDG_CONFIG_HOME'] . '/paheko/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')) {
rename($_ENV['XDG_DATA_HOME'] . '/garradin', $_ENV['XDG_DATA_HOME'] . '/paheko');
}
if (!file_exists($_ENV['XDG_DATA_HOME'] . '/paheko')) {
mkdir($_ENV['XDG_DATA_HOME'] . '/paheko', 0700, true);
}
if (!defined('Paheko\DATA_ROOT')) {
define('Paheko\DATA_ROOT', $_ENV['XDG_DATA_HOME'] . '/paheko');
}
// Cache directory: temporary stuff
if (empty($_ENV['XDG_CACHE_HOME']))
{
$_ENV['XDG_CACHE_HOME'] = $home . '/.cache';
}
if (file_exists($_ENV['XDG_CACHE_HOME'] . '/garradin')) {
rename($_ENV['XDG_CACHE_HOME'] . '/garradin', $_ENV['XDG_CACHE_HOME'] . '/paheko');
}
if (!file_exists($_ENV['XDG_CACHE_HOME'] . '/paheko'))
{
mkdir($_ENV['XDG_CACHE_HOME'] . '/paheko', 0700, true);
}
if (!defined('Paheko\CACHE_ROOT')) {
define('Paheko\CACHE_ROOT', $_ENV['XDG_CACHE_HOME'] . '/paheko');
}
if (!defined('Paheko\DB_FILE')) {
$last_file = $_ENV['XDG_CONFIG_HOME'] . '/paheko/last';
if ($_ENV['PAHEKO_STANDALONE'] != 1)
{
$last_sqlite = trim($_ENV['PAHEKO_STANDALONE']);
}
else if (file_exists($last_file))
{
$last_sqlite = trim(file_get_contents($last_file));
$last_sqlite = str_replace('.local/share/garradin', '.local/share/paheko', $last_sqlite);
}
else
{
$last_sqlite = $_ENV['XDG_DATA_HOME'] . '/paheko/association.sqlite';
}
file_put_contents($last_file, $last_sqlite);
define('Paheko\DB_FILE', $last_sqlite);
}
if (!defined('Paheko\LOCAL_LOGIN')) {
define('Paheko\LOCAL_LOGIN', -1);
}
}
else {
if (file_exists('/etc/paheko/config.php')) {
require_once '/etc/paheko/config.php';
}
if (!defined('Paheko\DATA_ROOT')) {
define('Paheko\DATA_ROOT', '/var/lib/paheko');
}
if (!defined('Paheko\CACHE_ROOT')) {
define('Paheko\CACHE_ROOT', '/var/cache/paheko');
}
}
if (file_exists(DATA_ROOT . '/plugins')) {
define('Paheko\PLUGINS_ROOT', DATA_ROOT . '/plugins');
}
else {
define('Paheko\PLUGINS_ROOT', __DIR__ . '/plugins');
}
if (!defined('Paheko\SECRET_KEY')) {
if (file_exists(CACHE_ROOT . '/key')) {
define('Paheko\SECRET_KEY', trim(file_get_contents(CACHE_ROOT . '/key')));
}
else {
define('Paheko\SECRET_KEY', base64_encode(random_bytes(64)));
file_put_contents(CACHE_ROOT . '/key', SECRET_KEY);
}
}
// Disable PDF for CLI server
if (PHP_SAPI == 'cli-server' && !defined('Paheko\PDF_COMMAND') && !file_exists(PLUGINS_ROOT . '/dompdf')) {
define('Paheko\PDF_COMMAND', null);
}

174
build/debian/makedeb.sh Executable file
View file

@ -0,0 +1,174 @@
#!/bin/bash
# Ripped from fossil makdedeb.sh
DEB_REV=${1-1} # .deb package build/revision number.
PACKAGE_DEBNAME=paheko
THISDIR=${PWD}
DEB_ARCH_NAME=all
PACKAGE_VERSION=`cat ../../src/VERSION`
[ ! -f ../paheko-${PACKAGE_VERSION}.tar.gz ] && (cd ../../src; make release)
tar xzvf ../paheko-${PACKAGE_VERSION}.tar.gz -C /tmp
SRCDIR="/tmp/paheko-${PACKAGE_VERSION}"
test -e ${SRCDIR} || {
echo "This script must be run from a BUILT copy of the source tree."
exit 1
}
DEBROOT=$PWD/deb.tmp
test -d ${DEBROOT} && rm -fr ${DEBROOT}
DEBLOCALPREFIX=${DEBROOT}/usr
BINDIR=${DEBLOCALPREFIX}/bin
mkdir -p ${BINDIR}
mkdir -p ${DEBLOCALPREFIX}/share/doc/${PACKAGE_DEBNAME}
cp ${THISDIR}/paheko ${BINDIR}
mkdir -p "${DEBLOCALPREFIX}/share/menu"
cp ${THISDIR}/paheko.menu "${DEBLOCALPREFIX}/share/menu/paheko"
mkdir -p "${DEBLOCALPREFIX}/share/applications"
cp ${THISDIR}/paheko.desktop "${DEBLOCALPREFIX}/share/applications/"
CODEDIR=${DEBLOCALPREFIX}/share/${PACKAGE_DEBNAME}
mkdir -p ${CODEDIR}
cp -r ${SRCDIR}/* ${CODEDIR}
cp ${THISDIR}/config.debian.php ${CODEDIR}/config.local.php
mv ${CODEDIR}/data/plugins ${CODEDIR}/plugins
rm -rf ${CODEDIR}/*.sqlite ${CODEDIR}/data
cp ${THISDIR}/paheko.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
mkdir DEBIAN
PACKAGE_DEB_VERSION=${PACKAGE_VERSION}
DEBFILE=${THISDIR}/${PACKAGE_DEBNAME}-${PACKAGE_DEB_VERSION}.deb
PACKAGE_TIME=$(/bin/date)
rm -f ${DEBFILE}
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/paheko /var/cache/paheko
chown root:www-data /etc/paheko
chmod g=rX,o= /etc/paheko
chmod ug=rwX,o= /var/lib/paheko /var/cache/paheko
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
This release has no changes over the core source distribution. It has
simply been Debianized.
Packaged by ${USER} <http://dev.kd2.org/paheko/> on
${PACKAGE_TIME}.
EOF
}
# 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}/paheko.1 > ${DEBLOCALPREFIX}/share/man/man1/${PACKAGE_DEBNAME}.1.gz
rm -f ${THISDIR}/paheko.1
} || {
echo "Fail."
exit 1
}
true && {
CONTROL=DEBIAN/control
echo "Generating ${CONTROL}..."
cat <<EOF > ${CONTROL}
Package: ${PACKAGE_DEBNAME}
Section: web
Priority: optional
Maintainer: Paheko <paheko@paheko.eu>
Architecture: ${DEB_ARCH_NAME}
Depends: dash | bash, php-cli (>=7.4), php-sqlite3, php-intl, php-mbstring, sensible-utils
Version: ${PACKAGE_DEB_VERSION}
Suggests: php-imagick
Replaces: garradin (<< 1.2.3~)
Breaks: garradin (<< 1.2.3~)
Homepage: https://fossil.kd2.org/paheko/
Description: Paheko is a tool to manage non-profit organizations.
It's only available in french.
Description-fr: Gestionnaire d'association en interface web ou CLI.
Paheko est un gestionnaire d'association à but non lucratif.
Il permet de gérer les membres, leur adhésion et leurs contributions financières.
Les membres peuvent se connecter eux-même et modifier leurs informations
ou communiquer entre eux par e-mail. Une gestion précise des droits et
autorisations est possible. Il est également possible de faire des
envois de mails en groupe.
.
Un module de comptabilité à double entrée assure une gestion financière
complète digne d'un vrai logiciel de comptabilité : suivi des opérations,
graphiques, bilan annuel, compte de résultat, exercices, etc.
.
Il y a également la possibilité de publier un site web simple,
et un gestionnaire de documents permettant de gérer les fichiers de
l'association.
EOF
}
true && {
fakeroot dpkg-deb -b ${DEBROOT} ${DEBFILE}
echo "Package file created:"
ls -la ${DEBFILE}
dpkg-deb --info ${DEBFILE}
}
cd - >/dev/null
true && {
echo "Cleaning up..."
rm -fr ${DEBROOT}
rm -rf ${SRCDIR}
}
echo "Done :)"

106
build/debian/manpage.txt Normal file
View file

@ -0,0 +1,106 @@
PAHEKO(1)
=========
:doctype: manpage
NAME
----
paheko - Gestionnaire d'association à but non lucratif
SYNOPSIS
--------
*paheko* ['OPTIONS'] ['COMMANDE'] ['BASE']
DESCRIPTION
-----------
Lancer paheko(1) sans argument lance le serveur web intégré sur
l'adresse localhost:8081 et le navigateur web par défaut.
*BASE* défini le chemin de la base de données (fichier .sqlite) à
utiliser. Par défaut, si aucune base n'est spécifiée, c'est le fichier
'association.sqlite' situé dans le répertoire des données qui est
utilisé.
OPTIONS
-------
*-p, --port*='PORT'::
Défini le port utilisé par le serveur web.
Par défaut c'est le port 8081 qui est utilisé.
*-b, --bind*='IP'::
Adresse IP où sera exposé le serveur web.
Par défaut c'est 127.0.0.1 qui est utilisé.
Utiliser 0.0.0.0 pour que le serveur web soit accessible d'autres
machines. (Attention cela peut présenter un risque de sécurité.)
*-v, --verbose*::
Affiche les messages du serveur web.
*-h, --help*::
Affiche un message d'aide sur l'utilisation de la commande.
COMMANDES
---------
*server*::
Lance le serveur web autonome de Paheko sans lancer de navigateur
web.
*ui*::
Lance le serveur web autonome et le navigateur par défaut.
EXIT STATUS
-----------
*0*::
Succès
*1*::
Erreur
EMPLACEMENTS DE STOCKAGE
------------------------
Les données sont stockées dans $XDG_DATA_HOME/paheko.
Généralement c'est ~/.local/share/paheko
CONFIGURATION
-------------
Il est possible de créer un fichier de configuration dans
$XDG_CONFIG_HOME/paheko/config.local.php
Voir la documentation pour plus de détails sur les constantes
de configuration acceptées.
INSTALLATION SERVEUR WEB
------------------------
Il est possible d'utiliser ce package avec Apache pour héberger
une instance Paheko.
La procédure est détaillée ici :
https://fossil.kd2.org/paheko/wiki?name=Installation%20sous%20Debian-Ubuntu
Les données et plugins seront stockés dans le répertoire
/var/lib/paheko
BUGS
----
Voir https://fossil.kd2.org/paheko/ pour un accès au bugtracker.
AUTEUR
------
Paheko est développé par bohwaz et d'autres contributeurs.
RESSOURCES
----------
Site principal : <https://fossil.kd2.org/paheko/>
COPYING
-------
Copyright \(C) 2011-2023 BohwaZ. Free use of this software is
granted under the terms of the GNU Affero General Public License v3
(AGPL).

123
build/debian/paheko Executable file
View file

@ -0,0 +1,123 @@
#!/bin/sh
ROOT=/usr/share/paheko/www
#ROOT=~/fossil/paheko/src/www
ROUTER=${ROOT}/_route.php
PORT=8081
ADDRESS="127.0.0.1"
VERBOSE=0
PID_FILE="${XDG_RUNTIME_DIR}/paheko/pid"
[ ! -d `dirname $PID_FILE` ] && mkdir -p `dirname $PID_FILE`
# Execute getopt
ARGS=`getopt -o "pb:vh" -l "port:,bind:,verbose,help" -n "paheko" -- "$@"`
# Bad arguments
if [ $? -ne 0 ];
then
exit 1
fi
# A little magic
eval set -- "$ARGS"
# Now go through all the options
while true;
do
case "$1" in
-p|--port)
PORT=$2
shift;;
-b|--bind)
ADDRESS=$2
shift;;
-v|--verbose)
VERBOSE=1
shift;;
-h|--help)
cat <<EOF
Usage : $0 [COMMANDE] [PROJET]
Où COMMANDE peut être :
server [-p|--port PORT] [-b|--bind IP]
Démarre un serveur web Paheko sur le port spécifié
(8081 par défaut) et l'IP spécifiée (127.0.0.1 par défaut)
ui [-p|--port PORT] [-b|--bind IP]
Idem que 'server' mais démarre ensuite le navigateur web par défaut
et connecte automatiquement avec le premier administrateur
de l'association.
Si aucune COMMANDE n'est donnée, Paheko utilisera 'ui' par défaut.
PROJET est le chemin menant à un projet Paheko précis
(fichier .sqlite). Si aucun projet n'est indiqué, le
dernier projet ouvert sera rouvert. Si aucun projet n'a jamais été
ouvert un nouveau projet sera créé.
Options :
-p|--port PORT
Spécifie le port pour le mode ui ou le mode serveur.
-b|--bind IP
Spécifie l'adresse IP du serveur web.
-v|--verbose
Affiche les requêtes reçues sur le serveur web.
-h|--help
Affiche ce message.
EOF
exit
shift;;
--)
shift
break;;
esac
done
CMD="$1"
[ "$CMD" = "" ] && {
CMD="ui"
}
PROJECT="$2"
[ "$PROJECT" = "" ] && PROJECT="1"
export PAHEKO_STANDALONE="$PROJECT"
[ -f $PID_FILE ] && kill `cat $PID_FILE` > /dev/null 2>&1 && rm -f $PID_FILE
PHP_CLI_SERVER_WORKER=2
[ $VERBOSE = 1 ] && {
php -S ${ADDRESS}:${PORT} -t ${ROOT} -d variables_order=EGPCS ${ROUTER} &
} || {
php -S ${ADDRESS}:${PORT} -t ${ROOT} -d variables_order=EGPCS ${ROUTER} > /dev/null 2>&1 &
}
php_pid=$!
echo $php_pid > $PID_FILE
sleep .5
[ "$CMD" = "ui" ] && {
URL="http://${ADDRESS}:${PORT}/admin/"
[ "$DISPLAY" != "" ] && {
sensible-browser ${URL} &
} || {
www-browser ${URL} &
}
} || {
wait $php_pid
}

View file

@ -0,0 +1,6 @@
[Desktop Entry]
Name=Paheko
Exec=paheko
Icon=paheko
Type=Application
Categories=Office;Finance;Database

3
build/debian/paheko.menu Normal file
View file

@ -0,0 +1,3 @@
?package(paheko):needs="X11" section="Applications/Office"\
title="Paheko" command="/usr/bin/paheko"\
icon="/usr/share/paheko/paheko.png"

BIN
build/debian/paheko.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

81
build/windows/Makefile Normal file
View file

@ -0,0 +1,81 @@
.PHONY := php installer clean publish
PHP_ARCHIVE := https://windows.php.net/downloads/releases/php-8.2.10-nts-Win32-vs16-x64.zip
all: installer
php.zip:
wget ${PHP_ARCHIVE} -O php.zip
php: php.zip
mkdir -p install_dir/php
unzip -o php.zip -d install_dir/php > /dev/null
# Remove unused files
@cd install_dir/php && rm -rf \
phpdbg.exe \
php8phpdbg.dll \
php8embed.lib \
php-cgi.exe \
php.ini-* \
dev \
phar* \
nghttp2.dll \
libpq.dll \
libenchant
# Remove unused extensions
@cd install_dir/php/ext && rm -f \
php_bz2.dll \
php_com_dotnet.dll \
php_curl.dll \
php_dba.dll \
php_dl_test.dll \
php_enchant.dll \
php_exif.dll \
php_ffi.dll \
php_ftp.dll \
php_gmp.dll \
php_imap.dll \
php_ldap.dll \
php_mysqli.dll \
php_oci8_19.dll \
php_odbc.dll \
php_opcache.dll \
php_pdo_firebird.dll \
php_pdo_mysql.dll \
php_pdo_oci.dll \
php_pdo_odbc.dll \
php_pdo_pgsql.dll \
php_pdo_sqlite.dll \
php_pgsql.dll \
php_shmop.dll \
php_snmp.dll \
php_soap.dll \
php_sysvshm.dll \
php_xsl.dll \
php_zend_test.dll
du -hs install_dir/php
installer: clean php
$(eval VERSION=$(shell cat ../../src/VERSION))
# NSIS only accepts numbers as version
$(eval NSIS_VERSION=$(shell sed -E 's/-(alpha|beta|rc)[0-9]+//' ../../src/VERSION))
mkdir -p install_dir
cp ../paheko-${VERSION}.tar.gz install_dir/
cd install_dir && tar xzf paheko-${VERSION}.tar.gz && mv paheko-${VERSION} paheko
cp config.local.php install_dir/paheko/
cp php.ini install_dir/php
cp launch.bat install_dir
cp paheko.ico install_dir
rm -f install_dir/paheko-${VERSION}.tar.gz
makensis -V3 -DNVERSION=${NSIS_VERSION} -DVERSION=${VERSION} paheko.nsis
clean:
rm -rf install_dir
publish:
$(eval VERSION=$(shell cat ../../src/VERSION))
fossil uv ls | grep '^paheko-.*\.exe' | xargs fossil uv rm
fossil uv add paheko-${VERSION}.exe
fossil uv sync

5
build/windows/README.md Normal file
View file

@ -0,0 +1,5 @@
# Paheko Windows build
## Requirements
NSIS: `apt install nsis`

View file

@ -0,0 +1,34 @@
<?php
namespace Paheko;
if (!empty(getenv('LOCALAPPDATA'))) {
// Store data in user AppData directory
define('Paheko\DATA_ROOT', trim(getenv('LOCALAPPDATA'), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . 'Paheko');
if (!file_exists(DATA_ROOT)) {
@mkdir(DATA_ROOT, 0700, true);
}
}
define('Paheko\PLUGINS_ROOT', __DIR__ . '/data/plugins');
// Store secret key in user directory
if (!defined('Paheko\SECRET_KEY')) {
if (file_exists(DATA_ROOT . '/key')) {
define('Paheko\SECRET_KEY', trim(file_get_contents(DATA_ROOT . '/key')));
}
else {
define('Paheko\SECRET_KEY', base64_encode(random_bytes(16)));
file_put_contents(DATA_ROOT . '/key', SECRET_KEY);
}
}
// Always log in as admin user
const LOCAL_LOGIN = -1;
// Disable PDF export
const PDF_COMMAND = null;
// Disable e-mails as Windows is not able to send e-mails
const DISABLE_EMAIL = true;

15
build/windows/launch.bat Normal file
View file

@ -0,0 +1,15 @@
@start "" http://127.0.0.1:8082/
@echo =================================================
@echo.
@echo Demarrage du serveur PHP de Paheko.
@echo.
@echo Paheko est disponible a l'adresse suivante :
@echo http://127.0.0.1:8082/
@echo.
@echo Fermer cette fenetre pour arreter le serveur.
@echo.
@echo =================================================
@echo.
php\php.exe -S 127.0.0.1:8082 -t paheko/www paheko/www/_route.php 2> NUL

BIN
build/windows/paheko.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

175
build/windows/paheko.nsis Normal file
View file

@ -0,0 +1,175 @@
# From https://www.conjur.org/blog/building-a-windows-installer-from-a-linux-ci-pipeline/
!define APP_NAME "Paheko"
!define COMP_NAME "Paheko.cloud"
#!define WEB_SITE "https://paheko.cloud/"
#!define VERSION "0.0.0.1"
!define COPYRIGHT "Paheko"
!define DESCRIPTION "Gestion d'association simple et efficace"
!define INSTALLER_NAME "paheko-${VERSION}.exe"
!define MAIN_APP_EXE "launch.bat"
!define ICON "paheko.ico"
#!define BANNER "[CHANGEME Installer Banner Filename .bmp]"
#!define LICENSE_TXT "[CHANGEME License Text Document]"
!define INSTALL_DIR "$PROGRAMFILES64\${APP_NAME}"
!define INSTALL_TYPE "SetShellVarContext all"
!define REG_ROOT "HKLM"
!define REG_APP_PATH "Software\Microsoft\Windows\CurrentVersion\App Paths\${MAIN_APP_EXE}"
!define UNINSTALL_PATH "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}"
!define REG_START_MENU "Start Menu Folder"
var SM_Folder
######################################################################
VIProductVersion "${NVERSION}.0"
VIAddVersionKey "ProductName" "${APP_NAME}"
VIAddVersionKey "CompanyName" "${COMP_NAME}"
VIAddVersionKey "LegalCopyright" "${COPYRIGHT}"
VIAddVersionKey "FileDescription" "${DESCRIPTION}"
VIAddVersionKey "FileVersion" "${VERSION}"
######################################################################
SetCompressor /SOLID Lzma
Name "${APP_NAME}"
Caption "${APP_NAME}"
OutFile "${INSTALLER_NAME}"
BrandingText "${APP_NAME}"
#InstallDirRegKey "${REG_ROOT}" "${REG_APP_PATH}" ""
InstallDir "${INSTALL_DIR}"
######################################################################
!define MUI_ICON "${ICON}"
!define MUI_UNICON "${ICON}"
Icon "${ICON}"
!ifdef BANNER
!define MUI_WELCOMEFINISHPAGE_BITMAP "${BANNER}"
!define MUI_UNWELCOMEFINISHPAGE_BITMAP "${BANNER}"
!endif
######################################################################
!include "MUI2.nsh"
!define MUI_ABORTWARNING
!define MUI_UNABORTWARNING
!insertmacro MUI_PAGE_WELCOME
!ifdef LICENSE_TXT
!insertmacro MUI_PAGE_LICENSE "${LICENSE_TXT}"
!endif
!insertmacro MUI_PAGE_DIRECTORY
!ifdef REG_START_MENU
!define MUI_STARTMENUPAGE_DEFAULTFOLDER "${APP_NAME}"
!define MUI_STARTMENUPAGE_REGISTRY_ROOT "${REG_ROOT}"
!define MUI_STARTMENUPAGE_REGISTRY_KEY "${UNINSTALL_PATH}"
!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "${REG_START_MENU}"
!insertmacro MUI_PAGE_STARTMENU Application $SM_Folder
!endif
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
!insertmacro MUI_UNPAGE_FINISH
!insertmacro MUI_LANGUAGE "French"
######################################################################
Section -MainProgram
${INSTALL_TYPE}
SetOverwrite ifnewer
SetOutPath "$INSTDIR"
File /r "install_dir\\"
SectionEnd
######################################################################
Section -Icons_Reg
SetOutPath "$INSTDIR"
WriteUninstaller "$INSTDIR\uninstall.exe"
!ifdef REG_START_MENU
!insertmacro MUI_STARTMENU_WRITE_BEGIN Application
CreateDirectory "$SMPROGRAMS\$SM_Folder"
CreateShortCut "$SMPROGRAMS\$SM_Folder\${APP_NAME}.lnk" "$INSTDIR\${MAIN_APP_EXE}" "" "$INSTDIR\paheko.ico"
CreateShortCut "$DESKTOP\${APP_NAME}.lnk" "$INSTDIR\${MAIN_APP_EXE}" "" "$INSTDIR\paheko.ico"
CreateShortCut "$SMPROGRAMS\$SM_Folder\Desinstaller ${APP_NAME}.lnk" "$INSTDIR\uninstall.exe"
!ifdef WEB_SITE
WriteIniStr "$INSTDIR\${APP_NAME} website.url" "InternetShortcut" "URL" "${WEB_SITE}"
CreateShortCut "$SMPROGRAMS\$SM_Folder\${APP_NAME} Website.lnk" "$INSTDIR\${APP_NAME} website.url"
!endif
!insertmacro MUI_STARTMENU_WRITE_END
!endif
!ifndef REG_START_MENU
CreateDirectory "$SMPROGRAMS\${APP_NAME}"
CreateShortCut "$SMPROGRAMS\${APP_NAME}\${APP_NAME}.lnk" "$INSTDIR\${MAIN_APP_EXE}" "" "$INSTDIR\paheko.ico"
CreateShortCut "$DESKTOP\${APP_NAME}.lnk" "$INSTDIR\${MAIN_APP_EXE}" "" "$INSTDIR\paheko.ico"
CreateShortCut "$SMPROGRAMS\${APP_NAME}\Desinstaller ${APP_NAME}.lnk" "$INSTDIR\uninstall.exe"
!ifdef WEB_SITE
WriteIniStr "$INSTDIR\${APP_NAME} website.url" "InternetShortcut" "URL" "${WEB_SITE}"
CreateShortCut "$SMPROGRAMS\${APP_NAME}\${APP_NAME} Website.lnk" "$INSTDIR\${APP_NAME} website.url"
!endif
!endif
WriteRegStr ${REG_ROOT} "${REG_APP_PATH}" "" "$INSTDIR\${MAIN_APP_EXE}"
WriteRegStr ${REG_ROOT} "${UNINSTALL_PATH}" "DisplayName" "${APP_NAME}"
WriteRegStr ${REG_ROOT} "${UNINSTALL_PATH}" "UninstallString" "$INSTDIR\uninstall.exe"
WriteRegStr ${REG_ROOT} "${UNINSTALL_PATH}" "DisplayIcon" "$INSTDIR\paheko.ico"
WriteRegStr ${REG_ROOT} "${UNINSTALL_PATH}" "DisplayVersion" "${VERSION}"
WriteRegStr ${REG_ROOT} "${UNINSTALL_PATH}" "Publisher" "${COMP_NAME}"
!ifdef WEB_SITE
WriteRegStr ${REG_ROOT} "${UNINSTALL_PATH}" "URLInfoAbout" "${WEB_SITE}"
!endif
SectionEnd
######################################################################
Section Uninstall
${INSTALL_TYPE}
RmDir /r "$INSTDIR"
!ifdef REG_START_MENU
!insertmacro MUI_STARTMENU_GETFOLDER "Application" $SM_Folder
Delete "$SMPROGRAMS\$SM_Folder\${APP_NAME}.lnk"
Delete "$SMPROGRAMS\$SM_Folder\Desinstaller ${APP_NAME}.lnk"
!ifdef WEB_SITE
Delete "$SMPROGRAMS\$SM_Folder\${APP_NAME} Website.lnk"
!endif
Delete "$DESKTOP\${APP_NAME}.lnk"
RmDir "$SMPROGRAMS\$SM_Folder"
!endif
!ifndef REG_START_MENU
Delete "$SMPROGRAMS\${APP_NAME}\${APP_NAME}.lnk"
Delete "$SMPROGRAMS\${APP_NAME}\Desinstaller ${APP_NAME}.lnk"
!ifdef WEB_SITE
Delete "$SMPROGRAMS\${APP_NAME}\${APP_NAME} Website.lnk"
!endif
Delete "$DESKTOP\${APP_NAME}.lnk"
RmDir "$SMPROGRAMS\${APP_NAME}"
!endif
DeleteRegKey ${REG_ROOT} "${REG_APP_PATH}"
DeleteRegKey ${REG_ROOT} "${UNINSTALL_PATH}"
SectionEnd

95
build/windows/php.ini Normal file
View file

@ -0,0 +1,95 @@
[PHP]
engine = On
short_open_tag = Off
precision = 14
output_buffering = 4096
zlib.output_compression = Off
implicit_flush = Off
unserialize_callback_func =
serialize_precision = -1
disable_functions =
disable_classes =
zend.enable_gc = On
zend.exception_ignore_args = Off
zend.exception_string_param_max_len = 15
expose_php = On
max_execution_time = 30
max_input_time = 60
memory_limit = 128M
error_reporting = E_ALL
display_errors = On
display_startup_errors = On
log_errors = On
ignore_repeated_errors = Off
ignore_repeated_source = Off
report_memleaks = On
variables_order = "GPCS"
request_order = "GP"
register_argc_argv = Off
auto_globals_jit = On
post_max_size = 256M
auto_prepend_file =
auto_append_file =
default_mimetype = "text/html"
default_charset = "UTF-8"
doc_root =
user_dir =
extension_dir = "ext"
enable_dl = Off
file_uploads = On
upload_max_filesize = 256M
max_file_uploads = 20
allow_url_fopen = On
allow_url_include = Off
default_socket_timeout = 60
extension=fileinfo
extension=gd
extension=gettext
extension=intl
extension=mbstring
extension=openssl
extension=sodium
extension=sqlite3
extension=tidy
[CLI Server]
cli_server.color = On
[mail function]
SMTP = localhost
smtp_port = 25
mail.add_x_header = Off
[bcmath]
bcmath.scale = 0
[Session]
session.save_handler = files
session.use_strict_mode = 0
session.use_cookies = 1
session.use_only_cookies = 1
session.name = PHPSESSID
session.auto_start = 0
session.cookie_lifetime = 0
session.cookie_path = /
session.cookie_domain =
session.cookie_httponly =
session.cookie_samesite =
session.serialize_handler = php
session.gc_probability = 1
session.gc_divisor = 1000
session.gc_maxlifetime = 1440
session.referer_check =
session.cache_limiter = nocache
session.cache_expire = 180
session.use_trans_sid = 0
session.sid_length = 26
session.trans_sid_tags = "a=href,area=href,frame=src,form="
session.sid_bits_per_character = 5
[Assertion]
zend.assertions = -1
[Tidy]
tidy.clean_output = Off

390
doc/admin/api.md Normal file
View file

@ -0,0 +1,390 @@
Une API de type REST est disponible dans Paheko.
Pour accéder à l'API il faut un identifiant et un mot de passe, à créer dans le menu ==Configuration==, onglet ==Fonctions avancées==, puis ==API==.
L'API peut ensuite recevoir des requêtes REST sur l'URL `https://adresse_association/api/{chemin}/`.
Remplacer =={chemin}== par un des chemins de l'API (voir ci-dessous). La méthode HTTP à utiliser est spécifiée pour chaque chemin.
Pour les requêtes de type `POST`, les paramètres peuvent être envoyés par le client sous forme de formulaire HTTP classique (`application/x-www-form-urlencoded`) ou sous forme d'objet JSON. Dans ce cas le `Content-Type` doit être positionné sur `application/json`.
Les réponses sont faites en JSON par défaut.
<<toc level=3>>
# Utiliser l'API
N'importe quel client HTTP capable de gérer TLS (HTTPS) et l'authentification basique fonctionnera.
En ligne de commande il est possible d'utiliser `curl`. Exemple pour télécharger la base de données :
```
curl https://test:coucou@[identifiant_association].paheko.cloud/api/download -o association.sqlite
```
On peut aussi utiliser `wget` en n'oubliant pas l'option `--auth-no-challenge` sinon l'authentification ne fonctionnera pas :
```
wget https://test:coucou@[identifiant_association].paheko.cloud/api/download --auth-no-challenge -O association.sqlite
```
Exemple pour créer une écriture sous forme de formulaire :
```
curl -v "http://test:test@[identifiant_association].paheko.cloud/api/accounting/transaction" -F id_year=1 -F label=Test -F "date=01/02/2023" …
```
Ou sous forme d'objet JSON :
```
curl -v "http://test:test@[identifiant_association].paheko.cloud/api/accounting/transaction" -H 'Content-Type: application/json' -d '{"id_year":1, "label": "Test écriture", "date": "01/02/2023"}'
```
# Authentification
Il ne faut pas oublier de fournir le nom d'utilisateur et mot de passe en HTTP :
```
curl http://test:abcd@paheko.monasso.tld/api/download/
```
# Erreurs
En cas d'erreur un code HTTP 4XX sera fourni, et le contenu sera un objet JSON avec une clé `error` contenant le message d'erreur.
# Chemins
## sql (POST)
Permet d'exécuter une requête SQL `SELECT` (uniquement, pas de requête UPDATE, DELETE, INSERT, etc.) sur la base de données. La requête SQL doit être passée dans le corps de la requête HTTP, ou dans le paramètre `sql`. Le résultat est retourné dans la clé `results` de l'objet JSON.
S'il n'y a pas de limite à la requête, une limite à 1000 résultats sera ajoutée obligatoirement.
```
curl https://test:abcd@paheko.monasso.tld/api/sql/ -d 'SELECT * FROM membres LIMIT 5;'
```
**ATTENTION :** Les requêtes en écriture (`INSERT, DELETE, UPDATE, CREATE TABLE`, etc.) ne sont pas acceptées, il n'est pas possible de modifier la base de données directement via Paheko, afin d'éviter les soucis de données corrompues.
Depuis la version 1.2.8, il est possible d'utiliser le paramètre `format` pour choisir le format renvoyé :
* `json` (défaut) : renvoie un objet JSON, dont la clé est `"results"` et contient un tableau de la liste des membres trouvés
* `csv` : renvoie un fichier CSV
* `ods` : renvoie un tableau LibreOffice Calc (ODS)
* `xlsx` : renvoie un tableau Excel (XLSX)
Exemple :
```
curl https://test:abcd@paheko.monasso.tld/api/sql/ -F sql='SELECT * FROM membres LIMIT 5;' -F format=csv
```
## Téléchargements
### download (GET)
Télécharger la base de données complète. Renvoie directement le fichier SQLite de la base de données.
Exemple :
```
curl https://test:abcd@paheko.monasso.tld/api/download -o db.sqlite
```
### download/files (GET)
*(Depuis la version 1.3.4)*
Télécharger un fichier ZIP contenant tous les fichiers (documents, fichiers des écritures, des membres, modules modifiés, etc.).
Exemple :
```
curl https://test:abcd@paheko.monasso.tld/api/download/files -o backup_files.zip
```
## Site web
### web/list (GET)
Renvoie la liste des pages du site web.
### web/attachment/{PAGE_URI}/{FILENAME} (GET)
Renvoie le fichier joint correspondant à la page et nom de fichier indiqués.
### web/page/{PAGE_URI} (GET)
Renvoie un objet JSON avec toutes les infos de la page donnée.
Rajouter le paramètre `?html` à l'URL pour obtenir en plus une clé `html` dans l'objet JSON qui contiendra la page au format HTML.
### web/html/{PAGE_URI} (GET)
Renvoie uniquement le contenu de la page au format HTML.
## Membres
### user/import (PUT)
Permet d'importer un fichier de tableur (CSV/XLSX/ODS) de la liste des membres, comme si c'était fait depuis l'interface de Paheko.
Cette route nécessite une clé d'API ayant les droits d'administration, car importer un fichier peut permettre de modifier l'identifiant de connexion d'un administrateur et donc potentiellement d'obtenir l'accès à l'interface d'administration.
Paheko s'attend à ce que la première est ligne du tableau contienne le nom des colonnes, et que le nom des colonnes correspond au nom des champs de la fiche membre (ou à leur nom unique). Par exemple si votre fiche membre contient les champs *Nom et prénom* et *Adresse postale*, alors le fichier fourni devra ressembler à ceci :
| Nom et prénom | Adresse postale |
| :- | :- |
| Ada Lovelace | 42 rue du binaire, 21000 DIJON |
Ou à ceci :
| nom_prenom | adresse_postale |
| :- | :- |
| Ada Lovelace | 42 rue du binaire, 21000 DIJON |
La méthode renvoie un code HTTP `200 OK` si l'import s'est bien passé, sinon un code 400 et un message d'erreur JSON dans le corps de la réponse.
Utilisez la route `user/import/preview` avant pour vérifier que l'import correspond à ce que vous attendez.
Exemple pour modifier le nom du membre n°42 :
```
echo 'numero,nom' > membres.csv
echo '42,"Nouveau nom"' >> membres.csv
curl https://test:abcd@monpaheko.tld/api/user/import -T membres.csv
```
#### Paramètres
Les paramètres sont à spécifier dans l'URL, dans la query string.
Depuis la version 1.2.8 il est possible d'utiliser un paramètre supplémentaire `mode` contenant une de ces options pour spécifier le mode d'import :
* `auto` (défaut si le mode n'est pas spécifié) : met à jour la fiche d'un membre si son numéro existe, sinon crée un membre si le numéro de membre indiqué n'existe pas ou n'est pas renseigné
* `create` : ne fait que créer de nouvelles fiches de membre, si le numéro de membre existe déjà une erreur sera produite
* `update` : ne fait que mettre à jour les fiches de membre en utilisant le numéro de membre comme référence, si le numéro de membre n'existe pas une erreur sera produite
Depuis la version 1.3.0 il est possible de spécifier :
* le nombre de lignes à ignorer avec le paramètre `skip_lines=X` : elles ne seront pas importées. Par défaut la première ligne est ignorée.
* la correspondance des colonnes avec des paramètres `column[x]` ou `x` est le numéro de la colonne (la numérotation commence à zéro), et la valeur contient le nom unique du champ de la fiche membre.
Exemple :
```
curl https://test:abcd@monpaheko.tld/api/user/import?mode=create&column[0]=nom_prenom&column[1]=code_postal&skip_lines=0 -T membres.csv
```
### user/import (POST)
Identique à la même méthode en `PUT`, mais les paramètres sont passés dans le corps de la requête, avec le fichier, dont le nom sera alors `file`.
```
curl https://test:abcd@monpaheko.tld/api/user/import \
-F mode=create \
-F 'column[0]=nom_prenom' \
-F 'column[1]=code_postal' \
-F skip_lines=0 \
-F file=@membres.csv
```
### user/import/preview (PUT)
Identique à `user/import`, mais l'import n'est pas enregistré, et la route renvoie les modifications qui seraient effectuées en important le fichier :
* `errors` : liste des erreurs d'import
* `created` : liste des membres ajoutés, chaque objet contenant tous les champs de la fiche membre qui serait créée
* `modified` : liste des membres modifiés, chaque membre aura une clé `id` et une clé `name`, ainsi qu'un objet `changed` contenant la liste des champs modifiés. Chaque champ modifié aura 2 propriétés `old` et `new`, contenant respectivement l'ancienne valeur du champ et la nouvelle.
* `unchanged` : liste des membres mentionnés dans l'import, mais qui ne seront pas affectés. Pour chaque membre une clé `name` et une clé `id` indiquant le nom et l'identifiant unique numérique du membre
Note : si `errors` n'est pas vide, alors il sera impossible d'importer le fichier avec `user/import`.
Exemple de retour :
```
{
"created": [
{
"numero": 3434351,
"nom": "Bla Bli Blu"
}
],
"modified": [
{
"id": 1,
"name": "Ada Lovelace",
"changed": {
"nom": {
"old": "Ada Lvelavce",
"new": "Ada Lovelace"
}
}
}
],
"unchanged": [
{
"id": 2,
"name": "Paul Muad'Dib"
}
]
}
```
### user/import/preview (POST)
Idem quel la méthode en `PUT` mais accepte les paramètres dans le corps de la requête (voir ci-dessus).
## Activités
### services/subscriptions/import (PUT)
_(Depuis Paheko 1.3.2)_
Permet d'importer les inscriptions des membres aux activités à partir d'un fichier CSV. Les activités et tarifs doivent déjà exister avant l'import.
Les colonnes suivantes peuvent être utilisées :
* Numéro de membre`**`
* Activité`**`
* Tarif
* Date d'inscription`**`
* Date d'expiration
* Montant à régler
* Payé ?
Les colonnes suivies de deux astérisques (`**`) sont obligatoires.
Exemple :
```
echo '"Numéro de membre","Activité","Tarif","Date d'inscription","Date d'expiration","Montant à régler","Payé ?"' > /tmp/inscriptions.csv
echo '42,"Cours de théâtre","Tarif adulte","01/09/2023","01/07/2023","123,50","Non"' >> /tmp/inscriptions.csv
curl https://test:abcd@monpaheko.tld/api/services/subscriptions/import -T /tmp/inscriptions.csv
```
## Erreurs
Paheko dispose d'un système dédié à la gestion des erreurs internes, compatible avec les formats des logiciels AirBrake et errbit.
### errors/report (POST)
Permet d'envoyer un rapport d'erreur (au format airbrake/errbit/Paheko), comme si c'était une erreur locale.
### errors/log (GET)
Renvoie le log d'erreurs système, au format airbrake/errbit ([voir la doc AirBrake pour un exemple du format](https://airbrake.io/docs/api/#create-notice-v3))
## Comptabilité
### accounting/years (GET)
Renvoie la liste des exercices.
### accounting/charts (GET)
Renvoie la liste des plans comptables.
### accounting/charts/{ID_CHART}/accounts (GET)
Renvoie la liste des comptes pour le plan comptable indiqué (voir `id_chart` dans la liste des exercices).
### accounting/years/{ID_YEAR}/journal (GET)
Renvoie le journal général des écritures de l'exercice indiqué.
Note : il est possible d'utiliser `current` comme paramètre pour `{ID_YEAR}` pour désigner l'exercice ouvert en cours. S'il y a plusieurs exercices ouverts, alors le plus ancien sera choisi.
### accounting/years/{ID_YEAR}/account/journal (GET)
Renvoie le journal des écritures d'un compte pour l'exercice indiqué.
Le compte est spécifié soit via le paramètre `code`, soit via le paramètre `id`. Exemple : `/accounting/years/4/account/journal?code=512A`
Note : il est possible d'utiliser `current` comme paramètre pour `{ID_YEAR}` pour désigner l'exercice ouvert en cours. S'il y a plusieurs exercices ouverts, alors le plus ancien sera choisi.
### accounting/transaction/{ID_TRANSACTION} (GET)
Renvoie les détails de l'écriture indiquée.
### accounting/transaction/{ID_TRANSACTION} (POST)
Modifie l'écriture indiquée. Voir plus bas le format attendu.
### accounting/transaction/{ID_TRANSACTION}/users (GET)
Renvoie la liste des membres liés à une écriture.
### accounting/transaction/{ID_TRANSACTION}/users (POST)
Met à jour la liste des membres liés à une écriture, en utilisant les ID de membres passés dans un tableau nommé `users`.
```
curl -v "http://…/api/accounting/transaction/9337/users" -F 'users[]=2'
```
### accounting/transaction/{ID_TRANSACTION}/users (DELETE)
Efface la liste des membres liés à une écriture.
### accounting/transaction/{ID_TRANSACTION}/subscriptions (GET)
(Depuis la version 1.3.6)
Renvoie la liste des inscriptions (aux activités) liées à une écriture.
### accounting/transaction/{ID_TRANSACTION}/subscriptions (POST)
(Depuis la version 1.3.6)
Met à jour la liste des inscriptions liées à une écriture, en utilisant les ID d'inscriptions passés dans un tableau nommé `subscriptions`.
```
curl -v "http://…/api/accounting/transaction/9337/subscriptions" -F 'subscriptions[]=2'
```
### accounting/transaction/{ID_TRANSACTION}/subscriptions (DELETE)
(Depuis la version 1.3.6)
Efface la liste des inscriptions liées à une écriture.
### accounting/transaction (POST)
Crée une nouvelle écriture, renvoie les détails si l'écriture a été créée. Voir plus bas le format attendu.
#### Structure pour créer / modifier une écriture
Les champs à spécifier pour créer ou modifier une écriture sont les suivants :
* `id_year`
* `date` (format YYYY-MM-DD)
* `type` peut être un type d'écriture simplifié (2 lignes) : `EXPENSE` (dépense), `REVENUE` (recette), `TRANSFER` (virement), `DEBT` (dette), `CREDIT` (créance), ou `ADVANCED` pour une écriture multi-ligne
* `amount` (uniquement pour les écritures simplifiées) : contient le montant de l'écriture
* `credit` (uniquement pour les écritures simplifiées) : contient le numéro du compte porté au crédit
* `debit` (uniquement pour les écritures simplifiées) : contient le numéro du compte porté au débit
* `lines` (pour les écritures multi-lignes) : un tableau dont chaque ligne doit contenir :
* `account` (numéro du compte) ou `id_account` (ID unique du compte)
* `credit` : montant à inscrire au crédit (doit être zéro ou non renseigné si `debit` est renseigné, et vice-versa)
* `debit` : montant à inscrire au débit
* `label` (facultatif) : libellé de la ligne
* `reference` (facultatif) : référence de la ligne (aussi appelé référence du paiement pour les écritures simplifiées)
* `id_project` : ID unique du projet à affecter
Champs optionnels :
* `reference` : numéro de pièce comptable
* `notes` : remarques (texte multi ligne)
* `id_project` : ID unique du projet à affecter (pour les écritures simplifiées uniquement)
* `payment_reference` (uniquement pour les écritures simplifiées) : référence de paiement
* `linked_users` : Tableau des IDs des membres à lier à l'écriture *(depuis 1.3.3)*
* `linked_transactions` : Tableau des IDs des écritures à lier à l'écriture *(depuis 1.3.5)*
* `linked_subscriptions` : Tableau des IDs des inscriptions à lier à l'écriture *(depuis 1.3.6)*
Exemple :
```
curl -F 'id_year=12' -F 'label=Test' -F 'date=01/02/2022' -F 'type=EXPENSE' -F 'amount=42' -F 'debit=512A' -F 'credit=601' …
```

493
doc/admin/brindille.md Normal file
View file

@ -0,0 +1,493 @@
Title: Documentation du langage Brindille dans Paheko
{{{.nav
* [Modules](modules.html)
* **[Documentation Brindille](brindille.html)**
* [Fonctions](brindille_functions.html)
* [Sections](brindille_sections.html)
* [Filtres](brindille_modifiers.html)
}}}
<<toc aside>>
# Introduction
La syntaxe utilisée dans les squelettes du site web et des modules s'appelle **Brindille**.
Si vous avez déjà fait de la programmation, elle ressemble à un mélange de Mustache, Smarty, Twig et PHP.
Son but est de permettre une grande flexibilité, sans avoir à utiliser un "vrai" langage de programmation, mais en s'en rapprochant suffisamment quand même.
## Fichiers
Un fichier texte contenant du code Brindille est appelé un **squelette**.
Seuls les fichiers ayant une des extensions `.tpl`, `.html`, `.htm`, `.skel` ou `.xml` seront traités par Brindille.
De même, les fichiers qui n'ont pas d'extension seront également traités par Brindille.
Les autres types de fichiers seront renvoyés sans traitement, comme des fichiers "bruts". En d'autres termes, il n'est pas possible de mettre du code *Brindille* dans des fichiers qui ne sont pas des fichiers textes.
# Syntaxe de base
## Variables
En programmation, une variable est une référence vers une donnée stockée en mémoire.
Dans Brindille, une variable commence par le symbole dollar `$` et suivi d'un nom.
Le nom est composé de lettres minuscules (sans accents), de chiffres et de tirets bas (`[a-z0-9_]`).
Exemples de variables :
```
$config
$compte_32
$nom_de_variable_long
```
### Types de variables
Dans Brindille, une variable peut avoir un des types suivants :
* `null` : utilisé pour une variable qui n'est pas définie, ou une variable définie qui n'a pas de valeur
* `boolean` : valeur booléenne, peut seulement avoir `true` ou `false` comme valeur
* `integer` : nombre entier (sans virgule). Exemple : `4200`.
* `float` : nombre à virgule flottante, exemple `3.14`. Leur usage est déconseillé, car les erreurs de calcul sont possibles, les ordinateurs ne sachant pas compter de manière précise avec les nombres à virgule flottante. Exemple : `0.2+0.3` est différent de `0.5`.
* `string` : chaîne de texte (aussi appelé chaîne de caractères, car c'est une suite de caractères). Exemple : `coucou`.
* `array` : tableau.
### Tableaux
Les tableaux sont une sorte de dictionnaire, ou pour chaque entrée (appelée "clé") on peut associer une valeur. qui peut être de n'importe lequel des types listés ci-dessus, y compris un autre tableau.
Les tableaux peuvent être de deux types :
1. tableau indexé (liste) : dans ce cas les clés ne sont pas choisies, on ajoute simplement des valeurs, et l'ordinateur incrémente le numéro de la clé à chaque nouvelle entrée dans le tableau. La numérotation commence au chiffre zéro.
2. tableau associatif (dictionnaire) : les clés sont des nombres ou des chaînes de texte, et permettent, comme dans un dictionnaire, de choisir la clé.
Exemple de tableau indexé :
```
[
0 => 'Texte 1',
1 => 'Texte 2'
]
```
Exemple de tableau associatif :
```
[
'un' => 'Texte 1',
'deux' => 'Texte 2'
]
```
## Affichage de variable
Une variable est affichée à l'aide de la syntaxe : `{{$date}}` affichera la valeur brute de la date par exemple : `2020-01-31 16:32:00`.
La variable peut être modifiée à l'aide de filtres de modification, qui sont ajoutés avec le symbole de la barre verticale (pipe `|`) : `{{$date|date_long}}` affichera une date au format long : `jeudi 7 mars 2021`.
Ces filtres peuvent accepter des paramètres, séparés par deux points `:`. Exemple : `{{$date|date:"d/m/Y"}}` affichera `31/01/2020`.
Par défaut la variable sera recherchée dans le contexte actuel de la section, si elle n'est pas trouvée elle sera recherchée dans le contexte parent (section parente), etc. jusqu'à trouver la variable.
### Protection contre le HTML (échappement)
Par défaut le filtre `escape` est appliqué à toutes les variables affichées, pour protéger les variables contre les injections de code HTML.
Ce filtre modifie (on dit qu'il "échappe") les caractères HTML `<>&"'` présents dans une chaîne de texte en entités HTML, évitant que le HTML éventuellement présent dans la chaîne de texte soit interprété par le navigateur.
Ce filtre est appliqué en dernier, après les autres filtres. Il est possible de contourner cet automatisme en rajoutant le filtre `escape` ou `raw` explicitement. `raw` désactive tout échappement, alors que `escape` est utilisé pour changer l'ordre d'échappement. Exemple :
```
{{:assign text = "Coucou\nça va ?" }}
{{$text|escape|nl2br}}
```
Donnera bien `Coucou<br />ça va ?`. Si on n'avait pas indiqué le filtre `escape` le résultat serait `Coucou&lt;br /&gt;ça va ?`.
### Variables de tableaux
Il est possible de faire référence à une clé d'un tableau avec la notation à points : `{{$article.date}}` renverra la clé `date` du tableau stocké dans la variable `$article`.
### Échappement des caractères spéciaux dans les chaînes de caractère
Pour inclure un caractère spécial (retour de ligne, guillemets ou apostrophe) dans une chaîne de caractère il suffit d'utiliser un antislash :
```
{{:assign text="Retour \n à la ligne"}}
{{:assign text="Utiliser des \"apostrophes\"}}
```
## Ordre de recherche des variables
Par défaut les variables sont recherchées dans l'ordre inverse, c'est à dire que sont d'abord recherchées les variables avec le nom demandé dans la section courante. Si la variable n'existe pas dans la section courante, alors elle est recherchée dans la section parente, et ainsi de suite jusqu'à ce que la variable soit trouvée, où qu'il n'y ait plus de section parente.
Prenons cet exemple :
```
{{#articles uri="Actualite"}}
<h1>{{$title}}</h1>
{{#images parent=$path limit=1}}
<img src="{{$thumb_url}}" alt="{{$title}}" />
{{/images}}
{{/articles}}
```
Dans la section `articles`, `$title` est une variable de l'article, donc la variable est celle de l'article.
Dans la section `images`, les images n'ayant pas de titre, la variable sera celle de l'article de la section parente, alors que `$thumb_url` sera lié à l'image.
## Conflit de noms de variables
Imaginons que nous voulions mettre un lien vers l'article sur l'image de l'exemple précédent :
```
{{#articles uri="Actualite"}}
<h1>{{$title}}</h1>
{{#images parent=$path limit=1}}
{{/images}}
{{/articles}}
```
Problème, ici `$url` fera référence à l'URL de l'image elle-même, et non pas l'URL de l'article.
La solution est d'ajouter un point au début du nom de variable : `{{$.url}}`.
Un point au début d'un nom de variable signifie que la variable est recherchée à partir de la section précédente. Il est possible d'utiliser plusieurs points, chaque point correspond à un niveau à remonter. Ainsi `$.url` cherchera la variable dans la section parente (et ses sections parentes si elle n'existe pas, etc.). De même, `$..url` cherchera dans la section parente de la section parente.
## Création manuelle de variable
### Variable simple
La création d'une variable se fait via l'appel de la fonction `{{:assign}}`.
Exemple :
```
{{:assign source='wiki'}}
{{* est identique à : *}}
{{:assign var='source' value='wiki'}}
```
Un deuxième appel à `{{:assign}}` avec le même nom de variable écrase la valeur précédente
```
{{:assign var='source' value='wiki'}}
{{:assign var='source' value='documentation'}}
{{$source}}
{{* => Affiche documentation *}}
```
### Nom de variable dynamique
Il est possible de créer une variable dont une partie du nom est dynamique.
```
{{:assign type='user'}}
{{:assign var='allowed_%s'|args:$type value='jeanne'}}
{{:assign type='side'}}
{{:assign var='allowed_%s'|args:$type value='admin'}}
{{$allowed_user}} => jeanne
{{$allowed_side}} => admin
```
[Documentation complète de la fonction {{:assign}}](brindille_functions.html#assign).
### Tableaux *(array)*
Pour créer des tableaux, il suffit d'utiliser des points `.` dans le nom de la variable (ex : `colors.yellow`). Il n'y a pas besoin d'initialiser le tableau avant de le remplir.
```
{{:assign var='colors.admin' value='blue'}}
{{:assign var='colors.website' value='grey'}}
{{:assign var='colors.debug' value='yellow'}}
```
On accède ensuite à la valeur d'un élément du tableau avec la même syntaxe : `{{$colors.website}}`
Méthode rapide de création du même tableau :
```
{{:assign var='colors' admin='blue' website='grey' debug='yellow'}}
```
Pour ajouter un élément à la suite du tableau sans spécifier de clef *(push)*, il suffit de terminer le nom de la variable par un point `.` sans suffixe.
Exemple :
```
{{* Ajouter les valeurs 17, 43 et 214 dans $processed_ids *}}
{{:assign var='processed_ids.' value=17}}
{{:assign var='processed_ids.' value=43}}
{{:assign var='processed_ids.' value=214}}
```
Donnera le tableau suivant :
```
[
0 => 17,
1 => 43,
2 => 214
]
```
#### Clef dynamique de tableau
Il est possible d'accéder dynamiquement à un des éléments d'un tableau de la manière suivante :
```
{{:assign location='admin'}}
{{:assign var='location_color' from='colors.%s'|args:$location}}
{{$location_color}} => blue
```
Exemple plus complexe :
```
{{:assign var='type_whitelist.text' value=1}}
{{:assign var='type_whitelist.html' value=1}}
{{#foreach from=$documents item='document'}}
{{:assign var='allowed' value='type_whitelist.%s'|args:$document->type}}
{{if $allowed !== null}}
{{:include file='document/'|cat:$type:'.tpl' keep='document'}}
{{/if}}
{{/foreach}}
```
Il est également possible de créer un membre dynamique d'un tableau en conjuguant les syntaxes précédentes.
Exemple :
```
{{:assign var='type_whitelist.%s'|args:$type value=1}}
```
## Conditions
Il est possible d'utiliser des conditions de type **"si"** (`if`), **"sinon si"** (`elseif`) et **"sinon"** (`else`). Celles-ci sont terminées par un block **"fin si"** (`/if`).
```
{{if $date|date:"%Y" > 2020}}
La date est en 2020
{{elseif $article.status == 'draft'}}
La page est un brouillon
{{else}}
Autre chose.
{{/if}}
```
Une condition peut être évaluée comme *vraie*, dans ce cas la partie qui suit le bloc `{{if …}}` sera exécutée.
Si la condition est évaluée comme *fausse*, alors la partie qui suit le bloc `{{if …}}` ne sera pas exécutée. Dans ce cas, soit une condition `{{elseif …}}` suivante est vraie et exécutée, mais sinon c'est le contenu du bloc `{{else}}` qui est exécuté et affiché.
Dans une condition on peut utiliser :
* une variable : `$nom_variable`
* une variable avec des filtres : `$nom_variable|filtre1:parametre1`
* une valeur (nombre, constante) : `42`, `-42`, `42.02` `null`, `true`, `false`
* des opérateurs de comparaison
* des opérateurs logiques
Attention : on ne peut pas grouper les conditions avec des parenthèses.
Les comparaisons supportées sont les suivantes :
| Opérateur de comparaison | Explication |
| :- | :- |
| `==` | égalité faible, ne prend pas en compte le type : `1 == true` et `2 == 2.00` serons évalués comme vrais |
| `===` | égalité forte, prend en compte le type : `1 === 1` sera vrai, mais `1 === true` sera faux |
| `!=` | différent de, en comparaison faible |
| `!==` | différent de, en comparaison forte |
| `>` | supérieur à |
| `>=` | supérieur ou égal à |
| `<` | inférieur à |
| `<=` | inférieur ou égal à |
Il est aussi possible de précéder une variable de l'opérateur `!`, c'est un raccourci pour `$variable == false`.
Voir [les opérateurs de comparaison PHP pour plus de détails](https://www.php.net/manual/fr/language.operators.comparison.php).
Les opérateurs logiques supportés sont :
| Opérateur | Explication |
| :- | :- |
| `&&` | Vrai si les conditions à gauche et à droite sont vraies |
| `||` | Vrai si une des conditions à gauche ou à droite est vraie |
Exemples :
* `false && true` : sera évalué comme faux
* `false || true` : sera évalué comme vrai
### Tester si une variable existe
Brindille ne fait pas de différences entre une variable qui n'existe pas, et une variable définie à `null`.
On peut donc tester l'existence d'une variable en la comparant à `null` comme ceci :
```
{{if $session !== null}}
Session en cours pour l'utilisateur/trice {{$session.user.name}}.
{{else}}
Session inexistante.
{{/if}}
```
## Fonctions
### Fonctions natives
Une fonction va répondre à certains paramètres et renvoyer un résultat ou réaliser une action.
**Un bloc de fonction commence par le signe deux points `:`.**
```
{{:http code=404}}
```
Contrairement aux autres types de blocs, et comme pour les variables, il n'y a pas de bloc fermant (avec un slash `/`).
## Sections
Une section est une partie de la page qui sera répétée une fois, plusieurs fois, ou zéro fois, selon ses paramètres et le résultat (c'est une "boucle"). Une section commence par un bloc avec un signe hash (`#`) et se termine par un bloc avec un slash (`/`).
Un exemple simple avec une section qui n'aura qu'une seule répétition :
```
{{#categories uri=$_GET.uri}}
<h1>{{$title}}</h1>
{{/categories}}
```
Il est possible d'utiliser une condition `{{else}}` avant la fin du bloc pour avoir du contenu alternatif si la section ne se répète pas (dans ce cas si aucune catégorie ne correspond au critère).
Un exemple de sous-section
```
{{#categories uri=$_GET.uri}}
<h1>{{$title}}</h1>
{{#articles parent=$path order="published DESC" limit="10"}}
<h2></h2>
<p>{{$content|truncate:600:"..."}}</p>
{{else}}
<p>Aucun article trouvé.</p>
{{/articles}}
{{/categories}}
```
Voir la référence des sections pour voir quelles sont les sections possibles et quel est leur comportement.
## Bloc litéral
Pour qu'une partie du code ne soit pas interprété, pour éviter les conflits avec certaines syntaxes, il est possible d'utiliser un bloc `literal` :
```
{{literal}}
<script>
// Ceci ne sera pas interprété
function test (a) {{
}}
</script>
{{/literal}}
```
## Commentaires
Les commentaires sont figurés dans des blocs qui commencent et se terminent par une étoile (`*`) :
```
{{* Ceci est un commentaire
Il sera supprimé du résultat final
Il peut contenir du code qui ne sera pas interprété :
{{if $test}}
OK
{{/if}}
*}}
```
# Liste des variables définies par défaut
Ces variables sont définies tout le temps :
| Nom de la variable | Valeur |
| :- | :- |
| `$_GET` | Tableau contenant tous les paramètres passés dans la chaîne de requêtre de l'URL. |
| `$_POST` | Tableau de tous les éléments de formulaire envoyés lors d'une requête POST. |
| `$root_url` | Adresse racine du site web Paheko. |
| `$request_url` | Adresse de la page courante. |
| `$admin_url` | Adresse de la racine de l'administration Paheko. |
| `$visitor_lang` | Langue préférée du visiteur, sur 2 lettres (exemple : `fr`, `en`, etc.). |
| `$logged_user` | Informations sur le membre actuellement connecté dans l'administration (vide si non connecté). |
| `$dialog` | Vaut `TRUE` si la page est dans un dialogue (iframe sous forme de pop-in dans l'administration). |
| `$now` | Contient la date et heure courante. |
| `$config.org_name` | Nom de l'association |
| `$config.org_email` | Adresse e-mail de l'association |
| `$config.org_phone` | Numéro de téléphone de l'association |
| `$config.org_address` | Adresse postale de l'association |
| `$config.org_web` | Adresse du site web de l'association |
| `$config.files.logo` | Adresse du logo de l'association, si définit dans la personnalisation |
| `$config.files.favicon` | Adresse de l'icône de favoris de l'association, si défini dans la personnalisation |
| `$config.files.signature` | Adresse de l'image de signature, si défini dans la personnalisation |
À celles-ci s'ajoutent [les variables spéciales des modules](modules.html#variables_speciales) lorsque le script est chargé dans un module.
# Erreurs
Si une erreur survient dans un squelette, que ça soit au niveau d'une erreur de syntaxe, ou une erreur dans une fonction, filtre ou section, alors elle sera affichée selon les règles suivantes :
* si le membre connecté est administrateur, une erreur est affichée avec le code du squelette ;
* sinon l'erreur est affichée sans le code.
# Avertissement sur la sécurité des requêtes SQL
Attention, en utilisant la section `{{#select ...}}`, ou une des sections SQL (voir plus bas), avec des paramètres qui ne seraient pas protégés, il est possible qu'une personne mal intentionnée ait accès à des parties de la base de données à laquelle vous ne désirez pas donner accès.
Pour protéger contre cela il est essentiel d'utiliser les paramètres nommés.
Exemple de requête dangereuse :
```
{{#sql select="*" tables="users" where="id = %s"|args:$_GET.id}}
...
{{/sql}}
```
On se dit que la requête finale sera donc : `SELECT * FROM users WHERE id = 42;` si le numéro 42 est passé dans le paramètre `id` de la page.
Imaginons qu'une personne mal-intentionnée indique dans le paramètre `id` de la page la chaîne de caractère suivante : `0 OR 1`. Dans ce cas la requête exécutée sera `SELECT * FROM users WHERE id = 0 OR 1;`. Cela aura pour effet de lister tous les membres, au lieu d'un seul.
Pour protéger contre cela il convient d'utiliser un paramètre nommé :
```
{{#sql select="*" tables="users" where="id = :id" :id=$_GET.id}}
```
Dans ce cas la requête malveillante générée sera `SELECT * FROM users WHERE id = '0 OR 1';`. Ce qui aura pour effet de ne lister aucun membre.
## Mesures prises pour la sécurité des données
Dans Brindille, il n'est pas possible de modifier ou supprimer des éléments dans la base de données avec les requêtes SQL directement. Seules les requêtes SQL en lecture (`SELECT`) sont permises.
Cependant certaines fonctions permettent de modifier ou créer des éléments précis (écritures par exemple), ce qui peut avoir un effet de remplir ou modifier des données par une personne mal-intentionnée, donc attention à leur utilisation.
Les autres mesures prises sont :
* impossibilité d'accéder à certaines données sensibles (mot de passe, logs de connexion, etc.)
* incitation forte à utiliser les paramètres nommés dans la documentation
* protection automatique des variables dans la section `{{#select}}`
* fourniture de fonctions pour protéger les chaînes de caractères contre l'injection SQL

View file

@ -0,0 +1,828 @@
Title: Référence des fonctions Brindille
{{{.nav
* [Modules](modules.html)
* [Documentation Brindille](brindille.html)
* **[Fonctions](brindille_functions.html)**
* [Sections](brindille_sections.html)
* [Filtres](brindille_modifiers.html)
}}}
<<toc aside>>
# Fonctions généralistes
## assign
Permet d'assigner une valeur dans une variable.
| Paramètre | Optionnel / obligatoire ? | Fonction |
| :- | :- | :- |
| `.` | optionnel | Assigner toutes les variables du contexte (section) actuel |
| `var` | optionnel | Nom de la variable à créer ou modifier |
| `value` | optionnel | Valeur de la variable |
| `from` | optionnel | Recopier la valeur depuis la variable ayant le nom fourni dans ce paramètre. |
Tous les autres paramètres sont considérés comme des variables à assigner.
Exemple :
```
{{:assign blabla="Coucou"}}
{{$blabla}}
```
Il est possible d'assigner toutes les variables d'une section dans une variable en utilisant le paramètre point `.` (`.="nom_de_variable"`). Cela permet de capturer le contenu d'une section pour le réutiliser à un autre endroit.
```
{{#pages uri="Informations" limit=1}}
{{:assign .="infos"}}
{{/pages}}
{{$infos.title}}
```
Il est aussi possible de remonter dans les sections parentes en utilisant plusieurs points. Ainsi deux points remonteront à la section parente, trois points à la section parente de la section parente, etc.
```
{{#foreach from=$infos item="info"}}
{{#foreach from=$info item="sous_info"}}
{{if $sous_info.titre == 'Coucou'}}
{{:assign ..="info_importante"}}
{{/if}}
{{/foreach}}
{{/foreach}}
{{$info_importante.titre}}
```
En utilisant le paramètre spécial `var`, tous les autres paramètres passés sont ajoutés à la variable donnée en valeur :
```
{{:assign var="tableau" label="Coucou" name="Pif le chien"}}
{{$tableau.label}}
{{$tableau.name}}
```
De la même manière on peut écraser une variable avec le paramètre spécial `value`:
```
{{:assign var="tableau" value=$infos}}
```
Il est également possible de créer des tableaux avec la syntaxe `.` dans le nom de la variable :
```
{{:assign var="liste.comptes.530" label="Caisse"}}
{{:assign var="liste.comptes.512" label="Banque"}}
{{#foreach from=$liste.comptes}}
{{$key}} = {{$value.label}}
{{/foreach}}
```
Il est possible de rajouter des éléments à un tableau simplement en utilisant un point seul :
```
{{:assign var="liste.comptes." label="530 - Caisse"}}
{{:assign var="liste.comptes." label="512 - Banque"}}
```
Enfin, il est possible de faire référence à une variable de manière dynamique en utilisant le paramètre spécial `from` :
```
{{:assign var="tableau" a="Coucou" b="Test !"}}
{{:assign var="titre" from="tableau.%s"|args:"b"}}
{{$titre}} -> Affichera "Test !", soit la valeur de {{$tableau.b}}
```
## break
Interrompt une section.
## continue
Passe à l'itération suivante d'une section. Le code situé entre cette instruction et la fin de la section ne sera pas exécuté.
```
{{#foreach from=$list item="event"}}
{{if $event.date == '2023-01-01'}}
{{:continue}}
{{/if}}
{{$event.title}}
{{/foreach}}
```
Il est possible de passer à l'itération suivante d'une section parente en utilisant un chiffre en paramètre :
```
{{#foreach from=$list item="event"}}
{{$event.title}}
{{#foreach from=$event.people item="person"}}
{{if $person.name == 'bohwaz'}}
{{:continue 2}}
{{/if}}
- {{$person.name}}
{{/foreach}}
{{/foreach}}
```
## debug
Cette fonction permet d'afficher le contenu d'une ou plusieurs variables :
```
{{:debug test=$title}}
```
Affichera :
```
array(1) {
["test"] => string(6) "coucou"
}
```
Si aucun paramètre n'est spécifié, alors toutes les variables définies sont renvoyées. Utile pour découvrir quelles sont les variables accessibles dans une section par exemple.
## error
Affiche un message d'erreur et arrête le traitement à cet endroit.
| Paramètre | Optionnel / obligatoire ? | Fonction |
| :- | :- | :- |
| `message` | **obligatoire** | Message d'erreur à afficher |
Exemple :
```
{{if $_POST.nombre != 42}}
{{:error message="Le nombre indiqué n'est pas 42"}}
{{/if}}
```
## form_errors
Affiche les erreurs du formulaire courant (au format HTML).
## http
Permet de modifier les entêtes HTTP renvoyés par la page. Cette fonction doit être appelée au tout début du squelette, avant tout autre code ou ligne vide.
| Paramètre | Optionnel / obligatoire ? | Fonction |
| :- | :- | :- |
| `code` | *optionnel* | Modifie le code HTTP renvoyé. [Liste des codes HTTP](https://fr.wikipedia.org/wiki/Liste_des_codes_HTTP) |
| `redirect` | *optionnel* | Rediriger vers l'adresse URL indiquée en valeur. |
| `type` | *optionnel* | Modifie le type MIME renvoyé |
| `download` | *optionnel* | Force la page à être téléchargée sous le nom indiqué. |
| `inline` | *optionnel* | Force la page à être affichée, et peut ensuite être téléchargée sous le nom indiqué (utile pour la généraion de PDF : permet d'afficher le PDF dans le navigateur avant de le télécharger). |
Note : si le type `application/pdf` est indiqué (ou juste `pdf`), la page sera convertie en PDF à la volée. Il est possible de forcer le téléchargement du fichier en utilisant le paramètre `download`.
Exemples :
```
{{:http code=404}}
{{:http redirect="/Nos-Activites/"}}
{{:http redirect="https://mon-site-web.tld/"}}
{{:http type="application/svg+xml"}}
{{:http type="pdf" download="liste_membres_ca.pdf"}}
```
## include
Permet d'inclure un autre squelette.
Paramètres :
| Paramètre | Optionnel / obligatoire ? | Fonction |
| :- | :- | :- |
| `file` | **obligatoire** | Nom du squelette à inclure |
| `keep` | *optionnel* | Liste de noms de variables à conserver |
| `capture` | *optionnel* | Si renseigné, au lieu d'afficher le squelette, son contenu sera enregistré dans la variable de ce nom. |
| … | *optionnel* | Tout autre paramètre sera utilisé comme variable qui n'existea qu'à l'intérieur du squelette inclus. |
```
{{* Affiche le contenu du squelette "navigation.html" dans le même répertoire que le squelette d'origine *}}
{{:include file="./navigation.html"}}
```
Par défaut, les variables du squelette parent sont transmis au squelette inclus, mais les variables définies dans le squelette inclus ne sont pas transmises au squelette parent. Exemple :
```
{{* Squelette page.html *}}
{{:assign title="Super titre !"}}
{{:include file="./_head.html"}}
{{$nav}}
```
```
{{* Squelette _head.html *}}
<h1>{{$title}}</h1>
{{:assign nav="Accueil > %s"|args:$title}}
```
Dans ce cas, la dernière ligne du premier squelette (`{{$nav}}`) n'affichera rien, car la variable définie dans le second squelette n'en sortira pas. Pour indiquer qu'une variable doit être transmise au squelette parent, il faut utiliser le paramètre `keep`:
```
{{:include file="./_head.html" keep="nav"}}
```
On peut spécifier plusieurs noms de variables, séparés par des virgules, et utiliser la notation à points :
```
{{:include file="./_head.html" keep="nav,article.title,name"}}
{{$nav}}
{{$article.title}}
{{$name}}
```
On peut aussi capturer le résultat d'un squelette dans une variable :
```
{{:include file="./_test.html" capture="test"}}
{{:assign var="test" value=$test|replace:'TITRE':'Ceci est un titre'}}
{{$test}}
```
Il est possible d'assigner de nouvelles variables au contexte du include en les déclarant comme paramètres tout comme on le ferait avec `{{:assign}}` :
```
{{:include file="./_head.html" title='%s documentation'|args:$doc.label visitor=$user}}
```
## captcha
Permet de générer une question qui doit être répondue correctement par l'utilisateur pour valider une action. Utile pour empêcher les robots spammeurs d'effectuer une action.
L'utilisation simplifiée utilise un de ces deux paramètres :
| Paramètre | Fonction |
| :- | :- |
| `html` | Si `true`, crée un élément de formulaire HTML et le texte demandant à l'utilisateur de répondre à la question |
| `verify` | Si `true`, vérifie que l'utilisateur a correctement répondu à la question |
L'utilisation avancée utilise d'abord ces deux paramètres :
| Paramètre | Fonction |
| :- | :- |
| `assign_hash` | Nom de la variable où assigner le hash (à mettre dans un `<input type="hidden" />`) |
| `assign_number` | Nom de la variable où assigner le nombre de la question (à afficher à l'utilisateur) |
Puis on vérifie :
| Paramètre | Fonction |
| :- | :- |
| `verify_hash` | Valeur qui servira comme hash de vérification (valeur du `<input type="hidden" />`) |
| `verify_number` | Valeur qui représente la réponse de l'utilisateur |
| `assign_error` | Si spécifié, le message d'erreur sera placé dans cette variable, sinon il sera affiché directement. |
Exemple :
```
{{if $_POST.send}}
{{:captcha verify_hash=$_POST.h verify_number=$_POST.n assign_error="error"}}
{{if $error}}
<p class="alert">Mauvaise réponse</p>
{{else}}
...
{{/if}}
{{/if}}
<form method="post" action="">
{{:captcha assign_hash="hash" assign_number="number"}}
<p>Merci de recopier le nombre suivant en chiffres : <tt>{{$number}}</tt></p>
<p>
<input type="text" name="n" placeholder="1234" />
<input type="hidden" name="h" value="{{$hash}}" />
<input type="submit" name="send" />
</p>
</form>
```
## mail
Permet d'envoyer un e-mail à une ou des adresses indiquées (sous forme de tableau).
Restrictions :
* le message est toujours envoyé en format texte ;
* l'expéditeur est toujours l'adresse de l'association ;
* l'envoi est limité à une seule adresse e-mail externe (adresse qui n'est pas celle d'un membre) dans une page ;
* l'envoi est limité à maximum 10 adresses e-mails internes (adresses de membres) dans une page ;
* un message envoyé à une adresse e-mail externe ne peut pas contenir une adresse web (`https://...`) autre que celle de l'association.
Note : il est également conseillé d'utiliser la fonction `captcha` pour empêcher l'envoi de spam.
| Paramètre | Obligatoire ou optionnel ? | Fonction |
| :- | :- | :- |
| `to` | **obligatoire** | Adresse email destinataire (seule l'adresse e-mail elle-même est acceptée, pas de nom) |
| `subject` | **obligatoire** | Sujet du message |
| `body` | **obligatoire** | Corps du message |
| `block_urls` | *optionnel* | (`true` ou `false`) Permet de bloquer l'envoi si le message contient une adresse `https://…` |
| `attach_file` | *optionnel* | Chemin vers un ou plusieurs documents à joindre au message (situé dans les documents) |
| `attach_from` | *optionnel* | Chemin vers un ou plusieurs squelettes à joindre au message (par exemple pour joindre un document généré) |
Pour le destinataire, il est possible de spécifier un tableau :
```
{{:assign var="recipients[]" value="membre1@framasoft.net"}}
{{:assign var="recipients[]" value="membre2@chatons.org"}}
{{:mail to=$recipients subject="Coucou" body="Contenu du message\nNouvelle ligne"}}
```
Exemple de formulaire de contact :
```
{{if !$_POST.email|check_email}}
<p class="alert">L'adresse e-mail indiquée est invalide.</p>
{{elseif $_POST.message|trim == ''}}
<p class="alert">Le message est vide</p>
{{elseif $_POST.send}}
{{:captcha verify=true}}
{{:mail to=$config.org_email subject="Formulaire de contact" body="%s a écrit :\n\n%s"|args:$_POST.email:$_POST.message block_urls=true}}
<p class="ok">Votre message nous a bien été transmis !</p>
{{/if}}
<form method="post" action="">
<dl>
<dt><label>Votre e-mail : <input type="email" required name="email" /></label></dt>
<dt><label>Votre message : <textarea required name="message" cols="50" rows="5"></textarea></label></dt>
<dt>{{:captcha html=true}}</dt>
</dl>
<p><input type="submit" name="send" value="Envoyer !" /></p>
</form>
```
## redirect
Redirige vers une nouvelle page.
Avec le paramètre `force`, si la page actuelle est ouverte dans une fenêtre modale (grâce à la cible `_dialog`), alors la fenêtre modale est fermée, et la redirection se passe dans la page parente.
Avec le paramètre `to`, si la page actuelle est ouverte dans une fenêtre modal (grâce à la cible `_dialog`), alors la fenêtre modale est fermée, et la page parente est rechargée. Si la page n'est pas ouvertre dans dans une fenêtre modale, la redirection est effectuée.
Seules les adresses internes sont acceptées, il n'est pas possible de rediriger vers une adresse extérieure.
| Paramètre | Obligatoire ou optionnel ? | Fonction |
| :- | :- | :- |
| `force` | optionnel | Adresse de redirection forcée |
| `to` | optionnel | Adresse de redirection si pas dans une fenêtre modale |
Si `to=null` est utilisé, alors la fenêtre modale sera fermée. Ou, si la page n'est pas dans une fenêtre modale, la page courante sera rechargée.
## api
Permet d'appeler l'API de Paheko, que ça soit sur l'instance locale, en cours, ou une autre instance externe.
Voir la [documentation de l'API](https://paheko.cloud/api) pour la liste des fonctions disponibles.
| Paramètre | Obligatoire ou optionnel ? | Fonction |
| :- | :- | :- |
| `method` | obligatoire | Méthode de requête : `GET`, `POST`, etc. |
| `path` | obligatoire | Chemin de la méthode de l'API à appeler. |
| `fail` | optionnel | Booléen. Si `true`, alors une erreur sera affichée si la requête échoue. Si `false`, aucune erreur ne sera affichée. Défaut : `true`. |
| `assign` | optionnel | Capturer le résultat dans cette variable. |
| `assign_code` | optionnel | Capturer le code de retour dans cette variable. |
Par défaut, les requêtes sont réalisées sur la base de données locale, dans ce cas les paramètres suivants sont également disponibles :
| Paramètre | Obligatoire ou optionnel ? | Fonction |
| :- | :- | :- |
| `access` | optionnel | Niveau d'autorisation de l'API (défaut : `admin`). |
```
{{:assign var="users." value=42}}
{{:api
method="POST"
path="accounting/transaction"
assign="result"
id_year=1
type="revenue"
date="01/01/2023"
label="Don de Ada Lovelace"
reference="DON-0001"
payment_reference="Credit Mutuel 00042"
amount="51,49"
debit="756"
credit="512A"
linked_users=$users
}}
L'écriture n°{{$result.id}} a été créée.
```
Mais cette fonction permet également d'appeler une API Paheko distante, dans ce cas les paramètres suivants sont nécessaires :
| Paramètre | Obligatoire ou optionnel ? | Fonction |
| :- | :- | :- |
| `url` | obligatoire | Adresse HTTP de l'instance Paheko distante. |
| `user` | obligatoire | Identifiant d'accès à l'API distante. |
| `password` | obligatoire | Mot de passe d'accès à l'API distante. |
```
{{:api
method="POST"
path="sql"
sql="SELECT * FROM users;"
url="https://mon-asso.paheko.cloud/"
user="zmgyfr1qnm"
password="OAqFTLFzujJWr6lLn1Mu7w"
assign="result"
assign_code="code"
fail=false
}}
{{if $code == 200}}
Il y a {{$result.count}} résultats.
{{else}}
La requête a échoué : code {{$code}} — {{$result.error}}
{{/if}}
```
# Fonctions relatives aux Modules
## save
Enregistre des données, sous la forme d'un document, dans la base de données, pour le module courant.
| Paramètre | Obligatoire ou optionnel ? | Fonction |
| :- | :- | :- |
| `key` | optionnel | Clé unique du document |
| `id` | optionnel | Numéro unique du document |
| `validate_schema` | optionnel | Fichier de schéma JSON à utiliser pour valider les données avant enregistrement |
| `validate_only` | optionnel | Liste des paramètres à valider (par exemple pour ne faire qu'une mise à jour partielle), séparés par des virgules. |
| `assign_new_id` | optionnel | Si renseigné, le nouveau numéro unique du document sera indiqué dans cette variable. |
| … | optionnel | Autres paramètres : traités comme des valeurs à enregistrer dans le document |
Si ni `key` ni `id` ne sont indiqués, un nouveau document sera créé avec un nouveau numéro (ID) unique.
Si le document indiqué existe déjà, il sera mis à jour. Les valeurs nulles (`NULL`) seront effacées.
```
{{:save key="facture_43" nom="Atelier mobile" montant=250}}
```
Enregistrera dans la base de données le document suivant sous la clé `facture_43` :
```
{"nom": "Atelier mobile", "montant": 250}
```
Exemple de mise à jour :
```
{{:save key="facture_43" montant=300}}
```
Exemple de récupération du nouvel ID :
```
{{:save titre="Coucou !" assign_new_id="id"}}
Le document n°{{$id}} a bien été enregistré.
```
### Validation avec un schéma JSON
```
{{:save titre="Coucou" texte="Très long" validate_schema="./document.schema.json"}}
```
Pour ne valider qu'une partie du schéma, par exemple si on veut faire une mise à jour du document :
```
{{:save key="test" titre="Coucou" validate_schema="./document.schema.json" validate_only="titre"}}
```
## delete
Supprime un document lié au module courant.
| Paramètre | Obligatoire ou optionnel ? | Fonction |
| :- | :- | :- |
| `key` | optionnel | Clé unique du document |
| `id` | optionnel | Numéro unique du document |
Il est possible de spécifier d'autres paramètres, ou une clause `where` et des paramètres dont le nom commence par deux points.
* Supprimer le document avec la clé `facture_43` : `{{:delete key="facture_43"}}`
* Supprimer le document avec la clé `ABCD` et dont la propriété `type` du document correspond à la valeur `facture` : `{{:delete key="ABCD" type="facture"}}`
* Supprimer tous les documents : `{{:delete}}`
* Supprimer tous les documents ayant le type `facture` : `{{:delete type="facture"}}`
* Supprimer tous les documents de type `devis` ayant une date dans le passé : `{{:delete :type="devis" where="$$.type = :type AND $$.date < datetime()"}}`
## read
Lire un fichier stocké dans les fichiers du code du module.
| Paramètre | Obligatoire ou optionnel ? | Fonction |
| :- | :- | :- |
| `file` | obligatoire | Chemin du fichier à lire |
| `assign` | optionnel | Variable dans laquelle placer le contenu du fichier. |
Si le paramètre `assign` n'est pas utilisé, le contenu du fichier sera affiché directement.
Exemple pour lire un fichier JSON :
```
{{#read file="baremes.json" assign="baremes"}}
{{:assign baremes=$baremes|json_decode}}
Barème kilométrique pour une voiture de 3 CV : {{$baremes.voiture.3cv}}
```
Exemple pour lire un fichier CSV :
```
{{#read file="baremes.csv" assign="baremes"}}
{{:assign baremes=$baremes|trim|explode:"\n"}}
{{#foreach from=$baremes item="line"}}
{{:assign bareme=$line|str_getcsv}}
Nom du barème : {{$bareme.0}}
Calcul : {{$bareme.1}}
{{/foreach}}
```
## admin_header
Affiche l'entête de l'administration de l'association.
| Paramètre | Obligatoire ou optionnel ? | Fonction |
| :- | :- | :- |
| `title` | *optionnel* | Titre de la page |
| `layout` | *optionnel* | Aspect de la page. Peut être `public` pour une page publique simple (sans le menu), ou `raw` pour une page vierge (sans aucun menu ni autre élément). Défaut : vide (affichage du menu) |
| `current` | *optionnel* | Indique quel élément dans le menu de gauche doit être marqué comme sélectionné |
| `custom_css` | *optionnel* | Fichier CSS supplémentaire à appeler dans le `<head>` |
```
{{:admin_header title="Gestion des dons" current="acc"}}
```
Liste des choix possibles pour `current` :
* `home` : menu Accueil
* `users` : menu Membres
* `users/new` : sous-menu "Ajouter" de Membres
* `users/services` : sous-menu "Activités et cotisations" de Membres
* `users/mailing` : sous-menu "Message collectif" de Membres
* `acc` : menu Comptabilité
* `acc/new` : sous-menu "Saisie" de Comptabilité
* `acc/accounts` : sous-menu "Comptes"
* `acc/simple` : sous-menu "Suivi des écritures"
* `acc/years` : sous-menu "Exercices et rapports"
* `docs` : menu Documents
* `web` : menu Site web
* `config` : menu Configuration
* `me` : menu "Mes infos personnelles"
* `me/services` : sous-menu "Mes activités et cotisations"
Exemple d'utilisation de `custom_css` depuis un module :
```
{{:admin_header title="Mon module" custom_css="./style.css"}}
```
## admin_footer
Affiche le pied de page de l'administration de l'association.
```
{{:admin_footer}}
```
## delete_form
Affiche un formulaire demandant la confirmation de suppression d'un élément.
| Paramètre | Obligatoire ou optionnel ? | Fonction |
| :- | :- | :- |
| `legend` | **obligatoire** | Libellé de l'élément `<legend>` du formulaire |
| `warning` | **obligatoire** | Libellé de la question de suppression (en gros en rouge) |
| `alert` | *optionnel* | Message d'alerte supplémentaire (bloc jaune) |
| `info` | *optionnel* | Informations liées à la suppression (expliquant ce qui va être impacté par la suppression) |
| `confirm` | *optionnel* | Libellé de la case à cocher pour la suppression, si ce paramètre est absent ou `NULL`, la case à cocher ne sera pas affichée. |
Le formulaire envoie un `POST` avec le bouton ayant le nom `delete`. Si le paramètre `confirm` est renseigné, alors la case à cochée aura le nom `confirm_delete`.
Exemple :
```
{{#load id=$_GET.id assign="invoice"}}
{{else}}
{{:error message="Facture introuvable"}}
{{/load}}
{{#form on="delete"}}
{{if !$_POST.confirm_delete}}
{{:error message="Merci de cocher la case"}}
{{/if}}
{{:delete id=$invoice.id}}
{{/form}}
{{:form_errors}}
{{:delete_form
legend="Suppression d'une facture"
warning="Supprimer la facture n°%d ?"|args:$invoice.id
info="Le devis lié sera également supprimé"
alert="La facture sera définitivement perdue !"
confirm="Cocher cette case pour confirmer la suppression de la facture"
}}
```
## input
Crée un champ de formulaire HTML. Cette fonction est une extension à la balise `<input>` en HTML, mais permet plus de choses.
| Paramètre | Obligatoire ou optionnel ? | Fonction |
| :- | :- | :- |
| `name` | **obligatoire** | Nom du champ |
| `type` | **obligatoire** | Type de champ |
| `required` | *optionnel* | Mettre à `true` si le champ est obligatoire |
| `label` | *optionnel* | Libellé du champ |
| `help` | *optionnel* | Texte d'aide, affiché sous le champ |
| `default` | *optionnel* | Valeur du champ par défaut, si le formulaire n'a pas été envoyé, et que la valeur dans `source` est vide |
| `source` | *optionnel* | Source de pré-remplissage du champ. Si le nom du champ est `montant`, alors la valeur de `[source].montant` sera affichée si présente. |
Si `label` ou `help` sont spécifiés, le champ sera intégré à une balise HTML `<dd>`, et le libellé sera intégré à une balise `<dt>`. Dans ce cas il faut donc que le champ soit dans une liste `<dl>`. Si ces deux paramètres ne sont pas spécifiés, le champ sera le seul tag HTML.
```
<dl>
{{:input name="amount" type="money" label="Montant" required=true}}
</dl>
```
Note : le champ aura comme `id` la valeur `f_[name]`. Ainsi un champ avec `amount` comme `name` aura `id="f_amount"`.
### Valeur du champ
La valeur du champ est remplie avec :
* la valeur dans `$_POST` qui correspond au `name` ;
* sinon la valeur dans `source` (tableau) avec le même nom (exemple : `$source[name]`) ;
* sinon la valeur de `default` est utilisée.
Note : le paramètre `value` n'est pas supporté sauf pour checkbox et radio.
### Types de champs supportés
* les types classiques de `input` en HTML : text, search, email, url, file, date, checkbox, radio, password, etc.
* Note : pour checkbox et radio, il faut utiliser le paramètre `value` en plus pour spécifier la valeur.
* `textarea`
* `money` créera un champ qui attend une valeur de monnaie au format décimal
* `datetime` créera un champ date et un champ texte pour entrer l'heure au format `HH:MM`
* `radio-btn` créera un champ de type radio mais sous la forme d'un gros bouton
* `select` crée un sélecteur de type `<select>`. Dans ce cas il convient d'indiquer un tableau associatif dans le paramètre `options`.
* `select_groups` crée un sélecteur de type `<select>`, mais avec des `<optgroup>`. Dans ce cas il convient d'indiquer un tableau associatif à deux niveaux dans le paramètre `options`.
* `list` crée un champ permettant de sélectionner un ou des éléments (selon si le paramètre `multiple` est `true` ou `false`) dans un formulaire externe. Le paramètre `can_delete` indique si l'utilisateur peut supprimer l'élément déjà sélectionné (si `multiple=false`). La sélection se fait à partir d'un formulaire dont l'URL doit être spécifiée dans le paramètre `target`. Les formulaires actuellement supportés sont :
* `!acc/charts/accounts/selector.php?targets=X` pour sélectionner un compte du plan comptable, où X est une liste de types de comptes qu'il faut permettre de choisir (séparés par des `:`)
* `!users/selector.php` pour sélectionner un membre
## button
Affiche un bouton, similaire à `<button>` en HTML, mais permet d'ajouter une icône par exemple.
```
{{:button type="submit" name="save" label="Créer ce membre" shape="plus" class="main"}}
```
| Paramètre | Obligatoire ou optionnel ? | Fonction |
| :- | :- | :- |
| `type` | optionnel | Type du bouton |
| `name` | optionnel | Nom du bouton |
| `label` | optionnel | Label du bouton |
| `shape` | optionnel | Affiche une icône en préfixe du label |
| `class` | optionnel | Classe CSS |
| `title` | optionnel | Attribut HTML `title` |
| `disabled` | optionnel | Désactive le bouton si `true` |
## link
Affiche un lien.
```
{{:link href="!users/new.php" label="Créer un nouveau membre"}}
```
| Paramètre | Obligatoire ou optionnel ? | Fonction |
| :- | :- | :- |
| `href` | **obligatoire** | Adresse du lien |
| `label` | **obligatoire** | Libellé du lien |
| `target` | *optionnel* | Cible du lien, utiliser `_dialog` pour que le lien s'ouvre dans une fenêtre modale. |
Préfixer l'adresse par "!" donnera une URL absolue en préfixant l'adresse par l'URL de l'administration.
Sans "!", l'adresse générée sera relative au contexte d'appel (module/plugin ou squelette site web).
## linkbutton
Affiche un lien sous forme de faux bouton, avec une icône si le paramètre `shape` est spécifié.
```
{{:linkbutton href="!users/new.php" label="Créer un nouveau membre" shape="plus"}}
```
| Paramètre | Obligatoire ou optionnel ? | Fonction |
| :- | :- | :- |
| `href` | **obligatoire* | Adresse du lien |
| `label` | **obligatoire** | Libellé du bouton |
| `target` | *optionnel* | Cible de l'ouverture du lien |
| `shape` | *optionnel* | Affiche une icône en préfixe du label |
Si on utilise `target="_dialog"` alors le lien s'ouvrira dans une fenêtre modale (iframe) par dessus la page actuelle.
Si on utilise `target="_blank"` alors le lien s'ouvrira dans un nouvel onglet.
## icon
Affiche une icône.
```
{{:icon shape="print"}}
```
| Paramètre | Obligatoire ou optionnel ? | Fonction |
| :- | :- | :- |
| `shape` | **obligatoire** | Forme de l'icône. |
### Formes d'icônes disponibles
![](shapes.png)
## user_field
Affiche un champ de la fiche membre.
| Paramètre | Obligatoire ou optionnel ? | Fonction |
| :- | :- | :- |
| `name` | **obligatoire** | Nom du champ. |
| `value` | **obligatoire** | Valeur du champ. |
## edit_user_field
Afficher un champ de formulaire pour modifier un champ de la fiche membre.
| Paramètre | Obligatoire ou optionnel ? | Fonction |
| :- | :- | :- |
| `name` | **obligatoire** | Nom du champ. |
| `source` | *optionnel* | Source de pré-remplissage du champ. Si le nom du champ est `montant`, alors la valeur de `[source].montant` sera utilisée comme valeur du champ. |
# Gestion de fichiers dans les modules
Les modules peuvent stocker des fichiers, mais seulement dans leur propre contexte. Un module ne peut pas gérer les fichiers du site web, des écritures comptables, des membres, ou des autres modules, il ne peut gérer que ses propres fichiers.
Quand les données d'un module sont supprimé, les fichiers du module sont aussi supprimés.
Mais si le module stocke des fichiers liés à un document JSON (par exemple dans un sous-répertoire pour chaque module), c'est au code du module de s'assurer que les fichiers seront supprimés lors de la suppression du document.
Par défaut, tous les fichiers des modules sont en accès restreint : ils ne peuvent être vus et modifiés que par les membres connectés qui sont au niveau d'accès indiqué dans les paramètres `restrict_section` et `restrict_level` du fichier `module.ini`.
Pour qu'un fichier soit visible publiquement aux personnes non connectées, il faut le placer dans le sous-répertoire `public` du module.
Attention : de par ce fonctionnement, **tous les fichiers** d'un module sont potentiellement accessibles par **tous les membres ayant accès au module** et connaissant le nom du fichier.
Il est donc recommandé de ne pas utiliser ce mécanisme pour stocker des données personnelles ou des données sensibles.
## admin_files
Affiche (dans le contexte de l'administration) la liste des fichiers dans un sous-répertoire, et éventuellement la possibilité d'en ajouter ou de les supprimer.
| Paramètre | Obligatoire ou optionnel ? | Fonction |
| :- | :- | :- |
| `path` | optionnel | Chemin du sous-répertoire où sont stockés les fichiers |
| `upload` | optionnel | Booléen. Si `true`, l'utilisateur pourra ajouter des fichiers. (Défaut : `false`) |
| `edit` | optionnel | Booléen. Si `true`, l'utilisateur pourra modifier ou supprimer les fichiers existants. (Défaut : `false`) |
| `use_trash` | optionnel | Booléen. Si `false`, le fichier sera supprimé, sans passer par la corbeille. Défaut : `true` |
Exemple pour afficher la liste des fichiers du sous-répertoire `facture43` et permettre de rajouter de nouveaux fichiers :
```
{{:admin_files path="facture43" upload=true edit=false}}
```
## delete_file
Supprimer un fichier ou un répertoire lié au module courant.
| Paramètre | Obligatoire ou optionnel ? | Fonction |
| :- | :- | :- |
| `path` | obligatoire | Chemin du fichier ou répertoire |
Exemple pour supprimer un fichier seul :
```
{{:delete_file path="facture43/justificatif.pdf"}}
```
Pour supprimer un répertoire et tous les fichiers dedans :
```
{{:delete_file path="facture43"}}
```

View file

@ -0,0 +1,785 @@
Title: Référence des filtres Brindille
{{{.nav
* [Modules](modules.html)
* [Documentation Brindille](brindille.html)
* [Fonctions](brindille_functions.html)
* [Sections](brindille_sections.html)
* **[Filtres](brindille_modifiers.html)**
}}}
<<toc aside>>
# Filtres PHP
Ces filtres viennent directement de PHP et utilisent donc les mêmes paramètres. Voir la documentation PHP pour plus de détails.
| Nom | Description | Documentation PHP |
| :- | :- | :- |
| `htmlentities` | Convertit tous les caractères éligibles en entités HTML | [Documentation PHP](https://www.php.net/htmlentities) |
| `htmlspecialchars` | Convertit les caractères spéciaux en entités HTML | [Documentation PHP](https://www.php.net/htmlspecialchars) |
| `trim` | Supprime les espaces et lignes vides au début et à la fin d'un texte | [Documentation PHP](https://www.php.net/trim) |
| `ltrim` | Supprime les espaces et lignes vides au début d'un texte | [Documentation PHP](https://www.php.net/ltrim) |
| `rtrim` | Supprime les espaces et lignes vides à la fin d'un texte | [Documentation PHP](https://www.php.net/rtrim) |
| `md5` | Génère un hash MD5 d'un texte | [Documentation PHP](https://www.php.net/md5) |
| `sha1` | Génère un hash SHA1 d'un texte | [Documentation PHP](https://www.php.net/sha1) |
| `strlen` | Nombre de caractères dans une chaîne de texte | [Documentation PHP](https://www.php.net/strlen) |
| `strpos` | Position d'un élément dans une chaîne de texte | [Documentation PHP](https://www.php.net/strpos) |
| `strrpos` | Position d'un dernier élément dans une chaîne de texte | [Documentation PHP](https://www.php.net/strrpos) |
| `substr` | Découpe une chaîne de caractère | [Documentation PHP](https://www.php.net/substr) |
| `strtotime` | Transforme une date en timestamp UNIX | [Documentation PHP](https://www.php.net/strtotime) |
| `strip_tags` | Supprime les tags HTML | [Documentation PHP](https://www.php.net/strip_tags) |
| `nl2br` | Remplace les retours à la ligne par des tags HTML `<br/>` | [Documentation PHP](https://www.php.net/nl2br) |
| `wordwrap` | Ajoute des retours à la ligne tous les 75 caractères | [Documentation PHP](https://www.php.net/wordwrap) |
| `abs` | Renvoie la valeur absolue d'un nombre (exemple : -42 sera transformé en 42) | [Documentation PHP](https://www.php.net/abs) |
| `gettype` | Renvoie le type d'une variable | |
| `intval` | Transforme une valeur en entier (integer) | [Documentation PHP](https://www.php.net/intval) |
| `boolval` | Transforme une valeur en booléen (true ou false) | [Documentation PHP](https://www.php.net/boolval) |
| `floatval` | Transforme une valeur en nombre flottant (à virgule) | [Documentation PHP](https://www.php.net/floatval) |
| `strval` | Transforme une valeur en chaîne de texte | [Documentation PHP](https://www.php.net/strval) |
| `arrayval` | Transforme une valeur en tableau | [Documentation PHP](https://www.php.net/manual/fr/language.types.type-juggling.php) |
| `json_decode` | Transforme une chaîne JSON en valeur | [Documentation PHP](https://www.php.net/json_decode) |
| `json_encode` | Transforme une valeur en chaîne JSON | [Documentation PHP](https://www.php.net/json_encode) |
| `http_build_query` | Transformer un tableau en chaîne *query string* pour URL | [Documentation PHP](https://www.php.net/http_build_query) |
| `str_getcsv` | Transformer une chaîne de texte de format CSV en tableau | [Documentation PHP](https://www.php.net/str_getcsv) |
# Filtres utiles pour les e-mails
## check_email
Permet de vérifier la validité d'une adresse email. Cette fonction vérifie la syntaxe de l'adresse mais aussi que le nom de domaine indiqué possède bien un enregistrement de type MX.
Renvoie `true` si l'adresse est valide.
```
{{if !$_POST.email|check_email}}
<p class="alert">L'adresse e-mail indiquée est invalide.</p>
{{/if}}
```
## protect_contact
Crée un lien protégé pour une adresse email, pour éviter que l'adresse ne soit recueillie par les robots spammeurs (empêche également le copier-coller et le lien ne fonctionnera pas avec javascript désactivé).
# Filtres de tableaux
## has
Renvoie vrai si le tableau contient l'élément passé en paramètre.
```
{{:assign var="table" a="bleu" b="orange"}}
{{if $table|has:"bleu"}}
Oui, il y a du bleu
{{/if}}
```
## in
Renvoie vrai si l'élément fait partie du tableau passé en paramètre.
C'est exactement la même chose que `has`, mais exprimé à l'envers.
```
{{:assign var="table" a="bleu" b="orange"}}
{{if "bleu"|in:$table}}
Oui, il y a du bleu
{{/if}}
```
## has_key
Renvoie vrai si le tableau contient la clé passée en paramètre.
```
{{:assign var="table" a="bleu" b="orange"}}
{{if $table|has_key:"b"}}
Oui, il y a la clé "b"
{{/if}}
```
## key_in
Renvoie vrai si la clé fait partie du tableau passé en paramètre.
C'est exactement la même chose que `has_key`, mais exprimé à l'envers.
```
{{:assign var="table" a="bleu" b="orange"}}
{{if "b"|key_in:$table}}
Oui, il y a la clé "b"
{{/if}}
```
## keys
Renvoie les clés du tableau, sous forme de tableau.
```
{{:assign var="table" a="bleu" b="orange"}}
{{:assign var="cles" value=$table|keys}}
{{$cles|implode:","}}
```
Donnera :
```
a,b
```
## values
Renvoie les valeurs du tableau, sous forme de tableau.
Cela revient en fait à supprimer les clés associatives.
```
{{:assign var="table" a="bleu" b="orange"}}
{{#foreach from=$table key="cle" item="valeur"}}
{{$cle}} = {{$valeur}}
{{/foreach}}
--
{{:assign var="valeurs" value=$table|values}}
{{#foreach from=$valeurs key="cle" item="valeur"}}
{{$cle}} = {{$valeur}}
{{/foreach}}
```
Donnera :
```
a = bleu
b = orange
--
0 = bleu
1 = orange
```
## count
Compte le nombre d'entrées dans un tableau.
```
{{$products|count}}
= 5
```
## explode
Sépare une chaîne de texte en tableau à partir d'une chaîne de séparation.
```
{{:assign var="table" value="a,b,c"|explode:","}}
- {{$table.0}}
- {{$table.1}}
- {{$table.2}}
```
Affichera :
```
- a
- b
- c
```
## implode
Réunit un tableau sous forme de chaîne de texte en utilisant éventuellement une chaîne de liaison entre chaque élément du tableau.
```
{{:assign var="table" a="bleu" b="orange"}}
{{$table|implode}}
{{$table|implode:" - "}}
```
Affichera :
```
bleuorange
bleu - orange
```
## map
Applique un filtre sur chaque élément du tableau.
Le premier paramètre doit être le nom du filtre. Les autres paramètres seront passés au filtre.
```
{{:assign var="table" a="01" b="02"}}
{{:assign var="table" value=$table|map:intval}}
- {{$table.a}}
- {{$table.b}}
```
Affichera :
```
- 1
- 2
```
## ksort, sort
Trie un tableau par ordre alpha-numérique, sans tenir compte des majuscules/minuscules. `ksort` trie le tableau en utilisant les clés, et `sort` trie le tableau en utilisant les valeurs.
```
{{:assign var="table" b="3" a="2" c="1"}}
{{$table|sort|implode:","}}
{{$table|ksort|implode:","}}
```
Affichera :
```
1,2,3
2,3,1
```
## max, min
Renvoie respectivement la valeur la plus haute ou la plus basse d'un tableau de valeurs numériques.
```
{{:assign var="table" b="3" a="2" c="1"}}
{{$table|max}}
{{$table|min}}
```
Affichera :
```
3
1
```
# Filtres de texte
## args
Remplace des arguments dans le texte selon le schéma utilisé par [sprintf](https://www.php.net/sprintf).
```
{{"Il y a %d résultats dans la recherche sur le terme '%s'."|args:$results_count:$query}}
= Il y a 5 résultat dans la recherche sur le terme 'test'.
```
## cat
Concaténer un texte avec un autre.
```
{{"Tangerine"|cat:" Dream"}}
= Tangerine Dream
```
## count_words
Compte le nombre de mots dans un texte.
## escape
Échappe le contenu pour un usage dans un document HTML. Ce filtre est appliqué par défaut à tout ce qui est affiché (variables, etc.) sauf à utiliser le filtre `raw` (voir plus bas).
## excerpt
Produit un extrait d'un texte.
Supprime les tags HTML, tronque au nombre de caractères indiqué en second argument (si rien n'est indiqué, alors 600 est utilisé), et englobe dans un paragraphe `<p>...</p>`.
Équivalent de :
```
<p>{{$html|strip_tags|truncate:600|nl2br}}</p>
```
## extract_leading_number
Extrait le numéro au début d'une chaîne de texte.
Exemple :
```
{{:assign title="02. Cours sur la physique nucléaire"}}
{{$title|extract_leading_number}}
```
Affichera :
```
02
```
## format_phone_number
Formatte un numéro de téléphone selon le format du pays de l'association.
Seule la France est supportée pour le moment.
Exemple :
```
{{:assign number="0102030405"}}
{{$number|format_phone_number}}
```
Affichera :
```
01 02 03 04 05
```
## markdown
Transforme un texte en HTML en utilisant la syntaxe Markdown.
Il est conseillé de rajouter le filtre `|raw` pour ne pas échapper le HTML produit, si on veut afficher le texte formatté dans une page HTML.
```
{{$texte|markdown|raw}}
```
## raw
Passer ce filtre désactive la protection automatique contre le HTML (échappement) dans le texte. À utiliser en connaissance de cause avec les contenus qui contiennent du HTML et sont déjà filtrés !
```
{{"<b>Test"}} = &lt;b&gt;Test
{{"<b>Test"|raw}} = <b>Test
```
## replace
Remplace des parties du texte par une autre partie.
```
{{"Tata yoyo"|replace:"yoyo":"yaya"}}
= Tata yaya
```
## regexp_replace
Remplace des valeurs en utilisant une expression rationnelles (regexp) ([documentation PHP](https://www.php.net/manual/fr/regexp.introduction.php)).
```
{{"Tartagueule"|regexp_replace:"/ta/i":"tou"}}
= tourtougueule
```
## remove_leading_number
Supprime le numéro au début d'un titre.
Cela permet de définir un ordre spécifique aux pages et catégories dans les listes.
```
{{"03. Beau titre"|remove_leading_number}}
Beau titre
```
## truncate
Tronque un texte à une longueur définie.
| Argument | Fonction | Valeur par défaut (si omis) |
| :- | :- | :- |
| 1 | longueur en nombre de caractères | 80 |
| 2 | texte à placer à la fin (si tronqué) | … |
| 3 | coupure stricte, si `true` alors un mot pourra être coupé en deux, si `false` le texte sera coupé au dernier mot complet | `false` |
```
{{:assign texte="Ceci n'est pas un texte."}}
{{$texte|truncate:19:"(...)":true}}
{{$texte|truncate:19:"":false}}
```
Affichera :
```
Ceci n'est pas un (...)
Ceci n'est pas un t
```
## typo
Formatte un texte selon les règles typographiques françaises : ajoute des espaces insécables devant ou derrière les ponctuations françaises (`« » ? ! :`).
## urlencode
Encode une chaîne de texte pour utilisation dans une adresse URL (alias de `rawurlencode` en PHP).
## xml_escape
Échappe le contenu pour un usage dans un document XML.
## Autres filtres de texte
Les filtres suivants modifient la casse (majuscule/minuscules) d'un texte et ne fonctionneront correctement que si l'extension `mbstring` est installée sur le serveur. Sinon les lettres accentuées ne seront pas modifiées.
Note : il est donc préférable d'utiliser la propriété CSS [`text-transform`](https://developer.mozilla.org/en-US/docs/Web/CSS/text-transform) pour modifier la casse si l'usage n'est que pour l'affichage, et non pas pour enregistrer les données.
* `tolower` : transforme un texte en minuscules
* `toupper` : transforme un texte en majuscules
* `ucfirst` : met la première lettre du texte en majuscule
* `ucwords` : met la première lettre de chaque mot en majuscule
* `lcfirst` : met la première lettre du texte en minuscule
# Filtres sur les sommes en devises
## money
Formatte une valeur de monnaie pour l'affichage.
Une valeur de monnaie doit **toujours** inclure les cents (exprimée sous forme d'entier). Ainsi `15,02` doit être exprimée sous la forme `1502`.
Paramètres optionnels :
1. `true` (défaut) pour ne rien afficher si la valeur est zéro, ou `false` pour afficher `0,00`
2. `true` pour afficher le signe `+` si le nombre est positif (`-` est toujours affiché si le nombre est négatif)
```
{{* 12 345,67 = 1234567 *}}
{{:assign amount=1234567}}
{{$amount|money}}
12 345,67
```
## money_currency
Comme `money` (même paramètres), formatte une valeur de monnaie (entier) pour affichage, mais en ajoutant la devise.
```
{{:assign amount=1502}}
{{$amount|money_currency}}
15,02 €
```
## money_html
Idem que `money`, mais pour l'affichage en HTML :
```
{{* 12 345,67 = 1234567 *}}
{{:assign amount=1234567}}
{{$amount|money_html}}
<span class="money">12&nbsp;345,67</span>
```
## money_currency_html
Idem que `money_currency`, mais pour l'affichage en HTML :
```
{{:assign amount=1502}}
{{$amount|money_currency_html}}
<span class="money">15,02&nbsp;</span>
```
## money_raw
Formatte une valeur de monnaie (entier) de manière brute : les milliers n'auront pas de séparateur.
```
{{:assign amount=1234567}}
{{$amount|money_raw}}
12345,67
```
## money_int
Transforme un nombre à partir d'une chaîne de caractère (par exemple `12345,67`) en entier (`1234567`) pour stocker une valeur de monnaie.
```
{{:assign montant=$_POST.montant|trim|money_int}}
```
# Filtres SQL
## quote_sql
Protège une chaîne contre les attaques SQL, pour l'utilisation dans une condition.
**Note : il est FORTEMENT déconseillé d'intégrer directement des sources extérieures dans les requêtes SQL, il est préférable d'utiliser les paramètres dans la boucle `sql` et ses dérivées, comme ceci : `{{#sql select="id, nom" tables="users" where="lettre_infos = :lettre" :lettre=$_GET.lettre}}`.**
Exemple :
```
{{:assign nom=$_GET.nom|quote_sql}}
{{#sql select="id, nom" tables="users" where="nom = %s"|args:$nom}}
```
## quote_sql_identifier
La même chose que `quote_sql`, mais pour les identifiants (par exemple nom de table ou de colonne).
Exemple :
```
{{:assign colonne=$_GET.colonne|quote_sql_identifier}}
{{#sql select="id, %s"|args:$colonne tables="users"}}
```
Il est possible d'utiliser un préfixe en argument, utile par exemple quand on a plusieurs tables avec le même nom de colonne :
```
{{:assign colonne=$_GET.colonne|quote_sql_identifier:"u1"}}
{{#sql select="u1.id, %s"|args:$colonne tables="users AS u1 INNER JOIN users AS u2 ON u2.id_parent = u1.id"}}
```
## sql_where
Permet de créer une partie d'une clause SQL `WHERE` complexe.
Le premier paramètre est le nom de la colonne (sans préfixe).
Paramètres :
1. Comparateur : `=, !=, IN, NOT IN, >, >=, <, <=`
2. Valeur à comparer (peut être un tableau)
Exemple pour afficher la liste des membres des catégories n°1 et n°2:
```
{{:assign var="list." value=1}}
{{:assign var="list." value=2}}
{{#sql select="nom" tables="users" where="id_category"|sql_where:'IN':$id_list}}
{{$nom}}
{{/sql}}
```
Le requête SQL générée sera alors `SELECT nom FROM users WHERE id_category IN (1, 2)`.
## sql_user_fields
Permet de récupérer le contenu de champs de la fiche utilisateur pour une requête SQL.
C'est particulièrement utile si le module permet de sélectionner dans sa configuration une liste de champs de membre (par exemple pour la carte de membre, ou les reçus fiscaux).
Si un champ mentionné n'existe plus dans les fiches de membres, il sera ignoré.
* Le premier paramètre est la liste des champs (tableau ou chaîne de texte)
* Le second est le préfixe à utiliser (alias de la table membres), optionnel
* Le troisième est la chaîne de texte à utiliser pour coller les champs entre eux
Exemple :
```
{{:assign var="champs_adresse." value="rue"}}
{{:assign var="champs_adresse." value="ville"}}
{{:assign var="champs_adresse_sql" value=$champs_adresse|sql_user_fields:"u":" - "}}
{{#select !champs_adresse_sql AS adresse FROM users AS u; !champs_adresse_sql=$champs_adresse_sql}}
{{$adresse}}
{{/select}}
```
Affichera :
```
30 rue de Machin Chose — Dijon
```
Et la clause SQL générée sera :
```
LTRIM(COALESCE(' - ' || u.rue, '') || COALESCE(' - ' || u.ville), ' - ')
```
# Filtres de date
## date
Formatte une date selon le format spécifié en premier paramètre.
Le format est identique au [format utilisé par PHP](https://www.php.net/manual/fr/datetime.format.php).
Si aucun format n'est indiqué, le défaut sera `d/m/Y à H:i`. (en français)
Exemples :
```
{{:assign this_year=$now|date:'Y'}}
{{$date|date:'d/m/Y'}}
```
## strftime
Formatte une date selon un format spécifié en premier paramètre.
Le format à utiliser est identique [au format utilisé par la fonction strftime de PHP](https://www.php.net/strftime).
Un format doit obligatoirement être spécifié.
En passant un code de langue en second paramètre, cette langue sera utilisée. Sont supportés le français (`fr`) et l'anglais (`en`). Le défaut est le français si aucune valeur n'est passée en second paramètre .
```
{{:assign this_year=$now|date:'%Y'}}
{{$date|date:'%d/%m/%Y'}}
```
## relative_date
Renvoie une date relative à la date du jour : `aujourd'hui`, `hier`, `demain`, ou sinon `mardi 2 janvier` (si la date est de l'année en cours) ou `2 janvier 2021` (si la date est d'une autre année).
En spécifiant `true` en premier paramètre, l'heure sera ajoutée au format `14h34`.
## date_short
Formatte une date au format court : `d/m/Y`.
En spécifiant `true` en premier paramètre l'heure sera ajoutée : `à H\hi`.
## date_long
Formatte une date au format long : `lundi 2 janvier 2021`.
En spécifiant `true` en premier paramètre l'heure sera ajoutée : `à 20h42`.
## date_hour
Formatte une date en renvoyant l'heure uniquement : `20h00`.
En passant `true` en premier paramètre, les minutes seront omises si elles sont égales à zéro : `20h`.
## atom_date
Formatte une date au format ATOM : `Y-m-d\TH:i:sP`
## parse_date
Vérifie le format d'une chaîne de texte représentant la date et la transforme en chaîne de date standardisée au format `AAAA-MM-JJ`.
Les formats acceptés sont :
* `AAAA-MM-JJ`
* `JJ/MM/AAAA`
* `JJ/MM/AA`
## parse_datetime
Vérifie le format d'une chaîne de texte représentant la date et l'heure et la transforme en chaîne de date et heure standardisée au format `AAAA-MM-JJ HH:mm`.
Les formats acceptés sont :
* `AAAA-MM-JJ HH:mm:ss`
* `AAAA-MM-JJ HH:mm`
* `JJ/MM/AAAA HH:mm`
## parse_time
Vérifie le format d'une chaîne de texte représentant l'heure et la transforme en chaîne de date standardisée au format `HH:MM`.
Les formats acceptés sont :
* `HH:MM`
* `H:M`
* `H:MM`
* `HH:M`
Le séparateur peut être `:` ou `h`.
# Filtres de condition
Ces filtres sont à utiliser dans les conditions
## match
Renvoie `true` si le texte indiqué en premier paramètre est trouvé dans la variable.
Ce filtre est insensible à la casse.
```
{{if $page.path|match:"/aide"}}Bienvenue dans l'aide !{{/if}}
```
## regexp_match
Renvoie `true` si l'expression régulière indiquée en premier paramètre est trouvée dans la variable.
Exemple pour voir si le texte contient les mots "Bonjour" ou "Au revoir" (insensible à la casse) :
```
{{if $texte|regexp_match:"/Bonjour|Au revoir/i"}}
Trouvé !
{{else}}
Rien trouvé :-(
{{/if}}
```
# Autres filtres
## math
Réalise un calcul mathématique. Cette fonction accepte :
* les nombres: `42`, `13,37`, `14.05`
* les signes : `+ - / *` pour additionner, diminuer, diviser ou multiplier
* les parenthèses : `( )`
* les fonctions : `round(0.5452, 2)` `ceil(29,09)` `floor(0.99)` mais aussi : min, max, cos, sin, tan, asin, acos, atan, sinh, cosh, tanh, exp, sqrt, abs, log, log10, et pi.
Le résultat est renvoyé sous la forme d'un entier, ou d'un nombre flottant dont les décimales sont séparées par un point.
```
{{"1+1"|math}}
= 2
```
Il est possible de donner d'autres arguments, de la même manière qu'avec `args` pour y inclure des données provenant de variables :
```
{{:assign age=42}}
{{"1+%d"|math:$age}}
= 43
{{:assign prix=39.99 tva=19.1}}
{{"round(%f*%f, 2)"|math:$prix:$tva}}
= 47.63
```
## or
Si la variable passée est évalue comme `false` (c'est à dire que sa valeur est un texte vide, ou un nombre qui vaut zéro, ou la valeur `false`), alors le premier paramètre sera utilisé.
```
{{:assign texte=""}}
{{$texte|or:"Le texte est vide"}}
```
Il est possible de chaîner les appels à `or` :
```
{{:assign texte1="" texte2="0"}}
{{$texte1|or:$texte2|or:"Aucun texte"}}
```
## size_in_bytes
Renvoie une taille en octets, Ko, Mo, ou Go à partir d'une taille en octets.
```
{{100|size_in_bytes}} = 100 o
{{1500|size_in_bytes}} = 1,50 Ko
{{1048576|size_in_bytes}} = 1 Mo
```
## spell_out_number
Épelle un nombre en toutes lettres.
Le premier paramètre peut être utilisé pour spécifier le code de la langue à utiliser (par défaut c'est le français, donc le code `fr`).
```
{{42|spell_out_number}}
```
Donnera :
```
quarante deux
```
## uuid
Renvoie un identifiant unique au format UUIDv4.

View file

@ -0,0 +1,827 @@
Title: Référence des sections Brindille
{{{.nav
* [Modules](modules.html)
* [Documentation Brindille](brindille.html)
* [Fonctions](brindille_functions.html)
* **[Sections](brindille_sections.html)**
* [Filtres](brindille_modifiers.html)
}}}
<<toc aside level=2>>
# Sections généralistes
## foreach
Permet d'itérer sur un tableau par exemple. Ainsi chaque élément du tableau exécutera une fois le contenu de la section.
| Paramètre | Optionnel / obligatoire ? | Fonction |
| :- | :- | :- |
| `from` | **obligatoire** | Variable sur laquelle effectuer l'itération |
| `key` | **optionnel** | Nom de la variable à utiliser pour la clé de l'élément |
| `item` | **optionnel** | Nom de la variable à utiliser pour la valeur de l'élément |
Considérons ce tableau :
```
{{:assign var="tableau" a="bleu" b="orange"}}
```
On peut alors itérer pour récupérer les clés (`a` et `b` ainsi que les valeurs `bleu` et `orange`) :
```
{{#foreach from=$tableau key="key" item="value"}}
{{$key}} = {{$value}}
{{/foreach}}
```
Cela affichera :
```
a = bleu
b = orange
```
Si on a un tableau à plusieurs niveaux, les éléments du tableau sont automatiquement transformés en variable :
```
{{:assign var="tableau.a" couleur="bleu"}}
{{:assign var="tableau.b" couleur="orange"}}
```
```
{{#foreach from=$variable}}
{{$couleur}}
{{/foreach}}
```
Affichera :
```
bleu
orange
```
### Itérer sans tableau
Il est aussi possible de faire `X` itérations, arbitrairement, sans avoir de tableau en entrée, en utilisant le paramètre `count`.
C'est l'équivalent des boucles `for` dans les autres langages de programmation.
Exemple :
```
{{#foreach count=3 key="i"}}
- {{$i}}
{{/foreach}}
```
Affichera :
```
- 0
- 1
- 2
```
## restrict
Permet de limiter (restreindre) une partie de la page aux membres qui sont connectés et/ou qui ont certains droits.
Deux paramètres optionnels peuvent être utilisés ensemble (il n'est pas possible d'utiliser seulement un des deux) :
| Paramètre | Optionnel / obligatoire ? | Fonction |
| :- | :- | :- |
| `level` | *optionnel* | Niveau d'accès : `read`, `write`, `admin` |
| `section` | *optionnel* | Section où le niveau d'accès doit s'appliquer : `users`, `accounting`, `web`, `documents`, `config` |
| `block` | *optionnel* | Si ce paramètre est présent et vaut `true`, alors l'accès sera interdit si les conditions d'accès demandées ne sont pas remplies : une page d'erreur sera renvoyée. |
Exemple pour voir si un membre est connecté :
```
{{#restrict}}
Un membre est connecté, mais on ne sait pas avec quels droits.
{{else}}
Aucun membre n'est connecté.
{{/restrict}}
```
Exemple pour voir si un membre qui peut administrer les membres est connecté :
```
{{#restrict section="users" level="admin"}}
Un membre est connecté, et il a le droit d'administrer les membres.
{{else}}
Aucun membre n'est connecté, ou un membre est connecté mais n'est pas administrateur des membres.
{{/restrict}}
```
Pour bloquer l'accès aux membres non connectés, ou qui n'ont pas accès en écriture à la comptabilité.
```
{{#restrict block=true section="accounting" level="write"}}
{{/restrict}}
```
Le mieux est de mettre ce code au début d'un squelette.
# Requêtes SQL
## select
Exécute une requête SQL `SELECT` et effectue une itération pour chaque résultat de la requête.
Pour une utilisation plus simplifiée des requêtes, voir aussi la section [sql](#sql).
Attention : la syntaxe de cette section est différente des autres sections Brindille. En effet après le début (`{{#select`) doit suivre la suite de la requête, et non pas les paramètres :
```
Liste des membres inscrits à la lettre d'informations :
{{#select nom, prenom FROM users WHERE lettre_infos = 1;}}
- {{prenom}} {{$nom}}<br />
{{else}}
Aucun membre n'est inscrit à la lettre d'information.
{{/select}}
```
Des paramètres nommés de SQL peuvent être présentés après le point-virgule marquant la fin de la requête SQL :
```
{{:assign prenom="Karim"}}
{{#select * FROM users WHERE prenom = :prenom;
:prenom=$prenom}}
...
{{/select}}
```
Notez les deux points avant le nom du paramètre. Ces paramètres sont protégés contre les injections SQL (généralement appelés paramètres nommés).
Pour intégrer des paramètres qui ne sont pas protégés (**attention !**), il faut utiliser le point d'exclamation :
```
{{:assign var="categories." value=1}}
{{:assign var="categories." value=2}}
{{#select * FROM users WHERE !categories;
!categories='id_category'|sql_where:'IN':$categories}}
```
Cela créera la requête suivante : `SELECT * FROM users WHERE id_category IN (1, 2);`
Il est aussi possible d'intégrer directement des variables dans la requête, en utilisant la syntaxe `{$variable|filtre:argument1:argument2}`, comme une variable classique donc, mais au lieu d'utiliser des doubles accolades, on utilise ici des accolades simples. Ces variables seront automatiquement protégées contre les injections SQL.
```
{{:assign prenom="Camille"}}
{{#select * FROM users WHERE initiale_prenom = {$prenom|substr:0:1};}}
```
Cependant, pour plus de lisibilité il est conseillé d'utiliser la syntaxe des paramètres nommés SQL (voir ci-dessus).
Il est aussi possible d'insérer directement du code SQL (attention aux problèmes de sécurité dans ce cas !), pour cela il faut rajouter un point d'exclamation après l'accolade ouvrante :
```
{{:assign var="prenoms." value="Karim"}}
{{:assign var="prenoms." value="Camille"}}
{{#select * FROM users WHERE {!"prenom"|sql_where:"IN":$prenoms};}}
...
{{/select}}
```
Il est aussi possible d'utiliser les paramètres suivants :
| Paramètre | Fonction |
| :- | :- |
| `debug` | Si ce paramètre existe, la requête SQL exécutée sera affichée avant le début de la boucle. |
| `explain` | Si ce paramètre existe, l'explication de la requête SQL exécutée sera affichée avant le début de la boucle. |
| `assign` | Si renseigné, une variable de ce nom sera créée, et le contenu de la ligne y sera assigné. |
Exemple avec `debug` :
```
{{:assign prenom="Karim"}}
{{#select * FROM users WHERE prenom = :prenom; :prenom=$prenom debug=true}}
...
{{/select}}
```
Affichera juste au dessus du résultat la requête exécutée :
```
SELECT * FROM users WHERE nom = 'Karim'
```
### Paramètre assign
Exemple avec `assign` :
```
{{#select * FROM users WHERE prenom = 'Camille' LIMIT 1; assign="membre"}}{{/select}}
{{$membre.nom}}
```
Il est possible d'utiliser un point final pour que toutes les lignes soient mises dans un tableau :
```
{{#select * FROM users WHERE prenom = 'Camille' LIMIT 10; assign="membres."}}{{/select}}
{{#foreach from=$membres}}
Nom : {{$nom}}<br />
Adresse : {{$adresse}}
{{/foreach}}
```
## sql
Effectue une requête SQL de type `SELECT` dans la base de données, mais de manière simplifiée par rapport à `select`.
```
{{#sql select="*, julianday(date) AS day" tables="membres" where="id_categorie = :id_categorie" :id_categorie=$_GET.id_categorie order="numero DESC" begin=":page*100" limit=100 :page=$_GET.page}}
{{/sql}}
```
| Paramètre | Optionnel / obligatoire ? | Fonction |
| :- | :- | :- |
| `tables` | **obligatoire** | Liste des tables à utiliser dans la requête (séparées par des virgules). |
| `select` | *optionnel* | Liste des colonnes à sélectionner, si non spécifié, toutes les colonnes (`*`) seront sélectionnées |
### Sections qui héritent de `sql`
Certaines sections (voir plus bas) héritent de `sql` et rajoutent des fonctionnalités. Dans toutes ces sections, il est possible d'utiliser les paramètres facultatifs suivants :
| Paramètre | Fonction |
| :- | :- |
| `where` | Condition de sélection des résultats |
| `begin` | Début des résultats, si vide une valeur de `0` sera utilisée. |
| `limit` | Limitation des résultats. Si vide, une valeur de `10000` sera utilisée. |
| `group` | Contenu de la clause `GROUP BY` |
| `having` | Contenu de la clause `HAVING` |
| `order` | Ordre de tri des résultats. Si vide le tri sera fait par ordre d'ajout dans la base de données. |
| `assign` | Si renseigné, une variable de ce nom sera créée, et le contenu de la ligne du résultat y sera assigné. |
| `debug` | Si ce paramètre existe, la requête SQL exécutée sera affichée avant le début de la boucle. |
| `explain` | Si ce paramètre existe, l'explication de la requête SQL exécutée sera affichée avant le début de la boucle. |
| `count` | Booléen ou texte. Si ce paramètre est `TRUE`, le nombre de résultats sera retourné. Si une chaîne de texte est indiquée, elle sera utilisée dans la clause `COUNT(<texte>)`. |
Il est également possible de passer des arguments dans les paramètres à l'aides des arguments nommés qui commencent par deux points `:` :
```
{{#articles where="title = :montitre" :montitre="Actualité"}}
```
Exemples d'utilisation du paramètre `count` :
```
{{#articles count=true}}
Il y a {{$count}} articles.
{{/articles}}
{{#articles count=true assign="result"}}
{{/articles}}
Il y a {{$result.count}} articles.
{{#articles count="DISTINCT title"}}
Il y a {{$count}} articles avec un titre différent.
{{/articles}}
```
# Membres
## users
Liste les membres.
Paramètres possibles :
| Paramètre | Optionnel / obligatoire ? | Fonction |
| :- | :- | :- |
| `id` | optionnel | Identifiant unique du membre, ou tableau contenant une liste d'identifiants. |
| `search_name` | optionnel | Ne lister que les membres dont le nom correspond au texte passé en paramètre. |
| `id_parent` | optionnel | Ne lister que les membres rattachés à l'identifiant unique du membre responsable indiqué. |
Chaque itération renverra la fiche du membre, ainsi que ces variables :
| Variable | Description |
| :- | :- |
| `$id` | Identifiant unique du membre |
| `$_name` | Nom du membre, tel que défini dans la configuration |
| `$_login` | Identifiant de connexion du membre, tel que défini dans la configuration |
| `$_number` | Numéro du membre, tel que défini dans la configuration |
## subscriptions
Liste les inscriptions à une ou des activités.
Paramètres possibles :
| Paramètre | | Fonction |
| :- | :- | :- |
| `user` | optionnel | Identifiant unique du membre |
| `active` | optionnel | Si `TRUE`, seules les inscriptions à jour sont listées |
| `id_service` | optionnel | Ne renvoie que les inscriptions à l'activité correspondant à cet ID. |
# Comptabilité
## accounts
Liste les comptes d'un plan comptable.
| Paramètre | Fonction |
| :- | :- |
| `codes` (optionel) | Ne renvoyer que les comptes ayant ces codes (séparer par des virgules). |
| `id` (optionel) | Ne renvoyer que le compte ayant cet ID. |
## balances
Renvoie la balance des comptes.
| Paramètre | Fonction |
| :- | :- |
| `codes` (optionel) | Ne renvoyer que les balances des comptes ayant ces codes (séparer par des virgules). |
| `year` (optionel) | Ne renvoyer que les balances des comptes utilisés sur l'année (indiquer ici un ID de year). |
## transactions
Renvoie des écritures.
| Paramètre | | Fonction |
| :- | :- | :- |
| `id` | optionnel | Indiquer un ID d'écriture pour récupérer ses informations. |
| `user` | optionnel | Indiquer ici un ID utilisateur pour lister les écritures liées à un membre. |
## years
Liste les exercices comptables
| Paramètre | Fonction |
| :- | :- |
| `closed` (optionel) | Mettre `closed=true` pour ne lister que les exercices clôturés, ou `closed=false` pour ne lister que les exercices ouverts. |
# Pour le site web
## breadcrumbs
Permet de récupérer la liste des pages parentes d'une page afin de constituer un [fil d'ariane](https://fr.wikipedia.org/wiki/Fil_d'Ariane_(ergonomie)) permettant de remonter dans l'arborescence du site
Un seul paramètre est possible :
| Paramètre | Fonction |
| :- | :- |
| `uri` (obligatoire) | Adresse unique de la page parente |
| ou `id_page` (obligatoire) | Numéro unique (ID) de la page parente |
Chaque itération renverra trois variables :
| Variable | Contenu |
| :- | :- |
| `$id` | Numéro unique (ID) de la page ou catégorie |
| `$title` | Titre de la page ou catégorie |
| `$uri` | Nom unique de la page ou catégorie |
| `$url` | Adresse HTTP de la page ou catégorie |
### Exemple
```
<ul>
{{#breadcrumbs id_page=$page.id}}
<li>{{$title}}</li>
{{/breadcrumbs}}
</ul>
```
## pages, articles, categories <sup>(sql)</sup>
Note : ces sections héritent de `sql` (voir plus haut).
* `pages` renvoie une liste de pages, qu'elles soient des articles ou des catégories
* `categories` ne renvoie que des catégories
* `articles` ne renvoie que des articles
À part cela ces trois types de section se comportent de manière identique.
| Paramètre | Fonction |
| :- | :- |
| `search` | Renseigner ce paramètre avec un terme à rechercher dans le texte ou le titre. Dans ce cas par défaut le tri des résultats se fait sur la pertinence, sauf si le paramètre `order` est spécifié. |
| `future` | Renseigner ce paramètre à `false` pour que les articles dont la date est dans le futur n'apparaissent pas, `true` pour ne renvoyer QUE les articles dans le futur, et `null` (ou ne pas utiliser ce paramètre) pour que tous les articles, passés et futur, apparaissent. |
| `uri` | Adresse unique de la page/catégorie à retourner. |
| `id_parent` | Numéro unique (ID) de la catégorie parente. Utiliser `null` pour n'afficher que les articles ou catégories de la racine du site. |
| `parent` | Adresse unique (URI) de la catégorie parente. Exemple pour renvoyer la liste des articles de la sous-catégorie "Événements" de la catégorie "Notre atelier" : `evenements`. Utiliser `null` pour n'afficher que les articles ou catégories de la racine du site. Ajouter un point d'exclamation au début de la valeur pour inverser la condition. |
Par exemple lister 5 articles de la catégorie "Actualité", qui ne sont pas dans le futur, triés du plus récent au plus ancien :
```
{{#articles future=false parent="actualite" order="published DESC" limit=5}}
<h3>{{$title}}</h3>
{{/articles}}
```
Chaque élément de ces boucles contiendra les variables suivantes :
| Nom de la variable | Description | Exemple |
| :- | :- | :- |
| `id` | Numéro unique de la page (ID) | `1312` |
| `id_parent` | Numéro unique de la catégorie parente (ID) | `42` |
| `type` | Type de page : `1` = catégorie, `2` = article | `2` |
| `uri` | Adresse unique de la page | `bourse-aux-velos` |
| `url` | Adresse HTTP de la page | `https://site.association.tld/bourse-aux-velos` |
| `path` | Chemin complet de la page | `actualite/atelier/bourse-aux-velos` |
| `parent` | Chemin de la catégorie parente | `actualite/atelier`|
| `title` | Titre de la page | `Bourse aux vélos` |
| `content` | Contenu brut de la page | `# Titre …` |
| `html` | Rendu HTML du contenu de la page | `<div class="web-content"><h1>Titre</h1>…</div>` |
| `has_attachments` | `true` si la page a des fichiers joints, `false` sinon | `true` |
| `published` | Date de publication | `2023-01-01 01:01:01` |
| `modified` | Date de modification | `2023-01-01 01:01:01` |
Si une recherche a été effectuée, deux autres variables sont fournies :
| Nom de la variable | Description | Exemple |
| :- | :- | :- |
| `snippet` | Extrait du contenu contenant le texte recherché (entouré de balises `<mark>`) | `LONU appelle la France à sattaquer aux « profonds problèmes » de <mark>racisme</mark> au sein des forces de…` |
| `url_highlight` | Adresse de la page, où le texte recherché sera mis en évidence | `https://.../onu-racisme#:~:text=racisme%20au%20sein` |
## attachments, documents, images <sup>(sql)</sup>
Note : ces sections héritent de `sql` (voir plus haut).
* `attachments` renvoie une liste de fichiers joints à une page du site web
* `documents` renvoie une liste de fichiers joints qui ne sont pas des images
* `images` renvoie une liste de fichiers joints qui sont des images
À part cela ces trois types de section se comportent de manière identique.
Note : seul les fichiers de la section site web sont accessibles, les fichiers de membres, de comptabilité, etc. ne sont pas disponibles.
| Paramètre | Optionnel / obligatoire ? | Fonction |
| :- | :- | :- |
| `parent` | **obligatoire** si `id_parent` n'est pas renseigné | Nom unique (URI) de l'article ou catégorie parente dont ont veut lister les fichiers |
| `id_parent` | **obligatoire** si `parent` n'est pas renseigné | Numéro unique (ID) de l'article ou catégorie parente dont ont veut lister les fichiers |
| `except_in_text` | *optionnel* | passer `true` à ce paramètre , et seuls les fichiers qui ne sont pas liés dans le texte de la page seront renvoyés |
# Sections relatives aux modules
## form
Permet de gérer la soumission d'un formulaire (`<form method="post">` en HTML).
Si l'élément dont le nom spécifié dans le paramètre `on` a été envoyé en `POST`, alors le code à l'intérieur de la section est exécuté.
Toute erreur à l'intérieur de la section arrêtera son exécution, et le message sera ajouté aux erreurs du formulaire.
Une vérification de sécurité [anti-CSRF](https://fr.wikipedia.org/wiki/Cross-site_request_forgery) est également appliquée. Si cette vérification échoue, le message d'erreur "Merci de bien vouloir renvoyer le formulaire." sera renvoyé. Pour que cela marche il faut que le formulaire dispose d'un bouton de type "submit", généré à l'aide de la fonction `button`. Exemple : `{{:button type="submit" name="save" label="Enregistrer"}}`.
En cas d'erreurs, le reste du contenu de la section ne sera pas exécuté. Les messages d'erreurs seront placés dans un tableau dans la variable `$form_errors`.
Il est aussi possible de les afficher simplement avec la fonction `{{:form_errors}}`. Cela revient à faire une boucle sur la variable `$form_errors`.
```
{{#form on="save"}}
{{if $_POST.titre|trim === ''}}
{{:error message="Le titre est vide."}}
{{/if}}
{{* La ligne suivante ne sera pas exécutée si le titre est vide. *}}
{{:save title=$_POST.titre|trim}}
{{else}}
{{:form_errors}}
{{/form}}
```
Il est possible d'utiliser `{{:form_errors}}` en dehors du bloc `{{else}}` :
```
{{#form on="save"}}
{{/form}}
{{:form_errors}}
```
<!--
NOTE (bohwaz, 24/05/2023) : l'utilisation des règles de validation de Laravel me semble donner du code peu lisible, ce n'est donc pas documenté/complètement implémenté pour le moment.
Si l'élément dont le nom spécifié dans le paramètre `on` a été envoyé en `POST`, alors le formulaire est vérifié selon les autres paramètres. Une vérification de sécurité anti-CSRF est également appliquée. Si cette vérification échoue, le message d'erreur "Merci de bien vouloir renvoyer le formulaire." sera renvoyé.
Chaque paramètre supplémentaire indique un champ du formulaire qui doit être récupéré et validé. Le nom du paramètre doit correspondre au nom du champ dans le formulaire. La valeur du paramètre doit contenir une liste de règles de validations, séparées par des virgules `,`. Chaque règle peut prendre des paramètres, après deux points `:`.
Exemple pour un champ de formulaire nommé `titre` dont on veut qu'il soit présent et fasse entre 5 et 100 caractères : `titre="required,min:5,max:100"`
Si le titre fait moins de 5 caractères, le message d'erreur suivant sera renvoyé : `Le champ "titre" fait moins de 5 caractères.`
On peut spécifier une règle spéciale nommée `label` pour changer le nom du champ : `titre="required,min:5,max:100,label:Titre du texte"`. Cela modifiera le message d'erreur : `Le champ "Titre du texte" fait moins de 5 caractères.`
Chacun de ces paramètres sera disponible à l'intérieur de la section sous la forme d'une variable :
```
{{#form titre="required,min:5"}}
{{:save title=$titre}}
{{/form}}
```
Toute erreur dans le corps de la section `{{#form}}…{{/form}}` fera arrêter l'exécution, et le message d'erreur sera ajouté à la liste des erreurs du formulaire :
```
{{#form on="save"}}
{{if !$_POST.titre|trim}}
{{:error message="Pas de titre !"}}
{{/if}}
{{* La ligne suivante ne sera pas exécutée si le titre est vide. *}}
{{:save title=$_POST.titre}}
{{/form}}
```
### Transformation des variables
Certaines règles de validation ont un effet de transformation sur les variables présentes dans le corps de la section :
* `string` s'assure que la variable est une chaîne de texte
* `int` transforme la variable en nombre entier
* `float` transforme la variable en nombre flottant
* `bool` transforme la variable en booléen
* `date` ou `date_format` transforment la variable en date
### Exemple
Considérons ce formulaire par exemple :
```
<form method="post" action="">
<fieldset>
<legend>Enregistrer un paiement</legend>
<dl>
{{:input type="text" required=true name="titre" label="Titre"}}
{{:input type="money" required=true name="montant" label="Montant"}}
</dl>
<p class="submit">
{{:button type="submit" label="Enregistrer" name="save"}}
</p>
</fieldset>
</form>
```
On pourrait l'enregistrer comme ceci :
```
{{if $_POST.save}}
{{if $_POST.titre|trim === ''}}
{{:assign error="Le titre est vide"}}
{{elseif $_POST.montant|trim === '' || $_POST.montant|money_int < 0}}
{{:assign error="Le montant est vide ou négatif"}}
{{else}}
{{:save title=$_POST.titre|trim amount=$_POST.montant|money_int}}
{{/if}}
{{/if}}
{{if $error}}
<p class="error block">{{$error}}</p>
{{/if}}
```
Mais alors dans ce cas il faut multiplier les conditions pour les champs.
La section `{{#form …}}` permet de simplifier ces tests, et s'assurer qu'aucune attaque CSRF n'a lieu :
```
{{#form on="save"
titre="required,string,min:1,label:Titre"
montant="required,money,min:0,label:Montant du paiement"
}}
{{:save title=$titre amount=$montant}}
{{else}}
{{:form_errors}}
{{/form}}
```
### Règles de validation
| Nom de la règle | Description | Paramètres |
| :- | :- | :- |
| `required` | ...
-->
## load <sup>(sql)</sup>
Note : cette section hérite de `sql` (voir plus haut). De ce fait, le nombre de résultats est limité à 10000 par défaut, si le paramètre `limit` n'est pas renseigné.
Charge un ou des documents pour le module courant.
| Paramètre | Optionnel / obligatoire ? | Fonction |
| :- | :- | :- |
| `module` | optionnel | Nom unique du module lié (par exemple : `recu_don`). Si non spécifié, alors le nom du module courant sera utilisé. |
| `key` | optionnel | Clé unique du document |
| `id` | optionnel | Numéro unique du document |
| `each` | optionnel | Traiter une clé du document comme un tableau |
Il est possible d'utiliser d'autres paramètres : `{{#load cle="valeur"}}`. Cela va comparer `"valeur"` avec la valeur de la clé `cle` dans le document JSON. C'est l'équivalent d'écrire `where="json_extract(document, '$.cle') = 'valeur'"`.
Pour des conditions plus complexes qu'une simple égalité, il est possible d'utiliser la syntaxe courte `$$…` dans le paramètre `where`. Ainsi `where="$$.nom LIKE 'Bourse%'` est l'équivalent de `where="json_extract(document, '$.nom') LIKE 'Bourse%'"`.
Voir [la documentation de SQLite pour plus de détails sur la syntaxe de json_extract](https://www.sqlite.org/json1.html#jex).
Note : un index SQL dynamique est créé pour chaque requête utilisant une clause `json_extract`.
Chaque itération renverra ces deux variables :
| Variable | Valeur |
| :- | :- |
| `$key` | Clé unique du document |
| `$id` | Numéro unique du document |
Ainsi que chaque élément du document JSON lui-même.
### Exemples
Afficher le nom du document dont la clé est `facture_43` :
```
{{#load key="facture_43"}}
{{$nom}}
{{/load}}
```
Afficher la liste des devis du module `invoice` depuis un autre module par exemple :
```
{{#load module="invoice" type="quote"}}
<h1>Titre du devis : {{$subject}}</h1>
<h2>Montant : {{$total}}</h2>
{{/load}}
```
### Utilisation du paramètre `each`
Le paramètre `each` est utile pour faire une boucle sur un tableau contenu dans le document. Ce paramètre doit contenir un chemin JSON valide. Par exemple `membres[1].noms` pour boucler sur le tableau `noms`, du premier élément du tableau `membres`. Voir la documentation [de la fonction json_each de SQLite pour plus de détails](https://www.sqlite.org/json1.html#jeach).
Pour chaque itération de la section, la variable `{{$value}}` contiendra l'élément recherché dans le critère `each`.
Par exemple nous pouvons avoir un élément `membres` dans notre document JSON qui contient un tableau de noms de membres :
```
{{:assign var="membres." value="Greta Thunberg}}
{{:assign var="membres." value="Valérie Masson-Delmotte"}}
{{:save membres=$membres}}
```
Nous pouvons utiliser `each` pour faire une liste :
```
{{#load each="membres"}}
- {{$value}}
{{/load}}
```
Ou pour récupérer les documents qui correspondent à un critère :
```
{{#load each="membres" where="value = 'Greta Thunberg'"}}
Le document n°{{$id}} est celui qui parle de Greta.
{{/load}}
```
## list
Attention : cette section n'hérite **PAS de `sql`**.
Un peu comme `{{#load}}` cette section charge les documents d'un module, mais au sein d'une liste (tableau HTML).
Cette liste gère automatiquement l'ordre selon les préférences des utilisateurs, ainsi que la pagination.
Cette section est très puissante et permet de générer des listes simplement, une fois qu'on a saisi la logique de son fonctionnement.
| Paramètre | Optionnel / obligatoire ? | Fonction |
| :- | :- | :- |
| `schema` | **requis** si `select` n'est pas fourni | Chemin vers un fichier de schéma JSON qui représenterait le document |
| `select` | **requis** si `schema` n'est pas fourni | Liste des colonnes à sélectionner, sous la forme `$$.colonne AS "Colonne"`, chaque colonne étant séparée par un point-virgule. |
| `module` | *optionnel* | Nom unique du module lié (par exemple : `recu_don`). Si non spécifié, alors le nom du module courant sera utilisé. |
| `columns` | *optionnel* | Permet de n'afficher que certaines colonnes du schéma. Indiquer ici le nom des colonnes, séparées par des virgules. |
| `order` | *optionnel* | Colonne utilisée par défaut pour le tri (si l'utilisateur n'a pas choisi le tri sur une autre colonne). Si `select` est utilisé, il faut alors indiquer ici le numéro de la colonne, et non pas son nom. |
| `desc` | *optionnel* | Si ce paramètre est à `true`, l'ordre de tri sera inversé. |
| `max` | *optionnel* | Nombre d'éléments à afficher dans la liste, sur chaque page. |
| `where` | *optionnel* | Condition `WHERE` de la requête SQL. |
| `debug` | *optionnel* | Si ce paramètre existe, la requête SQL exécutée sera affichée avant le début de la boucle. |
| `explain` | *optionnel* | Si ce paramètre existe, l'explication de la requête SQL exécutée sera affichée avant le début de la boucle. |
| `disable_user_ordering` | *optionnel* | Booléen. Si ce paramètre est `true`, il ne sera pas possible à l'utilisateur d'ordonner les colonnes. |
Pour déterminer quelles colonnes afficher dans le tableau, il faut utiliser soit le paramètre `schema` pour indiquer un fichier de schéma JSON qui sera utilisé pour donner le libellé des colonnes (via la `description` indiquée dans le schéma), soit le paramètre `select`, où il faut alors indiquer le nom et le libellé des colonnes sous la forme `$$.colonne1 AS "Libellé"; $$.colonne2 AS "Libellé 2"`.
Comme pour `load`, il est possible d'utiliser des paramètres supplémentaires : `cle="valeur"`. Cela va comparer `"valeur"` avec la valeur de la clé `cle` dans le document JSON. C'est l'équivalent d'écrire `where="json_extract(document, '$.cle') = 'valeur'"`.
Pour des conditions plus complexes qu'une simple égalité, il est possible d'utiliser la syntaxe courte `$$…` dans le paramètre `where`. Ainsi `where="$$.nom LIKE 'Bourse%'` est l'équivalent de `where="json_extract(document, '$.nom') LIKE 'Bourse%'"`.
Voir [la documentation de SQLite pour plus de détails sur la syntaxe de json_extract](https://www.sqlite.org/json1.html#jex).
Note : un index SQL dynamique est créé pour chaque requête utilisant une clause `json_extract`.
Chaque itération renverra toujours ces deux variables :
| Variable | Valeur |
| :- | :- |
| `$key` | Clé unique du document |
| `$id` | Numéro unique du document |
Ainsi que chaque élément du document JSON lui-même.
La section ouvre un tableau HTML et le ferme automatiquement, donc le contenu de la section **doit** être une ligne de tableau HTML (`<tr>`).
Dans chaque ligne du tableau il faut respecter l'ordre des colonnes indiqué dans `columns` ou `select`. Une dernière colonne est réservée aux boutons d'action : `<td class="actions">...</td>`.
**Attention :** une seule liste peut être utilisée dans une même page. Avoir plusieurs listes provoquera des problèmes au niveau du tri des colonnes.
### Exemples
Lister le nom, la date et le montant des reçus fiscaux, à partir du schéma JSON suivant :
```
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"date": {
"description": "Date d'émission",
"type": "string",
"format": "date"
},
"adresse": {
"description": "Adresse du bénéficiaire",
"type": "string"
},
"nom": {
"description": "Nom du bénéficiaire",
"type": "string"
},
"montant": {
"description": "Montant",
"type": "integer",
"minimum": 0
}
}
}
```
Le code de la section sera alors comme suivant :
```
{{#list schema="./recu.schema.json" columns="nom, date, montant"}}
<tr>
<th>{{$nom}}</th>
<td>{{$date|date_short}}</td>
<td>{{$montant|raw|money_currency}}</td>
<td class="actions">
{{:linkbutton shape="eye" label="Ouvrir" href="./voir.html?id=%d"|args:$id target="_dialog"}}
</td>
</tr>
{{else}}
<p class="alert block">Aucun reçu n'a été trouvé.</p>
{{/list}}
```
Si le paramètre `columns` avait été omis, la colonne `adresse` aurait également été incluse.
Il est à noter que si l'utilisation directe du schéma est bien pratique, cela ne permet pas de récupérer des informations plus complexes dans la structure JSON, par exemple une sous-clé ou l'application d'une fonction SQL. Dans ce cas il faut obligatoirement utiliser `select`. Par exemple ici on veut pouvoir afficher l'année, et trier sur l'année par défaut :
```
{{#list select="$$.nom AS 'Nom du donateur' ; strftime('%Y', $$.date) AS 'Année'" order=2}}
<tr>
<th>{{$nom}}</th>
<td>{{$col2}}</td>
<td class="actions">
{{:linkbutton shape="eye" label="Ouvrir" href="./voir.html?id=%d"|args:$id target="_dialog"}}
</td>
</tr>
{{else}}
<p class="alert block">Aucun reçu n'a été trouvé.</p>
{{/list}}
```
On peut utiliser le nom des clés du document JSON, mais sinon pour faire référence à la valeur d'une colonne spécifique dans la boucle, il faut utiliser son numéro d'ordre (qui commence à `1`, pas zéro). Ici on veut afficher l'année, donc la seconde colonne, donc `$col1`.
Noter aussi l'utilisation du numéro de la colonne de l'année (`2`) pour le paramètre `order`, qui avec `select` doit indiquer le numéro de la colonne à utiliser pour l'ordre.
<!--
TODO:
## files
Liste les fichiers du module courant, éventuellement limité à un sous-répertoire designé.
| Paramètre | Optionnel / obligatoire ? | Fonction |
| :- | :- | :- |
| `path` | optionnel | Désigne le sous-répertoire éventuel pour limiter la liste. |
| `recursive` | optionnel | Booléen. Indique si on veut aussi lister les fichiers dans les sous-répertoires. Défaut : `false`. |
Exemple :
```
<table>
{{#files path="facture43" recursive=false}}
<tr>
<td>{{if $is_dir}}Répertoire{{else}}{{$mime}}{{/if}}</td>
<td>{{$name}}</td>
<td>{{$size|size_in_bytes}}</td>
</tr>
{{/files}}
</table>
```
-->

44
doc/admin/keyboard.md Normal file
View file

@ -0,0 +1,44 @@
Title: Raccourcis claviers dans l'édition de texte — Paheko
{{{.nav
* **[Raccourcis claviers](keyboard.html)**
* [Syntaxe MarkDown complète](markdown.html)
* [Référence rapide MarkDown](markdown_quickref.html)
}}}
# Raccourcis clavier
Depuis l'édition du texte :
| Raccourci | Action |
| :- | :- |
| <kbd>Ctrl</kbd> + <kbd>G</kbd> | Mettre en gras |
| <kbd>Ctrl</kbd> + <kbd>I</kbd> | Mettre en italique |
| <kbd>Ctrl</kbd> + <kbd>T</kbd> | Mettre en titre |
| <kbd>Ctrl</kbd> + <kbd>L</kbd> | Transformer en lien |
| <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>I</kbd> | Insérer une image |
| <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>F</kbd> | Insérer un fichier |
| <kbd>Ctrl</kbd> + <kbd>P</kbd> | Prévisualiser |
| <kbd>Ctrl</kbd> + <kbd>S</kbd> | Enregistrer |
| <kbd>F11</kbd> | Activer ou désactiver l'édition plein écran |
| <kbd>F1</kbd> | Afficher l'aide |
| <kbd>Echap</kbd> | Prévisualiser (rappuyer pour revenir à l'édition) |
Depuis la prévisualisation :
| Raccourci | Action |
| :- | :- |
| <kbd>Ctrl</kbd> + <kbd>P</kbd> | Retour à l'édition |
Depuis l'aide ou l'insertion de fichier :
| Raccourci | Action |
| :- | :- |
| <kbd>Echap</kbd> | Fermer et revenir à l'édition |
# Ajouter un fichier ou une image
Il est aussi possible de faire glisser et déposer une image ou un fichier sur le champ d'édition du texte pour l'envoyer et l'insérer.
De même, il est aussi possible d'utiliser le copier/coller dans le texte pour insérer un fichier ou une image.

709
doc/admin/markdown.md Normal file
View file

@ -0,0 +1,709 @@
Title: Référence complète MarkDown — Paheko
{{{.nav
* [Raccourcis claviers](keyboard.html)
* **[Syntaxe MarkDown complète](markdown.html)**
* [Référence rapide MarkDown](markdown_quickref.html)
}}}
<<toc aside>>
# Syntaxe MarkDown
Paheko permet d'utiliser la syntaxe [MarkDown](https://fr.wikipedia.org/wiki/Markdown) dans les pages du site web.
Cette syntaxe est la plus répandue dans les outils d'édition de texte, si vous ne la connaissez pas encore, voici les règles qu'on peut utiliser pour formatter du texte avec MarkDown dans la plupart des outils (dont Paheko), ainsi que [les règles spécifiques supportées par Paheko](#extensions).
## Styles de texte
### Italique
Pour mettre un texte en italique il faut l'entourer de tirets bas ou d'astérisques :
```
Ce texte est en *italique, dingue !*
```
Donnera :
> Ce texte est en *italique, dingue !*
### Gras
Pour le gras, procéder de la même manière, mais avec deux tirets bas ou deux astérisques :
```
Ce texte est **très gras**.
```
> Ce texte est **très gras**.
### Gras et italique
Pour combiner, utiliser trois tirets ou trois astérisques :
```
Ce texte est ***gras et italique***.
```
> Ce texte est ***gras et italique***.
### Barré
Utiliser un symbole tilde pour barrer un texte :
```
Texte ~~complètement barré~~.
```
> Texte ~~complètement barré~~.
### Surligné
Il est possible de marquer une phrase ou un mot comme surligné en l'entourant de deux signes égal :
```
Ce texte est ==surligné==.
```
> Ce texte est ==surligné==.
### Code
Il est possible d'indiquer du code dans une ligne de texte avec un caractère *backtick* (accent grave en français, obtenu avec les touches [Alt Gr + 7](https://superuser.com/questions/254076/how-do-i-type-the-tick-and-backtick-characters-on-windows)) :
```
Le code `<html>` c'est rigolo !
```
> Le code `<html>` c'est rigolo !
### Avertissement sur les styles de texte
Un style de texte ne s'applique que dans un même paragraphe, il n'est pas possible d'appliquer un style sur plusieurs paragraphes :
Dans l'exemple suivant, les astérisques ne seront pas remplacées par du gras, elles resteront telles quelles :
```
Ce texte n'est pas très **gras.
Et celui-ci encore moins**.
```
> Ce texte n'est pas très **gras.
>
> Et celui-ci encore moins**.
## Liens
Créez un lien en mettant le texte désiré entre crochets et le lien associé entre parenthèses :
```
Je connais un super gestionnaire [d'association](https://paheko.cloud/) !
```
Donne :
> Je connais un super gestionnaire [d'association](https://paheko.cloud/) !
Il est possible de faire un lien vers une autre page du site web en utilisant son adresse unique :
```
N'oubliez pas de [vous inscrire à notre atelier](atelier-soudure).
```
Il est aussi possible de simplement inclure une adresse URL et elle sera automatiquement transformée en lien :
```
https://paheko.cloud/
```
## Blocs
### Paragraphes et retours à la ligne
Une ligne vide indique un changement de paragraphe :
```
Ceci est un paragraphe.
Ceci est est un autre.
```
Un retour à la ligne simple est traité comme tel :
```
Ceci est un
paragraphe.
```
> Ceci est un
> paragraphe.
### Titres et sous-titres
Pour faire un titre, vous devez mettre un ou plusieurs caractères *hash* (`#`) au début de la ligne.
Un titre avec un seul caractère est un titre principal (niveau 1), avec deux caractères c'est un sous-titre (niveau 2), etc. jusqu'au niveau 6.
```
# Titre principal (niveau 1)
## Sous-titre (niveau 2)
### Sous-sous-titre (niveau 3)
#### Niveau 4
##### Niveau 5
###### Dernier niveau de sous-titre (6)
```
Donnera :
> # Titre principal (niveau 1) {.no_toc}
> ## Sous-titre (niveau 2) {.no_toc}
> ### Sous-sous-titre (niveau 3) {.no_toc}
> #### Niveau 4 {.no_toc}
> ##### Niveau 5 {.no_toc}
> ###### Dernier niveau de sous-titre (6) {.no_toc}
### Listes
Vous pouvez créer des listes avec les caractères astérisque (`*`) et tiret `-` en début de ligne pour des listes non ordonnées :
```
* une élément
* un autre
- un sous élément
- un autre sous élément
* un dernier élément
```
> * une élément
> * un autre
> - un sous élément
> - un autre sous élément
> * un dernier élément
Ou avec des nombres pour des listes ordonnées :
```
1. élément un
2. élément deux
```
> 1. élément un
> 2. élément deux
L'ordre des nombres n'est pas important, seul le premier nombre est utilisé pour déterminer à quel numéro commencer la liste.
Exemple :
```
3. A
5. B
4. C
```
> 3. A
> 5. B
> 4. C
Il est ainsi possible d'utiliser uniquement le même numéro pour ne pas avoir à numéroter sa liste :
```
1. Un
1. Deux
```
> 1. Un
> 1. Deux
### Citations
Les citations se font en ajoutant le signe *supérieur à* (`>`) au début de la ligne :
```
> Programming is not a science. Programming is a craft.
```
> Programming is not a science. Programming is a craft.
### Code
Créez un bloc de code en indentant chaque ligne avec quatre espaces, ou en mettant trois accents graves ``` ` ``` (*backtick*, obtenu avec [Alt Gr + 7](https://superuser.com/questions/254076/how-do-i-type-the-tick-and-backtick-characters-on-windows)) sur la ligne au dessus et en dessous de votre code:
```
<html>...</html>
```
Résultat :
```
<html>...</html>
```
### Tableaux
Pour créer un tableau vous devez séparer les colonnes avec des barres verticales (`|`, obtenu avec les touches [AltGr + 6](https://fr.wikipedia.org/wiki/Barre_verticale#Saisie)).
La première ligne contient les noms des colonnes, la seconde ligne contient la ligne de séparation (chaque cellule doit contenir un ou plusieurs tirets), et les lignes suivantes représentent le contenu du tableau.
```
| Colonne 1 | Colonne 2 |
| - | - | - |
| AB | CD |
```
| Colonne 1 | Colonne 2 |
| - | - |
| AB | CD |
Par défaut les colonnes sont centrées. On peut aussi aligner le texte à gauche ou à droite en mettant deux points après le ou les tirets de la ligne suivant l'entête :
```
| Aligné à gauche | Centré | Aligné à droite |
| :--------------- |:---------------:| :--------------:|
| Aligné à gauche | ce texte | Aligné à droite |
| Aligné à gauche | est | Aligné à droite |
| Aligné à gauche | centré | Aligné à droite |
```
| Aligné à gauche | Centré | Aligné à droite |
| :--------------- |:---------------:| :--------------:|
| Aligné à gauche | ce texte | Aligné à droite |
| Aligné à gauche | est | Aligné à droite |
| Aligné à gauche | centré | Aligné à droite |
### Ligne de séparation
Il suffit de mettre au moins 3 tirets à la suite sur une ligne séparée pour ajouter une ligne de séparation :
```
---
```
Résultat :
---
### Commentaires
Pour ajouter un commentaire qui ne sera pas affiché dans le texte, utiliser la syntaxe suivante :
```
<!-- Ceci est un commentaire -->
```
## Notes de bas de page
Pour créer une note de base de page, il faut mettre entre crochets un signe circonflexe (obtenu en appuyant sur la touche circonflexe, puis sur espace) suivi du numéro ou du nom de la note. Enfin, à la fin du texte il faudra répéter les crochets, le signe circonflexe, suivi de deux points et de la définition.
```
Texte très intéressant[^1]. Approuvé par 100% des utilisateurs[^Source].
[^1]: Ceci est une note de bas de page
[^Source]: Enquête Paheko sur la base de 1 personne interrogée.
```
Donnera ceci :
> Texte très intéressant[^1]. Approuvé par 100% des utilisateurs[^Source].
>
> [^1]: Ceci est une note de bas de page
> [^Source]: Enquête Paheko sur la base de 1 personne interrogée.
## Insertion de vidéos depuis un service de vidéo
Certains services vidéo comme les instances Peertube permettent l'intégration des vidéos.
Pour cela il faut recopier le code d'intégration donné par le service vidéo. Voici un exemple :
```
<iframe title="ENQUÊTE : Brûler la Forêt pour Sauver le Climat ? | EP 3 - Le bois énergie" width="560" height="315" src="https://peertube.stream/videos/embed/12c52265-e3b3-4bad-93f3-f2c1df5bbe4f" frameborder="0" allowfullscreen="" sandbox="allow-same-origin allow-scripts allow-popups"></iframe>
```
Résultat :
<iframe title="ENQUÊTE : Brûler la Forêt pour Sauver le Climat ? | EP 3 - Le bois énergie" width="560" height="315" src="https://peertube.stream/videos/embed/12c52265-e3b3-4bad-93f3-f2c1df5bbe4f" frameborder="0" allowfullscreen="" sandbox="allow-same-origin allow-scripts allow-popups"></iframe>
## Identifiant et classe CSS sur les titres
Il est possible de spécifier l'ID et la classe CSS d'un titre en les rajoutant à la fin du titre, entre accolades, comme ceci :
```
## Titre de niveau 2 {#titre2} {.text-center}
```
Le code HTML résultant sera comme ceci :
```
<h2 id="titre2" class="text-center">Titre de niveau 2</h2>
```
## Classes CSS
Il est possible de donner une classe CSS parente à un ensemble d'éléments en les mettant au centre d'un bloc définissant cette classe :
```
{{{.custom-quote .custom-block
Paragraphe
> Citation
}}}
```
Créera le code HTML suivant :
```
<div class="custom-quote custom-block">
<p>Paragraphe</p>
<blockquote><p>Citation</p></blockquote>
</div>
```
## Tags HTML
Certains tags HTML sont autorisés :
| Tag | Utilisation | Exemple |
| :- | :- | :- |
| `<kbd>` | Touches de clavier | <kbd>Ctrl</kbd> + <kbd>B</kbd> |
| `<samp>` | Exemple de programme en console | <samp>bohwaz@platypus ~ % sudo apt install paheko</samp> |
| `<var>` | Variable dans un programme informatique | <var>ab</var> + <var>cd</var> = 42 |
| `<del>` | Texte supprimé | Texte <del>supprimé</del> |
| `<ins>` | Texte ajouté | Texte <ins>ajouté</ins> |
| `<sup>` | Texte en exposant | Texte<sup>exposant</sup> |
| `<sub>` | Texte en indice | Texte<sub>indice</sub> |
| `<mark>` | Texte surligné | Texte <mark>surligné</mark> |
| `<audio>` | Insérer un lecteur audio dans la page | `<audio src="mon_fichier.mp3">` |
| `<video>` | Insérer une vidéo dans la page | `<video src="mon_fichier.webm">` |
Mais leurs possibilités sont limitées, notamment sur les attributs autorisés.
# Extensions
Paheko propose des extensions au langage MarkDown, qui n'existent pas dans les autres logiciels utilisant aussi MarkDown.
Toutes ces extensions se présentent sous la forme d'un code situé entre deux signes **inférieur à** (`<<`) et deux signes **supérieur à** (`>>`), à ne pas confondre avec les guillements français (`«` et `»`).
## Images jointes
Il est possible d'intégrer une image jointe à la page web en plaçant le code suivant sur une ligne (sans autre texte) :
```
<<image|Nom_fichier.jpg|Alignement|Légende>>
```
* `Nom_fichier.jpg` : remplacer par le nom du fichier de l'image (parmi les images jointes à la page)
* `Alignement` : remplacer par l'alignement :
* `gauche` ou `left` : l'image sera placée à gauche en petit (200 pixels), le texte remplira l'espace laissé sur la droite de l'image ;
* `droite` ou `right` : l'image sera placée à droite en petit, le texte remplira l'espace laissé sur la gauche de l'image ;
* `centre` ou `center` : l'image sera placée au centre en taille moyenne (500 pixels), le texte sera placé au dessus et en dessous.
* Légende : indiquer ici une courte description de l'image.
Exemple :
```
<<image|mon_image.png|center|Ceci est une belle image>>
```
Il est aussi possible d'utiliser la syntaxe avec des paramètres nommés :
```
<<image file="Nom_fichier.jpg" align="center" caption="Légende">>
```
Les images qui ne sont pas mentionnées dans le texte seront affichées après le texte sous forme de galerie.
## Galerie d'images
Il est possible d'afficher une galerie d'images (sous forme d'images miniatures) avec la balise `<<gallery` qui contient la liste des images à mettre dans la galerie :
```
<<gallery
Nom_fichier.jpg
Nom_fichier_2.jpg
>>
```
Si aucun nom de fichier n'est indiqué, alors toutes les images jointes à la page seront affichées :
```
<<gallery>>
```
### Diaporama d'images
On peut également afficher cette galerie sous forme de diaporama. Dans ce cas une seule image est affichée, et on peut passer de l'une à l'autre.
La syntaxe est la même, mais on ajoute le mot `slideshow` après le mot `gallery` :
```
<<gallery slideshow
Nom_fichier.jpg
Nom_fichier_2.jpg
>>
```
## Fichiers joints
Pour créer un bouton permettant de voir ou télécharger un fichier joint à la page web, il suffit d'utiliser la syntaxe suivante :
```
<<file|Nom_fichier.ext|Libellé>>
```
* `Nom_fichier.ext` : remplacer par le nom du fichier (parmi les fichiers joints à la page)
* `Libellé` : indique le libellé du qui sera affiché sur le bouton, si aucun libellé n'est indiqué alors c'est le nom du fichier qui sera affiché
## Vidéos
Pour inclure un lecteur vidéo dans la page web à partir d'un fichier vidéo joint à la page, il faut utiliser le code suivant :
```
<<video|Nom_du_fichier.ext>>
```
On peut aussi spécifier d'autres paramètres :
* `file` : nom du fichier vidéo
* `poster` : nom de fichier d'une image utilisée pour remplacer la vidéo avant qu'elle ne soit lue
* `subtitles` : nom d'un fichier de sous-titres au format VTT ou SRT
* `width` : largeur de la vidéo (en pixels)
* `height` : hauteur de la vidéo (en pixels)
Exemple :
```
<<video file="Ma_video.webm" poster="Ma_video_poster.jpg" width="640" height="360" subtitles="Ma_video_sous_titres.vtt">>
```
## Sommaire / table des matières automatique
Il est possible de placer le code `<<toc>>` pour générer un sommaire automatiquement à partir des titres et sous-titres :
```
<<toc>>
```
Affichera un sommaire comme celui-ci :
<<toc>>
Il est possible de limiter les niveaux en utilisant le paramètre `level` comme ceci :
```
<<toc level=1>>
```
N'affichera que les titres de niveau 1 (précédés d'un seul signe hash `#`), comme ceci :
<<toc level=1>>
Enfin il est possible de placer la table des matières sur le côté du texte, en utilisant le paramètre `aside` :
```
<<toc level=1 aside>>
```
Note : en plus de la syntaxe `<<toc>>`, Paheko supporte aussi les syntaxes suivantes par compatibilité avec [les autres moteurs de rendu MarkDown](https://alexharv074.github.io/2018/08/28/auto-generating-markdown-tables-of-contents.html) : `{:toc}` `[[_TOC_]]` `[toc]`.
### Exclure un sous-titre du sommaire
Il est aussi possible d'indiquer qu'un titre ne doit pas être inclus dans le sommaire en utilisant la classe `no_toc` comme ceci :
```
## Sous-titre non-inclus {.no_toc}
```
## Grilles et colonnes
Pour une mise en page plus avancée, il est possible d'utiliser les *grilles*, adaptation des [grids en CSS](https://developer.mozilla.org/fr/docs/Web/CSS/CSS_Grid_Layout). Il faut utiliser la syntaxe `<<grid>>...Contenu...<</grid>>`.
Attention, les blocs `<<grid>>` et `<</grid>>` doivent obligatoirement être placés sur des lignes qui ne contiennent rien d'autre.
**Note :** sur petit écran (mobile ou tablette) les grilles et colonnes sont désactivées, tout sera affiché dans une seule colonne, comme si les grilles n'étaient pas utilisées.
Pour spécifier le nombre de colonnes on peut utiliser un raccourci qui *mime* les colonnes, comme ceci :
```
<<grid !!>>
```
Ce code indique qu'on veut créer une grille de 2 colonnes de largeur identique.
Dans les raccourcis, le point d'exclamation `!` indique une colonne simple, et le hash `#` indique une colonne qui prend le reste de la place selon le nombre de colonnes total.
D'autres exemples de raccourcis :
* `!!` : deux colonnes de largeur égale
* `!!!` : trois colonnes de largeur égale
* `!##` : deux colonnes, la première occupant un tiers de la largeur, la seconde occupant les deux tiers
* `!##!` : 4 colonnes, la première occupant un quart de la largeur, la seconde occupant la moitié, la dernière occupant le quart
Alternativement, pour plus de contrôle, ce bloc accepte les paramètres suivants :
* `short` : notation courte décrite ci-dessus
* `gap` : espacement entre les blocs de la grille
* `template` : description CSS complète de la grille (propriété [`grid-template`](https://developer.mozilla.org/fr/docs/Web/CSS/grid-template))
Après ce premier bloc `<<grid>>` qui définit la forme de la grille, on peut entrer le contenu de la première colonne.
Pour créer la seconde colonne il faut simplement placer un nouveau bloc `<<grid>>` vide (aucun paramètre) sur une ligne.
Enfin on termine en fermant la grille avec un block `<</grid>>`. Voici un exemple complet :
```
<<grid !!!>>
Col. 1
<<grid>>
Col. 2
<<grid>>
Col. 3
<</grid>>
```
<<grid short="!!!" debug>>
Col. 1
<<grid>>
Col. 2
<<grid>>
Col. 3
<</grid>>
Exemple avec 3 colonnes, dont 2 petites et une large :
```
<<grid !##!>>
Col. 1
<<grid>>
Colonne 2 large
<<grid>>
Col. 3
<</grid>>
```
<<grid short="!##!" debug>>
Col. 1
<<grid>>
Colonne 2 large
<<grid>>
Col. 3
<</grid>>
Il est possible de créer plus de blocs qu'il n'y a de colonnes, cela créera une nouvelle ligne avec le même motif :
```
<<grid !!>>
L1 C1
<<grid>>
L1 C2
<<grid>>
L2 C1
<<grid>>
L2 C2
<</grid>>
```
<<grid short="!!" debug>>
L1 C1
<<grid>>
L1 C2
<<grid>>
L2 C1
<<grid>>
L2 C2
<</grid>>
Enfin, il est possible d'utiliser la notation CSS [`grid-row`](https://developer.mozilla.org/en-US/docs/Web/CSS/grid-row) et [`grid-column`](https://developer.mozilla.org/en-US/docs/Web/CSS/grid-column) pour chaque bloc, permettant de déplacer les blocs, ou de faire en sorte qu'un bloc s'étende sur plusieurs colonnes ou plusieurs lignes. Pour cela il faut utiliser le paramètre `row` ou `column` qui précède le bloc :
```
<<grid short="#!!" column="span 2">>
A
<<grid row="span 2">>
B
<<grid>>
C
<<grid>>
D
<</grid>>
```
<<grid short="#!!" debug column="span 2">>
A
<<grid row="span 2">>
B
<<grid>>
C
<<grid>>
D
<</grid>>
Noter que dans ce cas on doit utiliser la notation `short="…"` pour pouvoir utiliser les autres paramètres.
Enfin, il est possible d'aligner un bloc verticalement par rapport aux autres en utilisant le paramètre `align` (équivalent de la propriété CSS [`align-self`](https://developer.mozilla.org/en-US/docs/Web/CSS/align-self)).
## Alignement du texte
Il suffit de placer sur une ligne seule le code `<<center>>` pour centrer du texte :
```
<<center>>
Texte centré
<</center>>
```
On peut procéder de même avec `<<left>>` et `<<right>>` pour aligner à gauche ou à droite.
## Couleurs
Comme sur les [Skyblogs](https://decoblog.skyrock.com/), il est possible de mettre en couleur le texte et le fond, et même de créer des dégradés !
Utiliser la syntaxe `<<color COULEUR>>...texte...<</color>>` pour changer la couleur du texte, ou `<<bgcolor COULEUR>>...texte...<</bgcolor>>` pour la couleur du fond.
Il est possible d'indiquer plusieurs couleurs, séparées par des espaces, pour créer des dégradés.
```
<<color red>>Rouge !<</color>>
<<bgcolor yellow>>Fond jaune pétant !<</bgcolor>>
<<color cyan green salmon>>Dégradé de texte !<</color>>
<<bgcolor chocolate khaki orange>>Dégradé du fond<</bgcolor>>
<<bgcolor darkolivegreen darkseagreen >>
<<color darkred>>
## Il est aussi possible de faire des blocs colorés
Avec des paragraphes
> Et citations
<</color>>
<</bgcolor>>
```
> <<color red>>Rouge !<</color>>
> <<bgcolor yellow>>Fond jaune pétant !<</bgcolor>>
> <<color cyan green salmon>>Dégradé de texte !<</color>>
> <<bgcolor chocolate khaki orange>>Dégradé du fond<</bgcolor>>
>
> <<bgcolor greenyellow indianred>>
> <<color darkred darkgreen>>
> ## Il est aussi possible de faire des blocs colorés {.no_toc}
>
> Avec des paragraphes
>
> > Et citations
>
> <</color>>
> <</bgcolor>>
Il est possible d'utiliser les couleurs avec [leur nom](https://developer.mozilla.org/en-US/docs/Web/CSS/named-color) ou leur code hexadécimal (exemple : `#ff0000` pour rouge).
**Attention : cette fonctionnalité est rigolote mais doit être utilisé avec parcimonie, en effet cela risque de rendre le texte illisible, notamment pour les personnes daltoniennes.**

View file

@ -0,0 +1,55 @@
Title: Référence rapide MarkDown — Paheko
{{{.nav
* [Raccourcis claviers](keyboard.html)
* [Syntaxe MarkDown complète](markdown.html)
* **[Référence rapide MarkDown](markdown_quickref.html)**
}}}
# Référence rapide MarkDown
|Nom | Syntaxe | Rendu | Notes |
| :- | :- | :- | :- |
| Italique | `*italique*` | *italique* | |
| Gras | `**gras**` | **gras** | |
| Gras et italique | `***gras et italique***` | ***gras et italique*** | |
| Barré | `~~barré~~` | ~~barré~~ | [^P] |
| Surligné | `==surligné==` | ==surligné== | [^P] |
| Lien | `[Libellé du lien](adresse)` | [Libellé du lien](https://paheko.cloud/) | |
| Titre niveau 1 | `# Titre 1` | <h1>Titre 1</h1> | |
| Titre niveau 2 | `## Titre 2` | <h2>Titre 2</h2> | |
| Titre niveau 3 | `### Titre 3` | <h3>Titre 3</h3> | |
| Titre niveau 4 | `#### Titre 4` | <h4>Titre 4</h4> | |
| Titre niveau 5 | `##### Titre 5` | <h5>Titre 5</h5> | |
| Titre niveau 6 | `###### Titre 6` | <h6>Titre 6</h6> | |
| Liste | <pre><code>\* Liste 1<br>\* Liste 2</code></pre> | <ul><li>Liste 1</li><li>Liste 2</li></ul> | |
| Liste imbriquée | <pre><code>\* Liste 1<br> \* Sous-liste 1</code></pre> | <ul><li>Liste 1<ul><li>Sous-liste 1</li></ul></li></ul> | |
| Liste numérotée | <pre><code>1. Liste 1<br>2. Liste 2</code></pre> | <ol><li>Liste 1</li><li>Liste 2</li></ol> | |
| Code dans du texte | Voir ce <code>\`code\`</code> | Voir ce `code` | |
| Bloc de code | <pre><code>\```<br>Bloc de code<br>\```</code></pre> | <pre><code>Bloc de code</code></pre> | |
| Citation | <pre><code>> Citation<br>> Citation</code></pre> | <blockquote>Citation<br>Citation</blockquote> | |
| Tableau | <pre><code>\| Colonne 1 \| Colonne 2 \|<br>\| - \| - \|<br>\| A \| B \|</code></pre> | <table><thead><tr><th>Colonne 1</th><th>Colonne 2</th></tr></thead><tbody><tr><td>A</td><td>B</td></tr></tbody></table> | |
| Ligne horizontale | `----` | <hr /> | |
| Référence à une note de bas de page | `[^1]` | [^1] | [^P] |
| Définition d'une note de bas de page | <pre><code>\[^1]: Définition</code></pre> | [^1] | [^P] |
| Bloc avec classe CSS | <pre><code>{{{.boutons<br />* [Paheko](https://paheko.cloud/)<br />}}}</code></pre> | <div class="boutons"><ul><li><a href="https://paheko.cloud/">Paheko</a></li></ul></div> | [^P] |
| Sommaire / table des matières | `<<toc>>` | *(ne peut être montré sur cette page)* | [^P] |
| Image jointe | `<<image|nom_image.jpg|center|Légende>>` | *(ne peut être montré sur cette page)* | [^P] |
| Fichier joint | `<<file|nom_fichier.pdf|Libellé>>` | *(ne peut être montré sur cette page)* | [^P] |
| Grille à 2 colonnes | <pre><code>\<<grid !!>><br>Colonne 1<br><br>\<<grid>><br>Colonne 2<br><br>\<</grid>></code></pre> | *(ne peut être montré sur cette page)* | [^P] |
| Texte centré | `<<center>>Centre<</center>>` | <div style="text-align: center;">Centre</div> | [^P] |
| Texte aligné à droite | `<<right>>Droite<</right>>` | <div style="text-align: right;">Droite</div> | [^P] |
| Texte coloré | `<<color red>>Rouge<</color>>` | <<color red>>Rouge<</color>> | [^P] |
| Fond coloré | `<<bgcolor green>>Vert<</color>>` | <<bgcolor green>>Vert<</color>> | [^P] |
| Dégradé de texte | `<<color orange cyan>>Orange à cyan<</color>>` | <<color orange cyan>>Orange à cyan<</color>> | [^P] |
| Dégradé de fond | `<<bgcolor orange cyan>>Orange à cyan<</color>>` | <<bgcolor orange cyan>>Orange à cyan<</color>> | [^P] |
| Clavier | `<kbd>Ctrl</kbd> + <kbd>C</kbd>` | <kbd>Ctrl</kbd> + <kbd>C</kbd> | |
| Exemple console | `<samp>Exemple</samp>` | <samp>Exemple</samp> | |
| Variable maths | `<var>ab</var> + <var>cd</var> = 42` | <var>ab</var> + <var>cd</var> = 42 | |
| Texte supprimé | `<del>supprimé</del>` | <del>supprimé</del> | |
| Texte ajouté | `<ins>ajouté</ins>` | <ins>ajouté</ins> | |
| Exposant | `Texte<sup>exposant</sup>` | Texte<sup>exposant</sup> | |
| Indice | `Texte<sub>indice</sub>` | Texte<sub>indice</sub> | |
[^1]: Exemple de note de bas de page
[^P]: Indique une syntaxe qui ne fait pas partie du standard Markdown, mais est spécifique à Paheko.

338
doc/admin/modules.md Normal file
View file

@ -0,0 +1,338 @@
Title: Développer des modules pour Paheko
{{{.nav
* **[Modules](modules.html)**
* [Documentation Brindille](brindille.html)
* [Fonctions](brindille_functions.html)
* [Sections](brindille_sections.html)
* [Filtres](brindille_modifiers.html)
}}}
<<toc aside>>
# Introduction
Depuis la version 1.3, Paheko dispose d'extensions modifiables, nommées **Modules**.
Les modules permettent de créer et modifier des formulaires, des modèles de documents simples, à imprimer, mais aussi de créer des "mini-applications" directement dans l'administration de l'association, avec le minimum de code, sans avoir à apprendre à programmer PHP.
Les modules utilisent le langage [Brindille](brindille.html), aussi utilisé pour le site web (qui est lui-même un module). Avec Brindille on parle d'un **squelette** pour un fichier texte contenant du code Brindille.
Les modules ne permettent pas d'exécuter du code PHP, ni de modifier la base de données en dehors des données du module, contrairement aux [plugins](https://fossil.kd2.org/paheko/wiki?name=Documentation/Plugin&p). Grâce à Brindille, les administrateurs de l'association peuvent modifier ou créer de nouveaux modules sans risques pour le serveur, car le code Brindille ne permet pas d'exécuter de fonctions dangereuses. Les **plugins** eux sont écrits en PHP et ne peuvent pas être modifiés par une association. Du fait des risques de sécurité, seuls les plugins officiels sont proposés sur Paheko.cloud.
# Exemples
Paheko fournit quelques modules par défaut, qui peuvent être modifiés ou servir d'inspiration pour de nouveaux modules :
* Reçu de don simple
* Reçu de paiement simple
* Reçu fiscal
* Cartes de membres
* Heures d'ouverture
* Modèles d'écritures comptables
Ces exemples sont développés directement avec Brindille et peuvent être modifiés ou lus depuis le menu **Configuration**, onglet **Extensions**.
Un module fourni dans Paheko peut être modifié, et en cas de problème il peut être remis à son état d'origine.
D'autres exemples d'utilisation sont imaginables :
* Auto-remplissage de la déclaration de la liste des dirigeants à la préfecture
* Compte de résultat et bilan conforme au modèle du plan comptable
* Formulaires partagés entre la partie privée, et le site web (voir par exemple le module "heures d'ouverture")
* Gestion de matériel prêté par l'association
# Pré-requis
Une connaissance de la programmation informatique est souhaitable pour commencer à modifier ou créer des modules, mais cela n'est pas requis, il est possible d'apprendre progressivement.
# Résumé technique
* Utilisation de la syntaxe Brindille
* Les modules peuvent utiliser toutes les fonctions et boucles de Brindille
* Les modules peuvent stocker et récupérer des données dans la base SQLite dans une table clé-valeur spécifique à chaque module
* Les données du module sont stockées en JSON, on peut faire des requêtes complètes avec l'extension [JSON de SQLite](https://www.sqlite.org/json1.html)
* Les données peuvent être validées avant enregistrement en utilisant [JSON Schema](https://json-schema.org/understanding-json-schema/)
* Un module peut également accéder aux données des autres modules
* Un module peut aussi accéder à toutes les données de la base de données, sauf certaines données à risque (voir plus bas)
* Un module ne peut pas modifier les données de la base de données
* Paheko crée automatiquement des index sur les requêtes SQL des modules, permettant de rendre les requêtes rapides
# Structure des répertoires
Chaque module a un nom unique (composé uniquement de lettres minuscules, de tirets bas et de chiffres) et dispose d'un sous-répertoire dans le dossier `modules`. Ainsi le module `recu_don` serait dans le répertoire `modules/recu_don`.
Dans ce répertoire le module peut avoir autant de fichiers qu'il veut, mais certains fichiers ont une fonction spéciale :
* `module.ini` : contient les informations sur le module, voir ci-dessous pour les détails
* `config.html` : si ce squelette existe, un bouton "Configurer" apparaîtra dans la liste des modules (Configuration -> Modules) et affichera ce squelette dans un dialogue
* `icon.svg` : icône du module, qui sera utilisée sur la page d'accueil, si le bouton est activé, et dans la liste des modules. Attention l'élément racine du fichier doit porter l'id `img` pour que l'icône fonctionne (`<svg id="img"...>`), notamment pour que les couleurs du thème s'appliquent à l'icône.
* `README.md` : si ce fichier existe, son contenu sera affiché dans les détails du module
## Snippets
Les modules peuvent également avoir des `snippets`, ce sont des squelettes qui seront inclus à des endroits précis de l'interface, permettant de rajouter des fonctionnalités, ils sont situés dans le sous-répertoire `snippets` du module :
* `snippets/transaction_details.html` : sera inclus en dessous de la fiche d'une écriture comptable
* `snippets/transaction_new.html` : sera inclus au début du formulaire de saisie d'écriture
* `snippets/user_details.html` : sera inclus en dessous de la fiche d'un membre
* `snippets/my_details.html` : sera inclus en dessous de la page "Mes informations personnelles"
* `snippets/my_services.html` : sera inclus en dessous de la page "Mes inscriptions et cotisations"
* `snippets/home_button.html` : sera inclus dans la liste des boutons de la page d'accueil (ce fichier ne sera pas appelé si `home_button` est à `true` dans `module.ini`, il le remplace)
### Snippets MarkDown
Il est également possible, depuis Paheko 1.3.2, d'étendre les fonctionnalités Markdown du site web en créant un snippet dans le répertoire `snippets/markdown/`, par exemple `snippets/markdown/map.html`.
Le snippet sera appelé quand on utilise le tag du même nom dans le contenu du site web. Ici par exemple ça serait `<<map>>`.
Le nom du snippet doit commencer par une lettre minuscule et peut être suivi de lettres minuscules, de chiffres, ou de tirets bas. Exemples : `map2024` `map_openstreetmap`, etc.
Le snippet reçoit ces variables :
* `$params` : les paramètres du tag
* `$block` : booléen, `TRUE` si le tag est seul sur une ligne, ou `FALSE` s'il se situe à l'intérieur d'un texte
* `$content` : le contenu du bloc, si celui-ci est sur plusieurs lignes
Exemple :
```
<<map center="Auckland, New Zealand"
Ceci est la capitale de Nouvelle-Zélande !
>>
Voici un marqueur : <<map marker>>
```
Dans le premier appel, `map.html` recevra ces variables :
```
$params = ['center' => 'Auckland, New Zealand']
$content = "Ceci est la capitale de Nouvelle-Zélande !"
$block = TRUE
```
Dans le second appel, le snippet recevra celles-ci :
```
$params = [0 => 'marker']
$content = NULL
$block = FALSE
```
## Fichier module.ini
Ce fichier décrit le module, au format INI (`clé=valeur`), en utilisant les clés suivantes :
* `name` (obligatoire) : nom du module
* `description` : courte description de la fonctionnalité apportée par le module
* `author` : nom de l'auteur
* `author_url` : adresse web HTTP menant au site de l'auteur
* `home_button` : indique si un bouton pour ce module doit être affiché sur la page d'accueil (`true` ou `false`)
* `menu` : indique si ce module doit être listé dans le menu de gauche (`true` ou `false`)
* `restrict_section` : indique la section auquel le membre doit avoir accès pour pouvoir voir le menu de ce module, parmi `web, documents, users, accounting, connect, config`
* `restrict_level` : indique le niveau d'accès que le membre doit avoir dans la section indiquée pour pouvoir voir le menu de ce module, parmi `read, write, admin`.
Attention : les directives `restrict_section` et `restrict_level` ne contrôlent *que* l'affichage du lien vers le module dans le menu et dans les boutons de la page d'accueil, mais pas l'accès aux pages du module.
# Variables spéciales
Toutes les pages d'un module disposent de la variable `$module` qui contient l'entité du module en cours :
* `$module.name` contient le nom unique (`recu_don` par exemple)
* `$module.label` le libellé du module
* `$module.description` la description
* `$module.config` la configuration du module
* `$module.url` l'adresse URL du module (`https://site-association.tld/m/recu_don/` par exemple)
# Stockage de données
Un module peut stocker des données de deux manières : dans sa configuration, ou dans son stockage de documents JSON.
## Configuration
La première manière est de stocker des informations dans la configuration du module. Pour cela on utilise la fonction `save` et la clé `config` :
```
{{:save key="config" accounts_list="512A,512B" check_boxes=true}}
```
On pourra retrouver ces valeurs dans la variable `$module.config` :
```
{{if $module.config.check_boxes}}
{{$module.config.accounts_list}}
{{/if}}
```
## Stockage de documents JSON
Chaque module peut stocker ses données dans une base de données clé-document qui stockera les données dans des documents au format JSON dans une table SQLite.
Grâce aux [fonctions JSON de SQLite](https://www.sqlite.org/json1.html) on pourra ensuite effectuer des recherches sur ces documents.
Pour enregistrer il suffit d'utiliser la fonction `save` :
```
{{:save key="facture001" type="facture" date="2022-01-01" label="Vente de petits pains au chocolat" total="42"}}
```
Si la clé indiquée (dans le paramètre `key`) n'existe pas, l'enregistrement sera créé, sinon il sera mis à jour avec les valeurs données.
### Validation
On peut utiliser un [schéma JSON](https://json-schema.org/understanding-json-schema/) pour valider que le document qu'on enregistre est valide :
```
{{:save validate_schema="./document.schema.json" type="facture" date="2022-01-01" label="Vente de petits pains au chocolat" total="42"}}
```
Le fichier `document.schema.json` devra être dans le même répertoire que le squelette et devra contenir un schéma valide. Voici un exemple :
```
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"date": {
"description": "Date d'émission",
"type": "string",
"format": "date"
},
"type": {
"description": "Type de document",
"type": "string",
"enum": ["devis", "facture"]
},
"total": {
"description": "Montant total",
"type": "integer",
"minimum": 0
},
"label": {
"description": "Libellé",
"type": "string"
},
"description": {
"description": "Description",
"type": ["string", "null"]
}
},
"required": [ "type", "date", "total", "label"]
}
```
Si le document fourni n'est pas conforme au schéma, il ne sera pas enregistré et une erreur sera affichée.
#### Propriété non requise
Si vous souhaitez utiliser dans votre document une propriété non requise, il ne faut pas la fournir en paramètre de la fonction `save`.
Si elle est fournie mais vide, il faut aussi autoriser le type `null` (en minuscules) au type de votre propriété.
Exemple :
[...]
"description": {
"description": "Description",
"type": ["string", "null"]
}
[...]
### Stockage JSON dans SQLite (pour information)
Explication du fonctionnement technique derrière la fonction `save`.
En pratique chaque enregistrement sera placé dans une table SQL dont le nom commence par `module_data_`. Ici la table sera donc nommée `module_data_factures` si le nom unique du module est `factures`.
Le schéma de cette table est le suivant :
```
CREATE TABLE module_data_factures (
id INTEGER PRIMARY KEY NOT NULL,
key TEXT NULL,
document TEXT NOT NULL
);
CREATE UNIQUE INDEX module_data_factures_key ON module_data_factures (key);
```
Comme on peut le voir, chaque ligne dans la table peut avoir une clé unique (`key`), et un ID ou juste un ID auto-incrémenté. La clé unique n'est pas obligatoire, mais peut être utile pour différencier certains documents.
Par exemple le code suivant :
```
{{:save key="facture_43" nom="Facture de courses"}}
```
Est l'équivalent de la requête SQL suivante :
```
INSERT OR REPLACE INTO module_data_factures (key, document) VALUES ('facture_43', '{"nom": "Facture de courses"}');
```
### Récupération et liste de documents
Il sera ensuite possible d'utiliser la boucle `load` pour récupérer les données :
```
{{#load id=42}}
Ce document est de type {{$type}} créé le {{$date}}.
<h2>{{$label}}</h2>
À payer : {{$total}} €
{{else}}
Le document numéro 42 n'a pas été trouvé.
{{/load}}
```
Cette boucle `load` permet aussi de faire des recherches sur les valeurs du document :
```
<ul>
{{#load where="$$.type = 'facture'" order="date DESC"}}
<li>{{$label}} ({{$total}} €)</li>
{{/load}}
</ul>
```
La syntaxe `$$.type` indique d'aller extraire la clé `type` du document JSON.
C'est un raccourci pour la syntaxe SQLite `json_extract(document, '$.type')`.
# Export et import de modules
Il est possible d'exporter un module modifié. Cela créera un fichier ZIP contenant à la fois le code modifié et le code non modifié.
De la même manière il est possible d'importer un module à partir d'un fichier ZIP d'export. Si vous créez votre fichier ZIP manuellement, attention à respecter le fait que le code du module doit se situer dans le répertoire `modules/nom_du_module` du fichier ZIP. Tout fichier ou répertoire situé en dehors de cette arborescence provoquera une erreur et l'impossibilité d'importer le module.
# Restrictions
* Il n'est pas possible de télécharger ou envoyer des données depuis un autre serveur
* Il n'est pas possible d'écrire un fichier local
## Envoi d'e-mail
Voir [la documentation de la fonction `{{:mail}}`](brindille_functions.html#mail)
## Tables et colonnes de la base de données
Pour des raisons de sécurité, les modules ne peuvent pas accéder à toutes les données de la base de données.
Les colonnes suivantes de la table `users` (liste des membres) renverront toujours `NULL` :
* `password`
* `pgp_key`
* `otp_secret`
Tenter de lire les données des tables suivantes résultera également en une erreur :
* emails
* emails_queue
* compromised_passwords_cache
* compromised_passwords_cache_ranges
* api_credentials
* plugins_signals
* config
* users_sessions
* logs

160
doc/admin/skriv.md Normal file
View file

@ -0,0 +1,160 @@
Title: Référence rapide SkrivML - Paheko
<<toc aside>>
# Syntaxe SkrivML
Paheko propose la syntaxe [SkrivML](https://fossil.kd2.org/paheko/doc/trunk/doc/skrivml.html) pour le formatage du texte des pages du site web.
## Styles de texte
| Style | Syntaxe |
| :- | :- |
| *Italique* | `Entourer le texte de ''deux apostrophes''` |
| **Gras** | `Entourer le texte de **deux astérisques**` |
| Texte <ins>Souligné</ins> | `Entourer le texte de deux __tirets bas__.` |
| ~~Barré~~ | `Deux --tirets hauts-- pour barrer.` |
| Texte <sup>Exposant</sup> | `XXI^^ème^^ siècle` |
| Texte <sub>Indice</sub> | `CO,,2,,` |
**Attention :** ces styles ne fonctionnent que si le code entoure des mots complets, ça ne fonctionne pas au milieu de mots.
```
Un **mot** en gras. Mais on ne peut pas cou**per** un mot avec du gras.
```
> Un **mot** en gras. Mais on ne peut pas cou\*\*per** un mot avec du gras.
## Titres
Doivent être précédé d'un ou plusieurs signe égal. Peuvent aussi être suivi du même nombre de signe égal.
```
= Titre niveau 1
== Titre niveau 2
=== Titre niveau 3 ===
==== Titre de niveau 4 ====
```
## Listes
Listes non ordonnées :
```
* Item 1
* Item 2
** Sous-item 2.1
** Sous-item 2.2
*** Sous-item 2.2.1
```
Listes ordonnées :
```
# Item 1
# Item 2
## Sub-item 2.1
## Sub-item 2.2
### Sub-item 2.2.1
```
## Liens
Lien interne :
```
Voir [[cette page|adresse-unique-autre-page]].
```
Lien externe :
```
[[https://paheko.cloud/]]
```
## Tableaux
```
!! Colonne 1 !! Colonne 2
|| Cellule 1 || Cellule 2
|| Cellule 3 || Cellule 4
```
## Autres
Consulter la documentation complète de [SkrivML](https://fossil.kd2.org/garradin/doc/trunk/doc/skrivml.html).
# Extensions
Toutes les extensions se présentent sous la forme d'un code situé entre deux signes **inférieur à** (`<<`) et deux signes **supérieur à** (`>>`), à ne pas confondre avec les guillements français (`«` et `»`).
## Images jointes
Il est possible d'intégrer une image jointe à la page web en plaçant le code suivant sur une ligne (sans autre texte) :
```
<<image|Nom_fichier.jpg|Alignement|Légende>>
```
* `Nom_fichier.jpg` : remplacer par le nom du fichier de l'image (parmi les images jointes à la page)
* `Alignement` : remplacer par l'alignement :
* `gauche` ou `left` : l'image sera placée à gauche en petit (200 pixels), le texte remplira l'espace laissé sur la droite de l'image ;
* `droite` ou `right` : l'image sera placée à droite en petit, le texte remplira l'espace laissé sur la gauche de l'image ;
* `centre` ou `center` : l'image sera placée au centre en taille moyenne (500 pixels), le texte sera placé au dessus et en dessous.
* Légende : indiquer ici une courte description de l'image.
Exemple :
```
<<image|mon_image.png|center|Ceci est une belle image>>
```
Il est aussi possible d'utiliser la syntaxe avec des paramètres nommés :
```
<<image file="Nom_fichier.jpg" align="center" caption="Légende">>
```
Les images qui ne sont pas mentionnées dans le texte seront affichées après le texte sous forme de galerie.
## Fichiers joints
Pour créer un bouton permettant de voir ou télécharger un fichier joint à la page web, il suffit d'utiliser la syntaxe suivante :
```
<<file|Nom_fichier.ext|Libellé>>
```
* `Nom_fichier.ext` : remplacer par le nom du fichier (parmi les fichiers joints à la page)
* `Libellé` : indique le libellé du qui sera affiché sur le bouton, si aucun libellé n'est indiqué alors c'est le nom du fichier qui sera affiché
# Raccourcis clavier
Depuis l'édition du texte :
| Raccourci | Action |
| :- | :- |
| <kbd>Ctrl</kbd> + <kbd>G</kbd> | Mettre en gras |
| <kbd>Ctrl</kbd> + <kbd>I</kbd> | Mettre en italique |
| <kbd>Ctrl</kbd> + <kbd>T</kbd> | Mettre en titre |
| <kbd>Ctrl</kbd> + <kbd>L</kbd> | Transformer en lien |
| <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>I</kbd> | Insérer une image |
| <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>F</kbd> | Insérer un fichier |
| <kbd>Ctrl</kbd> + <kbd>P</kbd> | Prévisualiser |
| <kbd>Ctrl</kbd> + <kbd>S</kbd> | Enregistrer |
| <kbd>F11</kbd> | Activer ou désactiver l'édition plein écran |
| <kbd>F1</kbd> | Afficher l'aide |
| <kbd>Echap</kbd> | Prévisualiser (rappuyer pour revenir à l'édition) |
Depuis la prévisualisation :
| Raccourci | Action |
| :- | :- |
| <kbd>Ctrl</kbd> + <kbd>P</kbd> | Retour à l'édition |
Depuis l'aide ou l'insertion de fichier :
| Raccourci | Action |
| :- | :- |
| <kbd>Echap</kbd> | Fermer et revenir à l'édition |

96
doc/admin/web.md Normal file
View file

@ -0,0 +1,96 @@
Title: Squelettes du site web dans Paheko
{{{.nav
* [Documentation Brindille](brindille.html)
* [Fonctions](brindille_functions.html)
* [Sections](brindille_sections.html)
* [Filtres](brindille_modifiers.html)
}}}
# Les squelettes du site web
Les squelettes sont un ensemble de fichiers qui permettent de modéliser l'apparence du site web selon ses préférences et besoins.
La syntaxe utilisée dans les squelettes s'appelle **[Brindille](brindille.html)**. Voir la [documentation de Brindille](brindille.html) pour son fonctionnement.
# Exemples de sites réalisés avec Paheko
* [Faidherbe Alumni](https://www.alumni-faidherbe.fr/)
* [ASBM Mortagne](https://asbm-mortagne.fr/)
* [Vélocité 63](https://www.velocite63.fr/)
* [La rustine, Dijon](https://larustine.org/)
* [Tauto école](https://tauto-ecole.net/) [(les squelettes sont disponibles ici)](https://gitlab.com/noizette/squelettes-garradin-tauto-ecole/)
* [La boîte à vélos](https://boiteavelos.chenove.net/)
# Fonctionnement des squelettes
Par défaut sont fournis plusieurs squelettes qui permettent d'avoir un site web basique mais fonctionnel : page d'accueil, menu avec les catégories de premier niveau, et pour afficher les pages, les catégories, les fichiers joints et images. Il y a également un squelette `atom.xml` permettant aux visiteurs d'accéder aux dernières pages publiées.
Les squelettes peuvent être modifiés via l'onglet **Configuration** de la section **Site web** du menu principal.
Une fois un squelette modifié, il apparaît dans la liste comme étant modifié, sinon il apparaît comme *défaut*. Si vous avez commis une erreur, il est possible de restaurer le squelette d'origine.
## Adresses des pages du site
Les squelettes sont appelés en fonction des règles suivantes (dans l'ordre) :
| Squelette appelé | Cas où le squelette est appelé |
| :---- | :---- |
| `adresse` | Si l'adresse `adresse` est appelée, et qu'un squelette du même nom existe |
| `adresse/index.html` | Si l'adresse `adresse/` est appelée, et qu'un squelette `index.html` dans le répertoire du même nom existe |
| `category.html` | Toute autre adresse se terminant par un slash `/`, si une catégorie du même nom existe |
| `article.html` | Toute autre adresse, si une page du même nom existe |
| `404.html` | Si aucune règle précédente n'a fonctionné |
Ainsi l'adresse `https://monsite.paheko.cloud/Actualite/` appellera le squelette `category.html`, mais l'adresse `https://monsite.paheko.cloud/Actualite` (sans slash à la fin) appellera le squelette `article.html` si un article avec l'URI `Actualite` existe. Si un squelette `Actualite` (sans extension) existe, c'est lui qui sera appelé en priorité et ni `category.html` ni `article.html` ne seront appelés.
Autre exemple : `https://monsite.paheko.cloud/atom.xml` appellera le squelette `atom.xml` s'il existe.
Ceci vous permet de créer de nouvelles pages dynamiques sur le site, par exemple pour notre atelier vélo nous avons une page `https://larustine.org/velos` qui appelle le squelette `velos` (sans extension), qui va afficher la liste des vélos actuellement en stock dans notre hangar.
Le type de fichier étant déterminé selon l'extension (`.html, .css, etc.`) pour les fichiers traités par Brindille, un fichier sans extension sera considéré comme un fichier texte par le navigateur. Si on veut que le squelette `velos` (sans extension) s'affiche comme du HTML il faut forcer le type en mettant le code `{{:http type="text/html"}}` au début du squelette (première ligne).
## Fichier content.css
Ce fichier est particulier, car il définit le style du contenu des pages et des catégories.
Ainsi il est également utilisé quand vous éditez un contenu dans l'administration. Donc si vous souhaitez modifier le style d'un élément du texte, il vaux mieux modifier ce fichier, sinon le rendu sera différent entre l'administration et le site public.
# Cache
Depuis la version 1.3, Paheko dispose d'un cache statique du site web.
Cela veut dire que les pages du site web sont enregistrées sous la forme de fichiers HTML statiques, et le serveur web renvoie directement ce fichier sans faire appel à Paheko et son code PHP.
Les fichiers liés aux pages web sont également mis en cache de cette manière, en utilisant des liens symboliques.
Ce cache permet d'avoir un site web très rapide, même s'il reçoit des millions de visites.
## Désactiver le cache
Le seul inconvénient c'est qu'une page mise en cache étant statique, si vous utilisez du contenu dynamique (par exemple afficher un texte différent selon la langue du visiteur) dans le squelette Brindille, alors cela ne fonctionnera plus.
Dans ce cas-là, vous pouvez assigner la variable `nocache` dans le squelette pour désactiver le cache pour cette page :
```
{{:assign nocache=true}}
```
Pour permettre des usages du type "affichage en temps presque réel des horaires d'ouverture", le cache d'une page HTML est effacé et remis à jour au bout d'une heure.
## Exceptions
Il est à noter que le cache n'est pas appelé dans les cas suivants :
* si la requête vers la page est d'un autre type que `GET` ou `HEAD`, ainsi par exemple l'envoi d'un formulaire (`POST`) ne sera jamais mis en cache ;
* si la requête vers la page contient des paramètres dans l'adresse (par exemple `velos.html?list=1` : cette page ne sera pas mise en cache) ;
* si le visiteur est connecté à l'administration de l'association. Ainsi si vous avez des parties du squelette qui varient en fonction de si la personne est connectée, le cache ne posera pas de problème.
Le cache est intégralement effacé à chaque modification du site web.
Le cache ne concerne que les pages et fichiers du site web public. Il ne concerne pas les modules, les extensions, ou l'administration.
Attention :
* avec un serveur sous Windows, le cache est désactivé car Windows ne sait pas gérer les liens symboliques ;
* seul Apache sait gérer le cache statique, le cache est désactivé avec les autres serveurs web (nginx, etc.).

BIN
doc/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 522 B

213
doc/index.md Normal file
View file

@ -0,0 +1,213 @@
# La gestion d'association libre et simple
<div id="prez">
<figure>
<img src="./selfhost2.png" alt="Illustration d'une personne aidant une autre à installer Paheko sur un ordinateur" />
</figure>
### Paheko — la gestion d'association simple</h3>
**Paheko** <small>(anciennement appelé *Garradin*)</small> signifie *coopérer* en *Māori*. C'est un logiciel de gestion d'association, libre, simple et efficace, développé depuis 2012. Son but est de&nbsp;:
* **réduire le temps** passé sur les tâches administratives&nbsp;;
* re-**donner de l'autonomie aux adhérent⋅e⋅s** dans la gestion de leurs données&nbsp;;
* **simplifier la gestion administrative** de l'association, pour inciter à y participer&nbsp;;
* **minimiser le nombre de logiciels à installer et maintenir** en intégrant les outils habituels.
Pour en savoir plus : [voir les principales fonctionnalités](#features).
</div>
<div id="warn">
<p><strong>Attention&nbsp;: ce site est dédié au logiciel libre Paheko.</strong><br />
Son installation, sur un serveur ou sur un ordinateur personnel, nécessite quelques compétences techniques.</p>
<p>Si votre association n'a pas ces compétences, nous recommandons l'utilisation de notre service d'hébergement&nbsp;:<br /><strong class="cloud"><a href="https://paheko.cloud/" target="_blank"><img src="./icon.png" alt="" /> Paheko.cloud</a></strong>
<small>(<strong>Essai gratuit</strong>, puis contribution à prix libre, à partir de 5&nbsp;€ par an)</small>
</div>
<nav id="gnav">
* [Guides d'installation](wiki:Installation)
* [Documentation](wiki:Documentation)
* [Entraide](wiki:Entraide)
* <a href="https://paheko.cloud/" target="_blank">Essayer gratuitement sur &nbsp; <b><img src="./icon.png" alt="" /> Paheko.cloud</b></a>
<ul id="news">
<li><a href="$ROOT/wiki/?name=Changelog">Nouveautés</a></li>
<li><a href="$ROOT/uvlist">Anciennes versions</a></li>
</ul>
</nav>
<p id="give"><a href="https://kd2.org/soutien.html" target="_blank">Soutenir Paheko en effectuant un don :-)</a></p>
<form method="GET" action="$ROOT/wiki" id="search_all" onsubmit="var t = this.querySelector('[type=radio]:checked'); this.querySelector('[name=s]').name=t.dataset.name; this.action=t.dataset.action; this.target=t.dataset.target;">
<fieldset class="searchForm searchFormWiki">
<legend>Rechercher</legend>
<input type="search" name="s" size="40" value="" />
<label><input type="radio" name="t" value="" data-name="s" data-action="/paheko/wiki" data-target="" checked="checked" /> Chercher dans la documentation technique</label>
<label><input type="radio" name="t" value="1" data-action="https://paheko.cloud/search" data-name="search" data-target="_blank" /> Chercher dans l'aide utilisateur</label>
<input type="submit" value="Rechercher" />
</fieldset>
</form>
<script type="text/javascript">
function isNewerVersion (oldVer, newVer) {
const oldParts = oldVer.split('.')
const newParts = newVer.split('.')
for (var i = 0; i < newParts.length; i++) {
const a = ~~newParts[i] // parse int
const b = ~~oldParts[i] // parse int
if (a > b) return true
if (a < b) return false
}
return false
}
fetch('/paheko/juvlist?'+(+(new Date))).then((r) => {
r.json().then((list) => {
let last = {};
let selected;
list.forEach((file) => {
var v = file.name.match(/^paheko-(\d+\.\d+\.\d+)\.(deb|exe|tar\.gz)$/);
if (!v || v[1].match(/-(alpha|rc|beta)/)) {
return;
}
file.type = v[2];
file.version = v[1];
file.human_size = (Math.round((file.size / 1024 / 1024) * 10) / 10 + ' Mo').replace(/\./, ',');
if (!last.hasOwnProperty(file.type) || isNewerVersion(last[file.type].version, file.version)) {
last[file.type] = file;
if (file.type == 'tar.gz') {
selected = file;
}
}
});
let days = ((+new Date)/1000 - selected.mtime) / 3600 / 24;
if (days < 31) {
time = Math.ceil(days) + ' jours';
}
else if (days >= 31) {
time = Math.round(days / 30.5) + ' mois';
}
document.querySelector('#news').innerHTML = `<li class="last"><strong>Dernière version : ${last['tar.gz'].version}</strong></li>
<li class="last"><em>il y a ${time}</em></li>` + document.querySelector('#news').innerHTML;
var links = `<div id="download">
<h2>Télécharger&nbsp;:</h2>
<nav>`;
if ('tar.gz' in last) {
links += `
<div>
<h3><a href="$ROOT/uv/${last['tar.gz'].name}"><img src="data:image/svg+xml;base64,PHN2ZwogIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICB3aWR0aD0iMjQiCiAgaGVpZ2h0PSIyNCIKICB2aWV3Qm94PSIwIDAgMjQgMjQiCiAgZmlsbD0ibm9uZSIKICBzdHJva2U9ImN1cnJlbnRDb2xvciIKICBzdHJva2Utd2lkdGg9IjIiCiAgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIgogIHN0cm9rZS1saW5lam9pbj0icm91bmQiCj4KICA8cmVjdCB4PSIyIiB5PSIyIiB3aWR0aD0iMjAiIGhlaWdodD0iOCIgcng9IjIiIHJ5PSIyIiAvPgogIDxyZWN0IHg9IjIiIHk9IjE0IiB3aWR0aD0iMjAiIGhlaWdodD0iOCIgcng9IjIiIHJ5PSIyIiAvPgogIDxsaW5lIHgxPSI2IiB5MT0iNiIgeDI9IjYuMDEiIHkyPSI2IiAvPgogIDxsaW5lIHgxPSI2IiB5MT0iMTgiIHgyPSI2LjAxIiB5Mj0iMTgiIC8+Cjwvc3ZnPgo=" alt="" /><span>Serveur</span></a></h3>
<p>pour auto-hébergement<br />
<em>(.tar.gz, ${last['tar.gz'].human_size})</em><br />
<small><a href="$ROOT/wiki/?name=Installation">Guides d'installation</a></small>
</p>
</div>`;
}
if ('deb' in last) {
links += `
<div>
<h4><a href="$ROOT/uv/${last['deb'].name}"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGoAAAB8AgMAAAD8wM2CAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAAlwSFlzAAAF3gAABd4BiRluJgAAAAxQTFRFAAAAR3BMAAAAAAAAoOHXxQAAAAR0Uk5T/QBQozL7B+YAAAPySURBVEjHndc9aBxHFADgd7u64hTv4eYgxRVulijYpQURpDgIKVwILtbN7GAt9jquEl/gItUOl5gUhgjUbNKkMBhhkDE2rhOY2LhwYVvNgiEu0qhOwKiISSAzszPz3q7mhIlKfczuzJv3swds4d8Y3tEu/fNyb4FxCQBl2HJFkIRtpI0spGYIVkM2qS0JWV5bFLKiNnwhsZm1KmAja2nA5ta6AZMnmCXonWDJCdY5btxZ9D8tDtkpgD5fYKVUFzQKWqT+P9ARD5yh80UB1b/jkPHkh1346dTPwXXJ8gG8Wn6NF0hsuXMaXkXDsMVnYBifCxucgXMwxIsn9hz69z6G00F7LP+8MYXdoD355qvP2KNx0KTOaP4XqOAcz6XSZmnAbrrMT4/bt6Y8+WLbyrCSiH2it7IqMEFpzqtnTcsiaPNfGf9bZ3cSsN/fvinFa0zQxtm/3GPbE0wmas/VXnpqnxDIszslKyqO1YmWwWRtMzFlkbZNxEzGlSnRbtvGEbu0V5d20rZZx7eLqG2yh22mZdyFWPiNehNud5nf6BgPWmEddps2cinLfcl7k0DqN25YhiXpe5ozgS1Aus04y7GtzN1mnBVoM9ebnI2wVRWxrF/gbI7tL49tP3Amsb9P4IO6Pp3B+wNMgKSuCWscditMnGhuDuFtRufLzLzdWhbdZKThH5jma23S6TAyKIbmRNZEvzG/VkwkrOVLPTrrVkzkrY0/wvGl4n6e2myYMjLQlkxgrI0OBi0rvcnbeHR1z0vmdq3BrGzZwFkWj9gim9CwKDtPLI++a1vqrOg8JsbV2dFmnd8a66jNG8Z18/UmW+sOTOOqDaKdxrrbZB3E6411V6Q3VR73qSX7P0piA2pnISoGaF1qfwCs+LisTSNid1W1vOfuIVOdCu9BxHrouvublGyOObGhO0V8aE2oiOJDv9adIn5q7ZrOLX/x67rikwvGcujrHPFJuK4rfvWGse39Uh8jQlMVX101dst2B/fQW2aOf27syBbuqrdCveCisdQWT+KNv6nYZWJj33wu1BEgJvwMri2r8H2Zv4vaWBcNO4W1bWJ+o89syFNl37tKrl+cuQDtoOV2L8LZNWWf2qqzQSuc5Wg8bc4CJnb9M/1Z6LqjRjwKbxvKXPpdtd/RZJ+Z/3zQ+5z6dBSHYxA+v9T1X8dvzBcqLlfId7LEj2ihY30RS4R+YO8wapxaZmolL1sfoMY2zHXzfstS+0h9R9N+ecy469fX45KajkXuZ8CmQQ5v1bfNA6ltC2fHpn5ntob3cUTmynTNxqzOCdGYfw8PmWtpWzqPGjP1yS8u58WHm73WfN/3xfnQ7jv426l8h99V/wEOtd7r5KQmrQAAAABJRU5ErkJggg==" alt="" /><span>Linux</span></a></h4>
<p>hors-ligne, pour ordinateur<br />
<em>(.deb, ${last['deb'].human_size})</em><br />
<small><a href="$ROOT/wiki/?name=Fonctionnement+hors-ligne">Guide d'installation</a></small>
</p>
</div>`;
}
if ('exe' in last) {
links += `
<div>
<h4><a href="$ROOT/uv/${last['exe'].name}"><img src="data:image/svg+xml;base64,PHN2ZyBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAyNCAyNCIgdmlld0JveD0iMCAwIDI0IDI0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Im0yMiAyLTEwLjggMS42djhsMTAuOC0uMXptLTExLjggMTAuNS04LjItLjF2Ni44bDguMSAxLjF6bS04LjItNy43djYuOGg4LjF2LTcuOXptOS4xIDcuN3Y3LjlsMTAuOSAxLjZ2LTkuNHoiLz48L3N2Zz4=" alt="" /><span>Windows</span></a></h4>
<p>hors-ligne, pour ordinateur<br />
<em>(.exe, ${last['exe'].human_size})</em><br />
<small><a href="$ROOT/wiki/?name=Installation/Windows">Guide d'installation</a></small>
</p>
</div>`;
}
links += `
</nav>
</div>`;
document.querySelector('#news').insertAdjacentHTML('afterend', links);
});
});
</script>
<a name="features"></a>
## C'est quoi ?
* **100% libre :** placé sous la licence [AGPL v3](https://www.gnu.org/licenses/why-affero-gpl.fr.html).
* Gestion des **adhérent⋅e⋅s** : fiches de membre personnalisables, recherches personnalisées…
* Gestion des **cotisations** et **activités** : suivi des adhérent⋅e⋅s à jour, des paiements en attente, **rappels automatiques** de cotisation par e-mail, etc.
* Envoi de **newsletters** avec suivi des adresses e-mail invalides
* **Comptabilité** puissante (à double entrée), **simple à utiliser par les débutant⋅e⋅s** : recettes, dépenses, suivi des dettes et créances, bilan et compte de résultat annuel, **comptabilité analytique**, export PDF, **reçus fiscaux**, etc.
* Stockage et **partage** de **documents** : édition collaborative, synchronisation des fichiers sur un ordinateur, etc.
* Gestion du **site web** de l'association
* Comptabilisation du **temps bénévole** et sa **valorisation**
* Gestion de la **caisse informatisée** d'un atelier ou d'une boutique
* Réservation de **créneaux et d'événements**
* **Conforme au RGPD** : export des données de l'adhérent⋅e, désabonnement des e-mails, chiffrement des mots de passe…
**<a href="http://paheko.cloud/a-propos" target="_blank">Présentation des fonctionnalités sur le site Paheko</a>**
## Dans quels buts ?
Le but est de permettre :
* la gestion des __adhérent⋅e⋅s__ : ajout, modification, suppression, possibilité de choisir les informations présentes sur les fiches adhérent, envoi de mails collectifs aux adhérent⋅e⋅s
* la tenue de la __comptabilité__ : avoir une gestion comptable complète à même de satisfaire un expert-comptable tout en restant à la portée de celles et ceux qui ne savent pas ce qu'est la comptabilité à double entrée, permettre la production des rapports et bilans annuels et de suivre au jour le jour le budget de l'association
* la gestion des __cotisations__ et __activités__ : suivi des cotisations à jour, inscriptions et paiement des activités, rappels automatiques par e-mail, etc.
* le travail __collaboratif__ et __collectif__ : gestion fine des droits d'accès aux fonctions, échange de mails entre membres…
* la __simplification administrative__ : prise de notes en réunion, archivage et partage de fichiers (afin d'éliminer le besoin d'archiver les documents papier), etc.
* la publication d'un __site web__ pour l'association, simple mais suffisamment flexible pour pouvoir adapter le fonctionnement à la plupart des besoins
* l'__autonomisation des adhérents__ : possibilité de mettre à jour leurs informations par eux-même, ou de s'inscrire seul depuis un ordinateur ou un smartphone
* la possibilité d'adapter aux besoins spécifiques de chaque association via des [__extensions__](wiki:Extensions).
* Fonctionnalités qu'il reste à implémenter : voir [la feuille de route (roadmap)](wiki:Roadmap).
* Paheko ne convient pas ? [Voir la liste des alternatives, libres ou propriétaires](wiki:Alternatives)
## Un seul logiciel
Paheko réunit en un seul outil les besoins suivants :
* gestion des membres : remplace Ciel Associations, EBP, Assoconnect ou Galette ;
* comptabilité : remplace Assoconnect, Odoo, Dolibarr, Grisbi, GNUcash, Sage, etc. ;
* gestion et partage de fichiers, remplace NextCloud, Google Drive ou Dropbox ;
* site web : remplace WordPress, Drupal, etc. ;
* suivi du bénévolat : remplace Bénévalibre et les tableaux Excel.
## Documentation et entraide
* D'abord lire la [documentation](/wiki/?name=Documentation) et notamment la [foire aux questions](wiki:FAQ)
* Voir la page [Entraide](/wiki/?name=Entraide) pour accéder aux listes de discussion et au salon de discussion IRC
## Participer
Tout coup de main est le bienvenu, pas besoin d'avoir des connaissances techniques ! Nous avons un [guide de contribution](wiki:Contribuer) pour vous aider à voir comment vous pouvez participer à Paheko :)
### Développement
Paheko est un logiciel libre, développé en PHP, utilisant la base de données SQLite, et avec une interface utilisant HTML, CSS et un peu de Javascript.
Nous acceptons les contributions (plugins, patch, code, tickets, etc.) avec plaisir, consultez la [documentation développeur⋅euse](wiki:Documentation développeur) pour découvrir comment vous pouvez contribuer.

BIN
doc/selfhost2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

1430
doc/skrivml.html Normal file

File diff suppressed because it is too large Load diff

766
manifest Normal file
View file

@ -0,0 +1,766 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
C Fix\squote\sin\slist
D 2024-01-06T13:45:04.578
F .editorconfig e6f131bd881371738fbc49cd771c470959e14df4b5baa398db781f21e2f98b34
F .fossil-settings/allow-symlinks 5a9cb4b1795fdc8982e907994a2e80eca49b6daf329c826d86903016391506ce
F .fossil-settings/ignore-glob 962019af50eb59ad515b3bdf7d4bc04b7a982a4b410d1d669a9561c095388772
F .fossil-settings/manifest 5a9cb4b1795fdc8982e907994a2e80eca49b6daf329c826d86903016391506ce
F .travis.yml 4da8c0eef1bdf524e1ad6cf8e7bfe3d4d26a680a
F COPYING 78e50e186b04c8fe1defaa098f1c192181b3d837
F README.md 827da5e24a451ad78aeff512e83128a3d23132cc34e00e2690bfa29668f08ebb
F SECURITY.md 58d2d41ec6509b4991e4ebcf46935ba1f33b568afc6e587df4a2d7ae703649f4
F archives/0.7.0_migration.sql acaa57e89553e8763fcbc2bcb50aa6a18b7327ad
F archives/0.7.2_migration.sql ba4b5fbcc7a56b971532d8fef20aba41e5c963ad
F archives/0.8.0_migration.sql b56b9689504b83b8ae279a5c5c42ce05e423d883
F archives/0.8.0_schema.sql 1c0ae41b79ce190843cc88a7d65f5bce65a0ca96
F archives/0.8.3_migration.sql 78f64dc82033abd49d4156b013c78828a795d326
F archives/0.8.3_schema.sql 80be656e5dde9e43cc7027d0ba6eb14b26ff3e7b
F archives/0.8.4_migration.sql 107bec2b2d0f7c958a87e71e3b2c9da3246b6762
F archives/0.9.0_migration.sql 90ab72f7f4dcb6d018df98790c3407e366881155
F archives/0.9.0_schema.sql 9f23495ff41c8810fee101826f74c80d44f7f56f
F archives/0.9.1_migration.sql 6227606b97cd3aa1296c0c2e7b884ae0b6aa2085
F archives/0.9.1_schema.sql efe750515a9909e2ee06db77bc97f005a2f8d923
F archives/0.9.5_schema.sql c8df01c2dd61ee0516f89fa2bfb78e5f208550e9
F archives/1.0.0_schema.sql 292ae067786851c89ca00bff59e08a12a43d40fd5f64ff85a313477e8007485f
F archives/plan_comptable.json c4962464667bb992c37d3b7363f80de0eeac9ad7
F build/debian/config.debian.php f3119a87085bb5fedbceca0c206442c3cfe49e14265125d48e5f2c5a23121d00
F build/debian/makedeb.sh dd8d4f904f9162b7ba0ef81bbc88514fb61803e2c8fb1c257c36a1f48528b2b6 x
F build/debian/manpage.txt 81ca70dd7d81d2e4578de5317057f03581326a7db15eca4a90d3d9885f5f3902
F build/debian/paheko a6de924cf5669b8d9c6db5277a6a74e26d5c9e76b388f338c8a11354fc4a4484 x
F build/debian/paheko.desktop f020895fffdbed4773f6cf9cfc99e6695ccf35084e80e8a2593167390e12d647
F build/debian/paheko.menu f93ffda8edce658a00928bb52e7757ca8ce3a17dc1e28944486b73d6fe4781d4
F build/debian/paheko.png e538df2fa2ebd8b873c77c8e71c1daad3cdc898901d8f06a14966eb655f3d5ab
F build/windows/Makefile 7b464ebe758771ad301e07cffcbd6dfe04c771a5562098c5bcaa3c5438b3442c
F build/windows/README.md 5c56cc2aa07f74d5b6f78899af2fd482b19d9f35803f1c9cdfc863a0868fbd8a
F build/windows/config.local.php f722b32a30b33980e301d264c3224b6fa4e5a4dbbe98cc5956fbee099b8584f9
F build/windows/launch.bat 4318d01c86cb116035345ea2bfefe584da2bc56520a4bb51e3a282377cce399d
F build/windows/paheko.ico 969b2f968c7bc5f8474f2fbdbadf515be1ed1798da2fd845faf6f42240f0fece
F build/windows/paheko.nsis 8f73d399b04c544b5d070fd821fdfbabbbafb861fae761826fba2d837b0e521c
F build/windows/php.ini 43ac89d6777fa71801cac6eb1d6515ce5f3bd460b022f328b75df0c27f2313be
F doc/admin/api.md 891b1aa042dd0c03ebdf4f9800de25bfd9d3f5c0565e1b084d3773c6eabb32e5
F doc/admin/brindille.md 8edc24b7ae8a3199365094300f7ba4f3fbc5575f8dcfc0872f9fafebee339470
F doc/admin/brindille_functions.md 227ccbad97ed1d0f0662624a8d57041bad12627c5746a5f5c8ede286e70558b2
F doc/admin/brindille_modifiers.md 5847dbdabd1a426f17a00c3a357c1ed4917e93dc7e61ec0d8e1ba3416329a3b1
F doc/admin/brindille_sections.md 6ef603f2600a7a22da271140537e226fe570bc6ea887539a86f82d309c5ccbd8
F doc/admin/keyboard.md e9a85dcaa57bac91a920bfb4cfb595c580f4059f46b4f56b03e662fb79eb8d33
F doc/admin/markdown.md 61cfd293d2831310e6a1ed051eff57db446a5658bb47edab1a18ebc4cd21f003
F doc/admin/markdown_quickref.md 6205777c597575cb8d3750325251ef59352ac4daa8489f8e75cf518a6eb3107d
F doc/admin/modules.md 8bbc7e0c4735fc0dd7b3c7a15e30d4dbf3484b0c64198f105a5d5dd24dc3d7d1
F doc/admin/skriv.md 840d985008180b189986c8006760b2945e5e55138429c44b0240bd86d5936a1f
F doc/admin/web.md 9859ee4f6c0b5eb464fe16a5b425473505fcacf015e5ac9c11caaf07bfe2d131
F doc/icon.png 13439ec7073ffb0bfdca7062ad90755961109b66ac9bf49179f6a2dd07f6a378
F doc/index.md 54ac4b8f732466b2a46be9d05738300665ef98d8d63a43c1e5055d207794cdd7
F doc/selfhost2.png 701da39174d67cc10da6b71fade8e1087d3c8b07e62e90b5b03ac7438031affd
F doc/skrivml.html b749ec40a9ef7f210f12108774b9e0f25c9a6c51fc3b1e6cc452b630a258aa41
F src/.htaccess.www 1fa848cf6a83049ffacd5db68281f6d2374a6a119ead4c6a3b7977c311e7ae68
F src/Makefile 2c0887f6862f285e1b11eaacb2bf984eeca725d02e97c0f937136122767fa559
F src/VERSION 586e3ccefcb1c33d7bbb9d9a5d045ac5237b4dde29cc64134e952cdf5206dbf3
F src/apache-htaccess.conf de974946e40c9da0a3ad98c7dee430c15297d344d499969ad0be272114db1c62
F src/apache-vhost.conf 04ec124c9b6632a8a638e78e63a5631b3638aa55cce07d18063ffd0d8970e5fe
F src/config.dist.php dd2986806a989758fd41c70f1c1bd9ff8ef4ce9af9d49f56f446536cc7b04ba9
F src/data/index.html abe89f9bfb756bbdfb2f535420e10bb5625eb4e2
F src/include/data/1.1.0_schema.sql ab4753bbe0e71c8e5910b94a4c73243191543e942a62304032a77f2060b130ab
F src/include/data/1.1.21_migration.sql 6a26982b556b4e91cab24c577b94b0d621cbcc6042aea0d1aa220bdb2126c7c0
F src/include/data/1.1.25_migration.sql 72b38ceb6c907083d59552efee8613a8bde94b87ada1503688c4f08c20f90ad2
F src/include/data/1.1.29_migration.sql 93d8b01db404c3a0adeaa01a26c5dac5cae0deefbbb102d14d727e7c8c204d95
F src/include/data/charts/be_pcmn_2019.csv 3f6549390acc521c8617b5f4cb67f5b33d528b75e281f739a4c76d9de6f9d26e
F src/include/data/charts/ch_asso.csv e384d6a13097e16163dcb6e0be0bcf445e11921df085ca978726b0d51ce93987
F src/include/data/charts/fr_cse_2015.csv 5386feeb8aac9533d0bd87781aab280db9738dcff79e27fac717d6b2a8a059d9
F src/include/data/charts/fr_pca_1999.csv cce600ccba024cfa5468101a08171d474a4cfdc7bbc1a3ea7b89bd4aebf27508
F src/include/data/charts/fr_pca_2018.csv b4e1b59a9637ca99f8700fb52f2ed8528b9ecbbe8097b43d3bce4ac38a94aea4
F src/include/data/charts/fr_pcc_2020.csv 2b88ba109a5724c43cb2e16260f791d6583e9848ef928983cc8977c80c94b0e8
F src/include/data/charts/fr_pcg_2014.csv a3ec7658abf73ff2704af6f51dfdc4e3e202c4df4e0e1360cce2e1aa55343aad
F src/include/data/charts/fr_pcs_2018.csv 301907d458e9351c416a793915bf1276ecd63b1dcd0db48fe8c6f937b4522292
F src/include/data/dictionary.fr d3245db784b299707cf47379ab48d82dd75439a3c5a77bfdf33f5c54408a3548
F src/include/data/schema.sql 57116110a23d96f4be9c8593b2e031930774e4234783612ba48ac1b4f3d17735 l
F src/include/data/users_fields_presets.ini c53432e075f004bbf156dd8d15194ade6af69cc4b7be8b7b1ed5ac8c82567b23
F src/include/init.php 764d5f963e25fd6febd55c3cc2195930dc33d2af4f1dc2921c5a7513e5a23773
F src/include/lib/Paheko/API.php 6f1b24a15426ba1479465312cc27c583ed653ee0f3d3a971c9450472c61b7173
F src/include/lib/Paheko/API_Credentials.php b8b75e5569b842f419eb1654163c4edf135a7e02e95b99b27c0d5a1874ec853e
F src/include/lib/Paheko/Accounting/Accounts.php f427cf5c529aec71faa83dd1809f7adb4b95414f2dcf636e448b3102c331d01b
F src/include/lib/Paheko/Accounting/AdvancedSearch.php 4dcebe68b436d34d394b4b69edd1ba5f878fd99f737862eac8e29f5a63323973
F src/include/lib/Paheko/Accounting/AssistedReconciliation.php c253756b1663c63a84a18c8efc6b23f05ed3e2bcf65751fee0de04064d34d1d6
F src/include/lib/Paheko/Accounting/Charts.php aa097f23d218a57e4652b6bdf9414035027ea51ef5c4cfaadd4eb6578d6f0538
F src/include/lib/Paheko/Accounting/Export.php 4f4ad7a47258d6e30b9be35d62b2d948af7484aafdf359532997f7c31b0f99c7
F src/include/lib/Paheko/Accounting/Graph.php 50db85fd4c4f4a4ac6e01d01af3f8cf7f368c73d1b3027ef32928527a6a2c1e6
F src/include/lib/Paheko/Accounting/Import.php 5dee4748b224b48309c3319bdf8f82bccd3f180dde92e71e138adfd9f96918b0
F src/include/lib/Paheko/Accounting/Projects.php f2c156faf2f4678103a432d468528b8c7d693de507de5148a2c18d7cc7c489f7
F src/include/lib/Paheko/Accounting/Reports.php e71e9321d9b54bf6eac5962ccd189c61bb3afb9827974d5e00f6d6a7d03b1a7d
F src/include/lib/Paheko/Accounting/Transactions.php bed5cfe0ccdf38f199b1f2ad18c29283412a4deb88ca5ea72aa3d970274f2e06
F src/include/lib/Paheko/Accounting/Years.php 6d8166387a20f437c5910dea43a5b4a903f4ef96ea2e574f3505fab7641da6f2
F src/include/lib/Paheko/AdvancedSearch.php 5a7f7c2a3842b676c2599db47b0a7ef81df957b1bc763d588adb66e09c2532ee
F src/include/lib/Paheko/Backup.php 8f8f3823f453908e3b5380f749294e58f65e8e18a9c60e48e944f7b6a053f435
F src/include/lib/Paheko/CSV.php 8482fbd483951db6b12f0ed14e70eb99adb93fd2e96bbd922d6742fa6186d14c
F src/include/lib/Paheko/CSV_Custom.php a30a154c6fca07d4217f123c3a9254d5e3d159975063306d6eedbb665ca9f7f7
F src/include/lib/Paheko/Config.php 38a8dfd9db963ef77cb4373975d2dea83b0a4df73558b9c5d58799a644d217d6
F src/include/lib/Paheko/DB.php 8ed15d427fb7b21be61c115c7d9c0bd5c4db644c75d34c1514292b65676be879
F src/include/lib/Paheko/DynamicList.php d40bde39fc4a1c30cdfa1c9ec7f5ad3e3fd91bea144298cd1a65017c18ba0341
F src/include/lib/Paheko/Email/Emails.php e36a3236d0c9bd47509658c1e112ed58bb708125722aaa14ca8f5a47224fefd1
F src/include/lib/Paheko/Email/Mailings.php 5286e9dc482beb953c237a6def36f3fbf5f026e09209c245771a732220b67fb2
F src/include/lib/Paheko/Email/Templates.php 27a909c9c9e9f261797769097f93b11fae7a1304d940b21e07a931b3f15b1d01
F src/include/lib/Paheko/Entities/API_Credentials.php af3482891c625853a9f38fe2a17f7deb9f6b51fc0eb2539c3c2f9391e04e8e68
F src/include/lib/Paheko/Entities/Accounting/Account.php a9dc45d2237aaa00c86e2fdb470f757e92cd24cd6d134fa50aa1b4b3edfa1988
F src/include/lib/Paheko/Entities/Accounting/Chart.php d7fb7ded59d304eb99d6b8fc4985bf73b6fd8f978e5a05963cb444ab7d2a7280
F src/include/lib/Paheko/Entities/Accounting/Line.php 473fcecdd3c22800106cfb733ea9105066ae0184b2e6ffa8587900c5cde77bfe
F src/include/lib/Paheko/Entities/Accounting/Project.php f221f56feec52d958a4df736b080dce528af7ac466ec799967365619b5fefed5
F src/include/lib/Paheko/Entities/Accounting/Transaction.php 877151f889d9aeb63a22953d31c42113f961c90b7445d7b1727ad575e081fd70
F src/include/lib/Paheko/Entities/Accounting/TransactionLinksTrait.php 9e8c62dbd3fb808b20412535d065279e57edeb0b3bca78f52747598a70f1a934
F src/include/lib/Paheko/Entities/Accounting/TransactionSubscriptionsTrait.php 6d7d38b625e1703c495fcf4bd3ec1c2cc273eb5942ce9b93a7d175bbfad5ab83
F src/include/lib/Paheko/Entities/Accounting/TransactionUsersTrait.php 5038ed021fba4e56bc8e6be768283f12f5e6881e6c97b8f37762e5d694a922ca
F src/include/lib/Paheko/Entities/Accounting/Year.php bd9796c31856f5ec40806784cead891c567683445f77c58496c2f286c403a3bb
F src/include/lib/Paheko/Entities/Email/Email.php e24405674c55b378a3fe4bea2ee57f1449049c74ec6352ce50a4a80649221fbd
F src/include/lib/Paheko/Entities/Email/Mailing.php e71284ec734199c060f27709e60227517a324e893ad7e7b7542f8143d8bf27fa
F src/include/lib/Paheko/Entities/Email/Message.php ba4dc91b79edc17533840b3af57f8e3b4cf1159f85722b5027cacd1915091339
F src/include/lib/Paheko/Entities/Files/File.php 2e4dbd2fd6b30a7704eaf85fb116b702553971112cb9a827f38bb0c2a3d9ed31
F src/include/lib/Paheko/Entities/Files/FilePermissionsTrait.php e5ac5707517af5932bcf286c1c95159f2d17d7529a9af842f8c860d76cd11c0d
F src/include/lib/Paheko/Entities/Files/FileThumbnailTrait.php 6608d4caab67ba703c467ee836f5346f91ea476276a330d6797db01e283acf81
F src/include/lib/Paheko/Entities/Files/FileVersionsTrait.php 6fc878b2fb66bb02ccfd4afa945756a9bdec0613d310d731d2b91b3e297a9a77
F src/include/lib/Paheko/Entities/Module.php 2bfdedeb7adee9579401ad5e3f78db292d43a135dc01b4a7c79a4798986735d9
F src/include/lib/Paheko/Entities/Plugin.php 5ba82415019306b83727f62460c57fc9f1475528cab3074fb13909e138f29d9c
F src/include/lib/Paheko/Entities/Search.php 9502b9219a5b40647651732fc2f56bfb0049c0f12bc3a025c7d710ab909394ef
F src/include/lib/Paheko/Entities/Services/Fee.php 3116155735de6a5f0e7649c40da9b789daa196d970e4523b091074e0d875d7b0
F src/include/lib/Paheko/Entities/Services/Reminder.php 51bb91ad7ac4d4804f887382c4c5a7ff58bab5eccfd5a44f06bb707fc505f613
F src/include/lib/Paheko/Entities/Services/ReminderMessage.php fbaef97c819df828721440d5fc47cabe2a1d23a26fb4dbbd2537516a4cba132b
F src/include/lib/Paheko/Entities/Services/Service.php 9de625b4c8ca882ebbb552552255d00ecf3315429a1bba631f2767aa94e096d7
F src/include/lib/Paheko/Entities/Services/Service_User.php 40f2eaf44b60d3ffb5cc8afe9902593dad11c1edc72a4e0a32a7430db2c6967b
F src/include/lib/Paheko/Entities/Signal.php a5e7ac2ccc7fbdcacdde3769249f0d267012785acf1362592939730c2c9c66be
F src/include/lib/Paheko/Entities/Users/Category.php 6413ce3b9175ed74a30c4cd685737b19e61ed959837dcd8e6b125d8dd3cec62b
F src/include/lib/Paheko/Entities/Users/DynamicField.php 082994b2d2c2314269321886289edbd7fbf6ac68f2f1fe2b2ccc727d5f7420c3
F src/include/lib/Paheko/Entities/Users/User.php e3c30ce20e15325c815586e66ae3385097309ea1a90faae1258ce7be963d9bd2
F src/include/lib/Paheko/Entities/Web/Page.php 42fca84ebfe3f747008cd68bb9ffcd29fa1a930982a36b5ede7cb7b5158679d7
F src/include/lib/Paheko/Entity.php b8ca90fb3a9034590c580cd897993bf04f51cff4dc84185bc7bc52f5382803d6
F src/include/lib/Paheko/Extensions.php 75ac18b3ca043cbf179aaadca4f2c8349da578b7f785036134487186726d27ac
F src/include/lib/Paheko/Files/Files.php 16545358437543c09c52d6380e015b4d6bf5bdf2887efa44a9ac09464d7ff4cb
F src/include/lib/Paheko/Files/Storage.php ba31577894ea74d9acad5fc73b5cb7f1038bf80469bb1a9f8fec0d9c86b56027
F src/include/lib/Paheko/Files/Storage/FileSystem.php 1e6d4c57f1d647287bc3f459cc3d47bbdcf00c49996bab6db50cb9824010d8d2
F src/include/lib/Paheko/Files/Storage/SQLite.php 8d794bb5a72c9f809ba9a9ed3407d1a035fea9fb747576fee4152b0a89deed97
F src/include/lib/Paheko/Files/Storage/StorageInterface.php 2921ea55a0f6e802950323abae575df6e6624e774ff9b1fe6edeeeaf791e3a4f
F src/include/lib/Paheko/Files/Transactions.php 1385346800e1a8d45d75a891657690b4d5fda06eb77c19b38861623b41afeede
F src/include/lib/Paheko/Files/Trash.php bbb480f47e0d87179824c1457dd252102852b83b15904d73336a8e9ae3abe11b
F src/include/lib/Paheko/Files/Users.php 03407caa6e0d61b3ef7b0fa896212611bd517cc9ae318883b836a03d03991d92
F src/include/lib/Paheko/Files/WebDAV/NextCloud.php 229f5fb71514108df6a23adaf454d8923ff239d0af27efa1d592bfbfd1e5d86a
F src/include/lib/Paheko/Files/WebDAV/Server.php 3f2d99c0c189211b6302057b791b583a4d404913aa891511294fc8100a8793b3
F src/include/lib/Paheko/Files/WebDAV/Session.php d427f05aa517fa12557c3470e828cfc48a7ff9ac4631d7a6b6c2087110498c58
F src/include/lib/Paheko/Files/WebDAV/Storage.php f55e8e076239e5fad6c0f3082dd102e6e0cb58caa4ef398d6d80e4033fb37220
F src/include/lib/Paheko/Files/WebDAV/WebDAV.php 73a217a837b2e90673dd35c8dffcc452cc0ec072e91c74abe98837afa36efed5
F src/include/lib/Paheko/Form.php 4d2c42aac6bc65fad279ae7b017b175faff35fb707c3ef62ba67314929c86d0b
F src/include/lib/Paheko/Install.php 38c05fd8307f6f4b2cc60bcf3aae64c5d52dbc68457407fa37fcd9c88439d937
F src/include/lib/Paheko/Log.php 17fdc8dca9b5fa3291bd61ebeb243dbdb32410b88f5e5805fd31d810f562759f
F src/include/lib/Paheko/Plugins.php 31c5631e873444fad42cde9e433c94288f437580f71fcb0e4ff63be03a987d31
F src/include/lib/Paheko/Search.php 6e24dc0bda30e39235cf505275f4e9d309f01437f3c5e3071283095cc712e49d
F src/include/lib/Paheko/Services/Fees.php a75ded20d288cbf6f086daf15cf36154780a05f2880de7e32b5eefde00059391
F src/include/lib/Paheko/Services/Reminders.php da771eb57ba22b54d8643ed5d76a50fce651e11f67fbe43b6313299a8da8c216
F src/include/lib/Paheko/Services/Services.php 6ec7982e4235f39763d401f84851933a429435cdc3a2da7ba823bba41ef42b88
F src/include/lib/Paheko/Services/Services_User.php 9e67c6257146aeba80f4a225ce463240e1de29c225a3c5eced10042a80469433
F src/include/lib/Paheko/Static_Cache.php edc4248208668422dc2d910933903bcb230d48c3612e42bd5417eddb1f5c6cb6
F src/include/lib/Paheko/Template.php 0b6840d1d669afd5815f9686eaca9d5995b050caa9ff76c69e849f304c5abc66
F src/include/lib/Paheko/Upgrade.php 1f6f24d62a884167c7a54a705c7924e15ef9f43ed0e5cbe2316b65411ba98042
F src/include/lib/Paheko/UserException.php 6f9f5ffa6da08080d84fc154f02ff20ad57d5f508da390fbf382534465a195ef
F src/include/lib/Paheko/UserTemplate/CommonFunctions.php b87628aa1010cbfb6ea8b6d2f746e82e0aa123c793f354ed89176d667eea31fe
F src/include/lib/Paheko/UserTemplate/CommonModifiers.php e21813cdbc0d6156d2b857bf85ae56acb2b2e28a34b12b3627a42ad5e0d7e0cc
F src/include/lib/Paheko/UserTemplate/Functions.php 440081c003aa222e4fbeded563f4971f5aac271e08d3b7cda1db7718098d0c4d
F src/include/lib/Paheko/UserTemplate/Modifiers.php 22201197247089daaa9bc4b61adf598cae3de084a04eb6d131558d192310c9f2
F src/include/lib/Paheko/UserTemplate/Modules.php c899e03ae03563b4bba626f31a9df8df806a74ca70f15e1a14610f6dab97ab3b
F src/include/lib/Paheko/UserTemplate/Sections.php cc144cf763041dbf5a148aa9e1d10638e65049d4f8fca6564d8188345890f6fc
F src/include/lib/Paheko/UserTemplate/UserTemplate.php 6b9729b0bebb6b53cb5f9fada8445985af0f593f1b5dc1366f577b3bfed9ff23
F src/include/lib/Paheko/Users/AdvancedSearch.php f508f34992cf1fa47e556f3b4185b52c66eeb78f874de858c408cc44f954f27d
F src/include/lib/Paheko/Users/Categories.php e3917ac1a89abef0ba1dd71793502d2d412e8ae278b4c2dbbc3f1bb423e4323a
F src/include/lib/Paheko/Users/DynamicFields.php bb7a043b7dfa12377b56f3131dd3daa773a429f25af4a8584bfed997f65ba569
F src/include/lib/Paheko/Users/Session.php 9e16088dbda0feef4e641faa83223e4eaec143f9bbf82d7a27701044a63567f8
F src/include/lib/Paheko/Users/Users.php 8b056aca383dc42802ec5ba7b8b96f9e5fdd7fdaa1162a5d1e1a1f7f2b72862d
F src/include/lib/Paheko/Utils.php 4381ec7b83632d5b56578772035bc0d95d2b1b37182a1376fdb1771392d4a637
F src/include/lib/Paheko/Web/Cache.php 541d11136dffacc1fed40f049cc260d7f3c2ef7ad318410bde9c80729499957f
F src/include/lib/Paheko/Web/Render/AbstractRender.php 576f498e9357474ec793aab4fbe460035c6c3fa3b9d55207f326588d8332552f
F src/include/lib/Paheko/Web/Render/Encrypted.php 055b068332ddf95ba0f29d43e715aa6f66227ee3c011df1369d135d0b1304142
F src/include/lib/Paheko/Web/Render/Extensions.php a42e230e2b6c7ae3dba5d3cbfd957bb95eb2105f8c79c38d20d93eb84c7d09c5
F src/include/lib/Paheko/Web/Render/Markdown.php d45beb860c8f99cd0f7b1e0f784b34d42e458afd67516807952e7260bafdff16
F src/include/lib/Paheko/Web/Render/Render.php bf9ea0b4507b7701c34778cc266be9e9529e6e4be150b4fa52e923a31f7c465a
F src/include/lib/Paheko/Web/Render/Skriv.php 472606401bd6631e54bcb7081a3b17f12790f9249a528aeba348b364126b0719
F src/include/lib/Paheko/Web/Router.php 562eda56629e12b5d0710703fc3f48071caa1df99127101f1cfdaea481c7c928
F src/include/lib/Paheko/Web/Sync.php 4745ad2187f7b0651b417d7b1c5b45a558eaf9f3aeb25e0252fd4233df27d51c
F src/include/lib/Paheko/Web/Web.php 853a03d12281d2cf2e976bc9f61439420e041af600c581b8025764d7016d39d5
F src/include/lib/dependencies.list a2ecd905ca0fc5fdc1cb35ab808f409ba96746c7b2fa891a83f6e8974ed1d875
F src/include/migrations/1.1/30.php c393e962ee1933a051ef041551b2ab1d27cb8f990eece5ccdcb0a2b78c5861a4
F src/include/migrations/1.1/31.sql 410442c903644007e377e60e0df7face87512613e91530c5f8b74c0f6036208b
F src/include/migrations/1.2/1.2.0.sql 0689e84c69dfabad05afd6f4638e3e30ceb02d3487c3be277457a2afd75b79cc
F src/include/migrations/1.2/1.2.1.sql b8ed39033fc2127eb9c8c3e5e9c950b02e7ca6a8ce35b0e051129cc06f7d2951
F src/include/migrations/1.2/1.2.2.php a4b2e1e6221dd431314fd872bd93e9d78357c97273060a5d934cbc98c45ed5f5
F src/include/migrations/1.2/schema.sql da30dfe665476016616504dd95adb74d712ea7dc8d9cafce0819052558b93104
F src/include/migrations/1.3/1.3.0-rc12.sql 11161ac317a08dda515f12560e778982950363cec241fa8a09bdb6988925ec49
F src/include/migrations/1.3/1.3.0-rc13.sql b6b78bf4c8116aa01c7fc55a571506d6627fb8f194ac5561824830083334c558
F src/include/migrations/1.3/1.3.0-rc14.php 93634bbe5dcc813eedfe3ccee41b65253b4211057faa7b799b28fd7007d0d96e
F src/include/migrations/1.3/1.3.0-rc14.sql cb37686db57f21310b326ef0bef7e0dc1b6785d15ad3b7bdfbf38b1aea80c06a
F src/include/migrations/1.3/1.3.0-rc15.sql fa08177ded47239bfd04ca852d9ed046eec0fecb491179ba25f0f54995890adb
F src/include/migrations/1.3/1.3.0-rc2.php 48d00a8704fec118b3378199cdd13b9800f1fcb160a5466e52ed6f5e9b110080
F src/include/migrations/1.3/1.3.0-rc5.php 04b6f67038ea82524e7f4d469eb79b253aab692b87c5012f01e1c01b289fbfea
F src/include/migrations/1.3/1.3.0-rc5.sql 870ceef216f7ae31189e389543aeaa4d990083ac8d382ff5d775b4b140395324
F src/include/migrations/1.3/1.3.0-rc7.php 49dfa481b37334158fc0df017a4749bae504900468301f866f2876e0be3fa02b
F src/include/migrations/1.3/1.3.0.php 37e1876293e26690ee923e04a4a466bda3bbe9a0a1d62266b833f14b42104169
F src/include/migrations/1.3/1.3.0.sql 02437ff2468951a43547a548965cbf37b8c5852fcc9ac31b05fdae40cf80ad9c
F src/include/migrations/1.3/1.3.0_bookings.sql 70038509b6da43357389713b1fffc47346ca6034efab63d0c6be9d9bd0b7bb93
F src/include/migrations/1.3/1.3.0_schema.sql cc2e6bf0f7ebbaa5ac1fe52f3c68bb993115fb14758379f9b05c64296458ad84
F src/include/migrations/1.3/1.3.2.sql 3a81504a4d49d8226aba81aadf40a0bc1955fcecd3ab5d009186080c70ce4318
F src/include/migrations/1.3/1.3.3.sql 765f1b91b165f2d806c00e2673491a76be9c78b37eaf82b2da06691443e403d6
F src/include/migrations/1.3/1.3.5.sql 0f6116f331fe383330e803d0261b16e0abf3123e088de8c9e427c85ba7899af6
F src/include/migrations/1.3/1.3.6.php 6641862274cd20981136cf9ccb8afa49f4193b357c62011e722e5118c5bb90f5
F src/include/migrations/1.3/1.3.6.sql d678a03fa53dfd80ac42479cd1e2deb4d39b07fd1fc3bb6d6f9adbd1d8a833f9
F src/include/migrations/1.3/schema.sql 789e6d39a66344c561a8f7538af4df9012dbab55f96887909525440473b48776
F src/include/test_required.php 22354c63e51c190b09cdebe4f67da51184e2d2d3f1ffe068dc016fd95fd83ac0
F src/index.php 3633bc39287a8bc3e4fc60b80287a12b61710f6e
F src/modules/README.txt dd5b3e533be29babbb6d1a3982deee2872519e9db63f4daf68bf765e781670cf
F src/pubkey.asc e8974cff9c91a4a2e6dc1749dfe79cc46ecd3750b57a829945aa748a932eb54a
F src/pubkey_old.asc 7eb815c6b8508e342c1383400c531c4774d75da553ec05687f7c3c495f6ed21a
F src/pubkey_signed.asc 2005d5e9303f9b455be7497161f03ddc835e25eaa1064b5144ba743cf44a3682
F src/scripts/cron.php b833b2c35fd1b1fcc053aa8ff775cb31cc5b7ec5ae962fd1fd3fabc5840c0b1f
F src/scripts/emails.php 8c7903525ba625f639e5006ced57e50b29c7c40048a44b4f097684049fea1062
F src/scripts/handle_bounce.php 8f113ead55cd356a42e223bd61216f26e758ec7bd5d524c69fe50434cf49f5c6
F src/scripts/storage.php 37792e3e82b0a0eec5f8651d91fdcfad74dadbaaa0e88ee212d22ea0e24a35a8
F src/scripts/upgrade.php c7191a17d2357dc940cf1c66e2084c1a255cccc8ae66b10a654d95bafe06df95
F src/sous-domaine.html 570b1ded6010aa8475f0fbd310916c2f171f02147824731a0f8fdb5c15b19492
F src/templates/_foot.tpl fd3f94279f98856e94e0bf7646da1d5a9a73d6c47f1f5a1718ec2bc9957db6f4
F src/templates/_head.tpl 285112325566e6290ab1f27820869bbfcc8f57f542ae482b38ac6e9e6b35ff7a
F src/templates/acc/_table_actions.tpl b564fc53bc4e9d88b2b9f73fe40fde55c69e1b7ddfb6719a97eaa140a835dedc
F src/templates/acc/_year_select.tpl 9d69235d945068789898d2dab051f4ad3aa4d241
F src/templates/acc/accounts/_nav.tpl 84ce1f0f134dd7c3bf3c417e6a49fe1455a6feb75e8ea44e98005fe83cb59952
F src/templates/acc/accounts/all.tpl 527b1a3cf17e6fab54b311b8b26cabb26168506e1359357768156149b745b58e
F src/templates/acc/accounts/deposit.tpl 5717951cb833afdf60d7cb0c596489290d350b9f7970c8de24a5d2d69569105b
F src/templates/acc/accounts/index.tpl 27ad87475ad3f6251445051c769eaf83c3d8308e746add8e5948d38267e3e6ef
F src/templates/acc/accounts/journal.tpl f1c1e22fe191f6a91e2657b9d6a57d7b4d1b181c2599f918412fee40b5b1bf70
F src/templates/acc/accounts/reconcile.tpl 763c8b6e15a7926b4794e3d7a718131a0088fc5cfa057690ede103c834dd2b2c
F src/templates/acc/accounts/reconcile_assist.tpl 5f4684d54a63e985bef8cb315bb031e0af610a9939bfd60c807f05f8f41cd1f3
F src/templates/acc/accounts/simple.tpl 492b45132e107abd27c3f6e5c83f0eca99b45707762924d38d62b3fe752ce236
F src/templates/acc/accounts/users.tpl d0ee19ce7a9dbf18ce4f494dddecd49671280d0f36ccedeb72b2945743a67c2b
F src/templates/acc/charts/_country_input.tpl 8970124fcce868eff491e4ea0bb41707fb1ddfb619d0f33c05c2284fc7f45b03
F src/templates/acc/charts/_nav.tpl 54421037ef8dd93411cdc8030b733bf3f9545961f0a9bde0881dd76ca5e6e4fc
F src/templates/acc/charts/accounts/_account_form.tpl 0f5791955c82409298a7a543a881f24d1279a68f808df870bf78b4b3affb1826
F src/templates/acc/charts/accounts/_nav.tpl 41dd69badc966c22e7b4b41835961a55d75fa543c29d5605912b710b5cc934aa
F src/templates/acc/charts/accounts/all.tpl 41a9827d7adbe228c72a49658782c6f124773753f8e3e86d2716413b2d4e2d07
F src/templates/acc/charts/accounts/delete.tpl a20a59f44d562f68568e8c617a83d690246b5df94fd98b0057cb3bd20958c090
F src/templates/acc/charts/accounts/edit.tpl f19aaf4a8f5c2a0588cc3c1f24f701dc3cf96718159b7f784ad4a94e267cd63a
F src/templates/acc/charts/accounts/index.tpl fae8c70754184c2a20a32c9be764bdac6530e6419344bd7fe8786d4567d2ce43
F src/templates/acc/charts/accounts/new.tpl 730cd32e4d87930127eea26f2ba2aaeaf18208a56ed4abebe5d98fea783ca3af
F src/templates/acc/charts/accounts/selector.tpl 0fe30f14a9c4d628e0746b7d783576457b3707599d5bdc7a0365e1b95331ef2e
F src/templates/acc/charts/delete.tpl 770eef87a72f0fd8f37ff638b21d743c5811e77af9569632275db9836bc45eac
F src/templates/acc/charts/edit.tpl b40615c384d6567a65dff280d4b72cb03f3f01321df43d332242833e5a16cdd2
F src/templates/acc/charts/index.tpl d93297a9f5d08d87df1fe621d0f4a5f1b477c3961397c70fe2b1c9b36f1148d4
F src/templates/acc/index.tpl 961141a8c7629606128ec79b936b30c607ec1d717336e5432df0203b05168b39
F src/templates/acc/projects/_list.tpl b400835f183326d1e20018b7905d0b594ef298abc776b6d76555e4515ca82ad5
F src/templates/acc/projects/_nav.tpl f31c70f86785821285a04a5ccf247d9b918861772a0479f17230df86b77f284f
F src/templates/acc/projects/config.tpl d654a3d8de49c284b90c32a91d18ea3e657b27471fec310667841de5a77b7e19
F src/templates/acc/projects/delete.tpl 50483883de6621504d4a3b6e2bdae3f54024e03ef3ae6db3b0636c4126ab6324
F src/templates/acc/projects/edit.tpl 866858263cf78aa66e7a0240dc8ed2f528972efa0dfd434ba51bd587f6e44cc3
F src/templates/acc/projects/index.tpl 1e74f6bf0469caed2a481a16166daf23fc4c311b80cb92b17d3fe4a567362abb
F src/templates/acc/reports/_header.tpl e478688d2dd27e8d909fa2bfe64d77bcbbbe154412efb2136378ed57adda4f46
F src/templates/acc/reports/_journal.tpl e70bc0c6869cb4f20309ac90bf5d124eec74c14ffdad6ec9b77738a137b7dab2
F src/templates/acc/reports/_journal_diff.tpl 97ed168abada0e4f4c52db6d12fffb2105cbd3d743e934b68783287521ea985a
F src/templates/acc/reports/_statement.tpl 8914b0b9aec0568d7736146e15eaf74474444670bc0b1865d3cac05deda573f5
F src/templates/acc/reports/_statement_table.tpl fd1b98776b4252de106b7265e977a9c3abb08e640060214e7ca62e479eefe38c
F src/templates/acc/reports/balance_sheet.tpl 78ec3533dd8fc56f2a1a3d73bdd1452003b5b8f806ebf182aea7adc0c7befc31
F src/templates/acc/reports/graphs.tpl ac8c23572f9bea47f62a6730647b8f6b34fdb435af90e8ae23630382de3e79f0
F src/templates/acc/reports/journal.tpl 2cdd15e90566050036fe662fcb86ece8380cfbbd899b1787575c16c11270dc56
F src/templates/acc/reports/ledger.tpl 3199442208fca1ecd7e9d3ad136f1392ea1448c6d93118583301b86e400cb0f3
F src/templates/acc/reports/statement.tpl b5b79a83845ad5533c02e578606e0a9c284c4571223228e88fbaf3435450303f
F src/templates/acc/reports/trial_balance.tpl f64c876e9d221355cddf5713a561b48e11a809e61c0383f6cf8961fa5cb1aedf
F src/templates/acc/search.tpl f6fc20649bada08a3765b4ac65337c251e1cf34a37335af6817eb32f8f7a06a5
F src/templates/acc/transactions/_form.tpl 2359d454365e2458f10fbe8037ca244469d1ce1c742961a01b140bacaa2a7240
F src/templates/acc/transactions/_lines_form.tpl bdefaea554333083b75c8a333e7ce9c05788ecc4678e08ebe049c280bfbe6274
F src/templates/acc/transactions/_pending_message.tpl 980bbc8a961d5ce2c23d70dfc99b8751401c233d6dc4245b95c9eab04e055bb8
F src/templates/acc/transactions/action_project.tpl c6e17886fe039f74a601aae8e59ac0b34de371f4343cb9165a78ef9138f3cc3b
F src/templates/acc/transactions/actions_delete.tpl e4e47c60f4889d5500f4c319c81c38b2903b8f5dc4e719eb6b8ea59dfb111f12
F src/templates/acc/transactions/creator.tpl 8d3d1b3556f579ef60d263840e701b875b1613b490bcbf14e1751c93a6b22b47
F src/templates/acc/transactions/delete.tpl a52ca8a4358c57f04f1d3651611ecd337cf3023385f8e3a2c0af18daa9615217
F src/templates/acc/transactions/details.tpl 9b35ee0ecc23e80996763f7edf843b8822921d8447e5b0e35bb16ffd0edc15a3
F src/templates/acc/transactions/edit.tpl f1b0629190fffbd6ec085f4d48562dd97530306ea1b66f400ec0d23009206f07
F src/templates/acc/transactions/lock.tpl a4d016d4407f984fcbba55b6e6b989bd04ea0792f0ec9e5a55cfec0932dabaa6
F src/templates/acc/transactions/new.tpl 5c27358fa01820f19734fcec1f8425a8a6520f37a452b3e4a417597a378e3ae9
F src/templates/acc/transactions/pending.tpl 0aeee62cf38e83b8c55811ad6f8446fde16724d58aff96119aee2fa22c3853d5
F src/templates/acc/transactions/selector.tpl 7b3ea49429b1700a2fee6b04f60a9c47257956034a8dc1b3cdf4ee8153dbb873
F src/templates/acc/transactions/service_user.tpl 6640beb19ffe0a684a4b71d14848898b1e095d6db6f212724e73c3fedb376b6f
F src/templates/acc/transactions/user.tpl 6a563c7bfe8d8af7b2c2bbb4db9f4fe7cb3253706ac2497312fd1cdaed9bcc41
F src/templates/acc/years/balance.tpl 1c03ed91c5e41188db976ca901ec570e380d53cffbf9a5fa5210222874d2668a
F src/templates/acc/years/close.tpl f4f366882050d2c62e1d0b6c0fbc7a6c41d6a8d1b55594fc4424f897d77c9b8f
F src/templates/acc/years/delete.tpl 5b6b3347d51916921e2fe93b90129297141c7dc8709651d7f8fc556629a94012
F src/templates/acc/years/edit.tpl 885bfd3bc578109d2153719ea6c5fd60c350576d15341779bdb3eac70167526c
F src/templates/acc/years/export.tpl 8758eb1e941fdd1338457c561808b722c3e20b9e63a8f1bd991c950bd088f465
F src/templates/acc/years/first_setup.tpl 9f5d11c30c99b0b9c56e665333dbf149d5737c5b0dc17b87b712e33e6345ac6e
F src/templates/acc/years/import.tpl e820cde50b74fa04a3887f9d2b179c707ecb9894effcbb290542392ae1e2573f
F src/templates/acc/years/index.tpl d3c41fa54dfcf9c1b00342cb4d6f929d9689a6977ba99f48cd3e53d091f3bda5
F src/templates/acc/years/new.tpl 6309d13cdc2cb38b5e2b8da1a565467b14588348d0c5504801fcf2032b703398
F src/templates/acc/years/select.tpl f5d95242b1dfc4e28da0a26e2572f11f0358bcc76a84e5a1b34bf115340d2d8e
F src/templates/ask_share_password.tpl 64a822abef8bffbd21d9d4d1ce5c05cc06d4fafeef01d068e0af6046f0343d02
F src/templates/common/_csv_help.tpl d2396fd24265c6d5ec0ad11db694bf685c73d00247d8d44034347f710a06adda
F src/templates/common/_csv_match_columns.tpl 3b26a258d5e2401494de4d1f52451cc49fad8fccca0484a26f183490773581f4
F src/templates/common/_sql_table.tpl c361e988d8163383ff52ba5b3e7bc735ad8187d7b8da1aa1796793faaa4f12ec
F src/templates/common/delete_form.tpl d0d845ada2b1b9c79c636160e5b7c0a08168a59fcad753f1c4dd7588eb1688d6
F src/templates/common/dynamic_list_head.tpl abde4332b8d2f310dc5d350877319f245416cc530f38045604b013fedcc6ee5d
F src/templates/common/files/_context_list.tpl 92d4b1a7cfda602aa3004a5f063dd1f84e8d47929ba31047630066ef074b0c7b
F src/templates/common/files/_file_render_encrypted.tpl 96a545c1d04ba674e9331aba1bf5dbb976d622c792f9dd3a882bb5d2e80815f6
F src/templates/common/files/_preview.tpl 2d5be4acf580f38311de0544a426bd467e62d61c6ef2a891948f84a09ee197d7
F src/templates/common/files/delete.tpl be0cff6dce2535e8e379daeaab56a68bed9bf673081364c68e2d07de2b093b47
F src/templates/common/files/edit_code.tpl fff859ec49c2d8929711ea37211cb3d96aee3b833f6e4110b81c65defc092678
F src/templates/common/files/edit_web.tpl 62e2d8808847a858da27a249dac0e4944c693089204889f3c699760c4686fb41
F src/templates/common/files/history.tpl 800cf176bc67e04a438429ed17c75608e1fdd899d35fdb76349db49def47da9c
F src/templates/common/files/history_rename.tpl cf3891da0eef64621152899dcb15059f3dcac2dbe081a3d3480325db61f6b749
F src/templates/common/files/rename.tpl 31f0f230d4d5c067ce3eefba7d13756574a8daa85df7b053f2e2da60f22a2501
F src/templates/common/files/share.tpl 8c51b4bce0edad18ff15289becd1f17a3a3b68edc36d62065f21603cbc1f9cee
F src/templates/common/files/upload.tpl f4e3d9978c99d9ae9c2f23a008cb1832d1ec55fc93464a94d76d2fa0b69d1826
F src/templates/common/search/advanced.tpl 399fb967f8c2b83af7fc60b3e023d909e05fe36417236ee1109641b1136b0953
F src/templates/common/search/saved_searches.tpl 25bd296f13c6056708c3e76bd800016bedbe9b37738dbd0a577abf91eb555271
F src/templates/config/_menu.tpl 8e80c00714d5a3550e2834a7938c5081febb0fcbe76ec99a2d99318d0e4059d6
F src/templates/config/advanced/api.tpl d8e3b6d3d4512c9ad82bf5f496fd8dd4d5a401a960ed1c52e24f7c6cdff74bfe
F src/templates/config/advanced/audit.tpl 5ecb9cb203ffe49626195e86c0101a2f8b4aa16f55b603139fb078de7e700ca6
F src/templates/config/advanced/errors.tpl 286b66c96854e23a163c99f1869c303fa31db7e0707c5cb921bc2ef57dee32e5
F src/templates/config/advanced/index.tpl b39fd9f3d537a19a15dad2ecc0c1732b2aa9110a283a0997bbb8063aa6a00384
F src/templates/config/advanced/reopen.tpl 4d422485411d63d9cfb15c13df9acbadda25d0cc008cce87b186cf0cf7bb456a
F src/templates/config/advanced/reset.tpl 0f77448e3ea524581acadf687f5fc3e8a7850f4e567654d3b5fa5a0477897a57
F src/templates/config/advanced/sql.tpl becbafaa6911ea6f65e9f23f43c1f334db754c8f76fec59b8ebfe4930b84bd36
F src/templates/config/advanced/sql_debug.tpl 6edc4e970bd5cd22454342053111494bd50875e07a96c17bce533ab9b4eb24ef
F src/templates/config/backup/_menu.tpl 697510b2be8f1c190a9841052aed7f31b19c43c1279d524f92e770319b8eff95
F src/templates/config/backup/auto.tpl e1cbf70807040a95b63928b1dd4abcb80425cd0b52d006729e9ec8b40f3cb350
F src/templates/config/backup/documents.tpl c9821014c8320c4cc2fcacba514484509d9c43207b7f41662217af6d2fc671d6
F src/templates/config/backup/index.tpl 1faf2939208049f19ee7e3f2ea5c728b97afc596384018021a98db5b78908853
F src/templates/config/backup/restore.tpl 98b0327c18d0b8ed21c88f9fc8f98b6365030dd222ce1bb8b0110bc81d751933
F src/templates/config/backup/versions.tpl 1c7d54cd7d0586aafc16d2d2c84c8eb6bca5f35b66d0c68baa4a0d924b3db3d6
F src/templates/config/backup/versions_delete.tpl b02242093c04d66b2e8bf37bc6737711ed8f3420dcbf7c4903cfd2b95bbc0038
F src/templates/config/categories/delete.tpl d68a5716bd966c99307ba350b5aed3c9128d3cbb1eefe73c444900b473565f86
F src/templates/config/categories/edit.tpl 69738b641dd4f432ea0c06a069dbf036b0f5b9723f8509ed8a287c63226cb46e
F src/templates/config/categories/index.tpl 2b49a28f7880c63971edf8c85570e9598b5e52e02f69170dc788b75caa83abd3
F src/templates/config/custom.tpl 852e5f8d66253c11551dfacf54bd663c1107e8d617b09d048d6b55037e3cf215
F src/templates/config/disk_usage.tpl 41fb60af426697cf57c69b121c6567399fe307e2cbab96176f92037fdc39a639
F src/templates/config/edit_image.tpl 249062b118e6a849827d2d853cedb5181b16326b95316890c78d63eef34a4a42
F src/templates/config/ext/_details.tpl c5a501557bb3e2e27666a489648c2b7fc4c732d7f81aac0ed0ac632636b6834a
F src/templates/config/ext/_nav.tpl fba85f993ea122b1255cfbb640d37f0d88f03a343c3eeec6041a803d76d86a97
F src/templates/config/ext/delete.tpl fc672871e7c2928fc62b0e3b932d4e3ebecc9a27290776fbd005991f3e615961
F src/templates/config/ext/details.tpl 8f8f84e658123b13eccfdde5d7541ccd0766ebcac0c0919a36eee42196fd8973
F src/templates/config/ext/diff.tpl c21a78df5af19cbb7f6f66f4ac6459d08aeb755a102db7176ca424ea6081aa1e
F src/templates/config/ext/edit.tpl d3e657b46b5283e46621e6bb17208b51316c5586581fffeffc81f0a79c261473
F src/templates/config/ext/import.tpl 6b4c385d0c81686fbad72f8ef274afc59add81e197b44127a9da87502b6ad7fa
F src/templates/config/ext/index.tpl 30d78b814eaec87660c6faad9e1b41eb84275876e5a0df360df6d15bfd02164e
F src/templates/config/ext/new.tpl 9a8b1a826f500dc0bfce7c25a8fc114dfdb33753ea606fa08355a9d9673c76cd
F src/templates/config/fields/delete.tpl 7f5227ca29989fc776e37745f875b1d50baa85f3a2846bdb3ec9a90dadd55aad
F src/templates/config/fields/edit.tpl 2651d7db047b2c64de95c65ea3a430f1ea8bf8f30dc3d87529674b3d91b600b2
F src/templates/config/fields/index.tpl efd6618c4663447375a623f0b6126e91d16ee5fe077958641c799d60f57b315e
F src/templates/config/fields/new.tpl 72353574ecf16f3e4771275f65a1e7ab7ccf872d8911a9e41f913278e7fe5738
F src/templates/config/index.tpl 95475a082ca670a84dc14063f2541d0f6469070883eaf5db1b04bff40899a5b7
F src/templates/config/server/index.tpl d91eb5a4e4abb2ac1351e6d3c6df3fcaea15eed2b087e912c9a43519cb49e734
F src/templates/config/upgrade.tpl cf8e3610f7d1402d20ecb4a5dbef7820237d84c84ed873f2e78ba45f7903785b
F src/templates/config/users/field_selector.tpl 4f5e4a822a803fa166638ac1489752d15cb1926dde15980db9d93cca7e442419
F src/templates/config/users/index.tpl 8b9b97d305ab0439f2cb6295955e7f1abe66b08627e9030f06a9e0f30518074e
F src/templates/docs/_nav.tpl 920527f86b1aefa5c699d82ab2ccddc5d98244969e06b3de69d771b7e3ed4698
F src/templates/docs/action_delete.tpl 85a65c16cbcfb058acf21dad9a0d0526eb4242d6aeadbf6f5f030221fb477fb9
F src/templates/docs/action_move.tpl cebb332df8dbcdc76a5deafb76f06acde18a3b7306f0544afd29e93682506600
F src/templates/docs/action_zip.tpl 114d5fbcba613fa60010bea0f5747072c8b7c1fb24aa19bd50851efa7857283c
F src/templates/docs/index.tpl 2fc0c3c4cec6fa948d4d28f79871cde72e76c0e427d6d7a3be5f2c1421db27a8
F src/templates/docs/new_dir.tpl efb439d26cd579114e13870c35c39e8a71abb66f1c60618b39465d4e7b3908cb
F src/templates/docs/new_doc.tpl 61bd4b47f99b57ebf71141fdc5360bcec4abb40ec811253cb04f8552448508d0
F src/templates/docs/new_file.tpl a6c698189b67b187207759403493cd92af38d46dbf004d0ebbde51ad59a28d1b
F src/templates/docs/search.tpl 56173f01c0aa5898bc01dd41016f93f87417737417d7b8f609d7e53b3db09300
F src/templates/docs/trash.tpl 239164286cd7954f48f5bee144628bc3f3df51f079dce5cc00797bf6e789fd16
F src/templates/docs/trash_delete.tpl 09f17d3438bc7406f8b7b8fbc32c5849a66c293b1d5ede463be41cccf413b777
F src/templates/emails/login_changed.tpl aaf10e05bad319868dacd8a9fbfa9a321e41adcb46d2d106eba45312db5e396b
F src/templates/emails/password_changed.tpl f2ac7406d790310e1854bc428cbc77f533ee662957b696b29c4d5b739d06766e
F src/templates/emails/password_recovery.tpl 6a0f64f4f79cfd6dfc667bc29b71784866f797c762166eb168a1f151f5a99403
F src/templates/emails/verify_email.tpl a4d3823daeb5ae9fed9bc85b6328235e9a22b8cc34239442a0fa85ad734406d8
F src/templates/error.tpl 50ad744aad666beafb6b0b43225732e1337e53698c01b20a045ed12e5704c406
F src/templates/index.html abe89f9bfb756bbdfb2f535420e10bb5625eb4e2
F src/templates/index.tpl 994ad84e962abdf7aab481571b788f933395a7d19d8f0d56b56447420420b656
F src/templates/install.tpl d95835b6de5de137de97570b723823c64efb15af8369cb8201d0e0123118275d
F src/templates/legal.tpl 10bbe6d7b52ada7763bac4016dbb8706d0e0b59cdb1db3de03fc7b5a47906b5e
F src/templates/login.tpl 8256c7641bd7315c96d7d2663379d07f4cde5f0d070c37c6c0874fcc8a191662
F src/templates/login_app.tpl aacba63dfc74e513295fae6ffe1b9a8f65ac8432c2856fccc531714de327bd67
F src/templates/login_otp.tpl ac9cba2f9f3656a31d14a951708740264b7da5834dfce3d59a91ea9d0a36e3ec
F src/templates/me/_nav.tpl 680aee52295b9a6a4dd4a564aff5f9ad0f302fe897995564156b8297b0ae65a6
F src/templates/me/edit.tpl 6962fa61d2acab7743ad26ab954f7647b8a8cce243cbfa791d27f7268c72bd0d
F src/templates/me/export.tpl bf02d04af7613f6e11e76d59b99c03b227facd7887e3657d315eb7cf1d04de8b
F src/templates/me/index.tpl 1e788bb34faa9ea957ea430fa611d871cda836931c5380f8b9f70ddb9c1bbcf4
F src/templates/me/preferences.tpl 18d75a6ee3998d7133090664098702da75e74bc76804f0874b8650de82101255
F src/templates/me/security.tpl 00429b96894ee5429e6d59bf0c040619986f5e66c0e76c488fbeeec6c7627a27
F src/templates/me/services.tpl 87e02c49816875997252d3c25499d83e79078c965f83127c84cf628c867f3383
F src/templates/optout.tpl 59ccf897026fae5afd48b0bcf9b4e34cba3c7397031fd559a9b33fe29fd46c38
F src/templates/password.tpl 31ba1206d06499ce283bea1fe3dd4725ae01995e6ec7fb7f5bd3442e95ac4302
F src/templates/password_change.tpl 6a5f87eb36c02174bc8dc45ba93c773856071c5e5ade90918b7a369223ce9dd8
F src/templates/services/_nav.tpl 5e52af7d0643eaeda6abc9ce7aff3418e6a255b1660cc2dfb797014c198bef5c
F src/templates/services/_service_form.tpl 7e9c55acbd09f74fe03f19ed55179a6c16d02461c986b609d0942a54aa924311
F src/templates/services/delete.tpl 347481046351c43cd14d97623e42b2a6e6d5f90c9351d095f80ed1faeadf7dcf
F src/templates/services/details.tpl 814e435b61db5974050841bb2392e5561fdac3b3eecac26ed3d4e4cb75331359
F src/templates/services/edit.tpl 12c859a833be1022ad33a9230f04e18e89715a2311820417ac428b15496db120
F src/templates/services/fees/_fee_form.tpl 5de507e3b93aba39dbc015200d08788ed3dbb52c18f808df2459da2ac0791493
F src/templates/services/fees/delete.tpl 820c8a6b776f55cbfe57aa9581c0e3ec2f8e005ef9e4ef5c2ff4ba3c868f8e74
F src/templates/services/fees/details.tpl 01c98ab39afc4587a7223f9a282b18a7752ad701bed14620f4d21ec11d0937b1
F src/templates/services/fees/edit.tpl df78282e9779644ac753be3e9e5de47433cd73dc92d6166a9ce395df6a2cda57
F src/templates/services/fees/index.tpl 46e7db2d1b3138dc855cb07c50927998a56d31eaf13f3cc578a95ba3fbf7a9ec
F src/templates/services/import.tpl 4484803cc7fdfa52391a265e506579ff0b6ee6a4665f52166dede5c374b81672
F src/templates/services/index.tpl 74054465a9f770b4d612764b5a11f224e4b985eb77d78a04313a01111422c7e6
F src/templates/services/reminders/_form.tpl 2645d5042ac9b9e0c3fb6410edecc7e84eb5bb17eca65a0ad5336586d9ad1547
F src/templates/services/reminders/delete.tpl 95bcd98fcf9bfd492c6dd55a80354f0d123b7916ea5cd68434df99c6ae2ae38e
F src/templates/services/reminders/details.tpl 827126e9349ec5307985c739e71ae016f0a48e583f22f25ac33693d923ad6ef8
F src/templates/services/reminders/edit.tpl bf5129f51cf1c454c1d9ca99ab0a5cf2baefc225c20fdcdbdeb1f97267a9a458
F src/templates/services/reminders/index.tpl d2a030a07f66fd34e275e0b8f5d967ed173ee08f5656326913f994b04918cd4d
F src/templates/services/reminders/new.tpl 8974fb9fde0b0d607997c6c56447bb30563fd1467800e5b1e4eead0c24e4b05d
F src/templates/services/reminders/preview.tpl 62b7b595c29f01ce071a04deed0d1a34d6f9b989e2fe214e62e98850bdc677ba
F src/templates/services/reminders/user.tpl 8f1d568b5d8b64ccdcc5d101df487b65b9c604c3be674c469b062a6ee7ff1b5c
F src/templates/services/user/_choice_form.tpl 2bdf0b250d0c1fac8159530837e674ea6047428a800042f9ba3ab4272ed9bea2
F src/templates/services/user/_service_user_form.tpl 2a5685417c79c0a723bfb8f340a7fef7f4c26d13a78fc5b5ae962e4911b4ac44
F src/templates/services/user/add.tpl a9b93751c54e6350de13fd94e4771105eb7d1a027433286db51337bb7a61bf62
F src/templates/services/user/delete.tpl 9a92a85389c44597036a2bdd27a6620e39470a5c1d642dbcdc56fd65be9759c9
F src/templates/services/user/edit.tpl 3f7ef103e93c9d98599979bab0bf619436c7badba2d05bf406b06ce5e36bbf39
F src/templates/services/user/index.tpl 3993d68104d477b5b3107602ce6d7dbd70b6081f478d34d598ff4f86e9a79dd7
F src/templates/services/user/link.tpl 6f582c8e1fb60863e0942c3bcc630fd062992943ba8a0fd138417664423ea4c6
F src/templates/services/user/payment.tpl d5e1991249dc65825bdc1513dc96a428ec23afd9bcbe726877346a20c4fbd2bb
F src/templates/services/user/subscribe.tpl 956f4af913ed7b1c7356653c774fe96edea481f020b98f86214a788aafd5c7f6
F src/templates/static/upgrade_post.html 189bab4a7794569385df112f9227bf928be00fb1071fa658d61a2b898b983fc6
F src/templates/users/_details.tpl b3fb59fa846c704a4212369327aa9a96aad20e3dd345b3fc66675a690f970374
F src/templates/users/_import_list.tpl c35d5796835eceb572e2a37741ce7ce1e4251114617a0879a06d96a749ed9eff
F src/templates/users/_list_actions.tpl 9e89b82f0aad2b5ac99d19cf35c5495c397bf3dd69ed8fe3f203afde57a8e0ef
F src/templates/users/_log_list.tpl 08b5d1bd093db3a61e1a8b0cc3a8ac56279612c1e88d9e4b6239525af0a168b8
F src/templates/users/_nav.tpl 4e65aedb035f076b1d53d4092ca19d69f854ccc3b090f7e9efd3938ae2093812
F src/templates/users/_nav_user.tpl 8a253455d6ae3d40ff81175d577eab1a2bd86df0de3dd0b7f31fb3cac628b885
F src/templates/users/_password_form.tpl fb3df829ba483036bc3e09ab6d87797a787552eff5f1bece6aa67caa59ddc48f
F src/templates/users/action.tpl 2f37b9ed9af60d94610f8cf5b309b90d9ad2b9b4024380de78b5defff423e735
F src/templates/users/delete.tpl 31f1744fa2732f3a91ea89fc9cec1d0b640ed4b48255651dfbd7338a80800e0e
F src/templates/users/details.tpl a4b7b4e4cb81fda977776195d423813dd0f21280412f769d89293430b608b5ed
F src/templates/users/edit.tpl b1a8abad3507fed835d89540cf38e46841208a0d4f245e8d5b414a8cf667c86d
F src/templates/users/edit_security.tpl 9f47b76628e1ffdf7862d1038d4a9afcc7e43f610bea22c472bb27b5b9b4d1eb
F src/templates/users/import.tpl c82adaa55c5e94a4462544e7922927a3c5fae87160c09b4594fdac3d87f4116b
F src/templates/users/index.tpl 98b52f2c45ffe371edb4ccc9d4f532c9be2c793cf2d0e4ea09c1c667ee9cf227
F src/templates/users/log.tpl 6a72a51d09deab43fe3caee7d9d333908c4973898afde9023810983fe3da8e94
F src/templates/users/mailing/_nav.tpl 63fc9f91241b6aa3ee139ea9a59b7a37787c505edf6b7c5daa02a6c1900c8e17
F src/templates/users/mailing/block.tpl d3cb8291678bac15d24b99ae07b01f9a95f8af7c83b19661103b7f9ff4d13ec4
F src/templates/users/mailing/delete.tpl 287d96382be6517ca133c8c8c97d747d57cd39eb2c276141b352d68f647b8fbd
F src/templates/users/mailing/details.tpl fa6f584102239e203474f16537e40c741454387e85c003963dd9b105af588b3c
F src/templates/users/mailing/index.tpl 7992bafc9ff2ef216d386139dc88b5d9ad869d56f2f72d6fb1b2d5969f7373f1
F src/templates/users/mailing/new.tpl 8dc2925045c064e48694d79e455048bbc6f7764aa7c3eb9df71c098c61514a8f
F src/templates/users/mailing/optout.tpl efbb38fa59ebae7425aea2ccb2b0413fbb1b52006cc00e8cea39f29037da0d4c
F src/templates/users/mailing/recipient_data.tpl d5ad4ec244404a0c1371d98a774094939fe7326cea8c4c655543b25fd2d43fa5
F src/templates/users/mailing/recipients.tpl 03df04746b6bdfe093e3ec8c89863356c21e2f1cb476c905fa2175a27b3319f0
F src/templates/users/mailing/rejected.tpl 11f5f93f7147be28a02075406f3526f9fe74252159e982daee5394aacdd94167
F src/templates/users/mailing/verify.tpl 3380d3fc0bc4b18c8158eb6c7ed41ad2d2e65dffa3b0ecd068f8e571a0cd09bf
F src/templates/users/mailing/write.tpl a5ee5946c0ad554aae8c68da54a26372b5f34f3b99c52f95fada058036f365b2
F src/templates/users/message.tpl 68d6edcd71bda70cb1025f88c83bed7def3b9afbb280274329075d7d6d3d4265
F src/templates/users/new.tpl dfa68c990d769719a079218337375b16d23809e3dd708fe4d6891c380ea7802f
F src/templates/users/search.tpl 865c43f3408d50382a733dc0189a1d5bbc7236519af66c8bf4a701c1b6ef85b0
F src/templates/users/selector.tpl bb00612e9169adc9e57d81e746ed0fd3accffc3c278f05fa3e80ba2fbc18f249
F src/templates/web/_attach.tpl 14872d8a8bd7a44a5b7975b53443a9fc34c8a4547cec4db75bd6309e8172218b
F src/templates/web/_history.tpl 8e1b0437e7f81bde064cd017c739b98a7ac9ad54964034b0c27dcf2f56f833d0
F src/templates/web/_list.tpl 471d580070e04c9c978441f7519706cc2548736e94fa7d0c916b560eb003f714
F src/templates/web/_page.tpl 4156c42d29bfd2a0242641cccab8998a1b6e58042e9019317c43866c107a2602
F src/templates/web/_selector.tpl 7ed2030acc7adb26b6b45c756f8eafa36db8cebcefbc6c963bd233ae423bb1e8
F src/templates/web/all.tpl aa5ef2cd454b8d636f9ee398511951efbe1c91a375bd1384df02cbb6b3abc48b
F src/templates/web/delete.tpl 7d5e7c30bf8b42d65bf566127b1fab38d0b4c664c48dd87693ea8e9d6c855f7d
F src/templates/web/edit.tpl c8ff1d7a39618f813852c3e162fbd68b92463d4a340abaa6079d10505bc1c4d2
F src/templates/web/index.tpl cda4822b30d24ea1af866c6381d2382d57227fce9a3efb1c55e8f9851d6aa997
F src/templates/web/new.tpl fecf4f84d90d66dfa82029a59dc0dfad2e461df3f212fe0d30974fa4466b2435
F src/templates/web/search.tpl 12d480905d1b460436854b7b3270bc57ecee5b9ba8ba2e3024432f804df0fd29
F src/www/_route.php fbc1235739cf597dd07e10b6f685df089de5a43eff5c0d82d96f441934ecc906
F src/www/admin/_inc.php ade6ec023564a91f2107826e7276a003d61e71fba7e154ad2d412dffe30a85e2
F src/www/admin/_serviceworker.js 94c15e9c0d42c4acfa82da0e784beefea888c992422855f76fad69fb6f7e56bc
F src/www/admin/acc/_inc.php cae640f5568028c3941a885ba88b9628b88dce1dd92ceb420b559de12c2213cc
F src/www/admin/acc/accounts/all.php 259df489f0ce8dc2d43535b29a3d41e56d13deff3daf53dda037cdcb23950ee6
F src/www/admin/acc/accounts/deposit.php 1551d00b01dccf41008bb41752dca083f13d572fc407596e378f2c5f295a5067
F src/www/admin/acc/accounts/index.php 8e62e8fe2f71623c366d26527a6933d03687b1bed2045d957fde57edf712e31c
F src/www/admin/acc/accounts/journal.php ec60c74084c422529d5af722160d65d5d1b48899272b6db8844cfcb314795e2e
F src/www/admin/acc/accounts/reconcile.php e40db86c79a2184ee63aabcc46429d74bba6f463f9093c550f9cabb0ea7c4f30
F src/www/admin/acc/accounts/reconcile_assist.php 479427fb8b43d89bbf55483037d87f8fdb522707e3e4c4258d985f2cb8634f68
F src/www/admin/acc/accounts/simple.php 5d4d5e06061543007033e29a3b9c339cb22438c6ab73560f63cadb841c449808
F src/www/admin/acc/accounts/users.php 40514630058b097e887dec8bb4896828cfdc913d9466f6d111cc71310863f7ef
F src/www/admin/acc/charts/accounts/_inc.php 7d4861d729a9ab7a646b81e48cacee16697b805a4a191f9ccf09ccffceb8d166
F src/www/admin/acc/charts/accounts/all.php 6cc19c0d16d21fbf77a0ab3498f1f19ebe26017b9a19017963115a2fe693b343
F src/www/admin/acc/charts/accounts/delete.php a15cf614a6b912fb31ad7ac69e89638111b0f77c79e9bbcf0bc67a05051bc90a
F src/www/admin/acc/charts/accounts/edit.php d996161f87fc99d8cc3ff9b89e6b816f72ac3d6a98b780422d4968cec4c8e8f2
F src/www/admin/acc/charts/accounts/index.php 8d5b8bdfd1583f01e6fafdafbf9845b64a8d338255cdea3a7d2330bd5f76b901
F src/www/admin/acc/charts/accounts/new.php 33f507b0f6d6453e5d7d774d06630a6598b3630293a9d2301f705f78d1b0fbd0
F src/www/admin/acc/charts/accounts/selector.php 1b98a5ac982e09aafc948ef0c56e63cc3a2c82f1c5986f089be304c79af692aa
F src/www/admin/acc/charts/delete.php 952a8b2bdcb95eaa49753cc04ae6e4bdf16fa86a34a59e4fd9f0b407504a4dde
F src/www/admin/acc/charts/edit.php cc4c1ce9c62425bc968b13eabe202d4ec6e13ebff47e8834e277f957598eaf2b
F src/www/admin/acc/charts/export.php ebcd95b86ed73f2d4000b7501c56b78ee461be9c7dac1cee651d5b739e77268c
F src/www/admin/acc/charts/index.php c7d0deab0d719c658831e3924203e730783a12cbfcf607aa3a017a64a4ab809d
F src/www/admin/acc/index.php 5cdc30cfce11aafc37e8f442e4e2e8ec0d1301712780037ef9f04191701f5c0f
F src/www/admin/acc/projects/config.php 4fe87b3d295c986b65a46664d0394fa234d89390109c9a7beecff3c515be1ba1
F src/www/admin/acc/projects/delete.php 7b5c59346a98c8c3d3f19d915e6d0921628b43c44d60e2a8971a8c4d101860a3
F src/www/admin/acc/projects/edit.php 6c31beb81d04cc73658103b84812cf1e07d8f3376cc50ea4c9a5f248277f5fa8
F src/www/admin/acc/projects/index.php 1273ca37f5f9a6c28131e0d9d9451d7ca83f3fe47d71c32921ca9805aaac1df1
F src/www/admin/acc/reports/_inc.php d0cf8a6629a3c1d2d92d5ad20366bed2190ff5f34ffd369dae62321c10cac578
F src/www/admin/acc/reports/balance_sheet.php 77da1df82dc55f4bdad7ec317fb34e077455473b4b1558c0c432d8f9b7424b2a
F src/www/admin/acc/reports/graph_pie.php 754cacd3890ee75e14c511bef556ad4e2903605c16d5e988416448da6fd0caa6
F src/www/admin/acc/reports/graph_plot.php fa120f9c68b525c42cdd5ffbe8af37b77f94b22e8f19a304eba20c156b8aefb8
F src/www/admin/acc/reports/graph_plot_all.php df40ccf7889494d01e2d5ed8a35bc1fac196f8a8176f9fdb17d76494ab86931f
F src/www/admin/acc/reports/graphs.php a0d771f15c29963fb4800625de9972da4767e520136295123d39aa5edd67f124
F src/www/admin/acc/reports/journal.php a71fc0c396b22a9dd154f342943e54590f07f492a1ea5b8520d025367b9adee9
F src/www/admin/acc/reports/ledger.php 110c942871607429aeebb96b06ff3578534718e1768536ff35ca4372d3426bb9
F src/www/admin/acc/reports/statement.php e8f2524f96a8d1496c07548e72c786d750e344cd85398a16332d4e3f9a0eb80c
F src/www/admin/acc/reports/trial_balance.php 21ba816df3c45af15a02e04e7c12e521e9ff92f819bf4e2f029c825b8b095813
F src/www/admin/acc/saved_searches.php 073ce71141c97ad3df1df0432bc9ce504913d2dad2d02f91595cf7c6a88f769d
F src/www/admin/acc/search.php 1536892f1316ed05faf741906e80852f921c5b94ea6839ec78d1ca2fe89b219a
F src/www/admin/acc/transactions/actions.php fc2048c55d23863161b2e718c9194ce7e37f1e424ee81d5aa69a346e68acfbbd
F src/www/admin/acc/transactions/creator.php e909867efed5e03a1372607c2d57d815c9ac461d3bb1aaf22526bdb6de496b6c
F src/www/admin/acc/transactions/delete.php 302c38dc9e46ea4c688605f8252e2bbbeb014d44450f1e07d5dcc174ed2a2efc
F src/www/admin/acc/transactions/details.php 1a82cb539aba1cefae849e91333f263f78b4f7ccb2bd4e1c9c313fe5467f6b17
F src/www/admin/acc/transactions/edit.php 8c9a45805a0afd6b975068f1dd1051c08827fef6cc9bd23bde8d56f78e8136bb
F src/www/admin/acc/transactions/lock.php 20bd2034e7d7f94f657853f4ebcb2352d9a96c38bdb7cf87c206c63a343f1e25
F src/www/admin/acc/transactions/new.php 66324e1269604038bfb8276006d83dfba168311dab4b5b939fa3a4749f2b3b4d
F src/www/admin/acc/transactions/pending.php 6f7db72b7ec7aad39dfbdea2e1417f56ed90598a9418da75d62ab0f0c7d8f8f3
F src/www/admin/acc/transactions/selector.php c32b47d2fdfde59e3f0dfe2f9d84ae35dc7c468bd87ce7c83a764638890dbc03
F src/www/admin/acc/transactions/service_user.php c55459a2ecc5768548a7baa68f44d2af137dc8243f8eac0bbacd0adb459c595f
F src/www/admin/acc/transactions/user.php b8ff73c47d6fdad975badc0585fd399fe1d628744c20b62a79e788aaff59c068
F src/www/admin/acc/years/balance.php e69827e7493236088c1a9f7bcdc8c2511fbff75e3f0cb48b62b9904d25a0a0fe
F src/www/admin/acc/years/close.php 19f4c7b62ec6bd98cba9ddd446ad5243572dc674c974da98ebfd2110c10c286c
F src/www/admin/acc/years/delete.php a0b5106cf351ba4917c8379830714254cc2bf37c1ead208b6495c6fab11b20fd
F src/www/admin/acc/years/edit.php 12a6439d201ac147eaa8fd39855d53a81300f18a7f73bff025489b7055205651
F src/www/admin/acc/years/export.php 188de31dff824e5682fdd3fc9e50f2ad28fa513224f185efa99896ffcda4945b
F src/www/admin/acc/years/first_setup.php 7a2a8e3723fb979b191f3d4750dda2cbd1267b566d14341bcb63dc0ef7d4c9c0
F src/www/admin/acc/years/import.php 5e69b590e1a6367821093cff4f247d11cc548af20adf9a66ef4040abd2392213
F src/www/admin/acc/years/index.php d91200350501d0b9c3f908e83b52bfc2460929027154a635abeeae74b31a7ce9
F src/www/admin/acc/years/new.php 2bce3c1c2bf136e22c790ce4261b511dbcb87ee25b96c7f7376cb6874de7bd37
F src/www/admin/acc/years/select.php 4ad57b28fed100d7d6fa0fbc975a70c86ad3b0050f68b07989d8c5ab99cecc32
F src/www/admin/common/files/_preview.php e1c2013500cd5e64b8879c7d74aa6560fedac0f78f76ad3693a85c5c52fe197d
F src/www/admin/common/files/delete.php f1535255a7103a67862ffb5d813a7c28329c33e10de95dd3ce47072346ce2732
F src/www/admin/common/files/edit.php 82ff52989824382fdeec8d2a760f59e7446d39254963075d743a3a2f76787227
F src/www/admin/common/files/history.php a3da49e4e2fc55073facaa02d282c7dedcc4fd7ea888fbcac5a7499339774443
F src/www/admin/common/files/preview.php 57467471f7339070f6cc4e593f882d385275160e55e6b2c51ee2461f5bcbeeff
F src/www/admin/common/files/rename.php 9a722ed83d3c52f3bc4d418ed7e36fe9cf3ec9cb23dec06fde950efc2d80733c
F src/www/admin/common/files/share.php cc2b2fe5cd433c909f1f62e1a9b77d9f8edbb861a244aa2a9d58ff47c9d30f54
F src/www/admin/common/files/upload.php 3ac3d647062bf54b277a5a6511116c933534eb197f84c0679fa246d0dc155061
F src/www/admin/common/saved_searches.php f6a7dfbe4fb521a0dbfcaec8f2c063656173c7ec44b0e8478eec8198d6f7801c
F src/www/admin/common/search.php 874b0d6ba447e2165521f3eeb66b65d5f9d08050e952a26d5c8f1344e90fb253
F src/www/admin/config/_inc.php 38dbaa8eceba69256ce410069345adbfb22d8fe7682f9df4decdacc6468f5186
F src/www/admin/config/advanced/api.php 0867da54514a62f8f2d20520cce6ad570fc0d1b8d493e4af61310c29fa8dc7cb
F src/www/admin/config/advanced/audit.php 03c22ee4a5984848ce4aec9056a0d2e69c4e869398622136556c0f5ecefaffc1
F src/www/admin/config/advanced/errors.php 11eac7346acc44f433896d8c298e4e4984513b3dd1d35a09868e98ad7361ffd7
F src/www/admin/config/advanced/index.php 62c60bb5dda9d2cafee5f506ed81fb6cf91ca9ab25f0b0e614034b59fd8f723f
F src/www/admin/config/advanced/reopen.php ee337b79851396fdae8ca2ffe341b26ff15e980daee08b2faba1459e9599ce24
F src/www/admin/config/advanced/reset.php 0393a990855aa3af0398e29c30872e6b19d7ff155c8e0267cd99fcea3b6ccafb
F src/www/admin/config/advanced/sql.php 39e06fc2830f26a8a9414885140d13b866df48b5803df9cd51b3fafb42e66dea
F src/www/admin/config/advanced/sql_debug.php 57db4c8a1e2372b8c2fc3b99fb9987f5fd1f4c9619bda792cb42422cc211fc17
F src/www/admin/config/backup/auto.php 41acbdd9ca793c1328e384adc431b2a6cd861230c79b667be3b3564b3f4eaafa
F src/www/admin/config/backup/documents.php e6be7da76e1f751c6ef46b47d5c9fc189e1079166838a76953498d8885b27e0f
F src/www/admin/config/backup/index.php 62bf45aec0e6e343b5200cb48c38f4961abe964558801d88e910d2296aac95d9
F src/www/admin/config/backup/restore.php 5b2b274e78a1a2c6292b8bd39dd28232a0e752bd4972b516afa7f8e3fa3cec37
F src/www/admin/config/backup/versions.php 5ff829ca122c68a95617e7e311370d419a36b491648a57502481fd3c5c19e2ac
F src/www/admin/config/categories/delete.php 916faad60b44a231ce8d030efbc7ef59c85a906bd527c06093ed11039f09d0a1
F src/www/admin/config/categories/edit.php ee348e18d4d44bec1c85015b2da557cf9136ea2d26a4b570a4173b64977af2f4
F src/www/admin/config/categories/index.php 448c26ecf521369c846c739883bf63f6fbbc693cd91853f257313ab2cce7cc08
F src/www/admin/config/custom.php 11ac0ff0852393501dcd33b6fb49c1538b0cc6f4b8b68ee31da2877d720da618
F src/www/admin/config/disk_usage.php a2b18d7edebe5fac6b733b629b2b1a3fac20b32351f1b40d3c4e1b37d7f0eb8d
F src/www/admin/config/donnees/import.php 63fd2e55bf602e3d5fe16d6e70777b313af7f87c465aafdfe2a435dbbc88d443
F src/www/admin/config/edit_file.php 692b6bbf107750afefe073622930a2e141d593554ea782a95561b172cc9fd025
F src/www/admin/config/ext/delete.php 2da7be8aa33eefbfe67d49e0b48b1364f8c69ac0a96fbb1dbe5ffbe1986af7cd
F src/www/admin/config/ext/details.php 566bc1c5fa2e61eda4fb87efcf1dfbd25290a6746f50302b856789c69496244a
F src/www/admin/config/ext/diff.php 234a1118d048e5c1f3f91917db8f462b2e4bb28548dc0641940fc66b4adabbd7
F src/www/admin/config/ext/edit.php b5243bc9140fe85b972b9d133b98563ade7dfea9f616321dcad6f186ab99848e
F src/www/admin/config/ext/import.php 964ad852bebff092c8692925ef1d53dadea1c709fe97668376dd370074795b14
F src/www/admin/config/ext/index.php bb4dbd0fa845c5e02d67679804aff26fccfbc5433837a852fb174f0446cc637c
F src/www/admin/config/ext/new.php 0961b290769a6173873ee4774a8d5c7d5ccf55dd280c11e117a4f4e6ad74b9fb
F src/www/admin/config/fields/delete.php 263592cb30b7504f7a0b427cee61bcf5081f29fd8a49fc06065a5d2012b94044
F src/www/admin/config/fields/edit.php f93c22353dde208d4d2847a7212ac019d1a0f79c6ab929f6aa77b902079b2d4b
F src/www/admin/config/fields/index.php 99f1f4d7bb810ab71630a63bd2fe256a23ca24e8d3805b3f0396e5af9957066a
F src/www/admin/config/fields/new.php bca14e9b81f76a107bde1b529133a5a73b81f3eaa5b6af877a2ac6258d7473c1
F src/www/admin/config/index.php 4db930d9b14080adfef2ce9e4ec8957a9440820dabe00c56a212180dd2ade8a8
F src/www/admin/config/server/index.php 7f7388c4fe053ba5d6df01b7f618d756174c80cd007ddc8364f3219f8bc7a66b
F src/www/admin/config/upgrade.php c5bb2b07cf8b4a1ec6ac86b863e69f887f5a1f39f1e16511fc960c6a60baf40a
F src/www/admin/config/users/field_selector.php f4671d4b51d890b704dcc3922fe0306068931d338a9938cc696bad1d358f0376
F src/www/admin/config/users/index.php 2f0fb565c5c00361c3764b238648f75292741a774f1727c747f50cc1e6c36358
F src/www/admin/docs/_inc.php ac1a2736b738ea049b291d091d4990de822a3dad9da8738c72ec37fc33721a9d
F src/www/admin/docs/action.php defab0b85f30183c24d18b0bf257f9265223ab0fef09de8dab16c26bb4a5307b
F src/www/admin/docs/index.php 4b81f3ee6581fe9c332372443e971e05541ce8575edd986b75131258079023c0
F src/www/admin/docs/new_dir.php d9a2d4e8ea9da76cde050fcdf7f753a897d5615684b8e5eb279acbacb794600c
F src/www/admin/docs/new_doc.php 82bd169bdaf9da94cd93835dbf22f242f4578ef360b2ad373920877760c82484
F src/www/admin/docs/new_file.php 46f2bffa0060f6adf4fea3c8234bd989749ed61c5c0189a10b8edb985930072c
F src/www/admin/docs/search.php 60c138d0ec74854f837509f53a7cf89051107b80005b4eb936a89c83dc5c7fb0
F src/www/admin/docs/trash.php d65494e835637c234604220b64b2dc42fceb2750d2cd9edfc4e993516719bb5c
F src/www/admin/handle_bounce.php ac546e03a21ec3687a12482fed3753a8e4632fab632297807c72afa9ef5394d6
F src/www/admin/index.php 6888125b475826e000e8c5a9dbe2e63c1a13bfc572c2bf3da862ac94ab00cd37
F src/www/admin/install.php ec203de9f710ce484103d5b623a0c1633c42cf296590049724d81064d9638444
F src/www/admin/legal.php 0a9422c75dcd77fa25491251bcd50133701cedea52b375ef4bb04dad99400a57
F src/www/admin/login.php 54c2d517c3c4593d25ce4d214bcfad2e30f642d7b83ed41659dbbd975041861c
F src/www/admin/login_app.php d686b28a90aed936f5cdcf7ff636b56a870c072cfa1b1b971bcf9dccc6411176
F src/www/admin/login_otp.php ac1615acf75604122a55095eaebd3fefa798258b3aa922ea05b462a112568f26
F src/www/admin/logout.php 5976597893d20d84a0b61f11aeb59ef4132db8a3ee4abf5ee02f67da2f95f1a9
F src/www/admin/manifest.php bfc8e82584902075944a114a09c28e22228633cab6d1d397cb9d527b7e6868a6
F src/www/admin/me/_inc.php 640b9e5ede51b34b04e9ae12dd8ce86a5880c0d419667613afbf9616eb29a66b
F src/www/admin/me/edit.php 3fea9f4c5895e7c9fc87821eeed975600f87dae95801c4c31523e4ae6cce5edc
F src/www/admin/me/export.php 64f543bd103a8fd984c6038d56e3f2df7f7f8a49a249551296f7dc91ef2d9da0
F src/www/admin/me/index.php 8a7bc848f78d5c99c98316d33cd3037d02aefb29a777df6164740d1eef48b952
F src/www/admin/me/preferences.php 8ae1dd650e1f59fb3b1ecfe633ee7152a47e220ad45019220cee58e7464dc074
F src/www/admin/me/security.php ed288514fbc34bddf0f0c519c296915d8f24a00d235734a603d72996588d9750
F src/www/admin/me/services.php 01519cc713f0657c8f261dbb184975de3ed48a57fce0ebfb3ec0f4b6ad06b7b7
F src/www/admin/optout.php a8e32e6d40ce7352c42607250ce195bdf0ecce812ff851df511efbd770839262
F src/www/admin/password.php ba2d7caf0bfa0c87955adc16d18f91d43f5582dccd5b6666e0ac8cdfdc0df695
F src/www/admin/services/_inc.php 2ee23bab80c9f3a0e11e0952eb9d4b7e08e6232ff3a8460f2b4f3e994a92a084
F src/www/admin/services/delete.php 9505dfb7053aa03d3a4c923f2d6aa08626a9b40bfda37669846f42a43217b9cc
F src/www/admin/services/details.php e1c3c955c42f1cd8541bba05ace6d18d2d06c982c336c134eddcb9c36161d150
F src/www/admin/services/edit.php 6480b8b88194204854bf074dbd00e90db82aab47a1dd19012cf567b06453ce42
F src/www/admin/services/fees/delete.php fb4d08069c863250ad7507a076f1c73ab8456fb42088d789cd45fd65e278c5c2
F src/www/admin/services/fees/details.php 1a695a0e563656c0aad0de57e4deaa9fed8c0ff78022cffcd85478eb944e756b
F src/www/admin/services/fees/edit.php 29f6e346ecd4120640f1bee44ed5e0bb6965cc0d328f5bf0c278fd4114228adf
F src/www/admin/services/fees/index.php 66ec678b3e5abe953b0a10b3a07a58579f254c295d96fb13be41b6392e1627f9
F src/www/admin/services/import.php 8b45124880cab3293a0358558e3fd69b337806d53616889a2a76629979591dc2
F src/www/admin/services/index.php 1c9db068ebf1bc219861aea1be9e6b3248bff9a3846ce885338af0fbd3d10757
F src/www/admin/services/reminders/delete.php 7fa839c1bc9119a3d1f76f536f2305bb2bae21ad7d76fe2a7c18b933d6be12ac
F src/www/admin/services/reminders/details.php 7fd507e005d1a5f1cfa790059ee5075c89af3e03ac4ea20828e4dd92493cc285
F src/www/admin/services/reminders/edit.php 1cec0cd9241342c30894289539220e73ace46cdd5e29f474449f52cae0fba338
F src/www/admin/services/reminders/index.php cc83df448673e653b80c81b56830848d9dba6dad747184b8a7ab078f4d46f92d
F src/www/admin/services/reminders/new.php 34e936f9f4e9f53cb9bf1aef8f418bf27804a926aff90a2375840a4ca116b94d
F src/www/admin/services/reminders/preview.php b614113fe991e2df7b24761e7f3cc91bad48bdf6133eabc4ccf954e57c0278dc
F src/www/admin/services/reminders/user.php 491234f0df7bf9ffebf8365fea031fa00750f6ce2c1935f2bc44d30783a8e224
F src/www/admin/services/user/_form.php 6c01868431afe4dd2cdcf392657ad64ae1790c80ceb3fbdba3a22f4e7cd5b848
F src/www/admin/services/user/add.php f211c6b3cd75cd0b82fb587937b7f1bbdbd98c057d38cd6e3c57e1b62fc1948f
F src/www/admin/services/user/delete.php 258ad809c74de1c88ef22ff8c673276f73ada517513967b6603fe9826fa88360
F src/www/admin/services/user/edit.php ac51e77e6c5f5bd531742d1b11caf3396270cfb4b65e7087195f5e17d5c43a8f
F src/www/admin/services/user/index.php f8e9112ec82b953c448f64f09ce2aa35a09d592cc10ff0e10d659e591a9003f9
F src/www/admin/services/user/link.php fadf825ef461c07fc967a4d93dcd95fbdfcdc28132a89cbe527debafd44b8831
F src/www/admin/services/user/payment.php ffae6c1087e650bad783d3500a117b8087eadce740b3bd86f193ed9d8e15a79b
F src/www/admin/services/user/subscribe.php f757166bd54bc23ad61f172357669333569fb6acee4f427700fbd8c3dc0b8428
F src/www/admin/static/admin.css 8d4155645ad7b6efdad7439b160751f3a52fbf2c992d7ae9d0c91b741104dafb
F src/www/admin/static/bg.png bb11a55a0d2630f7f225e01109c2fc8dddf1e9e6c989ef1d17d18852703f8438
F src/www/admin/static/bg_dev.png 890be2cba33ae3a2e874ceb33167005cab3474a1e61810baad37ad2b46920dd1
F src/www/admin/static/doc/api.html c49e5d658057d25634c7ecf725615b7670fa9882e108be1298177f354d5d1378
F src/www/admin/static/doc/brindille.html 175273e804f9e2505e0a78a4f3550c51d8442924c43ab39bee66c8c1330914db
F src/www/admin/static/doc/brindille_functions.html 0ab56fd11e704f4a023f5651defcd786f5d29bddfa50049e7c0a3d3fd398d2d2
F src/www/admin/static/doc/brindille_modifiers.html e69ee882906f75890cd1474892259f4e011b0b00356b9de2bda40350992b94ec
F src/www/admin/static/doc/brindille_sections.html 0d86861bfa5a41855a4620713effda34b830e86a85f1ae1bc4b22070885be07c
F src/www/admin/static/doc/keyboard.html 55dd27ea5d6efc22202a7ed7b72544c1ec8a4b3a36f4f684f6d096f53ef62821
F src/www/admin/static/doc/markdown.html dd127085d32ec6a1d20fdae1fa83c61ed7f38e02b331a6bb0850d3877bd63993
F src/www/admin/static/doc/markdown_quickref.html a03b76328e070ee482bdc0e512fbe13c40eeafcbfecd20b98b2f8bcd59121e56
F src/www/admin/static/doc/modules.html c143ed67d2bd4e5b741fdef76db80b9bf5af21d52d33e90487d3f0cca8ee0d45
F src/www/admin/static/doc/shapes.png cb46b164ccc62541b94dfa202494a947b7147f083701bfe244db5c3243178d9e
F src/www/admin/static/doc/skriv.html 1fdf3f7ccd0f1b3a2bf2eebed2c2d9f699b9d246bd320ccf1d56b2402e1273c4
F src/www/admin/static/doc/web.html fe4a7a605925630db3cb5be5b13278261a5807bd683d98943a6f9a24d3209513
F src/www/admin/static/favicon.png 18c14f40c3ed6d4d73ceb5319c55b05cff7b0677b52ad79ba28d69ef63036aee
F src/www/admin/static/font/config.json 5f5d1fe7aaec836ed53d819e312987df71d5ac596edae6662a4ed81b8c8ccd6c
F src/www/admin/static/font/paheko.css 73f799c34ebf03ef74668241b776c8f564409f0fc0b1f71147600dadcf00b0b5
F src/www/admin/static/font/paheko.eot 10c942b5f295de52b6f26dc4f595ab669c206af85083b447ac19cd20116d4050
F src/www/admin/static/font/paheko.svg aa7009cbc76c9ade6bb34f179e97004c542d121afdd3e8fb924a3cb7726b1a78
F src/www/admin/static/font/paheko.ttf 620692b9a4ec07f335a71aeded66b2c82ddfe5205c5087d0bb93d844df349ffc
F src/www/admin/static/font/paheko.woff 13bf306d815f923ee487f6db4af254b2589f9fcf0cd42f81f066600a69307f09
F src/www/admin/static/font/paheko.woff2 60c9a88a0493737e514eb824ac01c6f289adba789986cce918abac3a2694bf84
F src/www/admin/static/handheld.css 04e6d592984da5113d3cd6390d681c00dcdcde82aff859a7a89582b4fd2eb99c
F src/www/admin/static/icon.png 1387768a8bcff7465be6bb1b4afa8d6d9c22126655288c1edfbb614d86e575f5
F src/www/admin/static/pics/img_center.png c93c143b47b8d5a7e2caf3acce64251c4716b9a5
F src/www/admin/static/pics/img_flow.png d247e7abf93a2c37d2ba402be08ec432bb0d7bc1
F src/www/admin/static/pics/img_left.png e43aa44c9fe1b5508a2af6c1ec124654999b6c6b
F src/www/admin/static/pics/img_right.png e2021d96729d6f28fcc946b5ed6742f6732a967e
F src/www/admin/static/print.css 5b83453f12d3aea1f8d5f9106a85a9621bd2bf347003e21ba5269706e9476bbe
F src/www/admin/static/scripts/accounting.js 7062c9800f0535a3cebec4f44f778d512c4e1806d160e51c1ba3f087bb4318ca
F src/www/admin/static/scripts/accounting_setup.js 11af0b9e261c75dd30f0e17e532e3b3bf5a907873b09bd8fbbf7e6c8cea140a3
F src/www/admin/static/scripts/accounts_list.js c39abd92100678388e0bebb16a0a2c5b041c44e07aaa032bb3693c837184404d
F src/www/admin/static/scripts/advanced_search.js 38b7503d3ad679f89196e723516ba95d6c8ee67548ca56fe4408462afab89c10
F src/www/admin/static/scripts/auto_logout.js 9e0c4517de170d9d24c29eaf8f73b21a783fe77ecb2f769eae6edf7ad3c12aaa
F src/www/admin/static/scripts/code_editor.css f56ab02df74b8e494feccad9d611547dab875223272ccd4bb50ea1ab16557fe1
F src/www/admin/static/scripts/code_editor.js 7f7383a25f337f58bc75fffc25c6303ef9862089fe6fe29d36ed20c8a992aaa3
F src/www/admin/static/scripts/color_helper.js 5c89caa19b524d7f54eb9361968b043a641c2772c76e3472714f955ddc87373a
F src/www/admin/static/scripts/config_fields.js 4eb6a786648c1d35b9a9c61b2973fccf0fb79460cf8feaa9e91e3762ff0c57a1
F src/www/admin/static/scripts/dragdrop-table.js 9fa37ece4c56e3c3025a0cdc87993dba2beee4dedf12d853c85e899df9cf9d51
F src/www/admin/static/scripts/file_drag.js 4bb2ca2e887ba23d1ec02ef95d7dee7a8eaa50b2f71bfcdfb0f4e71d425a1a16
F src/www/admin/static/scripts/file_input.js 34388e3acf6a87b384f392c207509542cad1d8de641f9e636596ca001733efcc
F src/www/admin/static/scripts/global.js c5de6536d3cc1ba2e542ee15a6b36062d2a8d9da336c6c8c81be0dee35ee2ba2
F src/www/admin/static/scripts/homescreen.js 80dc4e87743bf7061484eb96cb9c546c27fe4b756935eca7851fd5aa53ab1e70
F src/www/admin/static/scripts/lib/code_editor.min.js b93b17e625c99e610d6fd3d8dd17d95421f6c6ff74211448a52c2feed464e21a
F src/www/admin/static/scripts/lib/datepicker2.min.js a4c81fc228bbb79c906350181d215a1ab36d44d97f632582b5314a0ba3529163
F src/www/admin/static/scripts/lib/gibberish-aes.min.js 8c82e940cf5cf6fb68433bdc6c3a62c71583a60d
F src/www/admin/static/scripts/lib/query_builder.js 2535abc10734bbdb7afeee16243047b67c067207f519821b6228fbbd66f9c057
F src/www/admin/static/scripts/lib/text_editor.min.js efdbdc1b49c459f111e32708e17aa201749308f683a661c75fe33c6eb9b17033
F src/www/admin/static/scripts/lib/unzipit.min.js 8729f4e48a77faee72b09d2503934f705fb5befab597262230c7c26836f52162
F src/www/admin/static/scripts/lib/webdav.css e95322578b2e34bde605ec29148d22faa17c7c01c2216f42f17298a1a77788d7
F src/www/admin/static/scripts/lib/webdav.fr.js 5101d45a9c20993e773d59bd185c3b93503fb4d2c4256f1f2c0bab6bc7bc9653
F src/www/admin/static/scripts/lib/webdav.js 986d04833f6c2fbefb127ca4d6ea663f6977c71233bb996b7445cf9f48236c14
F src/www/admin/static/scripts/password.js 6b890f3fa7aaef7c69b83a52cd6fc271984159983b52bc35bd0ead7dcad604e1
F src/www/admin/static/scripts/selector.js 62447412c8b62259e1b26e3555204373bc6d17de17a694f25333c13e56c69d0a
F src/www/admin/static/scripts/service_form.js 272a6811a71259018ee6713057e96dbcdd1cafb01d332950b8b4438ebb6b5a21
F src/www/admin/static/scripts/unzip_restore.js 67bdb4b62bc91deb97f2ec9334a9647908d5d7a03b00eda0614c5940ad6131c9
F src/www/admin/static/scripts/web_editor.css d40ba89e0042da03716a45e738870a87810bdd68719a99a442be455ee600af13
F src/www/admin/static/scripts/web_editor.js 2a468ebe296331790911d59c5640d9844620a0a14cb67dc823d90b7f26c95fd2
F src/www/admin/static/scripts/web_encryption.js 3ddbcf8aee1a21ecf5c76b969ba3a736442e40ec3f7407c23bb4ae8bdbf1b89d
F src/www/admin/static/scripts/web_files.js bb326d9c953442cefb014dafd4ce785fe9e866d618af3497796c558905f9cde8
F src/www/admin/static/scripts/web_gallery.js 945b4701755b4a3190cf4c436d2086a5e76bc3989f6ff028bd6dd1e03656320a
F src/www/admin/static/styles/00-reset.css f7194bdd794e5c85bf67854be876408609a39d66cb36591db021218fc843172e
F src/www/admin/static/styles/01-layout.css ceed4a07a76b4b1754397bc30e31f6d74694fd65126d99f5e27f5b821af98909
F src/www/admin/static/styles/02-common.css 796f6907d659d94c8d6b9e34fe403090721a41e63862d91b95960d4d66a04d55
F src/www/admin/static/styles/03-forms.css 98b68091275f1441772bb4bffa56d24ab57fe8903ae1e3757dd015545a3151c7
F src/www/admin/static/styles/04-dialogs.css b54d6fcc0dbc2889a866637974a6b20b723ea656951b5f81ade29f724e127cab
F src/www/admin/static/styles/05-navigation.css d163cfca22534f45eadf87a33b64cf00c3145b977d99018317153c8844ca13d9
F src/www/admin/static/styles/06-tables-export.css e8aa7570c2347baaa726574c1b9ba1f1d8af26afa05ffedddc086e120cf70f22
F src/www/admin/static/styles/07-tables.css 6e376f916abbf49fcb4dbaa4364f04fbe6eee2d86d81ad3072aeef52101b7373
F src/www/admin/static/styles/10-accounting.css 7ceb2aea3c8c62d597d5690a537d39ede6260a0e86f67c07113d9d3fffab90a0
F src/www/admin/static/styles/config.css c03629a39ab9a4c0c22aecba2bd3a5ff25531d6d23910a4f3d9998f13f17bb99
F src/www/admin/static/styles/web.css 2a54776ca23bdf24ad898ed225a13d6332c9aae1284ccacac71e3cd71850c44f
F src/www/admin/upgrade.php 513c93bccadb2aa60f0a1357e663d41eafcd2bf4e5c5d0cd73afb344700c1132
F src/www/admin/users/_inc.php abdbaa2f4ec0c59547ae197a8d648db4027dfd6c1b2de44090a85643dc73adb5
F src/www/admin/users/action.php ee26f54d10acca46fae2bfc23c478abaee4dd98bed45662dd1aa5b27ef18aa59
F src/www/admin/users/delete.php c708200474b17b8b7629d3b4ba663761e61e498b4725cdfb20fb4222825bc96d
F src/www/admin/users/details.php c1d42dd32cd69c9486d75eedca25a6cc5ec50b83b0763523ddc20a7ffddbc4d1
F src/www/admin/users/edit.php af964e43999c4d546360aa5055d595816c73b0dd02c24466a54f7fc647ac2d04
F src/www/admin/users/edit_security.php 675d9bee134106cba182829560ef928d1acdfb8ac5dbd94877246f916d519f60
F src/www/admin/users/import.php 09125f9e764153dac1ed5dbcf248f6fb03bbd01e9b4db3e6d4506ea49f101b08
F src/www/admin/users/index.php 08e654e48d389a4d19e59547f410ddf61a7f412824c581ea908529fe16b83f39
F src/www/admin/users/log.php 7ca90afa14599af6c6dc622392b405d22bf6d53b43c219f2f6d0a974028bb4f6
F src/www/admin/users/mailing/_inc.php 57578032cef46ba1018a6d63b2a9d5c521215e3f474b3b60943bb931abd1a1a3
F src/www/admin/users/mailing/block.php 0a3c768560a5f44f08cecebd15853abb6cb5e4e0569049d3fae5511a9d5715cd
F src/www/admin/users/mailing/delete.php 829abccebc1d9f907b56987c450710fbebef2ed38052109cc7882f1d9ec492ce
F src/www/admin/users/mailing/details.php 4d906518380e5b008eab1fddd91d711b47f14d86313a4a76c41df1bc251a0b22
F src/www/admin/users/mailing/index.php 1da23b3440d917cdb0757c036ab7a43e8a16864bc9147b769431db98335e788a
F src/www/admin/users/mailing/new.php 9438ffe5e76306bd9e09a06f962ce9b5483b58b54303beac91509793ba7735b9
F src/www/admin/users/mailing/optout.php f2e3a3544878b7e15e9d268e8a56627f726e1aa4317e37a7274070a6d2c0973f
F src/www/admin/users/mailing/recipient_data.php 7eb9cf0ebd67d3d7626e6dcee9faa3607de7fdf292c4437ff205642ed38dc24c
F src/www/admin/users/mailing/recipients.php 0eab354cfc17b56a7eb2dbdd126b957464eac120fcd0add5ca840f71c75af2bd
F src/www/admin/users/mailing/rejected.php 65ed7e261c552c9ce5e01abd171a8e973f55ea05f071463a69b0a3c5ba03b6b7
F src/www/admin/users/mailing/verify.php 0d8c00532429618bdb1ca518d761c874132e039027901a1555cb454e24331563
F src/www/admin/users/mailing/write.php 70659ff0aaffb58ea98585036a4c6f975ef71ae61abd0d2bdf94dc9b1a6f4246
F src/www/admin/users/message.php ef50b2da49b35e1865b21073cb28de7efb8c90dd7eb90cfba8754ccb65ab5ba7
F src/www/admin/users/new.php 85a684dbc6faa52ad3e2b34b4c75cbedb0cc2a9cf9360b8f97a7f8f3d53073aa
F src/www/admin/users/saved_searches.php cbae2bdad6c708a6a0af69e1c867c7728315e8bf34a1461c69d1e7d40bfdf71d
F src/www/admin/users/search.php 7d8a0ea291962cb262c1bf0aa75ac6fbc3de295b2f1a2c6bb6aaf4a3bbcaeba6
F src/www/admin/users/selector.php d06d23c96d9d0001bb665307f9836c1dfa29527108aa05e3366a13f238ba0405
F src/www/admin/web/_attach.php 5ce5c5a6ce3ea74583d084dbf70837cdfe11f6e98e5b2e4e13fcf4612ef93d9c
F src/www/admin/web/_inc.php 61b38f575aab20dbfea9a4e16a3583d4e8fb4dda74015253296e23e6230ade5b
F src/www/admin/web/_selector.php acf3fd557a77f05c39ad81736d16621b8d8a714ebf79ebef5da2b8d9c3ae36aa
F src/www/admin/web/all.php 6497e3ef800f01db03e0cf88c47415cdad8531bd38381182ebe19d061850eaa3
F src/www/admin/web/delete.php 6c70805189cbe52279a094db532b1ebfd75eec55ae4b24ae550687e2cb822042
F src/www/admin/web/edit.php 82ce1edb8719890cf118fc1b878b5047f74467a6a0c5a117c7ad8a51180b11b3
F src/www/admin/web/index.php 1bb6321afc904b6a23fb092482bcc701141177fb3709788cd34b10eacd7dab6b
F src/www/admin/web/new.php f938b8c559cd001605ea6911b2702dfddfa29e751079f9cc9fb1a0b95027c29d
F src/www/admin/web/search.php 98e07fd20629e0585ed4b4664bd9fc6b44e8dccb6d6cb28b8b52d707becd68a9
F src/www/index.php 7864c3a4fdac4b2976337429d1e8c00f45889f2e87ee3d6e6eabe264b9b2b24c
F tests/phpstan.config.php 584e38c18ba41beddd42f3950fea3507db5ca1c3a7acf8e1463877b202f74622
F tests/phpstan.neon a05dee1190e8b78ccf641bda959d0470082e65e6bce065fb275981bac8103e7b
F tests/psalm.xml cfd86f9bdcd8d968674aa49bd509b8591bd82fa73690c2e92ac1a07f74c3d12c
F tests/run.php 43c2b61a01dd66ef5dec76d3164a5313f113ad4f
F tests/unit_tests/01_basic/db.php 66b9155618cf937761664cbe5fa03e9dc830a68a
F tests/unit_tests/01_basic/paths.php 819d6c04bf6a904ddf21a211feb451f6faf1045a19fe91a99fd5937b76893fe0
F tests/unit_tests/01_basic/version.php 3d5d415dd958f5f7504c503fb8ae8aa4d37e8618c77b366618e5cf11ad2cbf6a
F tests/unit_tests/02_accounting/money.php b5a7b488bbeba2c166982967b2f613190828ab1a
F tools/categories_as_projects.sh 02cc9257edd231e54c643cbddb0cd119e09bf3d9 x
F tools/construire_plan_comptable.php 4618b08fe874943c7c9cd161b3a90fd85695453f
F tools/doc_md_to_html.php 72736f48da3c23135a273d1c848e71d52de4ebdc1d60d0e3a36e4b4574b19ce9
F tools/extract-credit-mutuel-csv.php 853d37e661a71c9160d27897930f57718d52839dd57a7c9c7a46f994044852fc
F tools/extract-paypal-csv.php bc690606745e3d6b14352a4e8c89d3a01e6dc11c4b7cad3ea8fdd1d49b96c190
F tools/factory/config.local.php c21a4081a63a046ba40cca869bc0a324e9c598e3bfd3e8b66fce25632772c7f1
F tools/factory/factory_cron.sh c03a756dec91466571735bea3bdab332e4d8a964bce75b8788d3c40aeacb208a x
F tools/factory/factory_cron_emails.sh 7427ba5d8c347a12be09f1017abc04e12a5726eae96c84bcae26dc9151bdaa26
F tools/factory/factory_upgrade.sh 21327b0cf6c61a5301588ad990664efd5e365a3e6bdb63073a8adb0b6876e2fe
F tools/fossil-verify.sh abbb39b79418d14364a689bd381686e217df35c9ba8dfbf4f7f18e9feebd95df x
F tools/make_installer.php 8b0d272bf113a74dc9cce91213bc875229858010a8f1a3830151755af3520d7d
F tools/plugin_check_0.8.php df13be68be836729f96a26ec5cb33133d5e6bbce
P c64b200ed0d55f953085918860f994bc493073f369a662b16b0237529a4f59da
R cd6c0ed44b4e707dd10ba8d5b899143a
T +sym-stable *
U bohwaz
Z 16eef90f5a5efddd361afd30c6f510a9
# Remove this line to create a well-formed Fossil manifest.
-----BEGIN PGP SIGNATURE-----
iQIzBAEBCgAdFiEExJkkebouil1CwYIBksnacbiI6jQFAmWZWWAACgkQksnacbiI
6jRrsBAAjj7Qakj2W6+2nL409awN9Hh+z442p85n6mwMMEIVo6mgV5XqhxKBTvlX
posVcQkgR7EuPqzh6C5SfL43CAzZtWIjPrNuD+YtocXC1CQxp6OVbN7AzJTP//xq
6O1HqI+Rld6Owk4aUmWze6p26fsYQ3we0bM35tZe6D7Kg2UINcpWqaKUH3OwObuO
pl5Emsh4XZSPtF4XQ7GtLuwznOOmtRwY9r0Q7mIwecOMDWz1XRuXhLnaz9a+wc+z
3OtLBj+DEiClrJcSV6jt58smkvppXFMAx6fP8CsnhUvB/kuKYcyN0vleLzepJIbY
8E98KqR5WaF8XqZPtR2TzgwBEUtFxOco3CPJy5fPoNLGYvh/3US3UG3ksp3FTaY2
BEH/wDqcx9/PLmWaJ9Ug8NSuo2STu3opG4xxNBCvuRxeOwdai6gJN0zTi5YS44nl
MBh5zN9zjJ2TT3JnxkEC9U0ryec9dc8VbM1cM+Ww7bEPFNvA5/mYHBTbN1HdM3Rw
g7Pbhqh/ERunRtz32NW8w10U9FtGHp8cjKOk7AX3gCdggmJRhDlLcmD2ZON/gmPu
z2t6nYFFtmANXFwr5stfLkEIEy4byBEwX7V/IfAanfC7lAioy++mfVlvyJLxKJG1
c7wPxLZf9Wkdh2F4t3UXMwWihtdDKzMfKxe7NtRNbvQC4LNzEPs=
=/3/y
-----END PGP SIGNATURE-----

1
manifest.uuid Normal file
View file

@ -0,0 +1 @@
e39bc64066ab87376ad4450bb15dc71ed8f142d78e16d61abcce7e8655a72283

View file

@ -0,0 +1,16 @@
Index: src/include/lib/Paheko/Services/Services_User.php
==================================================================
--- src/include/lib/Paheko/Services/Services_User.php
+++ src/include/lib/Paheko/Services/Services_User.php
@@ -142,11 +142,11 @@
$id_fee = null;
if (!empty($row->fee)) {
foreach ($fees as $fee) {
- if (strcasecmp($fee->label, $row->fee) === 0 && $fee->id === $id_service) {
+ if (strcasecmp($fee->label, $row->fee) === 0) {
$id_fee = $fee->id;
break;
}
}

34
src/.htaccess.www Normal file
View file

@ -0,0 +1,34 @@
# Désactiver le multiviews (conflit avec /admin/plugin.php) et les index (sécurité)
Options -MultiViews -Indexes
DirectoryIndex disabled
DirectoryIndex index.php index.html
# Au cas où
<IfModule mod_alias.c>
RedirectMatch 403 /include/
RedirectMatch 403 /templates/
RedirectMatch 403 ^/scripts/
RedirectMatch 403 /data/
RedirectMatch 403 /.*\.log
RedirectMatch 403 /(README|VERSION|COPYING|Makefile|cron\.php)
RedirectMatch 403 /config\.(.*)\.php
RedirectMatch 403 /sous-domaine\.html
RedirectMatch 403 _inc\.php
</IfModule>
# Redirection dynamique, pour les installations sans vhost dédié
# Objectif: supprimer le /www/ de l'URL
# Note: il est probable qu'il soit nécessaire d'adapter la configuration
# à votre hébergeur !
<IfModule mod_rewrite.c>
RewriteEngine on
## Remplacer dans les lignes suivantes
## /paheko/ par le nom du sous-répertoire où est installé Paheko
RewriteBase /paheko/
FallbackResource /paheko/www/_route.php
## Ne pas modifier les lignes suivantes, les décommenter simplement !
RewriteCond %{REQUEST_URI} !www/
RewriteRule ^(.*)$ www/$1 [QSA,L]
</IfModule>

1
src/.php-version Normal file
View file

@ -0,0 +1 @@
8.1.26

114
src/Makefile Normal file
View file

@ -0,0 +1,114 @@
.PHONY: dev-server release deps publish check-dependencies test minify phpstan www htaccess modules installer plugins
KD2_FILE := https://fossil.kd2.org/kd2fw/uv/KD2-7.4.zip
MODULES_FILE := https://fossil.kd2.org/paheko-modules/zip/trunk/modules.zip
PLUGINS_FILE := https://fossil.kd2.org/paheko-plugins/zip/trunk/plugins.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}
modules:
wget ${MODULES_FILE} -O modules.zip
unzip -u modules.zip
rm -f modules.zip
plugins:
wget ${PLUGINS_FILE} -O plugins.zip
unzip -u plugins.zip -d data
rm -f plugins.zip
dev-server:
php -S localhost:8082 -d upload_max_filesize=256M -d post_max_size=256M -t www www/_route.php
test:
find . -name '*.php' -not -path './data/*' -print0 | xargs -0 -n1 php -l > /dev/null
phpstan:
phpstan.phar analyze -c ../tests/phpstan.neon include www
psalm:
@# This is required by psalm, but useless
@-mkdir vendor
@-echo '{"require": {}}' > vendor/autoload.php
psalm.phar -c ../tests/psalm.xml
doc:
php ../tools/doc_md_to_html.php
htaccess:
# Removing DOCUMENT_ROOT is important for the cache when using .htaccess, keep it!
cat apache-vhost.conf \
| sed 's/#RewriteBase/RewriteBase/' \
| sed 's/RewriteCond %{DOCUMENT_ROOT}%{REQUEST_/RewriteCond %{REQUEST_/' \
> www/.htaccess
cat apache-htaccess.conf >> www/.htaccess
release: test minify doc
$(eval VERSION=$(shell cat VERSION))
rm -rf /tmp/paheko-build
mkdir -p /tmp/paheko-build
fossil zip ${VERSION} /tmp/paheko-build/src.zip --name paheko
unzip -d /tmp/paheko-build /tmp/paheko-build/src.zip
cd include/lib; \
rsync --files-from=dependencies.list -r ./ /tmp/paheko-build/paheko/src/include/lib/
mv www/admin/static/mini.css /tmp/paheko-build/paheko/src/www/admin/static/admin.css
# Generate .htaccess file
cd /tmp/paheko-build/paheko/src && make htaccess
cd /tmp/paheko-build/paheko/src/www/admin/static; \
rm -f font/*.css font/*.json
cd /tmp/paheko-build/paheko/src; \
rm -f Makefile include/lib/KD2/data/countries.en.json
# Download modules and only keep the stable ones
cd /tmp/paheko-build/paheko/src && \
wget https://fossil.kd2.org/paheko-modules/zip/trunk/modules.zip && \
unzip -o modules.zip && \
rm -rf `find modules/ -name 'ignore' -type f -execdir pwd \;` && \
rm -f modules.zip
# Download plugins and only keep the stable ones
cd /tmp/paheko-build/paheko/src/data && \
wget https://fossil.kd2.org/paheko-plugins/zip/dev/plugins.zip && \
unzip -o plugins.zip && \
rm -rf `find plugins/ -name 'ignore' -type f -execdir pwd \;` && \
rm -f plugins.zip
mv /tmp/paheko-build/paheko/src /tmp/paheko-build/paheko-${VERSION}
tar czvfh ../build/paheko-${VERSION}.tar.gz --hard-dereference -C /tmp/paheko-build paheko-${VERSION}
deb:
cd ../build/debian; ./makedeb.sh
windows:
cd ../build/windows; make installer
publish: installer release deb windows
$(eval VERSION=$(shell cat VERSION))
cd ../build && gpg --armor -u dev@paheko.cloud --detach-sign paheko-${VERSION}.tar.gz
fossil uv sync
#fossil uv ls | fgrep -v 'paheko-0.8.5' | grep '^paheko-.*\.(tar\.bz2|deb)' | xargs fossil uv rm
cd ../build && \
fossil uv add paheko-${VERSION}.tar.gz && \
fossil uv add paheko-${VERSION}.tar.gz.asc
cd ../build/debian && fossil uv add paheko-${VERSION}.deb
cd ../tools && fossil uv add install.php && rm install.php
fossil uv sync
cd ../build/windows && make publish
check-dependencies:
grep -hEo '^use \\?KD2\\[^; ]+|\\KD2\\[^\(:; ]+' -R include/lib/Garradin www | sed -r 's/^use \\?KD2\\|^\\KD2\\//' | sort | uniq
installer:
cd ../tools && php make_installer.php > install.php
minify:
cat `ls www/admin/static/styles/[0-9]*.css` | sed 's/\.\.\///' > www/admin/static/mini.css
@# Minify is only gaining 500 gzipped bytes (4kB uncompressed) but making things hard to read/hack
@#yui-compressor --nomunge www/admin/static/mini.css -o www/admin/static/mini.css

1
src/VERSION Normal file
View file

@ -0,0 +1 @@
1.3.6

21
src/apache-htaccess.conf Normal file
View file

@ -0,0 +1,21 @@
# Sinon le reste marchera, sauf les clients OC/NC
<IfModule !mod_rewrite.c>
# FallbackResource has a bug before Apache 2.4.15, requiring to disable DirectoryIndex
# see https://bz.apache.org/bugzilla/show_bug.cgi?id=58292
# and https://serverfault.com/questions/559067/apache-hangs-for-five-seconds-with-fallbackresource-when-accessing
DirectoryIndex disabled
DirectoryIndex index.php
# Redirect non-existing URLs to the router
FallbackResource /_route.php
# FallbackResource does not work for URLs ending with ".php"
# see https://stackoverflow.com/a/66136226
ErrorDocument 404 /_route.php
# NextCloud/ownCloud clients cannot work without mod_rewrite
<IfModule mod_alias.c>
Redirect 501 /remote.php
Redirect 501 /status.php
</IfModule>
</IfModule>

112
src/apache-vhost.conf Normal file
View file

@ -0,0 +1,112 @@
Options -Indexes -Multiviews +FollowSymlinks
DirectoryIndex index.php index.html
# Some security
<IfModule mod_alias.c>
RedirectMatch 404 _inc\.php
</IfModule>
# Recommended, if you have xsendfile module
# see https://tn123.org/mod_xsendfile/
# Also enable X-SendFile in config.local.php
#
#<IfModule mod_xsendfile.c>
# <Files *.php>
# XSendFile On
# XSendFilePath /home/paheko/
# </Files>
#</IfModule>
# This is to avoid caching mismatch when using mod_deflate
# see https://github.com/symfony/symfony-docs/issues/12644
<IfModule mod_deflate.c>
FileETag None
</IfModule>
# Allow uploads up to 256 MB where it's required
<If "%{REQUEST_URI} =~ m!^/admin/(?:common/files|config/backup)/|^/(?:web)?dav/|^/remote\.php/(?:web)?dav/! && -n %{HTTP_COOKIE}">
<IfModule mod_php.c>
php_value post_max_size 256M
php_value upload_max_filesize 256M
</IfModule>
<IfModule mod_php7.c>
php_value post_max_size 256M
php_value upload_max_filesize 256M
</IfModule>
<IfModule !mod_php.c>
<IfModule !mod_php7.c>
SetEnv PHP_VALUE "post_max_size=256M"
# There is no way to pass multiple PHP ini settings via PHP_VALUE :-(
# so we use PHP_ADMIN_VALUE here. It works unless we have more than 2 settings to change.
SetEnv PHP_ADMIN_VALUE "upload_max_filesize=256M"
</IfModule>
</IfModule>
</If>
<IfModule mod_rewrite.c>
AddDefaultCharset utf-8
AddCharset utf-8 .html .css .js .txt
RewriteEngine On
#RewriteBase /
RewriteRule \.cache - [R=404]
RewriteRule \.well-known/assetlinks.json - [R=404]
# Stop rewrite for /admin URL, except for /admin/p/ (plugins)
RewriteCond %{REQUEST_URI} ^/?admin(?!/p/)
RewriteRule ^ - [END]
# Skip directly to router if possible
# Do not try cache if method is not GET or HEAD
RewriteCond %{REQUEST_METHOD} !GET|HEAD [OR]
# Do not try to get from cache if URL is private, or belongs to modules/plugins
RewriteCond %{REQUEST_URI} ^/admin|^/?(?:dav|wopi|p|m|api)/|\.php$ [OR]
# NextCloud routes
RewriteCond %{REQUEST_URI} ^/?(?:remote\.php|index\.php|ocs|avatars|status\.php)/ [OR]
# Private files are not part of the cache
RewriteCond %{REQUEST_URI} ^/?(?:documents|user|transaction|ext|attachments|versions)/
# Skip, go to router directly
RewriteRule ^ - [skip=8]
# Store MD5 hashes in environment variables
RewriteCond %{REQUEST_URI} ^(.+)(?:\?|$)
RewriteRule ^ "-" [E=CACHE_URI:%1]
# Extract file extension (required for Apache to serve the correct mimetype)
RewriteCond %{REQUEST_URI} (\.[a-z0-9]+)(?:\?|$)
RewriteRule ^ "-" [E=CACHE_EXT:%1]
# If no extension, default to .html
RewriteCond %{REQUEST_URI} !\.[a-z0-9]+(?:\?|$)
RewriteRule ^ "-" [E=CACHE_EXT:.html]
RewriteCond expr "md5(%{ENV:CACHE_URI}) =~ /^(.+)$/"
RewriteRule ^ "-" [E=CACHE_URI_MD5:%1]
RewriteCond expr "md5(tolower(%{HTTP_HOST})) =~ /^((.{2}).+)$/"
RewriteRule ^ "-" [E=CACHE_HOST_MD5:%1,E=CACHE_HOST2_MD5:%2]
RewriteCond /.cache/%{ENV:CACHE_HOST_MD5}/%{ENV:CACHE_URI_MD5} (.+)
RewriteRule ^ "-" [E=CACHE_PATH:%1]
# Serve symlinks for files
RewriteCond %{QUERY_STRING} ="" [OR]
RewriteCond %{QUERY_STRING} ^h=[a-f0-9]+$
RewriteCond %{DOCUMENT_ROOT}%{ENV:CACHE_PATH}%{ENV:CACHE_EXT} -l
RewriteRule ^ %{ENV:CACHE_PATH}%{ENV:CACHE_EXT} [END]
# Do not try cache for pages if user is logged-in
RewriteCond %{HTTP_COOKIE} !pko=
# Serve static HTML pages
RewriteCond %{QUERY_STRING} =""
RewriteCond %{DOCUMENT_ROOT}%{ENV:CACHE_PATH}%{ENV:CACHE_EXT} -f
RewriteCond %{DOCUMENT_ROOT}%{ENV:CACHE_PATH}%{ENV:CACHE_EXT} !-l
RewriteRule ^ %{ENV:CACHE_PATH}%{ENV:CACHE_EXT} [END]
# Redirect to router
RewriteRule ^ /_route.php [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},END,QSA]
</IfModule>

905
src/config.dist.php Normal file
View file

@ -0,0 +1,905 @@
<?php
/**
* Ce fichier représente un exemple des constantes de configuration
* disponibles pour Paheko.
*
* NE PAS MODIFIER CE FICHIER!
*
* Pour configurer Paheko, copiez ce fichier en 'config.local.php'
* puis décommentez et modifiez ce dont vous avez besoin.
*/
// Nécessaire pour situer les constantes dans le bon namespace
namespace Paheko;
/**
* Clé secrète, doit être unique à chaque instance de Paheko
*
* 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, Paheko ajoutera automatiquement
* une valeur aléatoire dans le fichier config.local.php.
*/
//const SECRET_KEY = '3xUhIgGwuovRKOjVsVPQ5yUMfXUSIOX2GKzcebsz5OINrYC50r';
/**
* @var null|int|array
*
* Forcer la connexion locale
*
* Si un numéro est spécifié, alors le membre avec l'ID correspondant à ce
* numéro sera connecté (sans besoin de mot de passe).
*
* Exemple: LOCAL_LOGIN = 42 connectera automatiquement le membre avec id = 42
* Attention à ne pas utiliser en production !
*
* Si le nombre spécifié est -1, alors c'est le premier membre trouvé qui
* peut gérer la configuration (et donc modifier les droits des membres)
* qui sera connecté.
*
* Si un tableau est spécifié, alors Paheko considérera que l'utilisateur
* connecté fourni dans le tableau n'est pas un membre.
* Voir la documentation sur l'utilisation avec SSO et LDAP pour plus de détails.
*
* Exemple :
* const LOCAL_LOGIN = [
* 'user' => ['_name' => 'bohwaz'],
* 'permissions' => ['users' => 9, 'config' => 9]
* ];
*
* Défault : null (connexion automatique désactivée)
*/
//const LOCAL_LOGIN = null;
/**
* 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;
/**
* Répertoire se situe le code source de Paheko
*
* Défaut : répertoire racine de Paheko (__DIR__)
*/
//const ROOT = __DIR__;
/**
* Répertoire sont situées les données de Paheko
* (incluant la base de données SQLite, les sauvegardes, le cache, les fichiers locaux et les plugins)
*
* Défaut : sous-répertoire "data" de la racine
*/
//const DATA_ROOT = ROOT . '/data';
/**
* Répertoire est situé le cache,
* exemples : graphiques de statistiques, templates Brindille, etc.
*
* Défaut : sous-répertoire 'cache' de DATA_ROOT
*/
//const CACHE_ROOT = DATA_ROOT . '/cache';
/**
* Répertoire est situé le cache partagé entre instances
* Paheko utilisera ce répertoire pour stocker le cache susceptible d'être partagé entre instances, comme
* le code PHP généré à partir des templates Smartyer.
*
* Défaut : sous-répertoire 'shared' de CACHE_ROOT
*/
//const SHARED_CACHE_ROOT = CACHE_ROOT . '/shared';
/**
* Motif qui détermine l'emplacement des fichiers de cache du site web.
*
* Le site web peut créer des fichiers de cache pour les pages et catégories.
* Ensuite le serveur web (Apache) servira ces fichiers directement, sans faire
* appel au PHP, permettant de supporter beaucoup de trafic si le site web
* a une vague de popularité.
*
* Certaines valeurs sont remplacées :
* %host% = hash MD5 du hostname (utile en cas d'hébergement de plusieurs instances)
* %host.2% = 2 premiers caractères du hash MD5 du hostname
*
* Utiliser NULL pour désactiver le cache.
*
* Défault : CACHE_ROOT . '/web/%host%'
*
* @var null|string
*/
//const WEB_CACHE_ROOT = CACHE_ROOT . '/web/%host%';
/**
* Emplacement du fichier de base de données de Paheko
*
* 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';
/**
* Signaux système
*
* Permet de déclencher des signaux sans passer par un plugin.
* Le fonctionnement des signaux système est strictment identique aux signaux des plugins.
* Les signaux système sont exécutés en premier, avant les signaux des plugins.
*
* Format : pour chaque signal, un tableau comprenant une seule clé et une seule valeur.
* La clé est le nom du signal, et la valeur est la fonction.
*
* Défaut: [] (tableau vide)
*/
//const SYSTEM_SIGNALS = [['files.delete' => 'MyNamespace\Signals::deleteFile'], ['entity.Accounting\Transaction.save.before' => 'MyNamespace\Signals::saveTransaction']];
/**
* Adresse URI de la racine du site Paheko
* (doit se terminer par un slash)
*
* Défaut : découverte automatique à partir de SCRIPT_NAME
*/
//const WWW_URI = '/asso/';
/**
* Adresse URL HTTP(S) publique de Paheko
*
* Défaut : découverte automatique à partir de HTTP_HOST ou SERVER_NAME + WWW_URI
* @var null|string
*/
//const WWW_URL = 'http://paheko.chezmoi.tld' . WWW_URI;
/**
* Adresse URL HTTP(S) de l'admin Paheko
*
* Note : il est possible d'avoir un autre domaine que WWW_URL.
*
* Défaut : WWW_URL + 'admin/'
* @var null|string
*/
//const ADMIN_URL = 'https://admin.paheko.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 : TRUE (pour aider le debug de l'auto-hébergement)
*
* 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/Paheko
*
* 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é.
*
* Paheko accepte aussi les rapports d'erreur venant d'autres instances.
*
* Pour cela utiliser l'URL https://login:password@paheko.site.tld/api/errors/report
* (voir aussi API_USER et API_PASSWORD)
*
* Les erreurs seront ensuite visibles dans
* Configuration -> Fonctions avancées -> Journal d'erreurs
*
* Défaut : null
*/
//const ERRORS_REPORT_URL = null;
/**
* Template HTML d'erreur personnalisé (en production)
*
* Si SHOW_ERRORS est à FALSE un message d'erreur générique (sans détail technique)
* est affiché. Il est possible de personnaliser ce message avec cette constante.
*
* Voir include/init.php pour le template par défaut.
*/
// const ERRORS_TEMPLATE = null;
/**
* Loguer / envoyer par mail les erreurs utilisateur ?
*
* Si positionné à 1, *toutes* les erreurs utilisateur (champ mal rempli dans un formulaire,
* formulaire dont le token CSRF a expiré, etc.) seront loguées et/ou envoyées par mail
* (selon le réglage choisit ci-dessus).
*
* Si positionné à 2, alors l'exception sera remontée dans la stack, *et* loguée/envoyée.
*
* Utile pour le développement.
*
* Défaut : 0 (ne rien faire)
* @var int
*/
// const REPORT_USER_EXCEPTIONS = 0;
/**
* Activation des détails techniques (utile en auto-hébergement) :
* - version de PHP
* - page permettant de visualiser les erreurs présentes dans le error.log
* - permettre de migrer d'un stockage de fichiers à l'autre
* - vérification de nouvelle version (sur la page configuration)
*
* Ces infos ne sont visibles que par les membres ayant accès à la configuration.
*
* Défaut : true
* (Afin d'aider au rapport de bugs des instances auto-hébergées)
*/
//const ENABLE_TECH_DETAILS = true;
/**
* Activation du log SQL (option de développement)
*
* Si cette constante est renseignée par un chemin de fichier SQLite valide,
* alors *TOUTES* les requêtes SQL et leur contenu sera logué dans la base de données indiquée.
*
* Cette option permet ensuite de parcourir les requêtes via l'interface dans
* Configuration -> Fonctions avancées -> Journal SQL pour permettre d'identifier
* les requêtes qui mettent trop de temps, et comment elles pourraient
* être améliorées. Visualiser les requêtes SQL nécessite d'avoir également activé
* ENABLE_TECH_DETAILS.
*
* ATTENTION : cela signifie que des informations personnelles (mot de passe etc.)
* peuvent se retrouver dans le log. Ne pas utiliser à moins de tester en développement.
* Cette option peut significativement ralentir le chargement des pages.
*
* Défaut : null (= désactivé)
* @var string|null
*/
// const SQL_DEBUG = __DIR__ . '/debug_sql.sqlite';
/**
/**
* Mode de journalisation de SQLite
*
* Paheko recommande le mode 'WAL' de SQLite, qui permet à SQLite
* d'être extrêmement rapide.
*
* Cependant, sur certains hébergeurs utilisant NFS, ce mode peut
* provoquer dans certains cas une corruption de la base de données.
*
* Pour éviter un souci de corruption, depuis la version 1.2.4 'TRUNCATE' est
* le mode par défaut.
*
* Celui-ci ne présente pas de risque, mais la base de données est alors plus
* lente.
*
* Si votre hébergement n'utilise pas NFS, il est recommandé de mettre 'WAL'
* ici, cela rendra Paheko beaucoup plus rapide.
*
* @see https://www.sqlite.org/pragma.html#pragma_journal_mode
* @see https://www.sqlite.org/wal.html
* @see https://stackoverflow.com/questions/52378361/which-nfs-implementation-is-safe-for-sqlite-database-accessed-by-multiple-proces
*
* Défaut : 'TRUNCATE'
* @var string
*/
//const SQLITE_JOURNAL_MODE = 'TRUNCATE';
/**
* Activation du log HTTP (option de développement)
*
* Si cette constante est renseignée par un fichier texte, *TOUTES* les requêtes HTTP
* ainsi que leur contenu y sera enregistré.
*
* C'est surtout utile pour débuguer les problèmes de WebDAV par exemple.
*
* ATTENTION : cela signifie que des informations personnelles (mot de passe etc.)
* peuvent se retrouver dans le log. Ne pas utiliser à moins de tester en développement.
*
* Default : null (= désactivé)
* @var string|null
*/
// const HTTP_LOG_FILE = __DIR__ . '/http.log';
/**
* Activer la possibilité de faire une mise à jour semi-automatisée
* depuis fossil.kd2.org.
*
* Si mis à TRUE, alors un bouton sera accessible depuis le menu "Configuration"
* pour faire une mise à jour en deux clics.
*
* Il est conseillé de désactiver cette fonctionnalité si vous ne voulez pas
* permettre à un utilisateur de casser l'installation !
*
* Si cette constante est désactivée, mais que ENABLE_TECH_DETAILS est activé,
* la vérification de nouvelle version se fera quand même, mais plutôt que de proposer
* la mise à jour, Paheko proposera de se rendre sur le site officiel pour
* télécharger la mise à jour.
*
* Défaut : true
*
* @var bool
*/
//const ENABLE_UPGRADES = true;
/**
* Utilisation de cron pour les tâches automatiques
*
* Si "true" on s'attend à ce qu'une tâche automatisée appelle
* les scripts suivants:
* - scripts/cron.php toutes les 24 heures (envoi des rappels de cotisation,
* création des sauvegardes)
* - scripts/emails.php toutes les 5 minutes environ (envoi des emails en attente)
*
* Si "false", les actions de scripts/cron.php seront effectuées quand une personne
* se connecte. Et les emails seront envoyés instantanément (ce qui peut ralentir ou
* planter si un message a beaucoup de destinataires).
*
* 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 Paheko:
* XSendFile On
* XSendFilePath /var/www/paheko
*
* (remplacer le chemin par le répertoire racine de Paheko)
*
* 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';
/**
* Désactiver l'envoi d'e-mails
*
* Si positionné à TRUE, l'envoi d'e-mail ne sera pas proposé, et il ne sera
* pas non plus possible de récupérer un mot de passe perdu.
* Les parties de l'interface relatives à l'envoi d'e-mail seront cachées.
*
* Ce réglage est utilisé pour la version autonome sous Windows, car Windows
* ne permet pas l'envoi d'e-mails.
*
* Défaut : false
* @var bool
*/
//const DISABLE_EMAIL = false;
/**
* 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
*/
//const SMTP_USER = 'paheko@monserveur.com';
/**
* Mot de passe pour le serveur SMTP
*
* mettre à null pour utiliser un serveur local ou anonyme
*
* Défaut : null
*/
//const SMTP_PASSWORD = 'abcd';
/**
* Sécurité du serveur SMTP
*
* 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';
/**
* Nom du serveur utilisé dans le HELO SMTP
*
* Si NULL, alors le nom renseigné comme SERVER_NAME (premier nom du virtual host Apache)
* sera utilisé.
*
* Defaut : NULL
*
* @var null|string
*/
//const SMTP_HELO_HOSTNAME = 'mail.domain.tld';
/**
* Adresse e-mail destinée à recevoir les erreurs de mail
* (adresses invalides etc.) Return-Path
*
* Si laissé NULL, alors l'adresse e-mail de l'association sera utilisée.
* En cas d'hébergement de plusieurs associations, il est conseillé
* d'utiliser une adresse par association.
*
* Voir la documentation de configuration sur des exemples de scripts
* permettant de traiter les mails reçus à cette adresse.
*
* Défaut : null
*/
//const MAIL_RETURN_PATH = 'returns@monserveur.com';
/**
* Adresse e-mail expéditrice des messages (Sender)
*
* Si vous envoyez des mails pour plusieurs associations, il est souhaitable
* de forcer l'adresse d'expéditeur des messages pour passer les règles SPF et DKIM.
*
* Dans ce cas l'adresse de l'association sera indiquée en "Reply-To", et
* l'adresse contenue dans MAIL_SENDER sera dans le From.
*
* Si laissé NULL, c'est l'adresse de l'association indiquée dans la configuration
* qui sera utilisée.
*
* Défaut : null
*/
//const MAIL_SENDER = 'associations@monserveur.com';
/**
* Mot de passe pour l'accès à l'API permettant de gérer les mails d'erreur
* (voir MAIL_RETURN_PATH)
*
* Cette adresse HTTP permet de gérer un bounce email reçu en POST.
* C'est utile si votre serveur de mail est capable de faire une requête HTTP
* à la réception d'un message.
*
* La requête bounce doit contenir un paramètre "message", contenant l'intégralité
* de l'email avec les entêtes.
*
* Si on définit 'abcd' ici, il faudra faire une requête comme ceci :
* curl -F 'message=@/tmp/message.eml' https://bounce:abcd@monasso.com/admin/handle_bounce.php
*
* En alternative le serveur de mail peut aussi appeler le script
* 'scripts/handle_bounce.php'
*
* Défaut : null (l'API handlebounce est désactivée)
*
* @type string|null
*/
//const MAIL_BOUNCE_PASSWORD = null;
/**
* Couleur primaire de l'interface admin par défaut
* (peut être personnalisée dans la configuration)
*
* Défaut : #20787a
*/
//const ADMIN_COLOR1 = '#20787a';
/**
* Couleur secondaire de l'interface admin
* Défaut : #85b9ba
*/
//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/bg.png
*/
//const ADMIN_BACKGROUND_IMAGE = 'https://mon-asso.fr/fond_paheko.png';
/**
* Forcer l'image de fond et couleurs dans l'interface d'administration
*
* Si positionné à TRUE, les couleurs et l'image de fond définies dans la configuration
* seront ignorés.
*
* Utile pour s'assurer qu'on est sur une instance de test par exemple.
*
* Défault : false
* @var bool
*/
//const FORCE_CUSTOM_COLORS = false;
/**
* Désactiver le formulaire d'installation
*
* Si TRUE, alors le formulaire d'installation renverra une erreur.
*
* Utile pour une installation multi-associations.
*
* Défaut : false
* @var bool
*/
//const DISABLE_INSTALL_FORM = false;
/**
* Stockage des fichiers
*
* Indiquer ici le nom d'une classe de stockage de fichiers
* (parmis celles disponibles dans lib/Paheko/Files/Backend)
*
* Indiquer NULL si vous souhaitez stocker les fichier dans la base
* de données SQLite (valeur par défaut).
*
* Classes de stockage possibles :
* - SQLite : enregistre dans la base de données (défaut)
* - FileSystem : enregistrement des fichiers dans le système de fichier
*
* ATTENTION : activer FileSystem ET ne pas utiliser de sous-domaine (vhost dédié)
* ferait courir de graves risques de piratage à votre serveur web si vous ne protégez
* pas correctement le répertoire de stockage des fichiers !
*
* Défaut : null
*/
//const FILE_STORAGE_BACKEND = null;
/**
* Configuration du stockage des fichiers
*
* Indiquer dans cette constante la configuration de la classe de stockage
* des fichiers.
*
* Valeurs possibles :
* - SQLite : aucune configuration possible
* - FileSystem : (string) chemin du répertoire doivent être stockés les fichiers
*
* Pour migrer d'un stockage de fichiers à l'autre,
* voir Configuration > Avancé (accessible uniquement si ENABLE_TECH_DETAILS est à true)
*
* Défaut : null
*/
//const FILE_STORAGE_CONFIG = null;
/**
* Forcer le quota disponible pour les fichiers
*
* Si cette constante est renseignée (en octets) alors il ne sera
* pas possible de stocker plus que cette valeur.
* Tout envoi de fichier sera refusé.
*
* Défaut : null (dans ce cas c'est le stockage qui détermine la taille disponible, donc généralement l'espace dispo sur le disque dur !)
*/
//const FILE_STORAGE_QUOTA = 10*1024*1024; // Forcer le quota alloué à 10 Mo, quel que soit le backend de stockage
/**
* FILE_VERSIONING_POLICY
* Forcer la politique de versionnement des fichiers.
*
* null: laisser le choix de la politique (dans la configuration)
* 'none': ne rien conserver
* 'min': conserver 5 versions (1 minute, 1 heure, 1 jour, 1 semaine, 1 mois)
* 'avg': conserver 20 versions
* 'max': conserver 50 versions
*
* Note : indiquer 'none' fait qu'aucune nouvelle version ne sera créée,
* mais les versions existantes sont conservées.
*
* Si ce paramètre n'est pas NULL, alors il faudra aussi définir FILE_VERSIONING_MAX_SIZE.
*
* Défaut : null (laisser le choix dans la configuration)
*
* @var null|string
*/
//const FILE_VERSIONING_POLICY = 'min';
/**
* FILE_VERSIONING_MAX_SIZE
* Forcer la taille maximale des fichiers à versionner (en Mio)
*
* N'a aucun effet si le versionnement de fichiers est désactivé.
*
* Défaut : null (laisser le choix de la taille dans la configuration)
*
* @var int|null
*/
//const FILE_VERSIONING_MAX_SIZE = 10;
/**
* Adresse de découverte d'un client d'édition de documents (WOPI)
* (type OnlyOffice, Collabora, MS Office)
*
* Cela permet de savoir quels types de fichiers sont éditables
* avec l'éditeur web.
*
* Si NULL, alors l'édition de documents est désactivée.
*
* Défaut : null
*/
//const WOPI_DISCOVERY_URL = 'http://localhost:9980/hosting/discovery';
/**
* PDF_COMMAND
* Commande qui sera exécutée pour créer un fichier PDF à partir d'un HTML.
*
* Si laissé sur 'auto', Paheko essaiera de détecter une solution entre
* PrinceXML, Chromium, wkhtmltopdf ou weasyprint (dans cet ordre).
* Si aucune solution n'est disponible, une erreur sera affichée.
*
* Il est possible d'indiquer NULL pour désactiver l'export en PDF.
*
* Il est possible d'indiquer uniquement le nom du programme :
* 'chromium', 'prince', 'weasyprint', ou 'wkhtmltopdf'.
* Dans ce cas, Paheko utilisera les paramètres par défaut de ce programme.
*
* Alternativement, il est possible d'indiquer la commande complète avec
* les options, par exemple '/usr/bin/chromium --headless --print-to-pdf=%2$s %1$s'
* Dans ce cas :
* - %1$s sera remplacé par le chemin du fichier HTML existant,
* - %2$s sera remplacé par le chemin du fichier PDF à créer.
*
* Si vous utilisez une extension pour générer les PDF (comme DomPDF), alors
* laisser cette constante sur 'auto'.
*
* Exemples :
* 'weasyprint'
* 'wkhtmltopdf -q --print-media-type --enable-local-file-access %s %s'
*
* Si vous utilisez Prince, un message mentionnant l'utilisation de Prince
* sera joint aux e-mails utilisant des fichiers PDF, conformément à la licence :
* https://www.princexml.com/purchase/license_faq/#non-commercial
*
* Défaut : 'auto'
* @var null|string
*/
//const PDF_COMMAND = 'auto';
/**
* PDF_USAGE_LOG
* Chemin vers le fichier enregistrer la date de chaque export en PDF
*
* Ceci est utilisé notamment pour estimer le prix de la licence PrinceXML.
*
* Défaut : NULL
* @var null|string
*/
//const PDF_USAGE_LOG = null;
/**
* CALC_CONVERT_COMMAND
* Outil de conversion de formats de tableur vers un format propriétaire
*
* Paheko gère nativement les exports en ODS (OpenDocument : LibreOffice)
* et CSV, et imports en CSV.
*
* En indiquant ici le nom d'un outil, Paheko autorisera aussi
* l'import en XLSX, XLS et ODS, et l'export en XLSX.
*
* Pour cela il procédera simplement à une conversion entre les formats natifs
* ODS/CSV et XLSX ou XLS.
*
* Note : installer ces commandes peut introduire des risques de sécurité sur le serveur.
*
* Les outils supportés sont :
* - ssconvert (apt install gnumeric) (plus rapide)
* - unoconv (apt install unoconv) (utilise LibreOffice)
* - unoconvert (https://github.com/unoconv/unoserver/) en spécifiant l'interface
*
* Défault : null (= fonctionnalité désactivée)
* @var string|null
*/
//const CALC_CONVERT_COMMAND = 'unoconv';
//const CALC_CONVERT_COMMAND = 'ssconvert';
//const CALC_CONVERT_COMMAND = 'unoconvert --interface localhost --port 2022';
/**
* DOCUMENT_THUMBNAIL_COMMANDS
* Indique les commandes à utiliser pour générer des miniatures pour les documents
* (LibreOffice, OOXML, PDF, SVG, vidéos, etc.)
*
* Les options possibles sont (par ordre de rapidité) :
* - mupdf : les miniatures PDF/SVG/XPS/EPUB sont générées avec mutool
* (apt install mupdf-tools)
* - collabora : les miniatures de documents bureautiques sont générées
* par le serveur Collabora, via l'API dont l'URL est indiquée dans WOPI_DISCOVERY_URL
* - unoconvert : les miniatures des documents Office/LO sont générées
* avec unoconvert <https://github.com/unoconv/unoserver/>
* - ffmpeg : les miniatures de vidéos seront générées avec ffmpeg
*
* Bien que Collabora/Unoconvert puissent générer des miniatures de PDF, il est plutôt
* conseillé d'utiliser mupdf quand même, il est plus rapide et léger.
*
* Note : cette option créera de nombreux fichiers de cache, et risque d'augmenter
* la charge serveur de manière importante.
*
* Défaut : null (fonctionnalité désactivée)
* @var null|array
*/
//const DOCUMENT_THUMBNAIL_COMMANDS = ['mupdf', 'collabora', 'ffmpeg'];
/**
* PDFTOTEXT_COMMAND
* Outil de conversion de PDF au format texte.
*
* Utilisé pour indexer un fichier PDF pour pouvoir rechercher dans son contenu
* parmi les documents.
*
* Il est possible de spécifier ici la commande suivante :
* - mupdf (apt install mupdf-tools)
*
* Toute autre commande sera ignorée.
*
* Défaut : null (= fonctionnalité désactivée)
*/
//const PDFTOTEXT_COMMAND = 'mupdf';
/**
* API_USER et API_PASSWORD
* Login et mot de passe système de l'API
*
* Une API est disponible via l'URL https://login:password@paheko.association.tld/api/...
* Voir https://fossil.kd2.org/paheko/wiki?name=API pour la documentation
*
* Ces deux constantes permettent d'indiquer un nom d'utilisateur
* et un mot de passe pour accès à l'API.
*
* Cet utilisateur est distinct de ceux définis dans la page de gestion des
* identifiants d'accès à l'API, et aura accès à TOUT en écriture/administration.
*
* Défaut: null
*/
//const API_USER = 'coraline';
//const API_PASSWORD = 'thisIsASecretPassword42';
/**
* DISABLE_INSTALL_PING
*
* Lors de l'installation, ou d'une mise à jour, la version installée de Paheko,
* ainsi que celle de PHP et de SQLite, sont envoyées à Paheko.cloud.
*
* Cela permet de savoir quelles sont les versions utilisées, et également de compter
* le nombre d'installations effectuées.
*
* Aucune donnée personnelle n'est envoyée. Un identifiant anonyme est envoyé,
* permettant d'identifier l'installation et éviter les doublons.
* (voir le code dans lib/.../Install.php)
*
* Le code de stockage des statistiques est visible à :
* https://paheko.cloud/ping/
*
* Pour désactiver cet envoi il suffit de placer cette constante à TRUE.
*
* Défaut : false
*/
//const DISABLE_INSTALL_PING = false;
/**
* Informations légale sur l'hébergeur
*
* Ce texte (HTML) est affiché en bas de la page "mentions légales"
* (.../admin/legal.php)
*
* S'il est omis, l'association sera indiquée comme étant auto-hébergée.
*
* Défaut : null
*
* @var string|null
*/
//const LEGAL_HOSTING_DETAILS = 'OVH<br />5 rue de l'hébergement<br />ROUBAIX';
/**
* Message d'avertissement
*
* Sera affiché en haut de toutes les pages de l'administration.
*
* Code HTML autorisé.
* Utiliser NULL pour désactiver le message.
*
* Défaut : null
*
* @var null|string
*/
//const ALERT_MESSAGE = 'Ceci est un compte de test.';

9
src/config.local.php Normal file
View file

@ -0,0 +1,9 @@
<?php
namespace Paheko;
const SECRET_KEY = 'N7Ve3u8OcAtXuM3bF7tF3JX1uDFZAwcR7cmLm9hTV5RWPjcSdSUJh/zRuVOxnTKoaex+bMnmCm+bxAnLjZsYSw==';
// use mailcatcher
const SMTP_HOST = "localhost";
const SMTP_PORT = 1025;
const SMTP_SECURITY = "NONE";

View file

@ -0,0 +1,435 @@
CREATE TABLE IF NOT EXISTS config (
key TEXT PRIMARY KEY NOT NULL,
value TEXT NULL
);
CREATE TABLE IF NOT EXISTS users_categories
-- Users categories, mainly used to manage rights
(
id INTEGER PRIMARY KEY NOT NULL,
name TEXT NOT NULL,
-- Permissions, 0 = no access, 1 = read-only, 2 = read-write, 9 = admin
perm_web INTEGER NOT NULL DEFAULT 1,
perm_documents INTEGER NOT NULL DEFAULT 1,
perm_users INTEGER NOT NULL DEFAULT 1,
perm_accounting INTEGER NOT NULL DEFAULT 1,
perm_subscribe INTEGER NOT NULL DEFAULT 0,
perm_connect INTEGER NOT NULL DEFAULT 1,
perm_config INTEGER NOT NULL DEFAULT 0,
hidden INTEGER NOT NULL DEFAULT 0
);
CREATE INDEX IF NOT EXISTS users_categories_hidden ON users_categories (hidden);
-- 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 if fee is not linked to accounting, this is reset using a trigger if the year is deleted
id_year INTEGER NULL REFERENCES acc_years (id) ON DELETE SET NULL, -- NULL if fee is not linked to accounting
id_analytical INTEGER NULL REFERENCES acc_accounts (id) ON DELETE SET NULL
);
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, -- This can be NULL if there is no fee for the service
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,
sent_date TEXT NOT NULL DEFAULT CURRENT_DATE CHECK (date(sent_date) IS NOT NULL AND date(sent_date) = sent_date),
due_date TEXT NOT NULL CHECK (date(due_date) IS NOT NULL AND date(due_date) = due_date)
);
CREATE UNIQUE INDEX IF NOT EXISTS srs_index ON services_reminders_sent (id_user, id_service, id_reminder, due_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);
--
-- 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 -- 0 = fait partie du plan comptable original, 1 = 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);
-- Balance des comptes par exercice
CREATE VIEW IF NOT EXISTS acc_accounts_balances
AS
SELECT id_year, id, label, code, type, debit, credit,
CASE -- 3 = dynamic asset or liability depending on balance
WHEN position = 3 AND (debit - credit) > 0 THEN 1 -- 1 = Asset (actif) comptes fournisseurs, tiers créditeurs
WHEN position = 3 THEN 2 -- 2 = Liability (passif), comptes clients, tiers débiteurs
ELSE position
END AS position,
CASE
WHEN position IN (1, 4) -- 1 = asset, 4 = expense
OR (position = 3 AND (debit - credit) > 0)
THEN
debit - credit
ELSE
credit - debit
END AS balance,
CASE WHEN debit - credit > 0 THEN 1 ELSE 0 END AS is_debt
FROM (
SELECT t.id_year, a.id, a.label, a.code, a.position, a.type,
SUM(l.credit) AS credit,
SUM(l.debit) AS debit
FROM acc_accounts a
INNER JOIN acc_transactions_lines l ON l.id_account = a.id
INNER JOIN acc_transactions t ON t.id = l.id_transaction
GROUP BY t.id_year, a.id
);
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);
-- Make sure id_account is reset when a year is deleted
CREATE TRIGGER IF NOT EXISTS acc_years_delete BEFORE DELETE ON acc_years BEGIN
UPDATE services_fees SET id_account = NULL, id_year = NULL WHERE id_year = OLD.id;
END;
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, id_year);
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_transaction ON acc_transactions_lines (id_transaction);
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 api_credentials
(
id INTEGER NOT NULL PRIMARY KEY,
label TEXT NOT NULL,
key TEXT NOT NULL,
secret TEXT NOT NULL,
created TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
last_use TEXT NULL,
access_level INT NOT NULL
);
CREATE UNIQUE INDEX IF NOT EXISTS api_credentials_key ON api_credentials (key);
---------- FILES ----------------
CREATE TABLE IF NOT EXISTS files
-- Files metadata
(
id INTEGER NOT NULL PRIMARY KEY,
path TEXT NOT NULL,
parent TEXT NOT NULL,
name TEXT NOT NULL, -- File name
type INTEGER NOT NULL, -- File type, 1 = file, 2 = directory
mime TEXT NULL,
size INT NULL,
modified TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP CHECK (datetime(modified) = modified),
image INT NOT NULL DEFAULT 0,
CHECK (type = 2 OR (mime IS NOT NULL AND size IS NOT NULL))
);
-- Unique index as this is used to make up a file path
CREATE UNIQUE INDEX IF NOT EXISTS files_unique ON files (path);
CREATE INDEX IF NOT EXISTS files_parent ON files (parent);
CREATE INDEX IF NOT EXISTS files_name ON files (name);
CREATE INDEX IF NOT EXISTS files_modified ON files (modified);
CREATE TABLE IF NOT EXISTS files_contents
-- Files contents (empty if using another storage backend)
(
id INTEGER NOT NULL PRIMARY KEY REFERENCES files(id) ON DELETE CASCADE,
compressed INT NOT NULL DEFAULT 0,
content BLOB NOT NULL
);
CREATE VIRTUAL TABLE IF NOT EXISTS files_search USING fts4
-- Search inside files content
(
tokenize=unicode61, -- Available from SQLITE 3.7.13 (2012)
path TEXT NOT NULL,
title TEXT NULL,
content TEXT NOT NULL, -- Text content
notindexed=path
);
CREATE TABLE IF NOT EXISTS web_pages
(
id INTEGER NOT NULL PRIMARY KEY,
parent TEXT NOT NULL, -- Parent path, empty = web root
path TEXT NOT NULL, -- Full page directory name
uri TEXT NOT NULL, -- Page identifier
file_path TEXT NOT NULL, -- Full file path for contents
type INTEGER NOT NULL, -- 1 = Category, 2 = Page
status TEXT NOT NULL,
format TEXT NOT NULL,
published TEXT NOT NULL CHECK (datetime(published) = published),
modified TEXT NOT NULL CHECK (datetime(modified) = modified),
title TEXT NOT NULL,
content TEXT NOT NULL
);
CREATE UNIQUE INDEX IF NOT EXISTS web_pages_path ON web_pages (path);
CREATE UNIQUE INDEX IF NOT EXISTS web_pages_uri ON web_pages (uri);
CREATE UNIQUE INDEX IF NOT EXISTS web_pages_file_path ON web_pages (file_path);
CREATE INDEX IF NOT EXISTS web_pages_parent ON web_pages (parent);
CREATE INDEX IF NOT EXISTS web_pages_published ON web_pages (published);
CREATE INDEX IF NOT EXISTS web_pages_title ON web_pages (title);
-- FIXME: rename to english
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
);
CREATE TABLE IF NOT EXISTS emails (
-- List of emails addresses
-- We are not storing actual email addresses here for privacy reasons
-- So that we can keep the record (for opt-out reasons) even when the
-- email address has been removed from the users table
id INTEGER NOT NULL PRIMARY KEY,
hash TEXT NOT NULL,
verified INTEGER NOT NULL DEFAULT 0,
optout INTEGER NOT NULL DEFAULT 0,
invalid INTEGER NOT NULL DEFAULT 0,
fail_count INTEGER NOT NULL DEFAULT 0,
sent_count INTEGER NOT NULL DEFAULT 0,
fail_log TEXT NULL,
last_sent TEXT NULL,
added TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE UNIQUE INDEX IF NOT EXISTS emails_hash ON emails (hash);
CREATE TABLE IF NOT EXISTS emails_queue (
-- List of emails waiting to be sent
id INTEGER NOT NULL PRIMARY KEY,
sender TEXT NULL,
recipient TEXT NOT NULL,
recipient_hash TEXT NOT NULL,
subject TEXT NOT NULL,
content TEXT NOT NULL,
content_html TEXT NULL,
sending INTEGER NOT NULL DEFAULT 0, -- Will be changed to 1 when the queue run will start
sending_started TEXT NULL, -- Will be filled with the datetime when the email sending was started
context INTEGER NOT NULL
);

View file

@ -0,0 +1,4 @@
ALTER TABLE services_fees ADD COLUMN id_analytical INTEGER NULL REFERENCES acc_accounts (id) ON DELETE SET NULL;
UPDATE acc_charts SET code = 'PCA_2018' WHERE code = 'PCA2018';
UPDATE acc_charts SET code = 'PCA_1999' WHERE code = 'PCA1999';

View file

@ -0,0 +1,3 @@
UPDATE plugins_signaux SET signal = 'home.banner' WHERE signal = 'accueil.banniere';
UPDATE plugins_signaux SET signal = 'reminder.send.after' WHERE signal = 'rappels.auto';
UPDATE plugins_signaux SET signal = 'email.send.before' WHERE signal = 'email.envoi';

View file

@ -0,0 +1,23 @@
CREATE TEMP TABLE tmp_new_accounts (id_chart, code, label, position);
-- Add missing accounts
INSERT INTO tmp_new_accounts (code, label, position) VALUES
('438', 'Organismes sociaux - Charges à payer et produits à recevoir', 2),
('4382', 'Charges sociales sur congés à payer', 2),
('4386', 'Autres charges à payer', 2),
('4387', 'Produits à recevoir', 2);
UPDATE tmp_new_accounts SET id_chart = (SELECT id FROM acc_charts WHERE code = 'PCA_2018');
INSERT OR IGNORE INTO acc_accounts (id_chart, code, label, position, user) SELECT *, 0 FROM tmp_new_accounts WHERE id_chart IS NOT NULL;
DROP TABLE tmp_new_accounts;
CREATE TEMP TABLE IF NOT EXISTS su_fix_fee (id);
INSERT INTO su_fix_fee
SELECT su.id FROM services_users su LEFT JOIN services_fees sf ON sf.id = su.id_fee AND sf.id_service = sf.id_service
WHERE sf.id IS NULL AND su.id_fee IS NOT NULL;
-- Remove id_fee from subscriptions where it belongs to another service
UPDATE services_users SET id_fee = NULL WHERE id IN (SELECT id FROM su_fix_fee);

View file

@ -0,0 +1,445 @@
code,label,description,position,bookmark
1,"FONDS SOCIAL, PROVISIONS POUR RISQUES ET CHARGE ET DETTES À PLUS DUN AN",,Passif,
10,Fonds de lassociation ou de la fondation,,Passif,
12,Plus-values de réévaluation,,Passif,
120,Plus-values de réévaluation sur immobilisations incorporelles,,Passif,
121,Plus-values de réévaluation sur immobilisations corporelles,,Passif,
122,Plus-values de réévaluation sur immobilisations financières,,Passif,
124,Reprises de réductions de valeurs sur placements de trésorerie,,Passif,
13,Fonds affectés et autres réserves,,Passif,
130,Fonds affectés pour investissements,,Passif,
131,Fonds affectés pour passif social,,Passif,
132,Réserves immunisés,,Passif,
139,Autres fonds affectés et autres réserves,,Passif,
14,Résultats reportés (+)(-),Bénéfice ou déficit,Actif ou passif,
15,Subsides en capital,,Passif,
16,Provisions et impôts différés,,Passif,
160,Provisions pour pensions et obligations similaires,,Passif,
161,Provisions pour charge fiscales,,Passif,
162,Provisions pour grosses réparations et gros entretiens,,Passif,
163,Provisions pour obligations environnementales,,Passif,
164,Provisions pour autres risques et charge,,Passif,
167,"Provisions pour remboursement de subsides, legs et dons avec droit de reprise",,Passif,
168,Impôts différés,,Passif,
17,Dettes à plus d'un an,,Passif,
170,Emprunts subordonnés,,Passif,
171,Emprunts obligataires non subordonnés,,Passif,
172,Dettes de location-financement et dettes assimilées,,Passif,
173,Établissements de crédit,,Passif,
1730,Dettes en comptes,,Passif,
1731,Promesses,,Passif,
1732,Crédits d'acceptation,,Passif,
174,Autres emprunts,,Passif,
175,Dettes commerciales,,Passif,
1750,Fournisseurs,,Passif,
1751,Effets à payer,,Passif,
176,Acomptes sur commandes,,Passif,
178,Cautionnements en numéraire,,Passif,
179,Autres dettes,,Passif,
1790,Productives dintérêts,,Passif,
1791,Non productives dintérêts ou assorties dun intérêt anormalement faible,,Passif,
2,"FRAIS DÉTABLISSEMENT, ACTIFS IMMOBILISÉS ET CRÉANCES À PLUS DUN AN",,Actif,
20,Frais d'établissement,,Actif,
200,Frais de constitution,,Actif,
201,Frais d'émission d'emprunt,,Actif,
202,Autres frais d'établissement,,Actif,
204,Frais de restructuration,,Actif,
21,Immobilisations incorporelles,Actifs immobilisés,Actif,
210,Frais de recherche et de développement,,Actif,
211,"Concessions, brevets, licences, savoir-faire, marques et droits similaires",,Actif,
212,Goodwill,,Actif,
213,Acomptes versés,,Actif,
22,Terrains et constructions,,Actif,
220,Terrains,,Actif,
221,Constructions,,Actif,
222,Terrains bâtis,,Actif,
223,Autres droits réels sur des immeubles,,Actif,
23,"Installations, machines et outillage ",,Actif,
24,Mobilier et matériel roulant,,Actif,
25,Immobilisations détenues en location-financement et droits similaires,,Actif,
250,Terrains et construction,,Actif,
251,"Installations, machines et outillage",,Actif,
252,Mobilier et matériel roulant,,Actif,
26,Autres immobilisations corporelles,,Actif,
27,Immobilisations corporelles en cours et acomptes versés,,Actif,
28,Immobilisations financières,,Actif,
280,Participations dans des sociétés liées,,Actif,
2800,Valeur d'acquisition,,Actif,
2801,Montants non appelés,,Actif,
2808,Plus-values actées,,Actif,
2809,Réductions de valeur actées,,Actif,
281,Créances sur des entités liées,,Actif,
2810,Créances en compte,,Actif,
2811,Effets à recevoir,,Actif,
2812,Titres à revenu fixe,,Actif,
2817,Créances douteuses,,Actif,
2819,Réductions de valeurs actées,,Actif,
282,Participations dans des sociétés avec lesquelles il existe un lien de participation,,Actif,
2820,Valeur d'acquisition,,Actif,
2821,Montants non appelés,,Actif,
2828,Plus-values actées,,Actif,
2829,Réductions de valeurs actées,,Actif,
283,Créances sur des sociétés avec lesquelles il existe un lien de participation,,Actif,
2830,Créances en compte,,Actif,
2831,Effets à recevoir,,Actif,
2832,Titres à revenu fixe,,Actif,
2837,Créances douteuses,,Actif,
2839,Réductions de valeurs actées,,Actif,
284,Autres actions et parts,,Actif,
2840,Valeur d'acquisition,,Actif,
2841,Montants non appelés,,Actif,
2848,Plus-values actées,,Actif,
2849,Réductions de valeurs actées,,Actif,
285,Autres créances,,Actif,
2850,Créances en compte,,Actif,
2851,Effets à recevoir,,Actif,
2852,Titres à revenu fixe,,Actif,
2857,Créances douteuses,,Actif,
2859,Réductions de valeurs actées,,Actif,
288,Cautionnements versés en numéraire,,Actif,
29,Créances à plus d'un an,,Actif,
290,Créances commerciales,,Actif,
2900,Clients,,Actif,
2901,Effets à recevoir,,Actif,
2906,Acomptes versés,,Actif,
2907,Créances douteuses,,Actif,
2909,Réductions de valeurs actées,,Actif,
291,Autres créances,,Actif,
2910,Créances en compte,,Actif,
2911,Effets à recevoir,,Actif,
2912,Subsides à recevoir,,Actif,
2915,Créances non productives dintérêts ou assorties dun intérêt anormalement faible,,Actif,
2916,Créances douteuses,,Actif,
2919,Réductions de valeurs actées,,Actif,
3,STOCKS ET COMMANDES EN COURS D'EXÉCUTION,,Actif,
30,Matières premières,,Actif,
300,Valeur d'acquisition,,Actif,
309,Réductions de valeur actées,,Actif,
31,Fournitures,,Actif,
310,Valeur d'acquisition,,Actif,
319,Réductions de valeur actées,,Actif,
32,En-cours de fabrication,,Actif,
320,Valeur d'acquisition,,Actif,
329,Réductions de valeur actées,,Actif,
33,Produit finis,,Actif,
330,Valeur d'acquisition,,Actif,
339,Réductions de valeur actées,,Actif,
34,Marchandises,,Actif,
340,Valeur d'acquisition,,Actif,
349,Réductions de valeur actées,,Actif,
35,Immeubles destinés a la vente,,Actif,
350,Valeur d'acquisition,,Actif,
359,Réductions de valeur actées,,Actif,
36,Acomptes versés sur achats pour stocks,,Actif,
360,Acomptes versés,,Actif,
369,Réductions de valeur actées,,Actif,
37,Commandes en cours d'exécution,,Actif,
370,Valeur d'acquisition,,Actif,
371,Bénéfice pris en compte,,Actif,
379,Réductions de valeur actées,,Actif,
4,CRÉANCES ET DETTES À UN AN AU PLUS,,Passif,
40,Créances commerciales,,Passif,
400,Clients,,Passif,
401,Effets à recevoir,,Passif,
404,Produit à recevoir,,Passif,
406,Acomptes versés,,Passif,
407,Créances douteuses,,Passif,
409,Réductions de valeurs actées,,Passif,
41,Autres créances,,Passif,
410,Autres tiers,,Passif,
411,Tva à récupérer,,Passif,
412,Impôts et précomptes à récupérer,,Passif,
4120,4120 à 4124,,Passif,
4125,4125 à 4127 Autres impôts et taxes belges,,Passif,
4128,Impôts et taxes étrangers,,Passif,
413,Subsides à recevoir,,Passif,
414,Produit à recevoir,,Passif,
415,Créances non productives dintérêts ou assorties dun intérêt anormalement faible,,Passif,
416,Créances diverses,,Passif,
417,Créances douteuses,,Passif,
418,Cautionnements versés en numéraire,,Passif,
419,Réductions de valeurs actées,,Passif,
42,Dettes à plus d'un an échéant dans l'année (même subdivision que le compte 17),,Passif,
43,Dettes financières,,Passif,
430,Établissements de crédit Emprunts en compte à terme fixe,,Passif,
431,Établissements de crédit Promesses,,Passif,
432,Établissements de crédit Crédits d'acceptation,,Passif,
433,Établissements de crédit Dettes en compte courant,,Passif,
439,Autres emprunts,,Passif,
44,Dettes commerciales,,Passif,
440,Fournisseurs,,Passif,
441,Effets à payer,,Passif,
444,Factures à recevoir,,Passif,
45,"Dettes fiscales, salariales et sociales",,Passif,
450,Dettes fiscales estimées,,Passif,
4505, à 4507 Autres impôts et taxes belges,,Passif,
4508,Impôts et taxes étrangers,,Passif,
451,Tva à payer,,Passif,
452,Impôts et taxes à payer,,Passif,
4525,Autres impôts et taxes belges,,Passif,
4528,Impôts et taxes étrangers,,Passif,
453,Précomptes retenus,,Passif,
454,Office national de la Sécurité sociale,,Passif,
455,Rémunérations,,Passif,
456,Pécules de vacances,,Passif,
459,Autres dettes sociales,,Passif,
46,Acomptes sur commandes,,Passif,
48,Dettes diverses,,Passif,
480,Obligations et coupons échus,,Passif,
483,Subsides à rembourser,,Passif,
488,Cautionnements reçus en numéraire,,Passif,
489,Autres dettes diverses,,Passif,
4890,Productives dintérêts,,Passif,
4891,Non productives dintérêts ou assorties dun intérêt anormalement faible,,Passif,
49,Comptes de régularisation et d'attente,,Actif,
490,Charge à reporter,,Actif,
491,Produit acquis,,Actif,
492,Charge à imputer,,Passif,
493,Produit à reporter,,Passif,
4931,Produit à reporter (créditeur),,Passif,
4932,Produit à reporter (débiteur),,Actif,
499,Comptes d'attente,,Passif,
5,PLACEMENTS DE TRÉSORERIE ET VALEURS DISPONIBLES,,Actif,
50,"Placements de trésorerie autres que actions et parts, titres à revenu fixe et dépôts à terme",,Actif,
500,Valeur d'acquisition,,Actif,
509,Réductions de valeurs actées,,Actif,
51,Actions et parts,,Actif,
510,Valeur d'acquisition,,Actif,
511,Montants non appelés,,Actif,
519,Réductions de valeur actées,,Actif,
52,Titres à revenu fixe,,Actif,
520,Valeur d'acquisition,,Actif,
529,Réductions de valeurs actées,,Actif,
53,Dépôts à terme,,Actif,
530,De plus d'un an,,Actif,
531,De plus d'un mois et à un an au plus,,Actif,
532,D'un mois au plus,,Actif,
539,Réductions de valeur actées,,Actif,
54,Valeurs échues à l'encaissement,,Actif,
55,Établissements de crédit,,Actif,
56,Comptes bancaires,,Actif,Favori
57,Caisses,,Actif,
570,Caisses-espèces,,Actif,Favori
578,Caisses-timbres,,Actif,
58,Virements internes,,Actif,
6,CHARGES,,Charge,
60,Approvisionnements et marchandises,,Charge,
600,Achats de matières premières,,Charge,Favori
601,Achats de fournitures,,Charge,Favori
602,"Achats de services, travaux et études",,Charge,Favori
603,Sous-traitances générales,,Charge,Favori
604,Achats de marchandises,,Charge,Favori
605,Achats d'immeubles destinés à la vente,,Charge,
608,"Remises, ristournes et rabais obtenus",,Charge,
609,Variation des stocks,,Charge,
6090,de matières premières,,Charge,
6091,de fournitures,,Charge,
6094,de marchandises,,Charge,
6095,d'immeubles destinés à la vente,,Charge,
61,Services et biens divers,,Charge,Favori
617,Personnel intérimaire et personnes mises à  la disposition de lassociation ou de la fondation,,Charge,
618,"Rémunérations, primes pour assurances extralégales, pensions de retraite et de survie des administrateurs qui ne sont pas attribuées en vertu d'un contrat de travail",,Charge,
62,"Rémunérations, charges sociales et pensions",,Charge,
620,Rémunérations et avantages sociaux directs,,Charge,Favori
6200,Administrateurs ou gérants,,Charge,
6201,Personnel de direction,,Charge,
6202,Employés,,Charge,
6203,Ouvriers,,Charge,
6204,Autres membres du personnel,,Charge,
621,Cotisations patronales pour assurances sociales,,Charge,
622,Primes patronales pour assurances extra-légales,,Charge,
623,Autres frais du personnel,,Charge,
624,Pensions de retraite et de survie,,Charge,
6240,Administrateurs ou gérants (27),,Charge,
6241,Personnel,,Charge,
63,"Amortissements, réductions de valeur et provisions pour risques et charges",,Charge,
630,Dotations aux amortissements et aux réductions de valeur sur immobilisations,,Charge,
6300,Dotations aux amortissements sur frais d'établissement,,Charge,
6301,Dotation aux amortissements sur immobilisations incorporelles,,Charge,
6302,Dotation aux amortissements sur immobilisations corporelles,,Charge,
6308,Dotation aux réductions de valeurs sur immobilisations incorporelles,,Charge,
6309,Dotation aux réductions de valeurs sur immobilisations corporelles,,Charge,
631,Réductions de valeur sur stocks,,Charge,
6310,Dotations,,Charge,
6311,Reprises,,Charge,
632,Réductions de valeur sur commandes en cours d'exécution,,Charge,
6320,Dotations,,Charge,
6321,Reprises,,Charge,
633,Réductions de valeur sur créances commerciales à plus d'un an,,Charge,
6330,Dotations,,Charge,
6331,Reprises,,Charge,
634,Réductions de valeur sur créances à un an au plus,,Charge,
6340,Dotations,,Charge,
6341,Reprises,,Charge,
635,Provisions pour pensions et obligations similaires,,Charge,
6350,Dotations,,Charge,
6351,Utilisations et reprises,,Charge,
636,Provisions pour grosses réparations et gros entretiens,,Charge,
6360,Dotations,,Charge,
6361,Utilisations et reprises,,Charge,
637,Provisions pour obligations environnementales,,Charge,
6370,Dotations,,Charge,
6371,Utilisations et reprises,,Charge,
638,Provisions pour subsides et legs à rembourser et pour dons avec droit de reprise,,Charge,
6380,Dotations,,Charge,
6381,Utilisations et reprises,,Charge,
639,Provisions pour autres risques et charges,,Charge,
6390,Dotations,,Charge,
6391,Utilisations et reprises,,Charge,
64,Autres charges d'exploitation,,Charge,
640,Charges fiscales,,Charge,
641,Moins-values sur réalisations courantes d'immobilisations corporelles,,Charge,
642,Moins-values sur réalisations de créances commerciales,,Charge,
643,Dons,,Charge,
644,644-648 Charges d'exploitations diverses,À subdiviser,Charge,
649,Charges d'exploitation portées à l'actif au titre de frais de restructuration (),,Charge,
65,Charges financières,,Charge,
650,Charges des dettes,,Charge,
6500,"Intérêts, commissions et frais afférents aux dettes",,Charge,
6501,Amortissements frais d'émission d'emprunts et des primes de remboursement,,Charge,
6502,Intérêts intercalaires portés à l'actif,,Charge,
651,Réductions de valeur sur actifs circulants,,Charge,
6510,Dotations,,Charge,
6511,Reprises,,Charge,
652,Moins-values sur réalisation d'actifs circulants,,Charge,
653,Charges d'escompte de créances,,Charge,
654,Différences de change,,Charge,
655,Écarts de conversion des devises,,Charge,
656,Provisions à caractère financier,,Charge,
6560,Dotations,,Charge,
6561,Utilisations et reprises,,Charge,
657,Charges financières diverses,À subdiviser,Charge,
659,Charges financières portées à l'actif au titre de frais de restructuration,,Charge,
66,Charges dexploitation ou financières non récurrentes,,Charge,
660,Amortissements et réductions de valeur non récurrents (dotations),,Charge,
6600,sur frais d'établissement,,Charge,
6601,sur immobilisations incorporelles,,Charge,
6602,sur immobilisations corporelles,,Charge,
661,Réduction de valeur sur immobilisations financières (dotation),,Charge,
662,Provisions pour risques et charges non récurrents,,Charge,
6620,Provisions pour risques et charges dexploitation non récurrents,,Charge,
66200,Dotations,,Charge,
66201,Utilisations,,Charge,
6621,Provisions pour risques et charges financiers non récurrents,,Charge,
66210,Dotations,,Charge,
66211,Utilisation,,Charge,
663,Moins-values sur réalisation d'actifs immobilisés,,Charge,
6630,Moins-values sur réalisation d'immobilisations incorporelles et corporelles,,Charge,
6631,Moins-values sur réalisations d'actifs immobilisés,,Charge,
664,664 à 667 Autres charges d'exploitation non récurrentes,À subdiviser,Charge,
668,Autres charges financières non récurrentes,,Charge,
6690,Charges dexploitation portées à lactif au titre de frais de restructuration,,Charge,
6691,Charges financières non récurrentes portées à l'actif au titre de frais de restructuration,,Charge,
67,Impôts,,Charge,
670, Impôts belges sur le résultat de lexercice,,Charge,
6701,Excédent de versements d'impôts et de précomptes porté à lactif (),,Charge,
6702, Charges fiscales estimées,,Charge,
6710,Suppléments d'impôts dus ou versés,,Charge,
6711, Suppléments d'impôts estimés,,Charge,
6712,Provisions fiscales constituées," Impôts étrangers sur le résultat de lexercice, impôts étrangers sur le résultat d'exercices antérieurs",Charge,
68, Transferts aux impôts différés et aux réserves immunisées,,Charge,
680, Transferts aux impôts différés,,Charge,
689,Transferts aux réserves immunisées,,Charge,
69,Affectations et prélèvements,,Charge,
690,Résultat négatif de l'exercice antérieur reporté,,Passif,
691,Transfert aux fonds affectés et autres réserves,,Actif,
692,Résultat positif à reporter,,Actif,
7,PRODUITS,,Produit,
70,Chiffre d'affaires,,Produit,
700,Ventes et prestations de services,,Produit,Favori
708,"Remises, ristournes et rabais accordés",,Produit,
71,Variation des stocks et des commandes en cours dexécution,,Produit,
712,Des en-cours de fabrication,,Produit,Favori
713,Des produits finis,,Produit,Favori
715,Des immeubles construits destinés à la vente,,Produit,
717,Des commandes en cours d'exécution,,Produit,
7170,Valeur d'acquisition,,Produit,
7171,Bénéfice pris en compte,,Produit,
72,Production immobilisée,,Produit,
73,"Cotisations, dons, legs et subsides",,Produit,Favori
730,Cotisations,,Produit,Favori
731,Dons,,Produit,Favori
732,Legs,,Produit,Favori
733,Subsides,,Produit,Favori
74,Autres produits dexploitation,,Produit,Favori
741,Plus-values sur réalisations courantes d'immobilisations corporelles,,Produit,
742,Plus-values sur réalisation de créances commerciales,,Produit,
743,743-749 Produits d'exploitation divers,À subdiviser,Produit,
75,Produits financiers,,Produit,Favori
750,Produits des immobilisations financières,,Produit,
751,Produits des actifs circulants,,Produit,
752,Plus-values sur la réalisation d'actifs circulants,,Produit,
753,(libellé vide dans la version officielle),,Produit,
754,Différences de change,,Produit,
755,Écarts de conversion des devises,,Produit,
756,756-759 Produits financiers divers,À subdiviser,Produit,
76,Produits d'exploitation ou financiers non récurrents,,Produit,
760,Reprise d'amortissements et réductions de valeur,,Produit,
7600,Reprise sur immobilisations incorporelles,,Produit,
7601,Reprise sur immobilisations corporelles,,Produit,
761,Reprises de réductions de valeur sur immobilisations financières,,Produit,
762,Reprises de provisions pour risques et charges non récurrents,,Produit,
7620,Reprises de provisions pour risques et charges dexploitation non récurrents,,Produit,
7621,Reprises de provisions pour risques et charges financiers non récurrents,,Produit,
763,Plus-values sur réalisation d'actifs immobilisés,,Produit,
7630,Plus-values sur réalisation d'immobilisations incorporelles et corporelles,,Produit,
7631,Plus-values sur réalisations d'actifs immobilisés,,Produit,
764,764-768 Autres produits dexploitation non récurrents,À subdiviser,Produit,
769,Autres produits financiers non récurrents,,Produit,
77,Régularisation d'impôts,,Produit,
78,Prélèvement sur les réserves immunisées et les impôts différés,,Produit,
780,Prélèvement sur les impôts différés,,Produit,
789,Prélèvement sur les réserves immunisées,,Produit,
79,Affectations et prélèvements,,Produit,
790,Résultat positif de l'exercice antérieur reporté,Résultat excédentaire,Produit,
791,Autres réserves,,Produit,
792,Résultat négatif à reporter,Résultat déficitaire,Charge,
890,Ouverture,,,
891,Clôture,,,
0,DROITS ET ENGAGEMENTS HORS BILAN,Sont portés dans les comptes de la classe 0 les droits et engagements autres que ceux qui doivent être portés dans les comptes des classes 1 à 5.,,
00,Garanties constituées par des tiers pour compte de lassociation ou de la fondation,,,
000,"Créanciers de l'association ou de la fondation, bénéficiaires de garanties de tiers",,,
001,Tiers constituants de garanties pour compte de lassociation ou de la fondation,,,
01,Garanties personnelles pour compte de tiers,,,
010,Débiteurs pour engagements sur effets en circulation,,,
011,Créanciers d'engagements sur effets en circulation,,,
0110,Effets cédés par lassociation ou la fondation sous son endos,,,
0111,Autres engagements sur effets en circulation,,,
012,Débiteurs pour autres garanties personnelles,,,
013,Créanciers d'autres garanties personnelles,,,
02,Garanties réelles constituées sur avoirs propres,,,
020,"Créanciers de l'association ou de la fondation, bénéficiaires de garanties réelles",,,
021,Garanties réelles constituées pour compte propre,,,
022,"Créanciers de tiers, bénéficiaires de garanties réelles",,,
023,Garanties réelles constituées pour compte de tiers,,,
03,Garanties reçues,,,
032,Garanties reçues,,,
033,Constituants de garanties,,,
04,Biens et valeurs détenus par des tiers en leur nom mais aux risques et profits de lassociation ou de la fondation,,,
040,"Tiers, détenteurs en leur nom mais aux risques et profits de l'association ou de la fondation de biens et de valeurs",,,
041,Biens et valeurs détenus par des tiers en leur nom mais aux risques et profits de lassociation ou de la fondation,,,
05,Engagements d'acquisition et de cession dimmobilisations,,,
050,Engagements d'acquisition,,,
051,Créanciers d'engagements d'acquisition,,,
052,Débiteurs pour engagements de cession,,,
053,Engagements de cession,,,
06,Marchés à terme,,,
060,Marchandises achetées à terme - à recevoir,,,
061,Créanciers pour marchandises achetées à terme,,,
062,Débiteurs pour marchandises vendues à terme,,,
063,Marchandises vendues à terme - à livrer,,,
064,Devises achetées à terme - à recevoir,,,
065,Créanciers pour devises achetées à terme,,,
066,Débiteurs pour devises vendues à terme,,,
067,Devises vendues à terme - à livrer,,,
07,Biens et valeurs de tiers détenus par l'association ou la fondation,,,
070,Droits d'usage à long terme,,,
0700,Sur terrains et constructions,,,
0701,"Sur installations, machines et outillage",,,
0702,Sur mobilier et matériel roulant,,,
071,Créanciers de loyers et redevances,,,
072,"Biens et valeurs de tiers reçus en dépôt, en consignation ou à façon",,,
073,Commettants et déposants de biens et de valeurs,,,
074,Biens et valeurs détenus pour compte ou aux risques et profits de tiers,,,
075,Créanciers de biens et valeurs détenus pour compte de tiers ou à leurs risques et profits,,,
09,Droits et engagements divers,,,
1 code label description position bookmark
2 1 FONDS SOCIAL, PROVISIONS POUR RISQUES ET CHARGE ET DETTES À PLUS D’UN AN Passif
3 10 Fonds de l’association ou de la fondation Passif
4 12 Plus-values de réévaluation Passif
5 120 Plus-values de réévaluation sur immobilisations incorporelles Passif
6 121 Plus-values de réévaluation sur immobilisations corporelles Passif
7 122 Plus-values de réévaluation sur immobilisations financières Passif
8 124 Reprises de réductions de valeurs sur placements de trésorerie Passif
9 13 Fonds affectés et autres réserves Passif
10 130 Fonds affectés pour investissements Passif
11 131 Fonds affectés pour passif social Passif
12 132 Réserves immunisés Passif
13 139 Autres fonds affectés et autres réserves Passif
14 14 Résultats reportés (+)(-) Bénéfice ou déficit Actif ou passif
15 15 Subsides en capital Passif
16 16 Provisions et impôts différés Passif
17 160 Provisions pour pensions et obligations similaires Passif
18 161 Provisions pour charge fiscales Passif
19 162 Provisions pour grosses réparations et gros entretiens Passif
20 163 Provisions pour obligations environnementales Passif
21 164 Provisions pour autres risques et charge Passif
22 167 Provisions pour remboursement de subsides, legs et dons avec droit de reprise Passif
23 168 Impôts différés Passif
24 17 Dettes à plus d'un an Passif
25 170 Emprunts subordonnés Passif
26 171 Emprunts obligataires non subordonnés Passif
27 172 Dettes de location-financement et dettes assimilées Passif
28 173 Établissements de crédit Passif
29 1730 Dettes en comptes Passif
30 1731 Promesses Passif
31 1732 Crédits d'acceptation Passif
32 174 Autres emprunts Passif
33 175 Dettes commerciales Passif
34 1750 Fournisseurs Passif
35 1751 Effets à payer Passif
36 176 Acomptes sur commandes Passif
37 178 Cautionnements en numéraire Passif
38 179 Autres dettes Passif
39 1790 Productives d’intérêts Passif
40 1791 Non productives d’intérêts ou assorties d’un intérêt anormalement faible Passif
41 2 FRAIS D’ÉTABLISSEMENT, ACTIFS IMMOBILISÉS ET CRÉANCES À PLUS D’UN AN Actif
42 20 Frais d'établissement Actif
43 200 Frais de constitution Actif
44 201 Frais d'émission d'emprunt Actif
45 202 Autres frais d'établissement Actif
46 204 Frais de restructuration Actif
47 21 Immobilisations incorporelles Actifs immobilisés Actif
48 210 Frais de recherche et de développement Actif
49 211 Concessions, brevets, licences, savoir-faire, marques et droits similaires Actif
50 212 Goodwill Actif
51 213 Acomptes versés Actif
52 22 Terrains et constructions Actif
53 220 Terrains Actif
54 221 Constructions Actif
55 222 Terrains bâtis Actif
56 223 Autres droits réels sur des immeubles Actif
57 23 Installations, machines et outillage Actif
58 24 Mobilier et matériel roulant Actif
59 25 Immobilisations détenues en location-financement et droits similaires Actif
60 250 Terrains et construction Actif
61 251 Installations, machines et outillage Actif
62 252 Mobilier et matériel roulant Actif
63 26 Autres immobilisations corporelles Actif
64 27 Immobilisations corporelles en cours et acomptes versés Actif
65 28 Immobilisations financières Actif
66 280 Participations dans des sociétés liées Actif
67 2800 Valeur d'acquisition Actif
68 2801 Montants non appelés Actif
69 2808 Plus-values actées Actif
70 2809 Réductions de valeur actées Actif
71 281 Créances sur des entités liées Actif
72 2810 Créances en compte Actif
73 2811 Effets à recevoir Actif
74 2812 Titres à revenu fixe Actif
75 2817 Créances douteuses Actif
76 2819 Réductions de valeurs actées Actif
77 282 Participations dans des sociétés avec lesquelles il existe un lien de participation Actif
78 2820 Valeur d'acquisition Actif
79 2821 Montants non appelés Actif
80 2828 Plus-values actées Actif
81 2829 Réductions de valeurs actées Actif
82 283 Créances sur des sociétés avec lesquelles il existe un lien de participation Actif
83 2830 Créances en compte Actif
84 2831 Effets à recevoir Actif
85 2832 Titres à revenu fixe Actif
86 2837 Créances douteuses Actif
87 2839 Réductions de valeurs actées Actif
88 284 Autres actions et parts Actif
89 2840 Valeur d'acquisition Actif
90 2841 Montants non appelés Actif
91 2848 Plus-values actées Actif
92 2849 Réductions de valeurs actées Actif
93 285 Autres créances Actif
94 2850 Créances en compte Actif
95 2851 Effets à recevoir Actif
96 2852 Titres à revenu fixe Actif
97 2857 Créances douteuses Actif
98 2859 Réductions de valeurs actées Actif
99 288 Cautionnements versés en numéraire Actif
100 29 Créances à plus d'un an Actif
101 290 Créances commerciales Actif
102 2900 Clients Actif
103 2901 Effets à recevoir Actif
104 2906 Acomptes versés Actif
105 2907 Créances douteuses Actif
106 2909 Réductions de valeurs actées Actif
107 291 Autres créances Actif
108 2910 Créances en compte Actif
109 2911 Effets à recevoir Actif
110 2912 Subsides à recevoir Actif
111 2915 Créances non productives d’intérêts ou assorties d’un intérêt anormalement faible Actif
112 2916 Créances douteuses Actif
113 2919 Réductions de valeurs actées Actif
114 3 STOCKS ET COMMANDES EN COURS D'EXÉCUTION Actif
115 30 Matières premières Actif
116 300 Valeur d'acquisition Actif
117 309 Réductions de valeur actées Actif
118 31 Fournitures Actif
119 310 Valeur d'acquisition Actif
120 319 Réductions de valeur actées Actif
121 32 En-cours de fabrication Actif
122 320 Valeur d'acquisition Actif
123 329 Réductions de valeur actées Actif
124 33 Produit finis Actif
125 330 Valeur d'acquisition Actif
126 339 Réductions de valeur actées Actif
127 34 Marchandises Actif
128 340 Valeur d'acquisition Actif
129 349 Réductions de valeur actées Actif
130 35 Immeubles destinés a la vente Actif
131 350 Valeur d'acquisition Actif
132 359 Réductions de valeur actées Actif
133 36 Acomptes versés sur achats pour stocks Actif
134 360 Acomptes versés Actif
135 369 Réductions de valeur actées Actif
136 37 Commandes en cours d'exécution Actif
137 370 Valeur d'acquisition Actif
138 371 Bénéfice pris en compte Actif
139 379 Réductions de valeur actées Actif
140 4 CRÉANCES ET DETTES À UN AN AU PLUS Passif
141 40 Créances commerciales Passif
142 400 Clients Passif
143 401 Effets à recevoir Passif
144 404 Produit à recevoir Passif
145 406 Acomptes versés Passif
146 407 Créances douteuses Passif
147 409 Réductions de valeurs actées Passif
148 41 Autres créances Passif
149 410 Autres tiers Passif
150 411 Tva à récupérer Passif
151 412 Impôts et précomptes à récupérer Passif
152 4120 4120 à 4124 Passif
153 4125 4125 à 4127 Autres impôts et taxes belges Passif
154 4128 Impôts et taxes étrangers Passif
155 413 Subsides à recevoir Passif
156 414 Produit à recevoir Passif
157 415 Créances non productives d’intérêts ou assorties d’un intérêt anormalement faible Passif
158 416 Créances diverses Passif
159 417 Créances douteuses Passif
160 418 Cautionnements versés en numéraire Passif
161 419 Réductions de valeurs actées Passif
162 42 Dettes à plus d'un an échéant dans l'année (même subdivision que le compte 17) Passif
163 43 Dettes financières Passif
164 430 Établissements de crédit – Emprunts en compte à terme fixe Passif
165 431 Établissements de crédit – Promesses Passif
166 432 Établissements de crédit – Crédits d'acceptation Passif
167 433 Établissements de crédit – Dettes en compte courant Passif
168 439 Autres emprunts Passif
169 44 Dettes commerciales Passif
170 440 Fournisseurs Passif
171 441 Effets à payer Passif
172 444 Factures à recevoir Passif
173 45 Dettes fiscales, salariales et sociales Passif
174 450 Dettes fiscales estimées Passif
175 4505 à 4507 Autres impôts et taxes belges Passif
176 4508 Impôts et taxes étrangers Passif
177 451 Tva à payer Passif
178 452 Impôts et taxes à payer Passif
179 4525 Autres impôts et taxes belges Passif
180 4528 Impôts et taxes étrangers Passif
181 453 Précomptes retenus Passif
182 454 Office national de la Sécurité sociale Passif
183 455 Rémunérations Passif
184 456 Pécules de vacances Passif
185 459 Autres dettes sociales Passif
186 46 Acomptes sur commandes Passif
187 48 Dettes diverses Passif
188 480 Obligations et coupons échus Passif
189 483 Subsides à rembourser Passif
190 488 Cautionnements reçus en numéraire Passif
191 489 Autres dettes diverses Passif
192 4890 Productives d’intérêts Passif
193 4891 Non productives d’intérêts ou assorties d’un intérêt anormalement faible Passif
194 49 Comptes de régularisation et d'attente Actif
195 490 Charge à reporter Actif
196 491 Produit acquis Actif
197 492 Charge à imputer Passif
198 493 Produit à reporter Passif
199 4931 Produit à reporter (créditeur) Passif
200 4932 Produit à reporter (débiteur) Actif
201 499 Comptes d'attente Passif
202 5 PLACEMENTS DE TRÉSORERIE ET VALEURS DISPONIBLES Actif
203 50 Placements de trésorerie autres que actions et parts, titres à revenu fixe et dépôts à terme Actif
204 500 Valeur d'acquisition Actif
205 509 Réductions de valeurs actées Actif
206 51 Actions et parts Actif
207 510 Valeur d'acquisition Actif
208 511 Montants non appelés Actif
209 519 Réductions de valeur actées Actif
210 52 Titres à revenu fixe Actif
211 520 Valeur d'acquisition Actif
212 529 Réductions de valeurs actées Actif
213 53 Dépôts à terme Actif
214 530 De plus d'un an Actif
215 531 De plus d'un mois et à un an au plus Actif
216 532 D'un mois au plus Actif
217 539 Réductions de valeur actées Actif
218 54 Valeurs échues à l'encaissement Actif
219 55 Établissements de crédit Actif
220 56 Comptes bancaires Actif Favori
221 57 Caisses Actif
222 570 Caisses-espèces Actif Favori
223 578 Caisses-timbres Actif
224 58 Virements internes Actif
225 6 CHARGES Charge
226 60 Approvisionnements et marchandises Charge
227 600 Achats de matières premières Charge Favori
228 601 Achats de fournitures Charge Favori
229 602 Achats de services, travaux et études Charge Favori
230 603 Sous-traitances générales Charge Favori
231 604 Achats de marchandises Charge Favori
232 605 Achats d'immeubles destinés à la vente Charge
233 608 Remises, ristournes et rabais obtenus Charge
234 609 Variation des stocks Charge
235 6090 de matières premières Charge
236 6091 de fournitures Charge
237 6094 de marchandises Charge
238 6095 d'immeubles destinés à la vente Charge
239 61 Services et biens divers Charge Favori
240 617 Personnel intérimaire et personnes mises à  la disposition de l’association ou de la fondation Charge
241 618 Rémunérations, primes pour assurances extralégales, pensions de retraite et de survie des administrateurs qui ne sont pas attribuées en vertu d'un contrat de travail Charge
242 62 Rémunérations, charges sociales et pensions Charge
243 620 Rémunérations et avantages sociaux directs Charge Favori
244 6200 Administrateurs ou gérants Charge
245 6201 Personnel de direction Charge
246 6202 Employés Charge
247 6203 Ouvriers Charge
248 6204 Autres membres du personnel Charge
249 621 Cotisations patronales pour assurances sociales Charge
250 622 Primes patronales pour assurances extra-légales Charge
251 623 Autres frais du personnel Charge
252 624 Pensions de retraite et de survie Charge
253 6240 Administrateurs ou gérants (27) Charge
254 6241 Personnel Charge
255 63 Amortissements, réductions de valeur et provisions pour risques et charges Charge
256 630 Dotations aux amortissements et aux réductions de valeur sur immobilisations Charge
257 6300 Dotations aux amortissements sur frais d'établissement Charge
258 6301 Dotation aux amortissements sur immobilisations incorporelles Charge
259 6302 Dotation aux amortissements sur immobilisations corporelles Charge
260 6308 Dotation aux réductions de valeurs sur immobilisations incorporelles Charge
261 6309 Dotation aux réductions de valeurs sur immobilisations corporelles Charge
262 631 Réductions de valeur sur stocks Charge
263 6310 Dotations Charge
264 6311 Reprises Charge
265 632 Réductions de valeur sur commandes en cours d'exécution Charge
266 6320 Dotations Charge
267 6321 Reprises Charge
268 633 Réductions de valeur sur créances commerciales à plus d'un an Charge
269 6330 Dotations Charge
270 6331 Reprises Charge
271 634 Réductions de valeur sur créances à un an au plus Charge
272 6340 Dotations Charge
273 6341 Reprises Charge
274 635 Provisions pour pensions et obligations similaires Charge
275 6350 Dotations Charge
276 6351 Utilisations et reprises Charge
277 636 Provisions pour grosses réparations et gros entretiens Charge
278 6360 Dotations Charge
279 6361 Utilisations et reprises Charge
280 637 Provisions pour obligations environnementales Charge
281 6370 Dotations Charge
282 6371 Utilisations et reprises Charge
283 638 Provisions pour subsides et legs à rembourser et pour dons avec droit de reprise Charge
284 6380 Dotations Charge
285 6381 Utilisations et reprises Charge
286 639 Provisions pour autres risques et charges Charge
287 6390 Dotations Charge
288 6391 Utilisations et reprises Charge
289 64 Autres charges d'exploitation Charge
290 640 Charges fiscales Charge
291 641 Moins-values sur réalisations courantes d'immobilisations corporelles Charge
292 642 Moins-values sur réalisations de créances commerciales Charge
293 643 Dons Charge
294 644 644-648 Charges d'exploitations diverses À subdiviser Charge
295 649 Charges d'exploitation portées à l'actif au titre de frais de restructuration (–) Charge
296 65 Charges financières Charge
297 650 Charges des dettes Charge
298 6500 Intérêts, commissions et frais afférents aux dettes Charge
299 6501 Amortissements frais d'émission d'emprunts et des primes de remboursement Charge
300 6502 Intérêts intercalaires portés à l'actif Charge
301 651 Réductions de valeur sur actifs circulants Charge
302 6510 Dotations Charge
303 6511 Reprises Charge
304 652 Moins-values sur réalisation d'actifs circulants Charge
305 653 Charges d'escompte de créances Charge
306 654 Différences de change Charge
307 655 Écarts de conversion des devises Charge
308 656 Provisions à caractère financier Charge
309 6560 Dotations Charge
310 6561 Utilisations et reprises Charge
311 657 Charges financières diverses À subdiviser Charge
312 659 Charges financières portées à l'actif au titre de frais de restructuration Charge
313 66 Charges d’exploitation ou financières non récurrentes Charge
314 660 Amortissements et réductions de valeur non récurrents (dotations) Charge
315 6600 sur frais d'établissement Charge
316 6601 sur immobilisations incorporelles Charge
317 6602 sur immobilisations corporelles Charge
318 661 Réduction de valeur sur immobilisations financières (dotation) Charge
319 662 Provisions pour risques et charges non récurrents Charge
320 6620 Provisions pour risques et charges d’exploitation non récurrents Charge
321 66200 Dotations Charge
322 66201 Utilisations Charge
323 6621 Provisions pour risques et charges financiers non récurrents Charge
324 66210 Dotations Charge
325 66211 Utilisation Charge
326 663 Moins-values sur réalisation d'actifs immobilisés Charge
327 6630 Moins-values sur réalisation d'immobilisations incorporelles et corporelles Charge
328 6631 Moins-values sur réalisations d'actifs immobilisés Charge
329 664 664 à 667 Autres charges d'exploitation non récurrentes À subdiviser Charge
330 668 Autres charges financières non récurrentes Charge
331 6690 Charges d’exploitation portées à l’actif au titre de frais de restructuration Charge
332 6691 Charges financières non récurrentes portées à l'actif au titre de frais de restructuration Charge
333 67 Impôts Charge
334 670 Impôts belges sur le résultat de l’exercice Charge
335 6701 Excédent de versements d'impôts et de précomptes porté à l’actif (–) Charge
336 6702 Charges fiscales estimées Charge
337 6710 Suppléments d'impôts dus ou versés Charge
338 6711 Suppléments d'impôts estimés Charge
339 6712 Provisions fiscales constituées Impôts étrangers sur le résultat de l’exercice, impôts étrangers sur le résultat d'exercices antérieurs Charge
340 68 Transferts aux impôts différés et aux réserves immunisées Charge
341 680 Transferts aux impôts différés Charge
342 689 Transferts aux réserves immunisées Charge
343 69 Affectations et prélèvements Charge
344 690 Résultat négatif de l'exercice antérieur reporté Passif
345 691 Transfert aux fonds affectés et autres réserves Actif
346 692 Résultat positif à reporter Actif
347 7 PRODUITS Produit
348 70 Chiffre d'affaires Produit
349 700 Ventes et prestations de services Produit Favori
350 708 Remises, ristournes et rabais accordés Produit
351 71 Variation des stocks et des commandes en cours d’exécution Produit
352 712 Des en-cours de fabrication Produit Favori
353 713 Des produits finis Produit Favori
354 715 Des immeubles construits destinés à la vente Produit
355 717 Des commandes en cours d'exécution Produit
356 7170 Valeur d'acquisition Produit
357 7171 Bénéfice pris en compte Produit
358 72 Production immobilisée Produit
359 73 Cotisations, dons, legs et subsides Produit Favori
360 730 Cotisations Produit Favori
361 731 Dons Produit Favori
362 732 Legs Produit Favori
363 733 Subsides Produit Favori
364 74 Autres produits d’exploitation Produit Favori
365 741 Plus-values sur réalisations courantes d'immobilisations corporelles Produit
366 742 Plus-values sur réalisation de créances commerciales Produit
367 743 743-749 Produits d'exploitation divers À subdiviser Produit
368 75 Produits financiers Produit Favori
369 750 Produits des immobilisations financières Produit
370 751 Produits des actifs circulants Produit
371 752 Plus-values sur la réalisation d'actifs circulants Produit
372 753 (libellé vide dans la version officielle) Produit
373 754 Différences de change Produit
374 755 Écarts de conversion des devises Produit
375 756 756-759 Produits financiers divers À subdiviser Produit
376 76 Produits d'exploitation ou financiers non récurrents Produit
377 760 Reprise d'amortissements et réductions de valeur Produit
378 7600 Reprise sur immobilisations incorporelles Produit
379 7601 Reprise sur immobilisations corporelles Produit
380 761 Reprises de réductions de valeur sur immobilisations financières Produit
381 762 Reprises de provisions pour risques et charges non récurrents Produit
382 7620 Reprises de provisions pour risques et charges d’exploitation non récurrents Produit
383 7621 Reprises de provisions pour risques et charges financiers non récurrents Produit
384 763 Plus-values sur réalisation d'actifs immobilisés Produit
385 7630 Plus-values sur réalisation d'immobilisations incorporelles et corporelles Produit
386 7631 Plus-values sur réalisations d'actifs immobilisés Produit
387 764 764-768 Autres produits d’exploitation non récurrents À subdiviser Produit
388 769 Autres produits financiers non récurrents Produit
389 77 Régularisation d'impôts Produit
390 78 Prélèvement sur les réserves immunisées et les impôts différés Produit
391 780 Prélèvement sur les impôts différés Produit
392 789 Prélèvement sur les réserves immunisées Produit
393 79 Affectations et prélèvements Produit
394 790 Résultat positif de l'exercice antérieur reporté Résultat excédentaire Produit
395 791 Autres réserves Produit
396 792 Résultat négatif à reporter Résultat déficitaire Charge
397 890 Ouverture
398 891 Clôture
399 0 DROITS ET ENGAGEMENTS HORS BILAN Sont portés dans les comptes de la classe 0 les droits et engagements autres que ceux qui doivent être portés dans les comptes des classes 1 à 5.
400 00 Garanties constituées par des tiers pour compte de l’association ou de la fondation
401 000 Créanciers de l'association ou de la fondation, bénéficiaires de garanties de tiers
402 001 Tiers constituants de garanties pour compte de l’association ou de la fondation
403 01 Garanties personnelles pour compte de tiers
404 010 Débiteurs pour engagements sur effets en circulation
405 011 Créanciers d'engagements sur effets en circulation
406 0110 Effets cédés par l’association ou la fondation sous son endos
407 0111 Autres engagements sur effets en circulation
408 012 Débiteurs pour autres garanties personnelles
409 013 Créanciers d'autres garanties personnelles
410 02 Garanties réelles constituées sur avoirs propres
411 020 Créanciers de l'association ou de la fondation, bénéficiaires de garanties réelles
412 021 Garanties réelles constituées pour compte propre
413 022 Créanciers de tiers, bénéficiaires de garanties réelles
414 023 Garanties réelles constituées pour compte de tiers
415 03 Garanties reçues
416 032 Garanties reçues
417 033 Constituants de garanties
418 04 Biens et valeurs détenus par des tiers en leur nom mais aux risques et profits de l’association ou de la fondation
419 040 Tiers, détenteurs en leur nom mais aux risques et profits de l'association ou de la fondation de biens et de valeurs
420 041 Biens et valeurs détenus par des tiers en leur nom mais aux risques et profits de l’association ou de la fondation
421 05 Engagements d'acquisition et de cession d’immobilisations
422 050 Engagements d'acquisition
423 051 Créanciers d'engagements d'acquisition
424 052 Débiteurs pour engagements de cession
425 053 Engagements de cession
426 06 Marchés à terme
427 060 Marchandises achetées à terme - à recevoir
428 061 Créanciers pour marchandises achetées à terme
429 062 Débiteurs pour marchandises vendues à terme
430 063 Marchandises vendues à terme - à livrer
431 064 Devises achetées à terme - à recevoir
432 065 Créanciers pour devises achetées à terme
433 066 Débiteurs pour devises vendues à terme
434 067 Devises vendues à terme - à livrer
435 07 Biens et valeurs de tiers détenus par l'association ou la fondation
436 070 Droits d'usage à long terme
437 0700 Sur terrains et constructions
438 0701 Sur installations, machines et outillage
439 0702 Sur mobilier et matériel roulant
440 071 Créanciers de loyers et redevances
441 072 Biens et valeurs de tiers reçus en dépôt, en consignation ou à façon
442 073 Commettants et déposants de biens et de valeurs
443 074 Biens et valeurs détenus pour compte ou aux risques et profits de tiers
444 075 Créanciers de biens et valeurs détenus pour compte de tiers ou à leurs risques et profits
445 09 Droits et engagements divers

View file

@ -0,0 +1,167 @@
Numéro,Libellé,Description,Position,Favori
1,Actifs,,Actif,
10,Liquidités,,Actif,
100,Caisses,,Actif,
1000,Caisse,,Actif,Favori
1005,Caisse Euro,,Actif,Favori
1010,CCP,,Actif,
102,Banques,,Actif,
1020,Compte bancaire,,Actif,Favori
1030,Dépôts à court terme (< 3 mois),,Actif,
109,Comptes dattente,,Actif,
1090,Dépôts en attente,,Actif,Favori
11,Titres cotés en bourse et détenus à court terme,,Actif,
1100,Titres,,Actif,
12,Débiteurs,,Actif,
120,Débiteurs résultant de la vente de biens et de prestations de services,,Actif,
1200,Débiteurs résultant de la vente de biens et de prestations de services,,Actif,
125,Autres débiteurs,,Actif,
1250,Autres débiteurs,,Actif,
13,Stocks,,Actif,
1300,Stocks divers,,Actif,
14,Actifs transitoires (comptes de régularisation dactifs),,Actif,
1400,Impôts anticipés,,Actif,
1410,Produits à recevoir,,Actif,
1420,Charges payées d'avance,,Actif,
15,Immobilisations financières,,Actif,
1500,Cautions loyers,,Actif,
16,Participations,,Actif,
1600,Participations dans dautres entités,,Actif,
17,Immobilisations corporelles,,Actif,
1700,Mobilier,,Actif,
1710,Informatique,,Actif,
18,Immobilisations incorporelles,,Actif,
1800,Licences informatiques,,Actif,
2,Passifs,,Passif,
20,Créanciers,,Passif,
2000,Fournisseurs,,Passif,
2050,Autres dettes à court terme,,Passif,
21,Dettes à court terme liées aux charges de personnel,,Passif,
2100,Créanciers caisse AVS,,Passif,
2110,Créanciers LAA,,Passif,
2120,Créanciers LPP,,Passif,
2130,Créanciers impôt source,,Passif,
2140,Créanciers assurance indemnités journalières maladie,,Passif,
2180,Salaires à payer,,Passif,
22,Dettes financières à court terme,,Passif,
2200,Emprunts bancaires à rembourser dans l'année,,Passif,
23,Passifs transitoires (comptes de régularisation de passifs),,Passif,
2310,Produits constatés d'avance,,Passif,
2320,Charges à payer,,Passif,
24,Dettes à long terme,,Passif,
2400,Emprunts bancaires à rembourser à plus d'une année,,Passif,
2410,Autres dettes à long terme,,Passif,
26,Provisions,,Passif,
28,Fonds affectés (Swiss GAAP RPC),À subdiviser par projet,Passif,
29,Fonds propres,,Passif,
2900,Capital initial versé (ou capital de fondation),,Passif,
2910,Réserve associative,,Passif,
2990,Résultats reportés (fonds libres),,Passif,
2999,Résultat de l'exercice,,Passif,
29991,Résultat positif,,Passif,
29999,Résultat négatif,,Passif,
3,Charges,,Charge,
30,Charges directes de projets,À subdiviser par projet,Charge,
31,Charges de personnel,,Charge,
310,Salaires,,Charge,
3100,Salaires,,Charge,Favori
311,Charges sociales,,Charge,
3110,AVS-AI-AC-AMAT,,Charge,
3111,LAA professionnelle,,Charge,
3112,LAA complémentaire,,Charge,
3113,Assurance indemnités journalières maladie,,Charge,
3114,LPP,,Charge,
312,Autres charges de personnel,,Charge,
3120,Frais de formation,,Charge,Favori
3128,Autres frais de personnel,,Charge,
315,Compensations charges de personnel (revenus présentés en déduction des charges de personnel),,Charge,
3150,Indemnités d'assurance pour charges du personnel,,Charge,
3151,Mise à disposition de personnes,,Charge,
3152,Commission perception IS,,Charge,
3159,Autres compensations charges salariales,,Charge,
32,Charges de locaux,,Charge,
3200,Loyers,,Charge,Favori
3210,"Charges Eau, gaz, électricité ",,Charge,Favori
3220,Frais d'entretiens locaux,,Charge,Favori
3230,Assurance RC et choses,,Charge,
3280,Frais de location de salles,,Charge,Favori
33,Administration et informatique,,Charge,
330,Administration,,Charge,
3300,Fournitures de bureau,,Charge,Favori
3301,Télécommunications,,Charge,Favori
3302,Frais de port,,Charge,Favori
3303,Documents et abonnements,,Charge,
3304,Frais de cotisations,,Charge,
3306,Frais de réunion,,Charge,
335,Informatique,,Charge,
3350,Frais de licence,Par exemple pour décompter la contribution à un logiciel comptable ;-),Charge,Favori
3351,Frais de maintenance,,Charge,
3352,Petit matériel informatique,,Charge,Favori
34,Frais de promotion et de représentation,,Charge,
340,Matériel de promotion,,Charge,
3400,Impression de matériel de promotion,,Charge,
3401,Conception de matériel de promotion,,Charge,
3409,Autre matériel de promotion,,Charge,
341,Site internet et communication en ligne,,Charge,
3410,"Frais de maintenance de site internet, plateforme web, outils de communication en ligne",,Charge,
3411,"Conception de site internet, plateforme web, outils de communication en ligne",,Charge,
3419,Autres frais liés à la communication en ligne,,Charge,
346,Frais de représentation,,Charge,
3460,Frais de voyage,,Charge,
3461,Frais de repas,,Charge,Favori
3469,Autres frais de représentation,,Charge,
35,Mises à disposition gratuites (contrepartie : subventions non monétaires en 45),,Charge,
36,Autres charges dexploitation,,Charge,
360,Amortissements et dépréciations dactifs,,Charge,
3600,Amortissements,,Charge,
3601,Dépréciations dactifs,,Charge,
361,Charges sur débiteurs douteux,,Charge,
3610,Variation provision sur débiteurs douteux,,Charge,
3620,Pertes sur débiteurs douteux,,Charge,
369,Autres charges dexploitation,,Charge,
3690,Autres charges dexploitation,,Charge,
37,"Charges hors exploitation, exceptionnelles, uniques ou hors périodes",,Charge,
370,Charges hors exploitation,,Charge,
3700,Charges hors exploitation,,Charge,
371,Charges exceptionnelles ou uniques,,Charge,
3710,Charges exceptionnelles ou uniques,,Charge,
372,Charges hors périodes,,Charge,
3720,Charges liées aux exercices précédents,,Charge,
38,Charges financières,,Charge,
3800,Charges d'intérêts,,Charge,
3810,Frais bancaires,,Charge,Favori
3820,Pertes de change,,Charge,
39,Variation des fonds affectés (Swiss GAAP RPC),,Charge,
3900,Attribution aux fonds affectés,,Charge,
3910,Produits internes de fonds affectés,,Produit,
4,Revenus,,Produit,
40,Revenus de ventes et de prestations,,Produit,
4000,Revenu de prestations,,Produit,Favori
4010,Revenu de ventes,,Produit,Favori
41,Revenus des fonds affectés,,Produit,
410,Subventions,,Produit,Favori
4130,Donateurs privés fonds affectés,,Produit,
42,Dons non affectés,,Produit,
4220,Donateurs privés non affectés,,Produit,
43,Cotisations de membres,,Produit,
4400,Cotisations de membres,,Produit,Favori
45,Subventions non monétaires (contrepartie : mises à disposition gratuites en 35),,Produit,
46,Autres produits dexploitation,,Produit,
4600,Dissolutions de provisions,,Produit,
47,"Produits hors exploitation, exceptionnels, uniques ou hors périodes ",,Produit,
470,Produits hors exploitation,,Produit,
4700,Produits hors exploitation,,Produit,
471,Produits exceptionnels ou uniques,,Produit,
4710,Produits exceptionnels ou uniques,,Produit,
472,Produits hors période,,Produit,
4720,Produits liés aux exercices précédents,,Produit,
48,Revenus financiers,,Produit,
4800,Revenus d'intérêts,,Produit,
4820,Gains de change,,Produit,
49,Variation des fonds affectés (Swiss GAAP RPC),,Produit,
4900,Utilisation des fonds affectés,,Produit,
4910,Charges internes de fonds affectés,,Charge,
5,Comptes de tiers,,Actif ou passif,
9,Bilan,,,
9100,Bilan d'ouverture,,,
9101,Bilan de clôture,,,
1 Numéro Libellé Description Position Favori
2 1 Actifs Actif
3 10 Liquidités Actif
4 100 Caisses Actif
5 1000 Caisse Actif Favori
6 1005 Caisse Euro Actif Favori
7 1010 CCP Actif
8 102 Banques Actif
9 1020 Compte bancaire Actif Favori
10 1030 Dépôts à court terme (< 3 mois) Actif
11 109 Comptes d’attente Actif
12 1090 Dépôts en attente Actif Favori
13 11 Titres cotés en bourse et détenus à court terme Actif
14 1100 Titres Actif
15 12 Débiteurs Actif
16 120 Débiteurs résultant de la vente de biens et de prestations de services Actif
17 1200 Débiteurs résultant de la vente de biens et de prestations de services Actif
18 125 Autres débiteurs Actif
19 1250 Autres débiteurs Actif
20 13 Stocks Actif
21 1300 Stocks divers Actif
22 14 Actifs transitoires (comptes de régularisation d’actifs) Actif
23 1400 Impôts anticipés Actif
24 1410 Produits à recevoir Actif
25 1420 Charges payées d'avance Actif
26 15 Immobilisations financières Actif
27 1500 Cautions loyers Actif
28 16 Participations Actif
29 1600 Participations dans d’autres entités Actif
30 17 Immobilisations corporelles Actif
31 1700 Mobilier Actif
32 1710 Informatique Actif
33 18 Immobilisations incorporelles Actif
34 1800 Licences informatiques Actif
35 2 Passifs Passif
36 20 Créanciers Passif
37 2000 Fournisseurs Passif
38 2050 Autres dettes à court terme Passif
39 21 Dettes à court terme liées aux charges de personnel Passif
40 2100 Créanciers caisse AVS Passif
41 2110 Créanciers LAA Passif
42 2120 Créanciers LPP Passif
43 2130 Créanciers impôt source Passif
44 2140 Créanciers assurance indemnités journalières maladie Passif
45 2180 Salaires à payer Passif
46 22 Dettes financières à court terme Passif
47 2200 Emprunts bancaires à rembourser dans l'année Passif
48 23 Passifs transitoires (comptes de régularisation de passifs) Passif
49 2310 Produits constatés d'avance Passif
50 2320 Charges à payer Passif
51 24 Dettes à long terme Passif
52 2400 Emprunts bancaires à rembourser à plus d'une année Passif
53 2410 Autres dettes à long terme Passif
54 26 Provisions Passif
55 28 Fonds affectés (Swiss GAAP RPC) À subdiviser par projet Passif
56 29 Fonds propres Passif
57 2900 Capital initial versé (ou capital de fondation) Passif
58 2910 Réserve associative Passif
59 2990 Résultats reportés (fonds libres) Passif
60 2999 Résultat de l'exercice Passif
61 29991 Résultat positif Passif
62 29999 Résultat négatif Passif
63 3 Charges Charge
64 30 Charges directes de projets À subdiviser par projet Charge
65 31 Charges de personnel Charge
66 310 Salaires Charge
67 3100 Salaires Charge Favori
68 311 Charges sociales Charge
69 3110 AVS-AI-AC-AMAT Charge
70 3111 LAA professionnelle Charge
71 3112 LAA complémentaire Charge
72 3113 Assurance indemnités journalières maladie Charge
73 3114 LPP Charge
74 312 Autres charges de personnel Charge
75 3120 Frais de formation Charge Favori
76 3128 Autres frais de personnel Charge
77 315 Compensations charges de personnel (revenus présentés en déduction des charges de personnel) Charge
78 3150 Indemnités d'assurance pour charges du personnel Charge
79 3151 Mise à disposition de personnes Charge
80 3152 Commission perception IS Charge
81 3159 Autres compensations charges salariales Charge
82 32 Charges de locaux Charge
83 3200 Loyers Charge Favori
84 3210 Charges – Eau, gaz, électricité Charge Favori
85 3220 Frais d'entretiens locaux Charge Favori
86 3230 Assurance RC et choses Charge
87 3280 Frais de location de salles Charge Favori
88 33 Administration et informatique Charge
89 330 Administration Charge
90 3300 Fournitures de bureau Charge Favori
91 3301 Télécommunications Charge Favori
92 3302 Frais de port Charge Favori
93 3303 Documents et abonnements Charge
94 3304 Frais de cotisations Charge
95 3306 Frais de réunion Charge
96 335 Informatique Charge
97 3350 Frais de licence Par exemple pour décompter la contribution à un logiciel comptable ;-) Charge Favori
98 3351 Frais de maintenance Charge
99 3352 Petit matériel informatique Charge Favori
100 34 Frais de promotion et de représentation Charge
101 340 Matériel de promotion Charge
102 3400 Impression de matériel de promotion Charge
103 3401 Conception de matériel de promotion Charge
104 3409 Autre matériel de promotion Charge
105 341 Site internet et communication en ligne Charge
106 3410 Frais de maintenance de site internet, plateforme web, outils de communication en ligne Charge
107 3411 Conception de site internet, plateforme web, outils de communication en ligne Charge
108 3419 Autres frais liés à la communication en ligne Charge
109 346 Frais de représentation Charge
110 3460 Frais de voyage Charge
111 3461 Frais de repas Charge Favori
112 3469 Autres frais de représentation Charge
113 35 Mises à disposition gratuites (contrepartie : subventions non monétaires en 45) Charge
114 36 Autres charges d’exploitation Charge
115 360 Amortissements et dépréciations d’actifs Charge
116 3600 Amortissements Charge
117 3601 Dépréciations d’actifs Charge
118 361 Charges sur débiteurs douteux Charge
119 3610 Variation provision sur débiteurs douteux Charge
120 3620 Pertes sur débiteurs douteux Charge
121 369 Autres charges d’exploitation Charge
122 3690 Autres charges d’exploitation Charge
123 37 Charges hors exploitation, exceptionnelles, uniques ou hors périodes Charge
124 370 Charges hors exploitation Charge
125 3700 Charges hors exploitation Charge
126 371 Charges exceptionnelles ou uniques Charge
127 3710 Charges exceptionnelles ou uniques Charge
128 372 Charges hors périodes Charge
129 3720 Charges liées aux exercices précédents Charge
130 38 Charges financières Charge
131 3800 Charges d'intérêts Charge
132 3810 Frais bancaires Charge Favori
133 3820 Pertes de change Charge
134 39 Variation des fonds affectés (Swiss GAAP RPC) Charge
135 3900 Attribution aux fonds affectés Charge
136 3910 Produits internes de fonds affectés Produit
137 4 Revenus Produit
138 40 Revenus de ventes et de prestations Produit
139 4000 Revenu de prestations Produit Favori
140 4010 Revenu de ventes Produit Favori
141 41 Revenus des fonds affectés Produit
142 410 Subventions Produit Favori
143 4130 Donateurs privés – fonds affectés Produit
144 42 Dons non affectés Produit
145 4220 Donateurs privés – non affectés Produit
146 43 Cotisations de membres Produit
147 4400 Cotisations de membres Produit Favori
148 45 Subventions non monétaires (contrepartie : mises à disposition gratuites en 35) Produit
149 46 Autres produits d’exploitation Produit
150 4600 Dissolutions de provisions Produit
151 47 Produits hors exploitation, exceptionnels, uniques ou hors périodes Produit
152 470 Produits hors exploitation Produit
153 4700 Produits hors exploitation Produit
154 471 Produits exceptionnels ou uniques Produit
155 4710 Produits exceptionnels ou uniques Produit
156 472 Produits hors période Produit
157 4720 Produits liés aux exercices précédents Produit
158 48 Revenus financiers Produit
159 4800 Revenus d'intérêts Produit
160 4820 Gains de change Produit
161 49 Variation des fonds affectés (Swiss GAAP RPC) Produit
162 4900 Utilisation des fonds affectés Produit
163 4910 Charges internes de fonds affectés Charge
164 5 Comptes de tiers Actif ou passif
165 9 Bilan
166 9100 Bilan d'ouverture
167 9101 Bilan de clôture

View file

@ -0,0 +1,587 @@
code,label,description,position,bookmark
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,Écarts de réévaluation,,Passif,
1051,Écarts réévaluation sur biens sans droit reprise,,Passif,
1052,Écarts réévaluation sur biens avec droit reprise,,Passif,
106,Réserves,,Passif,
1061,Réserves « Attributions économiques et professionnelles »,,Actif ou passif,
1062,Réserves « Activités sociales et culturelles »,,Passif,
1063,Réserves Indisponibles,,Passif,
1064,Réserves statutaires,,Passif,
1068,Réserves réglementées,,Passif,
1069,Réserves pour projet de lentité,,Passif,
108,Dotations consomptibles,,Passif,
1081,Dotations consomptibles,,Passif,
1089,Dotation consomptibles inscrites au compte de résultat,,Passif,
11,REPORT à NOUVEAU,,Passif,
110,Report à nouveau (Solde créditeur),,Passif,
1101,Report à nouveau « Attributions économiques et professionnelles » (solde créditeur),,Passif,
1102,Report à nouveau « Activités sociales et culturelles » (solde créditeur),,Passif,
119,Report à nouveau (Solde débiteur),,Passif,
1191,Report à nouveau « Attributions économiques et professionnelles » (solde débiteur),,Passif,
1192,Report à nouveau « Activités sociales et culturelles » (solde débiteur),,Passif,
12,RÉSULTAT NET DE L'EXERCICE,,Passif,
120,Résultat de l'exercice (excédent),,Passif,
1201,Résultat de lexercice « Attributions économiques et professionnelles » (excédent),,Passif,
1202,Résultat de lexercice « Activités sociales et culturelles » (excédent),,Passif,
129,Résultat de l'exercice (déficit),,Passif,
1291,Résultat de lexercice « Attributions économiques et professionnelles » (déficit),,Passif,
1292,Résultat de lexercice « Activités sociales et culturelles » (déficit),,Passif,
13,SUBVENTIONS D'INVESTISSEMENTS,,Passif,
131,Subventions d'équipement,,Passif,
1311,État,,Passif,
1312,Régions,,Passif,
1313,Départements,,Passif,
1314,Communes,,Passif,
1315,Collectivités publiques,,Passif,
1316,Entreprises publiques,,Passif,
1317,Entreprises et organismes privés,,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 & prestations de services échangés siège-établissements,,Passif,
186,Biens & prestations de services entre établissements - Charges,,Passif,
187,Biens & prestations de services 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 dusufruit,,Passif,
194,Fonds dédiés sur subventions fonctionnement,,Passif,
195,Fonds dédiés sur contributions financières autres organismes,,Passif,
196,Fonds dédiés sur 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 dusufruit,,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énagements divers",,Actif,
2182,Matériel de transport,,Actif,
2183,Matériel de bureau et matériel informatique,Dune valeur supérieure à 500€,Actif,
2184,Mobilier,Dune valeur supérieure à 500€,Actif,
23,IMMOBILISATIONS EN COURS,,Actif,
231,Immobilisations corporelles en cours,,Actif,
238,"Avances, acomptes sur immobilisations 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 FINANCIÈRES,,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 IMMOBILISATIONS,,Actif,
280,Amortissements des immobilisations incorporelles,,Actif,
2801,Amortissements frais d'établissement,,Actif,
2804,Amortissements donations temporaires dusufruit,,Actif,
2805,"Amortissements brevets, licences, marques...",,Actif,
2806,Amortissements droit au bail,,Actif,
2808,Amortissements autres immo.incorporelles,,Actif,
2812,"Amortissements agencements, aménagements de terrains",,Actif,
28131,Amortissements bâtiments,,Actif,
28135,"Amortissements installations, agencements...",,Actif,
2814,Amt.constructions sur sol d'autrui,,Actif,
2815,"Amortissements installations techniques, matériel, outillage",,Actif,
28181,"Amortissements installations, agencements, aménagements",,Actif,
28182,Amortissements matériel de transport,,Actif,
28183,"Amortissement matériel de bureau, informatique",Dune valeur supérieure à 500€,Actif,
28184,Amortissements du mobilier,Dune valeur supérieure à 500€,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 production de services,,Actif,
341,Études 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 POUR DÉPRÉCIATIONS 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,Favori
403,Fournisseurs - Effets à payer,,Passif,
404,Fournisseurs d'immobilisations,,Actif ou passif,
405,Fournisseurs d'immobilisations - Effets à payer,,Passif,
408,Fournisseurs - Factures non parvenues,,Passif,
4091,Fournisseurs - Avances & acomptes,,Actif,
41,BÉNÉFICIAIRES ET COMPTES RATTACHÉS,,Actif ou passif,
410,Bénéficiaires et comptes rattachés,,Actif ou passif,
411,Bénéficiaires,,Actif ou passif,
4110,Autres bénéficiaires,Pour les dettes ou créances des membres,Actif ou passif,Favori
413,Bénéficiaires - Effets à recevoir,,Actif,
416,Bénéficiaires douteux ou litigieux,,Actif,
418,Bénéficiaires non encore facturés,,Actif,
419,Bénéficiaires créditeurs,,Passif,
4191,Bénéficiaires créditeurs : avances et acomptes,,Passif,
4198,"Rabais, remises, ristournes à accorder et autres avoirs à établir ",,Passif,
42,PERSONNEL ET COMPTES RATTACHÉS,,Actif ou passif,
421,Personnel : Rémunérations dues,,Passif,
4210,Autres membres du personnel,Dettes dues aux salarié⋅e⋅s,Actif ou passif,Favori
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,État ET AUTRES COLLECTIVITÉS PUBLIQUES,,Actif,
441,État - Subventions à recevoir,,Actif,
4421,Prélèvements à la source- Impôt sur le revenu,,Actif ou passif,
444,État - 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,État - Charges à payer,,Passif,
4487,État - Produits à recevoir,,Actif,
45,"CONFÉDÉRATION, FÉDÉRATION, UNIONS, etc. AFFILIÉES",,Actif ou passif,
451,"Confédération, fédération et associations affiliées",,Actif ou passif,
455,Partenaires - comptes courants,,Actif ou passif,
46,DÉBITEURS 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 RÉGULARISATION,,Actif ou passif,
481,Charges à répartir,,Passif,
486,Charges constatées d'avance,,Actif,
487,Produits constatés d'avance,,Passif,
49,DÉPRÉCIATIONS DES COMPTES DE TIERS,,Actif ou passif,
491,Provisions pour dépréciation des comptes d'usagers,,Passif,
496,Provisions pour dépréciations des comptes débiteurs divers,,Passif,
5,Classe 5 — Comptes financiers,,Actif,
50,VALEURS MOBILIÈRES DE PLACEMENT,,Actif,
503,Actions,,Actif,
506,Obligations,,Actif,
508,Autres valeurs mobilières de placement et créances assimilées,,Actif,
51,"BANQUES, ÉTABLISSEMENTS FINANCIERS",,Actif,
5112,Chèques à encaisser,,Actif ou passif,Favori
5115,Paiements par carte à encaisser,,Actif ou passif,
512,Banques,,Actif ou passif,
512A,Compte courant Fonctionnement,,Actif ou passif,Favori
512B,Compte courant Œuvres Sociales,,Actif ou passif,Favori
5186,Intérêts courus à payer,,Passif,
5187,Intérêts courus à recevoir,,Actif,
53,Caisses,,Actif ou passif,
530,Caisse,,Actif ou passif,Favori
58,VIREMENTS INTERNES,,Actif ou passif,
580,Virements internes,,Actif ou passif,
59,DÉPRÉCIATIONS DES COMPTES FINANCIERS,,Actif ou passif,
5903,Actions,,Actif ou passif,
5906,Obligations,,Actif ou passif,
5908,Autres valeurs mobilières de placement 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,Favori
6061,"Fournitures non stockables (eau, énergie...)","Facture d'eau, délectricité, etc.",Charge,Favori
60611,Eau,,Charge,Favori
60612,Électricité,,Charge,Favori
60613,Chauffage,,Charge,Favori
6063,Fournitures d'entretien et petit équipement,"Vis, et matériel de bricolage (sauf outils) par exemple",Charge,Favori
6064,Fournitures administratives,"Cartouches d'encre, papier, matériel bureautique, etc.",Charge,Favori
6065,Petits logiciels,Par exemple contribution à un logiciel de gestion associative génial :-),Charge,Favori
6068,Autres fournitures & matières,,Charge,Favori
607,Achats de marchandises,Marchandises destinées à être revendues en l'état.,Charge,Favori
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,"Rabais, remises, ristournes sur achats matières et fournitures",,Charge,
6092,"Rabais, remises, ristournes sur achats et autres approvisionnements",,Charge,
6097,"Rabais, remises, ristournes sur achats de marchandises",,Charge,
61,SERVICES EXTÉRIEURS,,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,Favori
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 dassurance local, activité, etc.",Charge,Favori
6161,Primes d'assurances multirisques,,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 EXTÉRIEURS,,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 demployeurs,Charge,Favori
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 divers intermédiaires & honoraires,,Charge,
623,"Publicité, publications, relations publiques","Bulletins, affiches, communication, etc.",Charge,Favori
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,Favori
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,Favori
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,Favori
628,Divers,,Charge,Favori
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 construction,,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évoyance,,Charge,
6458,Cotisations aux autres organismes sociaux,,Charge,
647,Autres charges sociales,,Charge,
6472,Versements aux comités d'entreprise et d'établissement,,Charge,
6473,Versement aux comités d'hygiène et de sécurité,,Charge,
6474,Versements aux autres œuvres 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, licences",,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,Favori
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,Favori
6586,Cotisations (vie statutaire),,Charge,
6588,Charges diverses de gestion courante,,Charge,
66,CHARGES FINANCIÈRES,,Charge,
661,Charges d'intérêts,,Charge,
665,Escomptes accordés,,Charge,
666,Pertes de changes,,Charge,
667,Charges nettes sur cessions de valeurs mobilières de placement,,Charge,
668,Autres charges financières,,Charge,
67,Charges exceptionnelles,,Charge,
670,Charges exceptionnelles,Autres dépenses exceptionnelles,Charge,Favori
6712,"Pénalités, amendes fiscales et 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,"Dotation AUX AMORTISSEMENTS, DÉPRÉCIATIONS ET ENGAGEMENTS",,Charge,
6811,Dotation aux amortissements des immobilisations,,Charge,
6812,Dotation aux amortissements charges à répartir,,Charge,
6815,Dotation aux provisions d'exploitation,,Charge,
6816,Dotation provisions pour dépréciations des immobillisations,,Charge,
68164,Dotation pr dépréc. dactifs reçus par legs ou donations,,Charge,
6817,Dotation 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,Dotation aux amortissements & Provisions - Charges financières,,Charge,
68662,Dotation aux amortissements & provisions immobilisations financières,,Charge,
68665,Dotation aux amortissements & provisions valeurs mobilières de placement,,Charge,
687,Dotation aux amortissements & Provisions - Charges exceptionnelles,,Charge,
689,Reports en fonds dédiés,,Charge,
6891,Reports en fonds reportés,,Charge,
6894,Reports en fonds dédiés / subventions dexploitation,,Charge,
6895,Reports en fonds dédiés / contributions financières d'autres organismes,,Charge,
6896,Reports en fonds dédiés / ressources générosité,,Charge,
69,IMPÔTS SUR LES BÉNÉFICES,,Charge,
695,Impôts sur les bénéfices,,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,Favori
702,Ventes de produits intermédiaires,,Produit,
703,Ventes de produits résiduels,,Produit,
704,Travaux,,Produit,
705,Études,,Produit,Favori
706,Prestations de services,,Produit,Favori
7063,Parrainages,,Produit,
707,Ventes de marchandises,Ventes de produits achetés et revendus en létat,Produit,Favori
7073,Ventes de dons en nature,,Produit,
708,Produits des activités annexes,,Produit,
7081,Produits des services exploités dans lintérêt du personnel,,Produit,
7083,Locations diverses,,Produit,
7085,Ports et frais accessoires facturés,,Produit,
7088,Autres produits d'activités annexes,,Produit,
709,"Rabais, remises, ristournes accordés",,Produit,
7091,"Rabais, remises, ristournes sur ventes de produits finis",,Produit,
7092,"Rabais, remises, ristournes sur ventes de produits intermédiaires",,Produit,
7094,"Rabais, remises, ristournes sur travaux",,Produit,
7095,"Rabais, remises, ristournes sur études",,Produit,
7096,"Rabais, remises, ristournes sur prest.de services",,Produit,
7097,"Rabais, remises, ristournes sur ventes marchandises",,Produit,
71,PRODUCTION STOCKÉE,,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 IMMOBILISÉE,,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,Favori
7403,Autres subventions,,Produit,Favori
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,Favori
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 dautres organismes,,Produit,
7552,Quotes-parts de générosité reçues,,Produit,
756,Cotisations,Cotisations des adhérent⋅e⋅s,Produit,Favori
7561,Cotisations sans contrepartie,,Produit,
7562,Cotisations avec contrepartie,,Produit,
756201,Subvention de fonctionnement reçue l'employeur,Produits affectés à la section « Attributions économiques et professionnelles »,Produit,Favori
756202,Contribution reçue de l'employeur,Produits affectés à la section « Activités sociales et culturelles »,Produit,Favori
757,Gains de change / créances et dettes dexploitation,,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 immobilisations financières,,Produit,
763,Revenus des autres créances,,Produit,
764,Revenus des valeurs mobilières de placement,,Produit,
765,Escomptes obtenus,,Produit,
766,Gains de change,,Produit,
767,Produits nets sur cession valeurs mobilières de placement,,Produit,
768,Autres produits financiers,,Produit,
77,PRODUITS EXCEPTIONNELS,,Produit,
771,Produits exceptionnels sur opération de gestion,,Produit,
7713,Libéralités perçues,,Produit,
7718,Autres produits exceptionnels sur opération de gestion,,Produit,
775,Produits des cessions d'actif,,Produit,
7754,Immobilisations reçues en legs ou donations à céder,,Produit,
777,Quote-part subvention d'investissement virée au résultat,,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,Favori
78,"REPRISES SUR AMORTISSEMENTS, DÉPRÉCIATIONS, ENGAGEMENTS",,Produit,
781,Reprises / Amortissements & Provisions d'exploitation,,Produit,
7811,Amortissements immobilisations corporelles & incorporelles,,Produit,
7815,Reprises sur provisions d'exploitation,,Produit,
7816,Dépréciations immobilisations corporelles & incorporelles,,Produit,
78164,Reprises dépréciations dactifs reçus par legs ou donations destinés à être cédés,,Produit,
7817,Dépréciations actifs circulant,,Produit,
786,Reprises sur provisions pour risques et dépréciations ,À inscrire dans les produits exceptionnels,Produit,
7865,Risques & charges financiers,,Produit,
7866,Déprec.des éléments financiers,,Produit,
787, Reprises sur provisions pour risques et dépréciations,À inscrire dans les produits exceptionnels,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 fonds reportés et de fonds dédiés,,Produit,
7891,Utilisations de fonds reportés,,Produit,
7894,Utilisations des fonds dédiés / subventions,,Produit,
7895,Utilisations des fonds dédiés / contributions,,Produit,
7896,Utilisations des fonds 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,,,
80,ENGAGEMENTS,,,
801,Engagements donnés par lentité,,,
8011,"Avals, cautions, garanties",,,
8014,Effets circulant sous lendos de lentité,,,
8016,Redevances crédit-bail restant à courir,,,
80161,Crédit-bail mobilier,,,
80165,Crédit-bail immobilier,,,
8018,Autres engagements donnés,,,
802,Engagements reçus par lentité,,,
8021,"Avals, cautions, garanties",,,
8024,Créances escomptées non échues,,,
8026,Engagements reçus pour utilisation en crédit-bail,,,
80261,Crédit-bail mobilier,,,
80265,Crédit-bail immobilier,,,
8028,Autres engagements reçus,,,
809,Contrepartie des engagements,,,
8091,Contrepartie 801,,,
8092,Contrepartie 802,,,
86,EMPLOI DES CONTRIBUTIONS VOLONTAIRES EN NATURE,,,
860,"Secours en nature (alimentaires, vestimentaires…)",,Charge,
861,"Mise à disposition gratuite de biens (locaux, matériels…)",,Charge,
862,Prestations,,Charge,
864,Personnel bénévole,,Charge,
87,CONTRIBUTIONS VOLONTAIRES EN NATURE,,,
870,Bénévolat,,Produit,
871,Prestations en nature,,Produit,
875,Dons en nature,,Produit,
89,COMPTES DE BILAN,,,
890,Bilan d'ouverture,,Actif ou passif,
891,Bilan de clôture,,Actif ou passif,
1 code label description position bookmark
2 1 Classe 1 — Comptes de capitaux (Fonds propres, emprunts et dettes assimilés) Passif
3 10 FONDS ASSOCIATIFS ET RÉSERVES Passif
4 102 Fonds associatifs sans droit de reprise Passif
5 1021 Première situation nette établie Passif
6 1022 Fonds statutaires Passif
7 1023 Dotations non consomptibles Passif
8 10231 Dotations non consomptibles initiales Passif
9 10232 Dotations non consomptibles complémentaires Passif
10 1024 Autres fonds propres sans droit de reprise Passif
11 103 Fonds associatif avec droit de reprise Passif
12 1032 Fonds statutaires Passif
13 1034 Autres fonds propres avec droit de reprise Passif
14 105 Écarts de réévaluation Passif
15 1051 Écarts réévaluation sur biens sans droit reprise Passif
16 1052 Écarts réévaluation sur biens avec droit reprise Passif
17 106 Réserves Passif
18 1061 Réserves « Attributions économiques et professionnelles » Actif ou passif
19 1062 Réserves « Activités sociales et culturelles » Passif
20 1063 Réserves Indisponibles Passif
21 1064 Réserves statutaires Passif
22 1068 Réserves réglementées Passif
23 1069 Réserves pour projet de l’entité Passif
24 108 Dotations consomptibles Passif
25 1081 Dotations consomptibles Passif
26 1089 Dotation consomptibles inscrites au compte de résultat Passif
27 11 REPORT à NOUVEAU Passif
28 110 Report à nouveau (Solde créditeur) Passif
29 1101 Report à nouveau « Attributions économiques et professionnelles » (solde créditeur) Passif
30 1102 Report à nouveau « Activités sociales et culturelles » (solde créditeur) Passif
31 119 Report à nouveau (Solde débiteur) Passif
32 1191 Report à nouveau « Attributions économiques et professionnelles » (solde débiteur) Passif
33 1192 Report à nouveau « Activités sociales et culturelles » (solde débiteur) Passif
34 12 RÉSULTAT NET DE L'EXERCICE Passif
35 120 Résultat de l'exercice (excédent) Passif
36 1201 Résultat de l’exercice « Attributions économiques et professionnelles » (excédent) Passif
37 1202 Résultat de l’exercice « Activités sociales et culturelles » (excédent) Passif
38 129 Résultat de l'exercice (déficit) Passif
39 1291 Résultat de l’exercice « Attributions économiques et professionnelles » (déficit) Passif
40 1292 Résultat de l’exercice « Activités sociales et culturelles » (déficit) Passif
41 13 SUBVENTIONS D'INVESTISSEMENTS Passif
42 131 Subventions d'équipement Passif
43 1311 État Passif
44 1312 Régions Passif
45 1313 Départements Passif
46 1314 Communes Passif
47 1315 Collectivités publiques Passif
48 1316 Entreprises publiques Passif
49 1317 Entreprises et organismes privés Passif
50 139 Subventions inscrites au compte de résultat Passif
51 14 PROVISIONS RÉGLEMENTÉES Passif
52 148 Autres provisions réglementées Passif
53 15 PROVISIONS POUR RISQUES ET CHARGES Passif
54 151 Provisions pour risques Passif
55 152 Provisions pour charges sur legs ou donations Passif
56 153 Provisions pour pensions et obligations simil Passif
57 155 Provisions pour impôts Passif
58 157 Provisions pour charges à répartir Passif
59 158 Autres provisions pour charges Passif
60 16 EMPRUNTS ET DETTES ASSIMILÉES Passif
61 163 Autres emprunts obligataires Passif
62 1631 Titres associatifs et assimilés Passif
63 164 Emprunts auprès des établissements de crédit Passif
64 165 Dépôts et cautionnements reçus Passif
65 1651 Dépôts Passif
66 1655 Cautionnements Passif
67 167 Emprunts et dettes sous conditions particulières Passif
68 168 Autres emprunts et dettes assimilées Passif
69 18 COMPTES DE LIAISONS Passif
70 181 Apports permanents siège-établissements Passif
71 185 Biens & prestations de services échangés siège-établissements Passif
72 186 Biens & prestations de services entre établissements - Charges Passif
73 187 Biens & prestations de services entre établissements - Produits Passif
74 19 FONDS DÉDIÉS OU REPORTÉS Passif
75 191 Fonds reportés liés aux legs ou donations Passif
76 1911 Legs ou donations Passif
77 1912 Donations temporaires d’usufruit Passif
78 194 Fonds dédiés sur subventions fonctionnement Passif
79 195 Fonds dédiés sur contributions financières autres organismes Passif
80 196 Fonds dédiés sur ressources liées à la générosité Passif
81 2 Classe 2 — Comptes d'immobilisations Actif
82 20 IMMOBILISATIONS INCORPORELLES Actif
83 201 Frais d'établissement Actif
84 203 Frais de recherche et de développement Actif
85 204 Donations temporaires d’usufruit Actif
86 205 Brevets, licences, marques... Actif
87 206 Droit au bail Actif
88 208 Autres immobilisations incorporelles Actif
89 21 IMMOBILISATIONS CORPORELLES Actif
90 211 Terrains Actif
91 212 Agencements / aménagements de terrains Actif
92 2131 Bâtiments Actif
93 2135 Installations, agencements...de constructions Actif
94 214 Constructions sur sol d'autrui Actif
95 215 Installations techniques, matériel, outillage Actif
96 2154 Matériel industriel Actif
97 2155 Outillage industriel Actif
98 218 Autres immobilisations corporelles Actif
99 2181 Installations, agencements, aménagements divers Actif
100 2182 Matériel de transport Actif
101 2183 Matériel de bureau et matériel informatique D’une valeur supérieure à 500€ Actif
102 2184 Mobilier D’une valeur supérieure à 500€ Actif
103 23 IMMOBILISATIONS EN COURS Actif
104 231 Immobilisations corporelles en cours Actif
105 238 Avances, acomptes sur immobilisations corporelles Actif
106 24 BIEN DESTINÉS À ÊTRE CÉDÉS Actif
107 240 Biens reçus par legs ou donations à céder Actif
108 26 PARTICIPATIONS ET CRÉANCES RATTACHÉES Actif
109 261 Titres de participation Actif
110 266 Autres formes de participation Actif
111 267 Créances rattachées à des participations Actif
112 269 Versements restants sur participations Actif
113 27 IMMOBILISATIONS FINANCIÈRES Actif
114 271 Titres immobilisés (droit de propriété) Actif
115 272 Titres immobilisés (droit de créance) Actif
116 274 Prêts Actif
117 2742 Prêts aux partenaires Actif
118 275 Dépôts et cautionnements versés Actif
119 276 Autres créances immobilisées Actif
120 28 AMORTISSEMENTS DES IMMOBILISATIONS Actif
121 280 Amortissements des immobilisations incorporelles Actif
122 2801 Amortissements frais d'établissement Actif
123 2804 Amortissements donations temporaires d’usufruit Actif
124 2805 Amortissements brevets, licences, marques... Actif
125 2806 Amortissements droit au bail Actif
126 2808 Amortissements autres immo.incorporelles Actif
127 2812 Amortissements agencements, aménagements de terrains Actif
128 28131 Amortissements bâtiments Actif
129 28135 Amortissements installations, agencements... Actif
130 2814 Amt.constructions sur sol d'autrui Actif
131 2815 Amortissements installations techniques, matériel, outillage Actif
132 28181 Amortissements installations, agencements, aménagements Actif
133 28182 Amortissements matériel de transport Actif
134 28183 Amortissement matériel de bureau, informatique D’une valeur supérieure à 500€ Actif
135 28184 Amortissements du mobilier D’une valeur supérieure à 500€ Actif
136 29 DÉPRÉCIATIONS DES IMMOBILISATIONS Actif
137 2904 Donations temporaires d'usufruit Actif
138 2905 Brevets, licences, marques... Actif
139 2906 Droit au bail Actif
140 2908 Autres immobilisations incorporelles Actif
141 2911 Terrains Actif
142 2931 Immobilisations corporelles en cours Actif
143 294 Biens reçus par legs ou donations à céder Actif
144 2961 Titres de participations Actif
145 2966 Autres formes de participations Actif
146 2967 Créances rattachées à des participations Actif
147 2971 Titres immobilisés (droit de propriété) Actif
148 2972 Titres immobilisés (droit de créance) Actif
149 2974 Prêts Actif
150 2975 Dépôts et cautionnements versés Actif
151 2976 Autres créances immobilisées Actif
152 3 Classe 3 — Comptes de stocks Actif
153 31 MATIÈRES PREMIÈRES ET FOURNITURES Actif
154 318 Matières premières et fournitures Actif
155 32 AUTRES APPROVISIONNEMENTS Actif
156 321 Matières consommables Actif
157 322 Fournitures consommables Actif
158 326 Emballages Actif
159 33 EN-COURS DE PRODUCTION DE BIENS Actif
160 331 Produits en cours Actif
161 335 Travaux en cours Actif
162 34 En-cours de production de services Actif
163 341 Études en cours Actif
164 345 Prestations de services en cours Actif
165 35 STOCKS DE PRODUITS Actif
166 351 Produits intermédiaires Actif
167 355 Produits finis Actif
168 358 Produits résiduels Actif
169 37 STOCKS DE MARCHANDISES Actif
170 370 Stocks de marchandises Actif
171 39 PROVISIONS POUR DÉPRÉCIATIONS STOCKS & EN-COURS Actif
172 391 Matières premières et fournitures Actif
173 392 Autres approvisionnements Actif
174 393 En-cours de production de biens Actif
175 394 En-cours de production de services Actif
176 395 Stocks de produits Actif
177 397 Stocks de marchandises Actif
178 4 Classe 4 — Comptes de tiers Actif ou passif
179 40 FOURNISSEURS ET COMPTES RATTACHÉS Actif ou passif
180 401 Fournisseurs Actif ou passif
181 4010 Autres fournisseurs Actif ou passif Favori
182 403 Fournisseurs - Effets à payer Passif
183 404 Fournisseurs d'immobilisations Actif ou passif
184 405 Fournisseurs d'immobilisations - Effets à payer Passif
185 408 Fournisseurs - Factures non parvenues Passif
186 4091 Fournisseurs - Avances & acomptes Actif
187 41 BÉNÉFICIAIRES ET COMPTES RATTACHÉS Actif ou passif
188 410 Bénéficiaires et comptes rattachés Actif ou passif
189 411 Bénéficiaires Actif ou passif
190 4110 Autres bénéficiaires Pour les dettes ou créances des membres Actif ou passif Favori
191 413 Bénéficiaires - Effets à recevoir Actif
192 416 Bénéficiaires douteux ou litigieux Actif
193 418 Bénéficiaires non encore facturés Actif
194 419 Bénéficiaires créditeurs Passif
195 4191 Bénéficiaires créditeurs : avances et acomptes Passif
196 4198 Rabais, remises, ristournes à accorder et autres avoirs à établir Passif
197 42 PERSONNEL ET COMPTES RATTACHÉS Actif ou passif
198 421 Personnel : Rémunérations dues Passif
199 4210 Autres membres du personnel Dettes dues aux salarié⋅e⋅s Actif ou passif Favori
200 422 Comités d'entreprise, d'établissement Actif ou passif
201 425 Personnel : Avances & acomptes Actif
202 427 Personnel - Oppositions Passif
203 4286 Personnel- Charges à payer Passif
204 4287 Personnel- Produits à recevoir Actif
205 43 SÉCURITÉ SOCIALE & AUTRES ORGANISMES SOCIAUX Passif
206 431 Sécurité sociale Passif
207 4372 Mutuelles Passif
208 4373 Caisses de retraites et de prévoyance Passif
209 4378 Autres organismes sociaux Passif
210 44 État ET AUTRES COLLECTIVITÉS PUBLIQUES Actif
211 441 État - Subventions à recevoir Actif
212 4421 Prélèvements à la source- Impôt sur le revenu Actif ou passif
213 444 État - Impôts sur les bénéfices Actif ou passif
214 4452 TVA due intracommunautaire Actif ou passif
215 4455 Taxes sur CA à décaisser Actif
216 44562 TVA déductible sur immobilisations Actif
217 44566 TVA déductible sur autres biens et services Actif
218 44571 TVA normale collectée Actif
219 445711 TVA réduite collectée Actif
220 445712 TVA super-réduite collectée Actif
221 445713 TVA intermédiaire collectée Actif
222 4458 Taxe sur CA à régulariser ou en attente Actif
223 447 Autres impôts, taxes et versements assimilés Actif
224 4486 État - Charges à payer Passif
225 4487 État - Produits à recevoir Actif
226 45 CONFÉDÉRATION, FÉDÉRATION, UNIONS, etc. AFFILIÉES Actif ou passif
227 451 Confédération, fédération et associations affiliées Actif ou passif
228 455 Partenaires - comptes courants Actif ou passif
229 46 DÉBITEURS DIVERS ET CREDIT.DVS Actif ou passif
230 461 Créances reçues par legs ou donations Actif
231 466 Dettes des legs ou donations Passif
232 4671 Débiteurs divers Actif ou passif
233 4672 Créditeurs divers Actif ou passif
234 4681 Frais des bénévoles Actif ou passif
235 4686 Divers - Charges à payer Passif
236 4687 Divers - Produits à recevoir Actif
237 47 COMPTES D'ATTENTE Actif ou passif
238 4715 Compte de transit Actif ou passif
239 4718 Compte d'attente Actif ou passif
240 48 COMPTES DE RÉGULARISATION Actif ou passif
241 481 Charges à répartir Passif
242 486 Charges constatées d'avance Actif
243 487 Produits constatés d'avance Passif
244 49 DÉPRÉCIATIONS DES COMPTES DE TIERS Actif ou passif
245 491 Provisions pour dépréciation des comptes d'usagers Passif
246 496 Provisions pour dépréciations des comptes débiteurs divers Passif
247 5 Classe 5 — Comptes financiers Actif
248 50 VALEURS MOBILIÈRES DE PLACEMENT Actif
249 503 Actions Actif
250 506 Obligations Actif
251 508 Autres valeurs mobilières de placement et créances assimilées Actif
252 51 BANQUES, ÉTABLISSEMENTS FINANCIERS Actif
253 5112 Chèques à encaisser Actif ou passif Favori
254 5115 Paiements par carte à encaisser Actif ou passif
255 512 Banques Actif ou passif
256 512A Compte courant Fonctionnement Actif ou passif Favori
257 512B Compte courant Œuvres Sociales Actif ou passif Favori
258 5186 Intérêts courus à payer Passif
259 5187 Intérêts courus à recevoir Actif
260 53 Caisses Actif ou passif
261 530 Caisse Actif ou passif Favori
262 58 VIREMENTS INTERNES Actif ou passif
263 580 Virements internes Actif ou passif
264 59 DÉPRÉCIATIONS DES COMPTES FINANCIERS Actif ou passif
265 5903 Actions Actif ou passif
266 5906 Obligations Actif ou passif
267 5908 Autres valeurs mobilières de placement et créances assimilées Actif ou passif
268 6 Classe 6 — Comptes de charges Charge
269 60 ACHATS (SAUF 603) Charge
270 601 Achats stockés - Matières premières et fournitures Charge
271 6010 Achats stockés de matières et fournitures Charge
272 6011 Achats stockés - Matières premières Charge
273 6017 Achats stockés - Fournitures Charge
274 602 Achats stockés - Autres approvisionnements Charge
275 6021 Achats stockés - Matières consommables Charge
276 60221 Achats stockés - Combustibles Charge
277 60222 Achats stockés - Produits d'entretien Charge
278 60223 Achats stockés - Fournitures d'atelier Charge
279 60224 Achats stockés - Fournitures de magasin Charge
280 60225 Fournitures de bureau Charge
281 6026 Achats stockés - Emballages Charge
282 603 Variations de stocks Charge
283 6031 Variations de stocks matières & fournitures Charge
284 6032 Variations stocks autres approvisionnements Charge
285 6037 Variations de stocks de marchandises Charge
286 604 Achats d'études et prestations de services Charge
287 605 Achats matériel, équipements & travaux Charge
288 606 Achats non stockés de matières et fournitures Charge Favori
289 6061 Fournitures non stockables (eau, énergie...) Facture d'eau, d’électricité, etc. Charge Favori
290 60611 Eau Charge Favori
291 60612 Électricité Charge Favori
292 60613 Chauffage Charge Favori
293 6063 Fournitures d'entretien et petit équipement Vis, et matériel de bricolage (sauf outils) par exemple Charge Favori
294 6064 Fournitures administratives Cartouches d'encre, papier, matériel bureautique, etc. Charge Favori
295 6065 Petits logiciels Par exemple contribution à un logiciel de gestion associative génial :-) Charge Favori
296 6068 Autres fournitures & matières Charge Favori
297 607 Achats de marchandises Marchandises destinées à être revendues en l'état. Charge Favori
298 608 Frais accessoires d'achats Charge
299 60811 Frais accessoires d'achats sur matières Charge
300 60817 Frais accessoires d'achats sur fournitures Charge
301 609 Rabais, remises et ristournes sur achats Charge
302 6091 Rabais, remises, ristournes sur achats matières et fournitures Charge
303 6092 Rabais, remises, ristournes sur achats et autres approvisionnements Charge
304 6097 Rabais, remises, ristournes sur achats de marchandises Charge
305 61 SERVICES EXTÉRIEURS Charge
306 611 Sous-traitance générale Charge
307 6122 Redevance crédit-bail mobilier Charge
308 6125 Redevances crédit-bail immobilier Charge
309 6132 Locations immobilières Locations versées pour un local ou du matériel. Charge Favori
310 6135 Locations mobilières Charge
311 6136 Malis sur emballages Charge
312 614 Charges locatives et de copropriété Charge
313 6152 Entretien sur biens immobiliers Charge
314 6155 Entretien sur biens mobiliers Charge
315 6156 Maintenance Charge
316 616 Primes d'assurance Frais d’assurance local, activité, etc. Charge Favori
317 6161 Primes d'assurances multirisques Charge
318 6164 Primes d'assurances / risques d'exploitation Charge
319 6165 Primes d'assurances / insolvabilité usagers Charge
320 6168 Autres assurances Charge
321 617 Etudes et recherches Charge
322 6181 Documentation générale Charge
323 6183 Documentation technique Charge
324 6185 Frais de colloques, séminaires, conférences Charge
325 6187 Prestations administratives Charge
326 62 AUTRES SERVICES EXTÉRIEURS Charge
327 621 Personnel extérieur à l'association Charge
328 6211 Personnel intérimaire Charge
329 6214 Personnel détaché ou prêté à l'association Charge
330 62141 Mises à disposition de personnel salarié Frais de mise à disposition via un groupement d’employeurs Charge Favori
331 622 Rémunérations d'intermédiaires et honoraires Charge
332 6221 Commissions ... sur achats Charge
333 6222 Commissions... sur ventes Charge
334 6226 Honoraires Charge
335 62264 Honoraires sur legs ou donations à céder Charge
336 6227 Frais d'actes et de contentieux Charge
337 6228 Rémunérations divers intermédiaires & honoraires Charge
338 623 Publicité, publications, relations publiques Bulletins, affiches, communication, etc. Charge Favori
339 6231 Annonces et insertions Charge
340 6232 Fêtes et cérémonies Charge
341 6233 Foires et expositions Charge
342 6234 Cadeaux Charge
343 6236 Catalogues et imprimés Charge
344 6237 Publications Charge
345 6238 Divers : pourboires, dons courants Charge
346 624 Transports de biens... Charge
347 6241 Transports sur achats Charge
348 6242 Transports sur ventes Charge
349 6243 Transports entre établissements Charge
350 6244 Transports administratifs Charge
351 6247 Transports collectifs du personnel Charge
352 6248 Transports divers Charge
353 625 Déplacements, missions et réceptions Billet de train, remboursement de frais kilométrique, etc. Charge Favori
354 6251 Voyages et déplacements Charge
355 6255 Frais de déménagement Charge
356 6256 Frais de missions Charge
357 6257 Frais de réceptions, représentations Charge
358 626 Frais postaux et de télécommunications Facture d'accès à Internet, timbres, etc. Charge Favori
359 6261 Liaisons spécialisées Charge
360 6263 Affranchissements, frais postaux Charge
361 6265 Téléphone Charge
362 627 Services bancaires et assimilés Frais bancaires Charge Favori
363 628 Divers Charge Favori
364 6281 Cotisations (liées à l'activité économique) Charge
365 6284 Frais de recrutement du personnel Charge
366 63 IMPÔTS, TAXES ET VERSEMENTS ASSIMILÉS Charge
367 631 Sur rémunérations - administration des impôts Charge
368 6311 Taxe sur les salaires Charge
369 633 Sur rémunérations - autres organismes Charge
370 6331 Versement de transport Charge
371 6332 Allocation logement Charge
372 6333 Formation professionnelle continue Charge
373 6334 Participations employeurs à l'effort de construction Charge
374 635 Autres - Administration des impôts Charge
375 63512 Taxes foncières Charge
376 63513 Autres impôts locaux Charge
377 6354 Droits d'enregistrement et de timbre Charge
378 637 Autres - Autres organismes Charge
379 64 CHARGES DE PERSONNEL Charge
380 641 Rémunérations du personnel Charge
381 6411 Salaires, appointements Charge
382 6412 Congés payés Charge
383 6413 Primes et gratifications Charge
384 6414 Indemnités et avantages divers Charge
385 6415 Supplément familial Charge
386 645 Charges de sécurité sociale et de prévoyance Charge
387 6451 Cotisations à l'URSSAF Charge
388 6452 Cotisations aux mutuelles Charge
389 6453 Cotisations caisses de retraites et de prévoyance Charge
390 6458 Cotisations aux autres organismes sociaux Charge
391 647 Autres charges sociales Charge
392 6472 Versements aux comités d'entreprise et d'établissement Charge
393 6473 Versement aux comités d'hygiène et de sécurité Charge
394 6474 Versements aux autres œuvres sociales Charge
395 6475 Médecine du travail, pharmacie Charge
396 648 Autres charges de personnel Charge
397 6481 Indemnités du personnel de culte Charge
398 6485 Charges sociales sur indemnités de culte Charge
399 6488 Autres charges de personnel Charge
400 65 AUTRES CHARGES DE GESTION COURANTE Charge
401 6511 Redevances pour concessions, brevets, licences Charge
402 6516 Droits d'auteur et de reproduction Charge
403 6518 Autres droits et valeurs similaires Charge
404 652 Licences fédérales Licences payées pour les adhérents (par exemple fédération sportive etc.) Charge Favori
405 653 Charges de la générosité du public Charge
406 6531 Autres charges sur legs ou donations Charge
407 654 Pertes sur créances irrécouvrables Charge
408 655 Quotes-parts sur opérations faites en commun Charge
409 657 Aides financières Charge
410 6571 Aides financières octroyées Charge
411 6572 Quotes-parts de générosité reversée Charge
412 658 Charges diverses de gestion courante Charge Favori
413 6586 Cotisations (vie statutaire) Charge
414 6588 Charges diverses de gestion courante Charge
415 66 CHARGES FINANCIÈRES Charge
416 661 Charges d'intérêts Charge
417 665 Escomptes accordés Charge
418 666 Pertes de changes Charge
419 667 Charges nettes sur cessions de valeurs mobilières de placement Charge
420 668 Autres charges financières Charge
421 67 Charges exceptionnelles Charge
422 670 Charges exceptionnelles Autres dépenses exceptionnelles Charge Favori
423 6712 Pénalités, amendes fiscales et pénales Charge
424 6713 Dons, libéralités Charge
425 6714 Créances devenues irrécouvrables Charge
426 6718 Autres charges exceptionnelles de gestion Charge
427 673 Apports ou affectations en numéraire Charge
428 675 Valeurs comptables des éléments d'actifs cédés Charge
429 6750 Valeurs comptables des actifs cédés Charge
430 6754 Immobilisations reçues par legs ou donations Charge
431 678 Autres charges exceptionnelles sur opération en capital Charge
432 68 Dotation AUX AMORTISSEMENTS, DÉPRÉCIATIONS ET ENGAGEMENTS Charge
433 6811 Dotation aux amortissements des immobilisations Charge
434 6812 Dotation aux amortissements charges à répartir Charge
435 6815 Dotation aux provisions d'exploitation Charge
436 6816 Dotation provisions pour dépréciations des immobillisations Charge
437 68164 Dotation pr dépréc. d’actifs reçus par legs ou donations Charge
438 6817 Dotation aux dépréciations des actifs circulants Charge
439 68173 Dotations dépréciations stocks et en-cours Charge
440 68174 Dotations dépréciations créances Charge
441 686 Dotation aux amortissements & Provisions - Charges financières Charge
442 68662 Dotation aux amortissements & provisions immobilisations financières Charge
443 68665 Dotation aux amortissements & provisions valeurs mobilières de placement Charge
444 687 Dotation aux amortissements & Provisions - Charges exceptionnelles Charge
445 689 Reports en fonds dédiés Charge
446 6891 Reports en fonds reportés Charge
447 6894 Reports en fonds dédiés / subventions d’exploitation Charge
448 6895 Reports en fonds dédiés / contributions financières d'autres organismes Charge
449 6896 Reports en fonds dédiés / ressources générosité Charge
450 69 IMPÔTS SUR LES BÉNÉFICES Charge
451 695 Impôts sur les bénéfices Charge
452 7 Classe 7 — Comptes de produits Produit
453 70 VENTES PROD.FINIS, MARCHANDISES, PRESTATIONS Produit
454 701 Ventes de produits finis Vente de produits fabriqués par l'association. Produit Favori
455 702 Ventes de produits intermédiaires Produit
456 703 Ventes de produits résiduels Produit
457 704 Travaux Produit
458 705 Études Produit Favori
459 706 Prestations de services Produit Favori
460 7063 Parrainages Produit
461 707 Ventes de marchandises Ventes de produits achetés et revendus en l’état Produit Favori
462 7073 Ventes de dons en nature Produit
463 708 Produits des activités annexes Produit
464 7081 Produits des services exploités dans l’intérêt du personnel Produit
465 7083 Locations diverses Produit
466 7085 Ports et frais accessoires facturés Produit
467 7088 Autres produits d'activités annexes Produit
468 709 Rabais, remises, ristournes accordés Produit
469 7091 Rabais, remises, ristournes sur ventes de produits finis Produit
470 7092 Rabais, remises, ristournes sur ventes de produits intermédiaires Produit
471 7094 Rabais, remises, ristournes sur travaux Produit
472 7095 Rabais, remises, ristournes sur études Produit
473 7096 Rabais, remises, ristournes sur prest.de services Produit
474 7097 Rabais, remises, ristournes sur ventes marchandises Produit
475 71 PRODUCTION STOCKÉE Produit
476 713 Variation de stocks (en-cours, productions) Produit
477 7133 Variation des en-cours de production de biens Produit
478 7134 Variation des en-cours de production services Produit
479 7135 Variations de stocks de produits Produit
480 72 PRODUCTION IMMOBILISÉE Produit
481 721 Production immobilisée incorporelle Produit
482 722 Production immobilisée corporelle Produit
483 73 CONCOURS PUBLICS Produit
484 730 Concours publics Produit
485 74 SUBVENTION D'EXPLOITATION Produit
486 740 Subventions reçues Produit Favori
487 7403 Autres subventions Produit Favori
488 748 Subventions d'exploitation diverses Produit
489 75 AUTRES PRODUITS DE GESTION COURANTE Produit
490 751 Redevances pour concessions, licences... Produit
491 753 Versements des fondateurs ou consommation dot Produit
492 7531 Versements des fondateurs Produit
493 7532 Quotes-parts de dotation consomptible virée a Produit
494 754 Ressources liées à la générosité du public Dons reçus Produit Favori
495 7541 Dons manuels Produit
496 75411 Dons manuels Produit
497 75412 Abandons de frais par les bénévoles Produit
498 7542 Mécénats Produit
499 7543 Legs, donations et assurances-vie Produit
500 75431 Assurances-vie Produit
501 75432 Legs ou donations Produit
502 75433 Autres produits sur legs ou donations Produit
503 755 Contributions financières Produit
504 7551 Contributions financières d’autres organismes Produit
505 7552 Quotes-parts de générosité reçues Produit
506 756 Cotisations Cotisations des adhérent⋅e⋅s Produit Favori
507 7561 Cotisations sans contrepartie Produit
508 7562 Cotisations avec contrepartie Produit
509 756201 Subvention de fonctionnement reçue l'employeur Produits affectés à la section « Attributions économiques et professionnelles » Produit Favori
510 756202 Contribution reçue de l'employeur Produits affectés à la section « Activités sociales et culturelles » Produit Favori
511 757 Gains de change / créances et dettes d’exploitation Produit
512 758 Produits divers de gestion courante Produit
513 7588 Autres produits divers de gestion courante Produit
514 76 PRODUITS FINANCIERS Produit
515 761 Produits des participations Produit
516 762 Produits des autres immobilisations financières Produit
517 763 Revenus des autres créances Produit
518 764 Revenus des valeurs mobilières de placement Produit
519 765 Escomptes obtenus Produit
520 766 Gains de change Produit
521 767 Produits nets sur cession valeurs mobilières de placement Produit
522 768 Autres produits financiers Produit
523 77 PRODUITS EXCEPTIONNELS Produit
524 771 Produits exceptionnels sur opération de gestion Produit
525 7713 Libéralités perçues Produit
526 7718 Autres produits exceptionnels sur opération de gestion Produit
527 775 Produits des cessions d'actif Produit
528 7754 Immobilisations reçues en legs ou donations à céder Produit
529 777 Quote-part subvention d'investissement virée au résultat Produit
530 778 Autres produits exceptionnels Produit
531 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 Favori
532 78 REPRISES SUR AMORTISSEMENTS, DÉPRÉCIATIONS, ENGAGEMENTS Produit
533 781 Reprises / Amortissements & Provisions d'exploitation Produit
534 7811 Amortissements immobilisations corporelles & incorporelles Produit
535 7815 Reprises sur provisions d'exploitation Produit
536 7816 Dépréciations immobilisations corporelles & incorporelles Produit
537 78164 Reprises dépréciations d’actifs reçus par legs ou donations destinés à être cédés Produit
538 7817 Dépréciations actifs circulant Produit
539 786 Reprises sur provisions pour risques et dépréciations À inscrire dans les produits exceptionnels Produit
540 7865 Risques & charges financiers Produit
541 7866 Déprec.des éléments financiers Produit
542 787 Reprises sur provisions pour risques et dépréciations À inscrire dans les produits exceptionnels Produit
543 7872 Provisions réglementées - Immobilisations Produit
544 7873 Provisions réglementées - stocks Produit
545 7874 Autres provisions réglementées Produit
546 7875 Risques et charges Produit
547 7876 Dépréciations exceptionnelles Produit
548 789 Utilisations fonds reportés et de fonds dédiés Produit
549 7891 Utilisations de fonds reportés Produit
550 7894 Utilisations des fonds dédiés / subventions Produit
551 7895 Utilisations des fonds dédiés / contributions Produit
552 7896 Utilisations des fonds dédiés / générosité Produit
553 79 TRANSFERT DE CHARGES Produit
554 791 Transferts de charges d'exploitation Produit
555 796 Transferts de charges financières Produit
556 797 Transferts de charges exceptionnelles Produit
557 8 Classe 8 ­— Comptes spéciaux
558 80 ENGAGEMENTS
559 801 Engagements donnés par l’entité
560 8011 Avals, cautions, garanties
561 8014 Effets circulant sous l’endos de l’entité
562 8016 Redevances crédit-bail restant à courir
563 80161 Crédit-bail mobilier
564 80165 Crédit-bail immobilier
565 8018 Autres engagements donnés
566 802 Engagements reçus par l’entité
567 8021 Avals, cautions, garanties
568 8024 Créances escomptées non échues
569 8026 Engagements reçus pour utilisation en crédit-bail
570 80261 Crédit-bail mobilier
571 80265 Crédit-bail immobilier
572 8028 Autres engagements reçus
573 809 Contrepartie des engagements
574 8091 Contrepartie 801
575 8092 Contrepartie 802
576 86 EMPLOI DES CONTRIBUTIONS VOLONTAIRES EN NATURE
577 860 Secours en nature (alimentaires, vestimentaires…) Charge
578 861 Mise à disposition gratuite de biens (locaux, matériels…) Charge
579 862 Prestations Charge
580 864 Personnel bénévole Charge
581 87 CONTRIBUTIONS VOLONTAIRES EN NATURE
582 870 Bénévolat Produit
583 871 Prestations en nature Produit
584 875 Dons en nature Produit
585 89 COMPTES DE BILAN
586 890 Bilan d'ouverture Actif ou passif
587 891 Bilan de clôture Actif ou passif

View file

@ -0,0 +1,295 @@
code,label,description,position,bookmark
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,
129,Résultat de l'exercice (déficit),,Passif,
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,Favori
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,Favori
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 ou passif,
445,État - Taxes sur le chiffre d'affaires,,Actif ou passif,
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 ou passif,Favori
5115,Paiements par carte à encaisser,,Actif ou passif,
512,Banques,,Actif ou passif,
53,CAISSE,,Actif,
530,Caisse,,Actif ou passif,Favori
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,Favori
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,Favori
6063,Fournitures d'entretien et de petit équipement,,Charge,Favori
6064,Fournitures administratives,"Cartouches d'encre, papier, matériel bureautique, etc.",Charge,Favori
6068,Autres matières et fournitures,,Charge,Favori
607,Achats de marchandises,Marchandises destinées à être revendues en l'état.,Charge,Favori
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,Favori
614,Charges locatives et de co-propriété,,Charge,
615,Entretiens et réparations,,Charge,
616,Primes d'assurance,,Charge,Favori
618,Divers,,Charge,
62,AUTRES SERVICES EXTÉRIEURS,,Charge,
621,Personnel extérieur à l'association,,Charge,
62141,Mises à disposition de personnel salarié,,Charge,Favori
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,Favori
6228,Divers,,Charge,
623,"Publicité, publications, relations publiques","Bulletins, affiches, communication, etc.",Charge,Favori
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,Favori
626,Frais postaux et de télécommunications,"Facture d'accès à Internet, timbres, etc.",Charge,Favori
627,Services bancaires et assimilés,Frais bancaires,Charge,Favori
628,Divers,,Charge,Favori
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,Favori
658,Charges diverses de gestion courante,,Charge,Favori
66,CHARGES FINANCIÈRES,,Charge,
661,Charges d'intérêts,,Charge,
67,CHARGES EXCEPTIONNELLES,,Charge,
670,Charges exceptionnelles,Autres dépenses exceptionnelles,Charge,Favori
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,Favori
706,Prestations de services,,Produit,Favori
707,Ventes de marchandises,,Produit,Favori
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,Favori
75,AUTRES PRODUITS DE GESTION COURANTE,,Produit,
754,Collectes,,Produit,Favori
756,Cotisations,,Produit,Favori
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,Favori
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,Favori
864,Personnel bénévole,,Charge,Favori
87,RÉPARTITION PAR NATURE DE RESSOURCES,,Produit,
870,Bénévolat,,Produit,Favori
871,Prestations en nature,,Produit,Favori
875,Dons en nature,,Produit,
89,BILAN,,,
890,Bilan d'ouverture,,Actif ou passif,
891,Bilan de clôture,,Actif ou passif,
1 code label description position bookmark
2 1 Classe 1 — Comptes de capitaux (Fonds propres, emprunts et dettes assimilés) Passif
3 10 FONDS ASSOCIATIFS ET RÉSERVES Passif
4 102 Fonds associatif sans droit de reprise Passif
5 1021 Valeur du patrimoine intégré Passif
6 1022 Fonds statutaire Passif
7 1024 Apports sans droit de reprise Passif
8 103 Fonds associatif avec droit de reprise Passif
9 1034 Apports avec droit de reprise Passif
10 105 Écarts de réévaluation Passif
11 106 Réserves Passif
12 1063 Réserves statutaires ou contractuelles Passif
13 1064 Réserves réglementées Passif
14 1068 Autres réserves (dont réserves pour projet associatif) Passif
15 11 REPORT À NOUVEAU Passif
16 110 Report à nouveau (Solde créditeur) Passif
17 119 Report à nouveau (Solde débiteur) Passif
18 12 RÉSULTAT NET DE L'EXERCICE Passif
19 120 Résultat de l'exercice (excédent) Passif
20 129 Résultat de l'exercice (déficit) Passif
21 13 SUBVENTIONS D'INVESTISSEMENT AFFECTÉES A DES BIENS NON RENOUVELABLES Passif
22 131 Subventions d'investissement (renouvelables) Passif
23 139 Subventions d'investissement inscrites au compte de résultat Passif
24 14 PROVISIONS REGLEMENTÉES Passif
25 15 PROVISIONS Passif
26 151 Provisions pour risques Passif
27 157 Provisions pour charges à répartir sur plusieurs exercices Passif
28 158 Autres provisions pour charges Passif
29 16 EMPRUNTS ET DETTES ASSIMILÉES Passif
30 164 Emprunts auprès des établissements de crédits Passif
31 165 Dépôts et cautionnements reçus Passif
32 167 Emprunts et dettes assorties de conditions particulières Passif
33 168 Autres emprunts et dettes assimilés Passif
34 17 DETTES RATTACHÉES À DES PARTICIPATIONS Passif
35 18 COMPTES DE LIAISON DES ÉTABLISSEMENTS Passif
36 181 Apports permanents entre siège social et établissements Passif
37 185 Biens et prestations de services échangés entre établissements et siège social Passif
38 186 Biens et prestations de services échangés entre établissements (charges) Passif
39 187 Biens et prestations de services échangés entre établissements (produits) Passif
40 19 FONDS DÉDIÉS Passif
41 194 Fonds dédiés sur subventions de fonctionnement Passif
42 195 Fonds dédiés sur dons manuels affectés Passif
43 197 Fonds dédiés sur legs et donations affectés Passif
44 198 Excédent disponible après affectation au projet associatif Passif
45 199 Reprise des fonds affectés au projet associatif Passif
46 2 Classe 2 — Comptes d'immobilisations Actif
47 20 IMMOBILISATIONS INCORPORELLES Actif
48 200 Immobilisations incorporelles Actif
49 21 IMMOBILISATIONS CORPORELLES Actif
50 210 Investissements Actif
51 22 IMMOBILISATIONS GREVÉES DE DROITS Actif
52 228 Immobilisations grevées de droits Actif
53 229 Droits des propriétaires Actif
54 23 IMMOBILISATIONS EN COURS Actif
55 231 Immobilisations corporelles en cours Actif
56 238 Avances et acomptes versés sur commande d'immobilisations corporelles Actif
57 26 PARTICIPATIONS ET CRÉANCES RATTACHÉES A DES PARTICIPATIONS Actif
58 261 Titres de participation Actif
59 27 AUTRES IMMOBILISATIONS FINANCIÈRES Actif
60 270 Participations financières Actif
61 275 Dépôts et cautionnements versés Actif
62 28 AMORTISSEMENTS DES IMMOBILISATIONS Actif
63 280 Amortissements des immobilisations incorporelles Actif
64 281 Amortissements des immobilisations corporelles Actif
65 29 DÉPRÉCIATION DES IMMOBILISATIONS Actif
66 290 Dépréciation des immobilisations incorporelles Actif
67 291 Dépréciation des immobilisations corporelles Actif
68 3 Classe 3 — Comptes de stocks Actif
69 31 MATIERES PREMIERES ET FOURNITURES Actif
70 311 Matières Actif
71 317 Fournitures Actif
72 32 AUTRES APPROVISIONNEMENTS Actif
73 321 Matières consommables Actif
74 322 Fournitures consommables Actif
75 33 EN-COURS DE PRODUCTION DE BIENS Actif
76 331 Produits en cours Actif
77 335 Travaux en cours Actif
78 34 EN-COURS DE PRODUCTION DE SERVICES Actif
79 35 STOCKS DE PRODUITS Actif
80 351 Produits intermédiaires Actif
81 355 Produits finis Actif
82 358 Produits résiduels Actif
83 3581 Déchets Actif
84 3585 Rebuts Actif
85 3586 Matière de récupération Actif
86 37 STOCKS DE MARCHANDISES Actif
87 370 Autres stocks de marchandises Actif
88 39 PROVISIONS POUR DEPRECIATION DES STOCKS ET EN-COURS Actif
89 391 Provisions pour dépréciation des matières premières et fournitures Actif
90 4 Classe 4 — Comptes de tiers Actif ou passif
91 40 FOURNISSEURS ET COMPTES RATTACHÉS Passif
92 401 Fournisseurs Passif
93 4010 Autres fournisseurs Actif ou passif Favori
94 408 Fournisseurs - Factures non parvenues Passif
95 409 Avances aux fournisseurs Actif
96 41 USAGERS ET COMPTES RATTACHÉS Actif
97 411 Usagers Actif
98 4110 Autres usagers Actif ou passif Favori
99 419 Avances aux usagers Passif
100 42 PERSONNEL ET COMPTES RATTACHÉS Passif
101 421 Personnel - Rémunérations dues Passif
102 4210 Autres membres du personnel Actif ou passif
103 425 Personnel - Avances et acomptes Actif
104 428 Personnel - Charges à payer et produits à recevoir Actif ou passif
105 43 SÉCURITÉ SOCIALE ET AUTRES ORGANISMES SOCIAUX Passif
106 430 Dettes et crédits envers les organismes sociaux Passif
107 431 Sécurité sociale Passif
108 437 Autres organismes sociaux Passif
109 4372 Mutuelles Passif
110 4373 Caisse de retraite et de prévoyance Passif
111 4374 Caisse d'allocations de chômage - Pôle emploi Passif
112 4375 AGESSA Passif
113 4378 Autres organismes sociaux - Divers Passif
114 438 Organismes sociaux - Charges à payer et produits à recevoir Actif ou passif
115 4382 Charges sociales sur congés à payer Passif
116 4386 Autres charges à payer Passif
117 4387 Produits à recevoir Actif
118 439 Avances auprès des organismes sociaux Passif
119 44 ÉTAT ET AUTRES COLLECTIVITÉS PUBLIQUES Actif
120 441 État - Subventions à recevoir Actif
121 4411 Subventions d'investissement Actif
122 4417 Subventions d'exploitation Actif
123 4418 Subventions d'équilibre Actif
124 4419 Avances sur subventions Actif
125 442 État - Impôts et taxes recouvrables sur des tiers Passif
126 444 État - Impôts sur les bénéfices Actif ou passif
127 445 État - Taxes sur le chiffre d'affaires Actif ou passif
128 4455 Taxes sur le chiffre d'affaires à décaisser Actif
129 44551 TVA à décaisser Actif
130 44558 Taxes assimilées à la TVA Actif
131 4456 Taxes sur le chiffre d'affaires déductibles Actif
132 44562 TVA sur immobilisations Actif
133 44566 TVA sur autres biens et services Actif
134 4457 Taxes sur le chiffre d'affaires collectées par l'association Actif
135 4458 Taxes sur le chiffre d'affaires à régulariser ou en attente Actif
136 44581 Acomptes - Régime simplifié d'imposition Actif
137 44582 Acomptes - Régime du forfait Actif
138 44583 Remboursement de taxes sur le chiffre d'affaires demandé Actif
139 44584 TVA récupérée d'avance Actif
140 44586 Taxes sur le chiffre d'affaires sur factures non parvenues Actif
141 44587 Taxes sur le chiffre d'affaires sur factures à établir Actif
142 447 Autres impôts, taxes et versements assimilés Passif
143 4471 Autres impôts, taxes et versements assimilés sur rémunérations (Administration des impôts) Passif
144 44711 Taxe sur les salaires Passif
145 44713 Participation des employeurs à la formation professionnelle continue Passif
146 44714 Cotisation par défaut d'investissement obligatoire dans la construction Passif
147 44718 Autres impôts, taxes et versements assimilés Passif
148 4473 Autres impôts, taxes et versements assimilés sur rémunérations (Autres organismes) Passif
149 44733 Participation des employeurs à la formation professionnelle continue Passif
150 44734 Participation des employeurs à l'effort de construction (versements à fonds perdus) Passif
151 4475 Autres impôts, taxes et versements assimilés (Administration des impôts) Passif
152 4477 Autres impôts, taxes et versements assimilés (Autres organismes) Passif
153 448 État - Charges à payer et produits à recevoir Passif
154 4482 Charges fiscales sur congés à payer Passif
155 4486 Autres charges à payer Passif
156 4487 Produits à recevoir Actif
157 449 Avances auprès de l'état et des collectivités publiques Passif
158 45 CONFÉDÉRATION, FÉDÉRATION, UNIONS ET ASSOCIATIONS AFFILIÉES Actif ou passif
159 451 Confédération, fédération et associations affiliées - Compte courant Actif ou passif
160 455 Sociétaires - Comptes courants Actif ou passif
161 46 DÉBITEURS DIVERS ET CRÉDITEURS DIVERS Actif ou passif
162 467 Autres comptes débiteurs et créditeurs Actif ou passif
163 468 Divers - Charges à payer et produits à recevoir Actif ou passif
164 4686 Charges à payer Passif
165 4687 Produits à recevoir Actif
166 47 COMPTES TRANSITOIRES OU D'ATTENTE Actif ou passif
167 471 Recettes à classer Passif
168 472 Dépenses à classer et à régulariser Actif
169 48 COMPTES DE RÉGULARISATION Actif ou passif
170 481 Charges à répartir sur plusieurs exercices Actif
171 486 Charges constatées d'avance Actif
172 487 Produits constatés d'avance Passif
173 49 DEPRECIATION DES COMPTES DE TIERS Actif
174 491 Dépréciation des comptes clients Actif
175 496 Dépréciation des comptes débiteurs divers Actif
176 5 Classe 5 — Comptes financiers Actif
177 50 VALEURS MOBILIÈRES DE PLACEMENT Actif
178 51 BANQUES, ÉTABLISSEMENTS FINANCIERS ET ASSIMILÉS Actif
179 511 Valeurs à l'encaissement Actif
180 5112 Chèques à encaisser Actif ou passif Favori
181 5115 Paiements par carte à encaisser Actif ou passif
182 512 Banques Actif ou passif
183 53 CAISSE Actif
184 530 Caisse Actif ou passif Favori
185 54 RÉGIES D'AVANCES ET ACCRÉDITIFS Actif
186 58 VIREMENTS INTERNES Actif
187 59 PROVISIONS POUR DÉPRÉCIATION DES COMPTES FINANCIERS Actif
188 6 Classe 6 — Comptes de charges Charge
189 60 ACHATS Charge
190 601 Achats stockés - Matières premières et fournitures Charge
191 602 Achats stockés - Autres approvisionnements Charge
192 604 Achat d'études et prestations de services Charge Favori
193 606 Achats non stockés de matières et fournitures Charge
194 6061 Fournitures non stockables (eau, énergie...) Facture d'eau, d'opérateur électrique, etc. Charge Favori
195 6063 Fournitures d'entretien et de petit équipement Charge Favori
196 6064 Fournitures administratives Cartouches d'encre, papier, matériel bureautique, etc. Charge Favori
197 6068 Autres matières et fournitures Charge Favori
198 607 Achats de marchandises Marchandises destinées à être revendues en l'état. Charge Favori
199 61 SERVICES EXTÉRIEURS Charge
200 611 Sous-traitance générale Charge
201 612 Redevances de crédit-bail Charge
202 613 Locations Locations versées pour un local ou du matériel. Charge Favori
203 614 Charges locatives et de co-propriété Charge
204 615 Entretiens et réparations Charge
205 616 Primes d'assurance Charge Favori
206 618 Divers Charge
207 62 AUTRES SERVICES EXTÉRIEURS Charge
208 621 Personnel extérieur à l'association Charge
209 62141 Mises à disposition de personnel salarié Charge Favori
210 622 Rémunérations d'intermédiaires et honoraires Charge
211 6226 Honoraires Charge
212 6227 Frais d'actes et de contentieux Insertion au Journal Officiel, frais de justice, etc. Charge Favori
213 6228 Divers Charge
214 623 Publicité, publications, relations publiques Bulletins, affiches, communication, etc. Charge Favori
215 624 Transports de biens et transports collectifs du personnel Charge
216 625 Déplacements, missions et réceptions Billet SNCF, remboursement de frais kilométrique, etc. Charge Favori
217 626 Frais postaux et de télécommunications Facture d'accès à Internet, timbres, etc. Charge Favori
218 627 Services bancaires et assimilés Frais bancaires Charge Favori
219 628 Divers Charge Favori
220 63 IMPÔTS, TAXES ET VERSEMENTS ASSIMILÉS Charge
221 631 Impôts, taxes et versements assimilés sur rémunérations (Administration des impôts) Charge
222 6311 Taxes sur les salaires Charge
223 6313 Participations des employeurs à la formation professionnelle continue Charge
224 635 Autres impôts, taxes et versements assimilés (Administration des impôts) Charge
225 6351 Impôts directs (sauf impôts sur les bénéfices) Charge
226 6353 Impôts indirects Charge
227 637 Autres impôts, taxes et versements assimilés (Autres organismes) Charge
228 64 CHARGES DE PERSONNEL Charge
229 641 Rémunérations du personnel Charge
230 643 Rémunérations du personnel artistique et assimilés Charge
231 645 Charges de sécurité sociale et de prévoyance Charge
232 647 Autres charges sociales Charge
233 648 Autres charges de personnel Charge
234 65 AUTRES CHARGES DE GESTION COURANTE Charge
235 652 Licences fédérales Licences payées pour les adhérents (par exemple fédération sportive etc.) Charge Favori
236 658 Charges diverses de gestion courante Charge Favori
237 66 CHARGES FINANCIÈRES Charge
238 661 Charges d'intérêts Charge
239 67 CHARGES EXCEPTIONNELLES Charge
240 670 Charges exceptionnelles Autres dépenses exceptionnelles Charge Favori
241 671 Charges exceptionnelles sur opérations de gestion Charge
242 6713 Dons, libéralités Charge
243 678 Autres charges exceptionnelles Charge
244 6788 Charges exceptionnelles diverses Charge
245 68 DOTATIONS AUX AMORTISSEMENTS, DÉPRÉCIATIONS, PROVISIONS ET ENGAGEMENTS Charge
246 681 Dotations aux amortissements, dépréciations et provisions - Charges d'exploitation Charge
247 6811 Dotations aux amortissements des immobilisations incorporelles et corporelles Charge
248 68111 Immobilisations incorporelles Charge
249 68112 Immobilisations corporelles Charge
250 686 Dotations aux amortissements, dépréciations et provisions - Charges financières Charge
251 69 PARTICIPATION DES SALARIÉS - IMPÔTS SUR LES BÉNÉFICES ET ASSIMILÉS Charge
252 695 Impôts sur les sociétés (y compris impôts sur les sociétés des personnes morales non lucratives) Charge
253 7 Classe 7 — Comptes de produits Produit
254 70 VENTES DE PRODUITS FINIS, PRESTATIONS DE SERVICES, MARCHANDISES Produit
255 701 Ventes de produits finis Vente de produits fabriqués par l'association. Produit Favori
256 706 Prestations de services Produit Favori
257 707 Ventes de marchandises Produit Favori
258 708 Produits des activités annexes Produit
259 71 PRODUCTION STOCKÉE (OU DÉSTOCKAGE) Produit
260 72 PRODUCTION IMMOBILISÉE Produit
261 74 SUBVENTIONS D'EXPLOITATION Produit
262 740 Subventions reçues Produit Favori
263 75 AUTRES PRODUITS DE GESTION COURANTE Produit
264 754 Collectes Produit Favori
265 756 Cotisations Produit Favori
266 758 Produits divers de gestion courante Produit
267 7587 Ventes de dons en nature Produit
268 7588 Autres produits de la générosité du public Produit
269 76 PRODUITS FINANCIERS Produit
270 760 Produits financiers Produit
271 77 PRODUITS EXCEPTIONNELS Produit
272 771 Produits exceptionnels sur opérations de gestion Produit
273 7713 Libéralités reçues Produit
274 7715 Subventions d'équilibre Produit
275 775 Produits des cessions d'éléments d'actifs Produit
276 778 Autres produits exceptionnels Produit
277 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 Favori
278 7788 Produits exceptionnels divers Produit
279 78 REPRISES SUR AMORTISSEMENTS ET PROVISIONS Produit
280 79 TRANSFERT DE CHARGES Produit
281 791 Transferts de charges d'exploitation Produit
282 796 Transferts de charges financières Produit
283 797 Transferts de charges exceptionnels Produit
284 8 Classe 8 ­— Comptes spéciaux
285 86 RÉPARTITION PAR NATURE DE CHARGES Charge
286 861 Mise à dispositions gratuites de biens Charge
287 862 Prestations Charge Favori
288 864 Personnel bénévole Charge Favori
289 87 RÉPARTITION PAR NATURE DE RESSOURCES Produit
290 870 Bénévolat Produit Favori
291 871 Prestations en nature Produit Favori
292 875 Dons en nature Produit
293 89 BILAN
294 890 Bilan d'ouverture Actif ou passif
295 891 Bilan de clôture Actif ou passif

View file

@ -0,0 +1,553 @@
code,label,description,position,bookmark
1,"Classe 1 — Comptes de capitaux (Fonds propres, emprunts et dettes assimilés)",,Passif,
10,Fonds propres et réserves,,Passif,
102,Fonds propres 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 propres 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 lentité,,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 lexercice,,Passif,
120,Résultat de l'exercice (excédent),,Passif,
129,Résultat de l'exercice (déficit),,Passif,
13,Subventions dinvestissement,,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 dusufruit,,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 dusufruit,,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,Biens 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 financières,,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 immobilisations,,Actif,
2801,Amt. frais d'établissement,,Actif,
2804,Amt. donations temporaires dusufruit,,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 production 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 pour dépréciations stocks et 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,Favori
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,Favori
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,Favori
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 et 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,
438,Organismes sociaux - Charges à payer et produits à recevoir,,Passif,
4382,Charges sociales sur congés à payer,,Passif,
4386,Autres charges à payer,,Passif,
4387,Produits à recevoir,,Passif,
44,État et autres collectivités publiques,,Actif,
441,État - Subventions à recevoir,,Actif,
4421,Prélèvements à la source - Impôt sur le revenu,,Actif ou passif,
444,État - 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,État - Charges à payer,,Passif,
4487,État - Produits à recevoir,,Actif,
45,"Confédération, fédération, unions… affiliées",,Actif ou passif,
451,"Confédération, fédération et associations affiliées",,Actif ou passif,
455,Partenaires - comptes courants,,Actif ou passif,
46,Débiteurs divers et créditeurs divers,,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 dattente,,Actif ou passif,
4715,Compte de transit,,Actif ou passif,
4718,Compte d'attente,,Actif ou passif,
48,Comptes de régularisation,,Actif ou passif,
481,Charges à répartir,,Passif,
486,Charges constatées d'avance,,Actif,
487,Produits constatés d'avance,,Passif,
49,Dépréciations des comptes de tiers,,Actif ou passif,
491,Provision pour dépreciation des comptes d'usagers,,Passif,
496,Provision pour dépreciation des comptes débiteurs divers,,Passif,
5,Classe 5 — Comptes financiers,,Actif,
50,Valeurs mobilières de placement,,Actif,
503,Actions,,Actif,
506,Obligations,,Actif,
508,Autres VMP et créances assimilées,,Actif,
51,"Banques, établissements financiers",,Actif,
5112,Chèques à encaisser,,Actif ou passif,Favori
5115,Paiements par carte à encaisser,,Actif ou passif,
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 ou passif,Favori
58,Virements internes,,Actif ou passif,
580,Virements internes,,Actif ou passif,
59,Dépréciations 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,Favori
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,Favori
6064,Fournitures administratives,"Cartouches d'encre, papier, matériel bureautique, etc.",Charge,Favori
6065,Petits logiciels,Par exemple contribution à un logiciel de gestion associative génial :-),Charge,Favori
6068,Autres fournitures & matières,,Charge,Favori
607,Achats de marchandises,Marchandises destinées à être revendues en l'état.,Charge,Favori
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 extérieurs,,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,Favori
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 dassurance local, activité, etc.",Charge,Favori
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,Études 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 extérieurs,,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 demployeurs,Charge,Favori
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 divers intermédiaires & honoraires,,Charge,
623,"Publicité, publications, relations publiques","Bulletins, affiches, communication, etc.",Charge,Favori
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,Favori
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,Favori
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,Favori
628,Divers,,Charge,Favori
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 construction,,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évoyance,,Charge,
6458,Cotisations aux autres organismes sociaux,,Charge,
647,Autres charges sociales,,Charge,
6472,Versements aux comités d'entreprise et d'établissement,,Charge,
6473,Versement aux comités d'hygiène et de sécurité,,Charge,
6474,Versements aux autres œuvres 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, licences",,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,Favori
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,Favori
6586,Cotisations (vie statutaire),,Charge,
6588,Charges diverses de gestion courante,,Charge,
66,Charges financières,,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 exceptionnelles,,Charge,
670,Charges exceptionnelles,Autres dépenses exceptionnelles,Charge,Favori
6712,"Pénalités, amendes fiscales et pénales",,Charge,
6713,"Dons, libéralités",,Charge,
6714,Créances devenues irrécouvrables,,Charge,
6718,Autres charges exceptionnelles de gestion,,Charge,
672,Charges sur exercices antérieurs,,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,"Dotations aux amortissements, dépréciations 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 immobilisations,,Charge,
68164,Dot. pour dépréciation dactifs 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 amortissements & provisions - Charges financières,,Charge,
68662,Dot. aux amortissements & provisions des immobilisations financières,,Charge,
68665,Dot. aux amortissements & provisions des valeurs mobilières de placement,,Charge,
687,Dot. aux amortissements & provisions - Charges exceptionnelles,,Charge,
689,Reports en fonds dédiés,,Charge,
6891,Reports en fonds reportés,,Charge,
6894,Reports en fonds dédiés / subventions dexploitation,,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 bénéfices,,Charge,
695,IS sur personnes non lucratives,,Charge,
7,Classe 7 — Comptes de produits,,Produit,
70,"Ventes de produits finis, marchandises, prestations",,Produit,
701,Ventes de produits finis,Vente de produits fabriqués par l'association.,Produit,Favori
702,Ventes de produits intermédiaires,,Produit,
703,Ventes de produits résiduels,,Produit,
704,Travaux,,Produit,
705,Études,,Produit,
706,Prestations de services,,Produit,Favori
7063,Parrainages,,Produit,
707,Ventes de marchandises,Ventes de produits achetés et revendus en létat,Produit,Favori
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 stockée,,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 immobilisée corporelle,,Produit,
721,Production immobilisée incorporelle,,Produit,
722,Production immobilisée corporelle,,Produit,
73,Concours publics,,Produit,
730,Concours publics,,Produit,
74,Subventions dexploitation,,Produit,
740,Subventions reçues,,Produit,Favori
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,Favori
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 dautres organismes,,Produit,
7552,Quotes-parts de générosité reçues,,Produit,
756,Cotisations,Cotisations des adhérent⋅e⋅s,Produit,Favori
7561,Cotisations sans contrepartie,,Produit,
7562,Cotisations avec contrepartie,,Produit,
757,Gains de change / créances et dettes dexploitation,,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 immobilisations financières,,Produit,
763,Revenus des autres créances,,Produit,
764,Revenus des valeurs mobilières de placement,,Produit,
765,Escomptes obtenus,,Produit,
766,Gains de change,,Produit,
767,Produits nets sur cession valeurs mobilières de placement,,Produit,
768,Autres produits financiers,,Produit,
77,Produits exceptionnels,,Produit,
771,Produits exceptionnels sur opération de gestion,,Produit,
7713,Libéralités perçues,,Produit,
7718,Autres produits exceptionnel sur opération de gestion,,Produit,
772,Produits sur exercices antérieurs,,Produit,
775,Produits des cessions d'actif,,Produit,
7754,Immobilisations reçues en legs ou donations à céder,,Produit,
777,Quote-part de subvention d'investissement virée au résultat,,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,Favori
78,"Reprises sur amortissement, dépréciations, engagements",,Produit,
781,Reprises / amortissements & provisions d'exploitation,,Produit,
7811,Amortissement immobilisations corporelles & incorporelles,,Produit,
7815,Reprises sur provisions d'exploitation,,Produit,
7816,Dépréciation immobilisations corporelles & incorporelles,,Produit,
78164,Reprises de dépréciations dactifs reçus par legs ou donations destinés à être cédés,,Produit,
7817,Dépréciations actifs circulant,,Produit,
786,Reprises / amortissements & provisions financiers,,Produit,
7865,Risques et charges financiers,,Produit,
7866,Dépréciations 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 fonds reportés et de fonds dédiés,,Produit,
7891,Utilisations de fonds reportés,,Produit,
7894,Utilisations des fonds dédiés / subventions,,Produit,
7895,Utilisations des fonds dédiés / contributions,,Produit,
7896,Utilisations des fonds 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 des contributions volontaires en nature,,,
860,Secours en nature,,Charge,Favori
8601,Alimentaires,,Charge,Favori
8602,Vestimentaires,,Charge,Favori
861,Mise à dispositions gratuites de biens,,Charge,Favori
8611,Locaux,,Charge,Favori
8612,Matériels,,Charge,Favori
862,Prestations,,Charge,Favori
864,Personnel bénévole,,Charge,Favori
87,Contributions volontaires en nature,,,
870,Dons en nature,,Produit,Favori
871,Prestations en nature,,Produit,Favori
875,Bénévolat,,Produit,Favori
89,Comptes de bilan,,,
890,Bilan d'ouverture,,Actif ou passif,
891,Bilan de clôture,,Actif ou passif,
1 code label description position bookmark
2 1 Classe 1 — Comptes de capitaux (Fonds propres, emprunts et dettes assimilés) Passif
3 10 Fonds propres et réserves Passif
4 102 Fonds propres sans droit de reprise Passif
5 1021 Première situation nette établie Passif
6 1022 Fonds statutaires Passif
7 1023 Dotations non consomptibles Passif
8 10231 Dotations non consomptibles initiales Passif
9 10232 Dotations non consomptibles complémentaires Passif
10 1024 Autres fonds propres sans droit de reprise Passif
11 103 Fonds propres avec droit de reprise Passif
12 1032 Fonds statutaires Passif
13 1034 Autres fonds propres avec droit de reprise Passif
14 105 Ecarts de réévaluation Passif
15 1051 Ecarts réévaluation sur biens sans dt reprise Passif
16 1052 Ecarts réévaluation sur biens avec dt reprise Passif
17 106 Réserves Passif
18 1062 Réserves indisponibles Passif
19 1063 Réserves statutaires Passif
20 1064 Réserves réglementées Passif
21 1068 Réserves pour projet de l’entité Passif
22 108 Dotations consomptibles Passif
23 1081 Dotations consomptibles Passif
24 1089 Dot. consomptibles inscrites au cpte de résul Passif
25 11 Report à nouveau Passif
26 110 Report à nouveau (Solde créditeur) Passif
27 119 Report à nouveau (Solde débiteur) Passif
28 12 Résultat net de l’exercice Passif
29 120 Résultat de l'exercice (excédent) Passif
30 129 Résultat de l'exercice (déficit) Passif
31 13 Subventions d’investissement Passif
32 131 Subventions d'équipement Passif
33 139 Subventions inscrites au compte de résultat Passif
34 14 Provisions réglementées Passif
35 148 Autres provisions réglementées Passif
36 15 Provisions pour risques et charges Passif
37 151 Provisions pour risques Passif
38 152 Provisions pour charges sur legs ou donations Passif
39 153 Provisions pour pensions et obligations simil Passif
40 155 Provisions pour impôts Passif
41 157 Provisions pour charges à répartir Passif
42 158 Autres provisions pour charges Passif
43 16 Emprunts et dettes assimilées Passif
44 163 Autres emprunts obligataires Passif
45 1631 Titres associatifs et assimilés Passif
46 164 Emprunts auprès des établissements de crédit Passif
47 165 Dépôts et cautionnements reçus Passif
48 1651 Dépôts Passif
49 1655 Cautionnements Passif
50 167 Emprunts et dettes sous conditions particulières Passif
51 168 Autres emprunts et dettes assimilées Passif
52 18 Comptes de liaisons Passif
53 181 Apports permanents siège-établissements Passif
54 185 Biens & PS échangés siège-établissements Passif
55 186 Biens & PS entre établissements - Charges Passif
56 187 Biens & PS entre établissements - Produits Passif
57 19 Fonds dédiés ou reportés Passif
58 191 Fonds reportés liés aux legs ou donations Passif
59 1911 Legs ou donations Passif
60 1912 Donations temporaires d’usufruit Passif
61 194 Fonds dédiés sur subventions fonctionnement Passif
62 195 F.d. / contributions financières autres org. Passif
63 196 F.d. / ressources liées à la générosité Passif
64 2 Classe 2 — Comptes d'immobilisations Actif
65 20 Immobilisations incorporelles Actif
66 201 Frais d'établissement Actif
67 203 Frais de recherche et de développement Actif
68 204 Donations temporaires d’usufruit Actif
69 205 Brevets, licences, marques... Actif
70 206 Droit au bail Actif
71 208 Autres immobilisations incorporelles Actif
72 21 Immobilisations corporelles Actif
73 211 Terrains Actif
74 212 Agencements / aménagements de terrains Actif
75 2131 Bâtiments Actif
76 2135 Installations, agencements...de constructions Actif
77 214 Constructions sur sol d'autrui Actif
78 215 Installations techniques, matériel, outillage Actif
79 2154 Matériel industriel Actif
80 2155 Outillage industriel Actif
81 218 Autres immobilisations corporelles Actif
82 2181 Installations, agencements, aménagem. divers Actif
83 2182 Matériel de transport Actif
84 2183 Matériel bureau et informatique Actif
85 2184 Mobilier Actif
86 23 Immobilisations en cours Actif
87 231 Immobilisations corporelles en cours Actif
88 238 Avances, acomptes sur immobilis. corporelles Actif
89 24 Biens destinés à être cédés Actif
90 240 Biens reçus par legs ou donations à céder Actif
91 26 Participations et créances rattachées Actif
92 261 Titres de participation Actif
93 266 Autres formes de participation Actif
94 267 Créances rattachées à des participations Actif
95 269 Versements restants sur participations Actif
96 27 Immobilisations financières Actif
97 271 Titres immobilisés (droit de propriété) Actif
98 272 Titres immobilisés (droit de créance) Actif
99 274 Prêts Actif
100 2742 Prêts aux partenaires Actif
101 275 Dépôts et cautionnements versés Actif
102 276 Autres créances immobilisées Actif
103 28 Amortissements des immobilisations Actif
104 2801 Amt. frais d'établissement Actif
105 2804 Amt. donations temporaires d’usufruit Actif
106 2805 Amt brevets, licences, marques... Actif
107 2806 Amt. droit au bail Actif
108 2808 Amt. autres immo.incorporelles Actif
109 2812 Amt.agencements, aménagements de terrains Actif
110 28131 Amortissements bâtiments Actif
111 28135 Amt. installations, agencements... Actif
112 2814 Amt.constructions sur sol d'autrui Actif
113 2815 Amt instal. techniques, matériel, outillage Actif
114 28181 Amt. intallations, agencements, aménagements Actif
115 28182 Amt. matériel de transport Actif
116 28183 Amortiss.matériel de bureau, informatique Actif
117 28184 Amortissements du mobilier Actif
118 29 Dépréciations des immobilisations Actif
119 2904 Donations temporaires d'usufruit Actif
120 2905 Brevets, licences, marques... Actif
121 2906 Droit au bail Actif
122 2908 Autres immobilisations incorporelles Actif
123 2911 Terrains Actif
124 2931 Immobilisations corporelles en cours Actif
125 294 Biens reçus par legs ou donations à céder Actif
126 2961 Titres de participations Actif
127 2966 Autres formes de participations Actif
128 2967 Créances rattachées à des participations Actif
129 2971 Titres immobilisés (droit de propriété) Actif
130 2972 Titres immobilisés (droit de créance) Actif
131 2974 Prêts Actif
132 2975 Dépôts et cautionnements versés Actif
133 2976 Autres créances immobilisées Actif
134 3 Classe 3 — Comptes de stocks Actif
135 31 Matières premières et fournitures Actif
136 318 Matières premières et fournitures Actif
137 32 Autres approvisionnements Actif
138 321 Matières consommables Actif
139 322 Fournitures consommables Actif
140 326 Emballages Actif
141 33 En-cours de production de biens Actif
142 331 Produits en cours Actif
143 335 Travaux en cours Actif
144 34 En-cours de production de services Actif
145 341 Etudes en cours Actif
146 345 Prestations de services en cours Actif
147 35 Stocks de produits Actif
148 351 Produits intermédiaires Actif
149 355 Produits finis Actif
150 358 Produits résiduels Actif
151 37 Stocks de marchandises Actif
152 370 Stocks de marchandises Actif
153 39 Provisions pour dépréciations stocks et en-cours Actif
154 391 Matières premières et fournitures Actif
155 392 Autres approvisionnements Actif
156 393 En-cours de production de biens Actif
157 394 En-cours de production de services Actif
158 395 Stocks de produits Actif
159 397 Stocks de marchandises Actif
160 4 Classe 4 — Comptes de tiers Actif ou passif
161 40 Fournisseurs et comptes rattachés Actif ou passif
162 401 Fournisseurs Actif ou passif
163 4010 Autres fournisseurs Actif ou passif Favori
164 403 Fournisseurs - Effets à payer Passif
165 404 Fournisseurs d'immobilisations Actif ou passif
166 405 Fournisseurs d'immos - Effets à payer Passif
167 408 Fournisseurs - Factures non parvenues Passif
168 4091 Fournisseurs - Avances & acomptes Actif
169 41 Usagers et comptes rattachés Actif ou passif
170 411 Usagers Actif ou passif
171 4110 Autres usagers Pour les dettes ou créances des membres Actif ou passif Favori
172 413 Usagers - Effets à recevoir Actif
173 416 Usagers douteux ou litigieux Actif
174 418 Usagers non encore facturés Actif
175 4191 Usagers créditeurs : Avances et acomptes Passif
176 42 Personnel et comptes rattachés Actif ou passif
177 421 Personnel : Rémunérations dues Passif
178 4210 Autres membres du personnel Dettes dûes aux salarié⋅e⋅s Actif ou passif Favori
179 422 Comités d'entreprise, d'établissement Actif ou passif
180 425 Personnel : Avances & acomptes Actif
181 427 Personnel - Oppositions Passif
182 4286 Personnel- Charges à payer Passif
183 4287 Personnel- Produits à recevoir Actif
184 43 Sécurité sociale et autres organismes sociaux Passif
185 431 Sécurité sociale Passif
186 4372 Mutuelles Passif
187 4373 Caisses de retraites et de prévoyance Passif
188 4378 Autres organismes sociaux Passif
189 438 Organismes sociaux - Charges à payer et produits à recevoir Passif
190 4382 Charges sociales sur congés à payer Passif
191 4386 Autres charges à payer Passif
192 4387 Produits à recevoir Passif
193 44 État et autres collectivités publiques Actif
194 441 État - Subventions à recevoir Actif
195 4421 Prélèvements à la source - Impôt sur le revenu Actif ou passif
196 444 État - Impôts sur les bénéfices Actif ou passif
197 4452 TVA due intracommunautaire Actif ou passif
198 4455 Taxes sur CA à décaisser Actif
199 44562 TVA déductible sur immobilisations Actif
200 44566 TVA déductible sur autres biens et services Actif
201 44571 TVA normale collectée Actif
202 445711 TVA réduite collectée Actif
203 445712 TVA super-réduite collectée Actif
204 445713 TVA intermédiaire collectée Actif
205 4458 Taxe sur CA à régulariser ou en attente Actif
206 447 Autres impôts, taxes et versements assimilés Actif
207 4486 État - Charges à payer Passif
208 4487 État - Produits à recevoir Actif
209 45 Confédération, fédération, unions… affiliées Actif ou passif
210 451 Confédération, fédération et associations affiliées Actif ou passif
211 455 Partenaires - comptes courants Actif ou passif
212 46 Débiteurs divers et créditeurs divers Actif ou passif
213 461 Créances reçues par legs ou donations Actif
214 466 Dettes des legs ou donations Passif
215 4671 Débiteurs divers Actif ou passif
216 4672 Créditeurs divers Actif ou passif
217 4681 Frais des bénévoles Actif ou passif
218 4686 Divers - Charges à payer Passif
219 4687 Divers - Produits à recevoir Actif
220 47 Comptes d’attente Actif ou passif
221 4715 Compte de transit Actif ou passif
222 4718 Compte d'attente Actif ou passif
223 48 Comptes de régularisation Actif ou passif
224 481 Charges à répartir Passif
225 486 Charges constatées d'avance Actif
226 487 Produits constatés d'avance Passif
227 49 Dépréciations des comptes de tiers Actif ou passif
228 491 Provision pour dépreciation des comptes d'usagers Passif
229 496 Provision pour dépreciation des comptes débiteurs divers Passif
230 5 Classe 5 — Comptes financiers Actif
231 50 Valeurs mobilières de placement Actif
232 503 Actions Actif
233 506 Obligations Actif
234 508 Autres VMP et créances assimilées Actif
235 51 Banques, établissements financiers Actif
236 5112 Chèques à encaisser Actif ou passif Favori
237 5115 Paiements par carte à encaisser Actif ou passif
238 512 Banques Actif ou passif
239 5186 Intérêts courus à payer Passif
240 5187 Intérêts courus à recevoir Actif
241 53 Caisses Actif ou passif
242 530 Caisse Actif ou passif Favori
243 58 Virements internes Actif ou passif
244 580 Virements internes Actif ou passif
245 59 Dépréciations des comptes financiers Actif ou passif
246 5903 Actions Actif ou passif
247 5906 Obligations Actif ou passif
248 5908 Autres VMP et créances assimilées Actif ou passif
249 6 Classe 6 — Comptes de charges Charge
250 60 Achats (sauf 603) Charge
251 601 Achats stockés - Matières premières et fournitures Charge
252 6010 Achats stockés de matières et fournitures Charge
253 6011 Achats stockés - Matières premières Charge
254 6017 Achats stockés - Fournitures Charge
255 602 Achats stockés - Autres approvisionnements Charge
256 6021 Achats stockés - Matières consommables Charge
257 60221 Achats stockés - Combustibles Charge
258 60222 Achats stockés - Produits d'entretien Charge
259 60223 Achats stockés - Fournitures d'atelier Charge
260 60224 Achats stockés - Fournitures de magasin Charge
261 60225 Fournitures de bureau Charge
262 6026 Achats stockés - Emballages Charge
263 603 Variations de stocks Charge
264 6031 Variations de stocks matières & fournitures Charge
265 6032 Variations stocks autres approvisionnements Charge
266 6037 Variations de stocks de marchandises Charge
267 604 Achats d'études et prestations de services Charge
268 605 Achats matériel, équipements & travaux Charge
269 606 Achats non stockés de matières et fournitures Charge
270 6061 Fournitures non stockables (eau, énergie...) Facture d'eau, d’électricité, etc. Charge Favori
271 60611 Eau Charge
272 60612 Electricité Charge
273 60613 Chauffage Charge
274 6063 Fournitures d'entretien et petit équipement Vis, et matériel de bricolage (sauf outils) par exemple Charge Favori
275 6064 Fournitures administratives Cartouches d'encre, papier, matériel bureautique, etc. Charge Favori
276 6065 Petits logiciels Par exemple contribution à un logiciel de gestion associative génial :-) Charge Favori
277 6068 Autres fournitures & matières Charge Favori
278 607 Achats de marchandises Marchandises destinées à être revendues en l'état. Charge Favori
279 608 Frais accessoires d'achats Charge
280 60811 Frais accessoires d'achats sur matières Charge
281 60817 Frais accessoires d'achats sur fournitures Charge
282 609 Rabais, remises et ristournes sur achats Charge
283 6091 RRR sur achats matières et fournitures Charge
284 6092 RRR sur achats et autres approvisionnements Charge
285 6097 RRR sur achats de marchandises Charge
286 61 Services extérieurs Charge
287 611 Sous-traitance générale Charge
288 6122 Redevance crédit-bail mobilier Charge
289 6125 Redevances crédit-bail immobilier Charge
290 6132 Locations immobilières Locations versées pour un local ou du matériel. Charge Favori
291 6135 Locations mobilières Charge
292 6136 Malis sur emballages Charge
293 614 Charges locatives et de copropriété Charge
294 6152 Entretien sur biens immobiliers Charge
295 6155 Entretien sur biens mobiliers Charge
296 6156 Maintenance Charge
297 616 Primes d'assurance Frais d’assurance local, activité, etc. Charge Favori
298 6161 Primes d'assurances mutirisques Charge
299 6164 Primes d'assurances / risques d'exploitation Charge
300 6165 Primes d'assurances / insolvabilité usagers Charge
301 6168 Autres assurances Charge
302 617 Études et recherches Charge
303 6181 Documentation générale Charge
304 6183 Documentation technique Charge
305 6185 Frais de colloques, séminaires, conférences Charge
306 6187 Prestations administratives Charge
307 62 Autres services extérieurs Charge
308 621 Personnel extérieur à l'association Charge
309 6211 Personnel intérimaire Charge
310 6214 Personnel détaché ou prêté à l'association Charge
311 62141 Mises à disposition de personnel salarié Frais de mise à disposition via un groupement d’employeurs Charge Favori
312 622 Rémunérations d'intermédiaires et honoraires Charge
313 6221 Commissions… sur achats Charge
314 6222 Commissions… sur ventes Charge
315 6226 Honoraires Charge
316 62264 Honoraires sur legs ou donations à céder Charge
317 6227 Frais d'actes et de contentieux Charge
318 6228 Rémunérations divers intermédiaires & honoraires Charge
319 623 Publicité, publications, relations publiques Bulletins, affiches, communication, etc. Charge Favori
320 6231 Annonces et insertions Charge
321 6232 Fêtes et cérémonies Charge
322 6233 Foires et expositions Charge
323 6234 Cadeaux Charge
324 6236 Catalogues et imprimés Charge
325 6237 Publications Charge
326 6238 Divers : pourboires, dons courants Charge
327 624 Transports de biens Charge
328 6241 Transports sur achats Charge
329 6242 Transports sur ventes Charge
330 6243 Transports entre établissements Charge
331 6244 Transports administratifs Charge
332 6247 Transports collectifs du personnel Charge
333 6248 Transports divers Charge
334 625 Déplacements, missions et réceptions Billet de train, remboursement de frais kilométrique, etc. Charge Favori
335 6251 Voyages et déplacements Charge
336 6255 Frais de déménagement Charge
337 6256 Frais de missions Charge
338 6257 Frais de réceptions, représentations Charge
339 626 Frais postaux et de télécommunications Facture d'accès à Internet, timbres, etc. Charge Favori
340 6261 Liaisons spécialisées Charge
341 6263 Affranchissements, frais postaux Charge
342 6265 Téléphone Charge
343 627 Services bancaires et assimilés Frais bancaires Charge Favori
344 628 Divers Charge Favori
345 6281 Cotisations (liées à l'activité économique) Charge
346 6284 Frais de recrutement du personnel Charge
347 63 Impôts, taxes et versements assimilés Charge
348 631 Sur rémunérations - administration des impôts Charge
349 6311 Taxe sur les salaires Charge
350 633 Sur rémunérations - autres organismes Charge
351 6331 Versement de transport Charge
352 6332 Allocation logement Charge
353 6333 Formation professionnelle continue Charge
354 6334 Participations employeurs à l'effort de construction Charge
355 635 Autres - Administration des impôts Charge
356 63512 Taxes foncières Charge
357 63513 Autres impôts locaux Charge
358 6354 Droits d'enregistrement et de timbre Charge
359 637 Autres - Autres organismes Charge
360 64 Charges de personnel Charge
361 641 Rémunérations du personnel Charge
362 6411 Salaires, appointements Charge
363 6412 Congés payés Charge
364 6413 Primes et gratifications Charge
365 6414 Indemnités et avantages divers Charge
366 6415 Supplément familial Charge
367 645 Charges de sécurité sociale et de prévoyance Charge
368 6451 Cotisations à l'URSSAF Charge
369 6452 Cotisations aux mutuelles Charge
370 6453 Cotisations caisses de retraites et de prévoyance Charge
371 6458 Cotisations aux autres organismes sociaux Charge
372 647 Autres charges sociales Charge
373 6472 Versements aux comités d'entreprise et d'établissement Charge
374 6473 Versement aux comités d'hygiène et de sécurité Charge
375 6474 Versements aux autres œuvres sociales Charge
376 6475 Médecine du travail, pharmacie Charge
377 648 Autres charges de personnel Charge
378 6481 Indemnités du personnel de culte Charge
379 6485 Charges sociales sur indemnités de culte Charge
380 6488 Autres charges de personnel Charge
381 65 Autres charges de gestion courante Charge
382 6511 Redevances pour concessions, brevets, licences Charge
383 6516 Droits d'auteur et de reproduction Charge
384 6518 Autres droits et valeurs similaires Charge
385 652 Licences fédérales Licences payées pour les adhérents (par exemple fédération sportive etc.) Charge Favori
386 653 Charges de la générosité du public Charge
387 6531 Autres charges sur legs ou donations Charge
388 654 Pertes sur créances irrécouvrables Charge
389 655 Quotes-parts sur opérations faites en commun Charge
390 657 Aides financières Charge
391 6571 Aides financières octroyées Charge
392 6572 Quotes-parts de générosité reversée Charge
393 658 Charges diverses de gestion courante Charge Favori
394 6586 Cotisations (vie statutaire) Charge
395 6588 Charges diverses de gestion courante Charge
396 66 Charges financières Charge
397 661 Charges d'intérêts Charge
398 665 Escomptes accordés Charge
399 666 Pertes de changes Charge
400 667 Charges nettes sur cessions de VMP Charge
401 668 Autres charges financières Charge
402 67 Charges exceptionnelles Charge
403 670 Charges exceptionnelles Autres dépenses exceptionnelles Charge Favori
404 6712 Pénalités, amendes fiscales et pénales Charge
405 6713 Dons, libéralités Charge
406 6714 Créances devenues irrécouvrables Charge
407 6718 Autres charges exceptionnelles de gestion Charge
408 672 Charges sur exercices antérieurs Charge
409 673 Apports ou affectations en numéraire Charge
410 675 Valeurs comptables des éléments d'actifs cédés Charge
411 6750 Valeurs comptables des actifs cédés Charge
412 6754 Immobilisations reçues par legs ou donations Charge
413 678 Autres charges exceptionnelles sur opération en capital Charge
414 68 Dotations aux amortissements, dépréciations et engagements Charge
415 6811 Dot. aux amortissements des immobilisations Charge
416 6812 Dot. aux amortissements charges à répartir Charge
417 6815 Dot. aux provisions d'exploitation Charge
418 6816 Dot. provisions pour dépréciations des immobilisations Charge
419 68164 Dot. pour dépréciation d’actifs reçus par legs ou donations Charge
420 6817 Dot. aux dépréciations des actifs circulants Charge
421 68173 Dotations dépréciations stocks et en-cours Charge
422 68174 Dotations dépréciations créances Charge
423 686 Dot. aux amortissements & provisions - Charges financières Charge
424 68662 Dot. aux amortissements & provisions des immobilisations financières Charge
425 68665 Dot. aux amortissements & provisions des valeurs mobilières de placement Charge
426 687 Dot. aux amortissements & provisions - Charges exceptionnelles Charge
427 689 Reports en fonds dédiés Charge
428 6891 Reports en fonds reportés Charge
429 6894 Reports en fonds dédiés / subventions d’exploitation Charge
430 6895 Reports en fds dédiés / contributions financières d'autres organismes Charge
431 6896 Reports en fds dédiés / ressources générosité Charge
432 69 Impôts sur les bénéfices Charge
433 695 IS sur personnes non lucratives Charge
434 7 Classe 7 — Comptes de produits Produit
435 70 Ventes de produits finis, marchandises, prestations Produit
436 701 Ventes de produits finis Vente de produits fabriqués par l'association. Produit Favori
437 702 Ventes de produits intermédiaires Produit
438 703 Ventes de produits résiduels Produit
439 704 Travaux Produit
440 705 Études Produit
441 706 Prestations de services Produit Favori
442 7063 Parrainages Produit
443 707 Ventes de marchandises Ventes de produits achetés et revendus en l’état Produit Favori
444 7073 Ventes de dons en nature Produit
445 708 Produits des activités annexes Produit
446 7081 Produits des prestations fournies au personne Produit
447 7083 Locations diverses Produit
448 7085 Ports et frais accessoires facturés Produit
449 7088 Autres produits d'activités annexes Produit
450 709 RRR accordés Produit
451 7091 RRR sur ventes de produits finis Produit
452 7092 RRR sur ventes de produits intermédiaires Produit
453 7094 RRR sur travaux Produit
454 7095 RRR sur études Produit
455 7096 RRR sur prest.de services Produit
456 7097 RRR sur ventes marchandises Produit
457 71 Production stockée Produit
458 713 Variation de stocks (en-cours, productions) Produit
459 7133 Variation des en-cours de production de biens Produit
460 7134 Variation des en-cours de production services Produit
461 7135 Variations de stocks de produits Produit
462 72 Production immobilisée corporelle Produit
463 721 Production immobilisée incorporelle Produit
464 722 Production immobilisée corporelle Produit
465 73 Concours publics Produit
466 730 Concours publics Produit
467 74 Subventions d’exploitation Produit
468 740 Subventions reçues Produit Favori
469 748 Subventions d'exploitation diverses Produit
470 75 Autres produits de gestion courante Produit
471 751 Redevances pour concessions, licences… Produit
472 753 Versements des fondateurs ou consommation dot Produit
473 7531 Versements des fondateurs Produit
474 7532 Quotes-parts de dotation consomptible virée a Produit
475 754 Ressources liées à la générosité du public Dons reçus Produit Favori
476 7541 Dons manuels Produit
477 75411 Dons manuels Produit
478 75412 Abandons de frais par les bénévoles Produit
479 7542 Mécénats Produit
480 7543 Legs, donations et assurances-vie Produit
481 75431 Assurances-vie Produit
482 75432 Legs ou donations Produit
483 75433 Autres produits sur legs ou donations Produit
484 755 Contributions financières Produit
485 7551 Contributions financières d’autres organismes Produit
486 7552 Quotes-parts de générosité reçues Produit
487 756 Cotisations Cotisations des adhérent⋅e⋅s Produit Favori
488 7561 Cotisations sans contrepartie Produit
489 7562 Cotisations avec contrepartie Produit
490 757 Gains de change / créances et dettes d’exploitation Produit
491 758 Produits divers de gestion courante Produit
492 7588 Autres produits divers de gestion courante Produit
493 76 Produits financiers Produit
494 761 Produits des participations Produit
495 762 Produits des autres immobilisations financières Produit
496 763 Revenus des autres créances Produit
497 764 Revenus des valeurs mobilières de placement Produit
498 765 Escomptes obtenus Produit
499 766 Gains de change Produit
500 767 Produits nets sur cession valeurs mobilières de placement Produit
501 768 Autres produits financiers Produit
502 77 Produits exceptionnels Produit
503 771 Produits exceptionnels sur opération de gestion Produit
504 7713 Libéralités perçues Produit
505 7718 Autres produits exceptionnel sur opération de gestion Produit
506 772 Produits sur exercices antérieurs Produit
507 775 Produits des cessions d'actif Produit
508 7754 Immobilisations reçues en legs ou donations à céder Produit
509 777 Quote-part de subvention d'investissement virée au résultat Produit
510 778 Autres produits exceptionnels Produit
511 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 Favori
512 78 Reprises sur amortissement, dépréciations, engagements Produit
513 781 Reprises / amortissements & provisions d'exploitation Produit
514 7811 Amortissement immobilisations corporelles & incorporelles Produit
515 7815 Reprises sur provisions d'exploitation Produit
516 7816 Dépréciation immobilisations corporelles & incorporelles Produit
517 78164 Reprises de dépréciations d’actifs reçus par legs ou donations destinés à être cédés Produit
518 7817 Dépréciations actifs circulant Produit
519 786 Reprises / amortissements & provisions financiers Produit
520 7865 Risques et charges financiers Produit
521 7866 Dépréciations des éléments financiers Produit
522 787 Reprises sur amt & prov. exceptionnelles Produit
523 7872 Provisions réglementées - Immobilisations Produit
524 7873 Provisions réglementées - stocks Produit
525 7874 Autres provisions réglementées Produit
526 7875 Risques et charges Produit
527 7876 Dépréciations exceptionnelles Produit
528 789 Utilisations fonds reportés et de fonds dédiés Produit
529 7891 Utilisations de fonds reportés Produit
530 7894 Utilisations des fonds dédiés / subventions Produit
531 7895 Utilisations des fonds dédiés / contributions Produit
532 7896 Utilisations des fonds dédiés / générosité Produit
533 79 Transfert de charges Produit
534 791 Transferts de charges d'exploitation Produit
535 796 Transferts de charges financières Produit
536 797 Transferts de charges exceptionnelles Produit
537 8 Classe 8 ­— Comptes spéciaux
538 86 Emplois des contributions volontaires en nature
539 860 Secours en nature Charge Favori
540 8601 Alimentaires Charge Favori
541 8602 Vestimentaires Charge Favori
542 861 Mise à dispositions gratuites de biens Charge Favori
543 8611 Locaux Charge Favori
544 8612 Matériels Charge Favori
545 862 Prestations Charge Favori
546 864 Personnel bénévole Charge Favori
547 87 Contributions volontaires en nature
548 870 Dons en nature Produit Favori
549 871 Prestations en nature Produit Favori
550 875 Bénévolat Produit Favori
551 89 Comptes de bilan
552 890 Bilan d'ouverture Actif ou passif
553 891 Bilan de clôture Actif ou passif

View file

@ -0,0 +1,111 @@
code,label,description,position,bookmark
1,"Classe 1 — Provisions, avances, subventions et emprunts",,Passif,
10,PROVISIONS ET AVANCES,,Passif,
103,Avances,,Passif,
106,Provisions pour travaux,Provisions pour travaux au titre de la délégation de pouvoirs accordée au conseil syndical,Passif,
11,REPORT À NOUVEAU (SOLDE CRÉDITEUR OU DÉBITEUR),,Passif,
110,Report à nouveau (solde créditeur),,Passif,
119,Report à nouveau (solde débiteur),,Passif,
12,Solde en attente sur travaux et opérations exceptionnelles,,Passif,
121,Travaux décidés par l'assemblée générale,,Passif,
122,Travaux délégués au conseil syndical ,,Passif,
13,SUBVENTIONS,,Passif,
131, Subventions accordées en instance de versement,,Passif,
138,Autres subventions dinvestissement ,,Passif,
139,Subventions dinvestissement inscrites au compte de résultat,,Passif,
4,Classe 4 — COPROPRIÉTAIRES ET TIERS,,Actif ou passif,
40,Fournisseurs,,Actif ou passif,
42,Personnel,,Actif ou passif,
43,SÉCURITÉ SOCIALE & AUTRES ORGANISMES SOCIAUX,,Passif,
431,Sécurité sociale,,Passif,
432,Autres organismes sociaux,,Passif,
44,ÉTAT ET COLLECTIVITÉS TERRITORIALES ,,Actif,
441,État et autres organismes - subventions à recevoir,,Actif,Favori
442,État - impôts et versements assimilés,,Actif ou passif,Favori
443,Collectivités territoriales aides,,Actif ou passif,
45,COLLECTIVITÉ DES COPROPRIÉTAIRES,,Actif ou passif,
46,DÉBITEURS ET CRÉDITEUR DIVERS,,Actif ou passif,
47,COMPTES D'ATTENTE,,Actif ou passif,
471,Compte en attente dimputation débiteur,,Actif ou passif,
472,Compte en attente dimputation créditeur,,Actif ou passif,
48,COMPTES DE RÉGULARISATION,,Actif ou passif,
486,Charges payées d'avance,,Actif,Favori
487,Produits encaissés davance,,Passif,Favori
49,DÉPRÉCIATIONS DES COMPTES DE TIERS,,Actif ou passif,
491,Copropriétaires,,Passif,Favori
496,Personnes autres que les copropriétaires,,Passif,Favori
5,Classe 5 — Comptes financiers,,Actif,
50,FONDS PLACÉS,,Actif,
51,"Banques, ou fonds disponibles en banque pour le syndicat",,Actif,
5112,Chèques à encaisser,,Actif ou passif,Favori
5115,Paiements par carte à encaisser,,Actif ou passif,
512,Banques,,Actif ou passif,
53,Caisses,,Actif ou passif,
530,Caisse,,Actif ou passif,Favori
6,Classe 6 — Comptes de charges,,Charge,
60,ACHATS DE MATIÈRES ET FOURNITURES,,Charge,
601,Eau,,Charge,Favori
602,Électricité,,Charge,Favori
603,"Chauffage, énergie et combustibles",,Charge,Favori
604,Achats produits d'entretien et petits équipements,,Charge,Favori
605,Matériel,,Charge,Favori
606,Fournitures,,Charge,Favori
61,SERVICES EXTÉRIEURS,,Charge,
611,Nettoyage des locaux,,Charge,Favori
612,Locations immobilières,,Charge,Favori
613,Locations mobilières,,Charge,
614,Contrats de maintenance,,Charge,Favori
615,Entretien et petites réparations,,Charge,Favori
616,Primes d'assurance,,Charge,Favori
62,FRAIS DADMINISTRATION ET HONORAIRES,,Charge,
621,Rémunération du syndic sur gestion copropriété,,Charge,
6211,Rémunération du syndic,,Charge,
6212,Débours,,Charge,
6213,Frais postaux,,Charge,Favori
622,Autres honoraires du syndic,,Charge,
6221,Honoraires travaux,,Charge,Favori
6222,Prestations particulières,,Charge,
6223,Autres honoraires,,Charge,
623,Rémunérations de tiers intervenants,,Charge,
624,Frais du conseil syndical,,Charge,
63,"IMPÔTS, TAXES ET VERSEMENTS ASSIMILÉS",,Charge,
632,Taxe de balayage,,Charge,Favori
633,Taxe foncière,,Charge,Favori
634,Autre impôt et taxe,,Charge,Favori
64,FRAIS DE PERSONNEL,,Charge,
641,Salaires,,Charge,Favori
642,Charges sociales et organismes sociaux,,Charge,Favori
644,"Autres (médecine du travail, mutuelle, etc.)",,Charge,Favori
65,MONTANT SPÉCIFIQUE ALLOUÉ AU CONSEIL SYNDICAL,"Montant spécifique alloué au conseil syndical, au sein du budget prévisionnel, pour l'exercice de sa délégation de pouvoirs",Charge,
66,"CHARGES FINANCIÈRES DES EMPRUNTS, AGIOS OU AUTRES",,Charge,
661,Remboursements d'annuités d'emprunt,,Charge,Favori
662,Autres charges financières et agios,,Charge,
67,CHARGES POUR TRAVAUX ET OPÉRATIONS EXCEPTIONNELLES,,Charge,
671,Travaux décidés par lassemblée générale,,Charge,Favori
672,Travaux urgents,,Charge,Favori
673,"Études techniques, diagnostic, consultation",,Charge,
677,Pertes sur créances irrécouvrables,,Charge,
678,Charges exceptionnelles,,Charge,
68,DOTATIONS AUX DÉPRÉCIATIONS SUR CRÉANCES DOUTEUSES,,Charge,
7,Classe 7 — Comptes de produits,,Produit,
70,APPELS DE FONDS,,Produit,
701,Provisions sur opérations courantes,,Produit,Favori
702,Provisions sur travaux de larticle 14-2 et opérations exceptionnelles,,Produit,
703,Avances,,Produit,Favori
704,Remboursements dannuités demprunts,,Produit,
705,Études,,Produit,
706,Provisions au titre de la délégation de pouvoirs accordée au conseil syndical,,Produit,Favori
7061,Provisions sur opérations courantes,,Produit,Favori
7062,Provisions sur travaux et opérations exceptionnelles,,Produit,
71,AUTRES PRODUITS,,Produit,
711,Subventions,,Produit,Favori
712,Emprunts,,Produit,Favori
713,Indemnités dassurance,,Produit,
714,Produits divers (dont intérêts légaux dus par les copropriétaires),,Produit,
716,Produits financiers,,Produit,Favori
718,Produits exceptionnels,,Produit,
78,REPRISES DE DÉPRÉCIATIONS SUR CRÉANCES DOUTEUSES,Reprises de dépréciations sur créances douteuses,Produit,
8,Classe 8 ­— Comptes spéciaux,,,
89,COMPTES DE BILAN,,,
890,Bilan d'ouverture,,Actif ou passif,
891,Bilan de clôture,,Actif ou passif,
1 code label description position bookmark
2 1 Classe 1 — Provisions, avances, subventions et emprunts Passif
3 10 PROVISIONS ET AVANCES Passif
4 103 Avances Passif
5 106 Provisions pour travaux Provisions pour travaux au titre de la délégation de pouvoirs accordée au conseil syndical Passif
6 11 REPORT À NOUVEAU (SOLDE CRÉDITEUR OU DÉBITEUR) Passif
7 110 Report à nouveau (solde créditeur) Passif
8 119 Report à nouveau (solde débiteur) Passif
9 12 Solde en attente sur travaux et opérations exceptionnelles Passif
10 121 Travaux décidés par l'assemblée générale Passif
11 122 Travaux délégués au conseil syndical Passif
12 13 SUBVENTIONS Passif
13 131 Subventions accordées en instance de versement Passif
14 138 Autres subventions d’investissement Passif
15 139 Subventions d’investissement inscrites au compte de résultat Passif
16 4 Classe 4 — COPROPRIÉTAIRES ET TIERS Actif ou passif
17 40 Fournisseurs Actif ou passif
18 42 Personnel Actif ou passif
19 43 SÉCURITÉ SOCIALE & AUTRES ORGANISMES SOCIAUX Passif
20 431 Sécurité sociale Passif
21 432 Autres organismes sociaux Passif
22 44 ÉTAT ET COLLECTIVITÉS TERRITORIALES Actif
23 441 État et autres organismes - subventions à recevoir Actif Favori
24 442 État - impôts et versements assimilés Actif ou passif Favori
25 443 Collectivités territoriales – aides Actif ou passif
26 45 COLLECTIVITÉ DES COPROPRIÉTAIRES Actif ou passif
27 46 DÉBITEURS ET CRÉDITEUR DIVERS Actif ou passif
28 47 COMPTES D'ATTENTE Actif ou passif
29 471 Compte en attente d’imputation débiteur Actif ou passif
30 472 Compte en attente d’imputation créditeur Actif ou passif
31 48 COMPTES DE RÉGULARISATION Actif ou passif
32 486 Charges payées d'avance Actif Favori
33 487 Produits encaissés d’avance Passif Favori
34 49 DÉPRÉCIATIONS DES COMPTES DE TIERS Actif ou passif
35 491 Copropriétaires Passif Favori
36 496 Personnes autres que les copropriétaires Passif Favori
37 5 Classe 5 — Comptes financiers Actif
38 50 FONDS PLACÉS Actif
39 51 Banques, ou fonds disponibles en banque pour le syndicat Actif
40 5112 Chèques à encaisser Actif ou passif Favori
41 5115 Paiements par carte à encaisser Actif ou passif
42 512 Banques Actif ou passif
43 53 Caisses Actif ou passif
44 530 Caisse Actif ou passif Favori
45 6 Classe 6 — Comptes de charges Charge
46 60 ACHATS DE MATIÈRES ET FOURNITURES Charge
47 601 Eau Charge Favori
48 602 Électricité Charge Favori
49 603 Chauffage, énergie et combustibles Charge Favori
50 604 Achats produits d'entretien et petits équipements Charge Favori
51 605 Matériel Charge Favori
52 606 Fournitures Charge Favori
53 61 SERVICES EXTÉRIEURS Charge
54 611 Nettoyage des locaux Charge Favori
55 612 Locations immobilières Charge Favori
56 613 Locations mobilières Charge
57 614 Contrats de maintenance Charge Favori
58 615 Entretien et petites réparations Charge Favori
59 616 Primes d'assurance Charge Favori
60 62 FRAIS D’ADMINISTRATION ET HONORAIRES Charge
61 621 Rémunération du syndic sur gestion copropriété Charge
62 6211 Rémunération du syndic Charge
63 6212 Débours Charge
64 6213 Frais postaux Charge Favori
65 622 Autres honoraires du syndic Charge
66 6221 Honoraires travaux Charge Favori
67 6222 Prestations particulières Charge
68 6223 Autres honoraires Charge
69 623 Rémunérations de tiers intervenants Charge
70 624 Frais du conseil syndical Charge
71 63 IMPÔTS, TAXES ET VERSEMENTS ASSIMILÉS Charge
72 632 Taxe de balayage Charge Favori
73 633 Taxe foncière Charge Favori
74 634 Autre impôt et taxe Charge Favori
75 64 FRAIS DE PERSONNEL Charge
76 641 Salaires Charge Favori
77 642 Charges sociales et organismes sociaux Charge Favori
78 644 Autres (médecine du travail, mutuelle, etc.) Charge Favori
79 65 MONTANT SPÉCIFIQUE ALLOUÉ AU CONSEIL SYNDICAL Montant spécifique alloué au conseil syndical, au sein du budget prévisionnel, pour l'exercice de sa délégation de pouvoirs Charge
80 66 CHARGES FINANCIÈRES DES EMPRUNTS, AGIOS OU AUTRES Charge
81 661 Remboursements d'annuités d'emprunt Charge Favori
82 662 Autres charges financières et agios Charge
83 67 CHARGES POUR TRAVAUX ET OPÉRATIONS EXCEPTIONNELLES Charge
84 671 Travaux décidés par l’assemblée générale Charge Favori
85 672 Travaux urgents Charge Favori
86 673 Études techniques, diagnostic, consultation Charge
87 677 Pertes sur créances irrécouvrables Charge
88 678 Charges exceptionnelles Charge
89 68 DOTATIONS AUX DÉPRÉCIATIONS SUR CRÉANCES DOUTEUSES Charge
90 7 Classe 7 — Comptes de produits Produit
91 70 APPELS DE FONDS Produit
92 701 Provisions sur opérations courantes Produit Favori
93 702 Provisions sur travaux de l’article 14-2 et opérations exceptionnelles Produit
94 703 Avances Produit Favori
95 704 Remboursements d’annuités d’emprunts Produit
96 705 Études Produit
97 706 Provisions au titre de la délégation de pouvoirs accordée au conseil syndical Produit Favori
98 7061 Provisions sur opérations courantes Produit Favori
99 7062 Provisions sur travaux et opérations exceptionnelles Produit
100 71 AUTRES PRODUITS Produit
101 711 Subventions Produit Favori
102 712 Emprunts Produit Favori
103 713 Indemnités d’assurance Produit
104 714 Produits divers (dont intérêts légaux dus par les copropriétaires) Produit
105 716 Produits financiers Produit Favori
106 718 Produits exceptionnels Produit
107 78 REPRISES DE DÉPRÉCIATIONS SUR CRÉANCES DOUTEUSES Reprises de dépréciations sur créances douteuses Produit
108 8 Classe 8 ­— Comptes spéciaux
109 89 COMPTES DE BILAN
110 890 Bilan d'ouverture Actif ou passif
111 891 Bilan de clôture Actif ou passif

View file

@ -0,0 +1,367 @@
code,label,description,position,bookmark
1,COMPTES DE CAPITAUX,,Passif,
10,CAPITAL ET RÉSERVES,,Passif,
101,Capital,,Passif,
1011,Capital souscrit -non appelé,,Passif,
1012,"Capital souscrit -appelé, non versé",,Passif,
1013,"Capital souscrit - appelé, versé",,Passif,
102,Fonds fiduciaires,,Passif,
104,Primes liées au capital social,,Passif,
105,Écarts de réévaluation,,Passif,
106,Réserves,,Passif,
1068,Autres réserves,,Passif,
107,Écart déquivalence,,Passif,
108,Compte de lexploitant,,Passif,
109,Actionnaires : capital souscrit non appelé,,Passif,
11,REPORT À NOUVEAU (SOLDE CRÉDITEUR OU DÉBITEUR),,Passif,
110,Report à nouveau (solde créditeur),,Passif,
119,Report à nouveau (solde débiteur),,Passif,
12,RÉSULTAT DE LEXERCICE (BÉNÉFICE OU PERTE),,Passif,
120,Résultat de lexercice (bénéfice),,Passif,
129,Résultat de lexercice (perte),,Passif,
13,SUBVENTIONS DINVESTISSEMENT,,Passif,
131,Subventions déquipement,,Passif,
1311,État,,Passif,
1312,Régions,,Passif,
1313,Départements,,Passif,
1314,Communes,,Passif,
1315,Collectivités publiques,,Passif,
1316,Entreprises publiques,,Passif,
1317,Entreprises et organismes privés,,Passif,
1318,Autres,,Passif,
138,Autres subventions dinvestissement,"Même ventilation que celle du compte 131, à rajouter si nécessaire",Passif,
139,Subventions dinvestissement inscrites au compte de résultat,,Passif,
1391,"Subventions d'équipement","Même ventilation que celle du compte 131, à rajouter si nécessaire",Passif,
1398,Autres subventions dinvestissement ,"Même ventilation que celle du compte 131, à rajouter si nécessaire",Passif,
14,PROVISIONS RÉGLEMENTÉES,,Passif,
142,Provisions réglementées relatives aux immobilisations,,Passif,
143,Provisions réglementées relatives aux stocks,,Passif,
144,Provisions réglementées relatives aux autres éléments de lactif,,Passif,
145,Amortissements dérogatoires,,Passif,
146,Provision spéciale de réévaluation,,Passif,
147,Plus-values réinvesties,,Passif,
148,Autres provisions réglementées,,Passif,
15,PROVISIONS POUR RISQUES ET CHARGES,,Passif,
151,Provisions pour risques,,Passif,
153,Provisions pour pensions et obligations similaires,,Passif,
154,Provisions pour restructurations,,Passif,
155,Provisions pour impôts,,Passif,
156,Provisions pour renouvellement des immobilisations (entreprises concessionnaires),,Passif,
157,Provisions pour charges à répartir sur plusieurs exercices,,Passif,
158,Autres provisions pour charges,,Passif,
16,EMPRUNTS ET DETTES ASSIMILÉES,,Passif,
161,Emprunts obligataires convertibles,,Passif,
163,Autres emprunts obligataires,,Passif,
164,Emprunts auprès des établissements de crédit,,Passif,
165,Dépôts et cautionnements reçus,,Passif,
166,Participation des salariés aux résultats,,Passif,
167,Emprunts et dettes assortis de conditions particulières,,Passif,
168,Autres emprunts et dettes assimilées,,Passif,
169,Primes de remboursement des obligations,,Passif,
17,DETTES RATTACHÉES À DES PARTICIPATIONS,,Passif,
171,Dettes rattachées à des participations (groupe),,Passif,
174,Dettes rattachées à des participations (hors groupe),,Passif,
178,Dettes rattachées à des sociétés en participation,,Passif,
18,COMPTES DE LIAISON DES ÉTABLISSEMENTS ET SOCIÉTÉS EN PARTICIPATION,,Passif,
181,Comptes de liaison des établissements,,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,
188,Comptes de liaison des sociétés en participation,,Passif,
2,COMPTES DIMMOBILISATIONS,,Actif,
20,IMMOBILISATIONS INCORPORELLES,,Actif,
201,Frais détablissement,,Actif,
203,Frais de recherche et de développement,,Actif,
205,"Concessions et droits similaires, brevets, licences, marques, procédés, logiciels, droits et valeurs similaires",,Actif,
206,Droit au bail,,Actif,
207,Fonds commercial,,Actif,
208,Autres immobilisations incorporelles,,Actif,
21,IMMOBILISATIONS CORPORELLES,,Actif,
211,Terrains,"Au besoin, créer des sous-comptes 2111 et suivants : Terrains nus, Terrains aménagés, Sous - sols et sursols, Terrains de gisement et Terrains bâtis.",Actif,
212,Agencements et aménagements de terrains (même ventilation que celle du compte 211,(même ventilation que celle du compte 211) ,Actif,
213,Constructions,,Actif,
214,Constructions sur sol dautrui (même ventilation que celle du compte 213,,Actif,
215,"Installations techniques, matériels et outillage industriels",,Actif,
218,Autres immobilisations corporelles,,Actif,
22,IMMOBILISATIONS MISES EN CONCESSION,,Actif,
23,IMMOBILISATIONS EN COURS,,Actif,
231,Immobilisations corporelles en cours,,Actif,
232,Immobilisations incorporelles en cours,,Actif,
237,Avances et acomptes versés sur immobilisations incorporelles,,Actif,
238,Avances et acomptes versés sur commandes dimmobilisations corporelles,,Actif,
25,PARTS DANS DES ENTREPRISES LIÉES ET CRÉANCES SUR DES ENTREPRISES LIÉES,,Actif,
26,PARTICIPATIONS ET CRÉANCES RATTACHÉES À DES PARTICIPATIONS,,Actif,
261,Titres de participation,,Actif,
266,Autres formes de participation,,Actif,
267,Créances rattachées à des participations,,Actif,
268,Créances rattachées à des sociétés en participation,,Actif,
269,Versements restant à effectuer sur titres de participation non libérés,,Actif,
27,AUTRES IMMOBILISATIONS FINANCIÈRES,,Actif,
271,Titres immobilisés autres que les titres immobilisés de lactivité de portefeuille (droit de propriété),,Actif,
272,Titres immobilisés (droit de créance),,Actif,
273,Titres immobilisés de lactivité de portefeuille,,Actif,
274,Prêts,,Actif,
275,Dépôts et cautionnements versés,,Actif,
276,Autres créances immobilisées,,Actif,
277,(Actions propres ou parts propres),,Actif,
278,Mali de fusion sur actifs financiers,,Actif,
279,Versements restant à effectuer sur titres immobilisés non libérés,,Actif,
28,AMORTISSEMENTS DES IMMOBILISATIONS,,Actif,
280,Amortissements des immobilisations incorporelles,,Actif,
281,Amortissements des immobilisations corporelles,,Actif,
282,Amortissements des immobilisations mises en concession,,Actif,
29,DÉPRÉCIATIONS DES IMMOBILISATIONS,,Actif,
290,Dépréciations des immobilisations incorporelles,,Actif,
291,Dépréciations des immobilisations corporelles ,Même ventilation que celle du compte 21,Actif,
292,Dépréciations des immobilisations mises en concession,,Actif,
293,Dépréciations des immobilisations en cours,,Actif,
296,Provisions pour dépréciation des participations et créances rattachées à des participations,,Actif,
297,Provisions pour dépréciation des autres immobilisations financières,,Actif,
3,COMPTES DE STOCKS ET EN-COURS,,Actif,
31,MATIÈRES PREMIÈRES (ET FOURNITURES),,Actif,
311,Matières (ou groupe) A,,Actif,
312,Matières (ou groupe) B,,Actif,
317,"Fournitures A, B, C",,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 PRODUCTION DE SERVICES,,Actif,
341,Études 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 (ou matières de récupération),,Actif,
37,STOCKS DE MARCHANDISES,,Actif,
371,Marchandises (ou groupe) A,,Actif,
372,Marchandises (ou groupe) B,,Actif,
39,PROVISIONS POUR DÉPRÉCIATION DES STOCKS ET EN-COURS,,Actif,
391,Provisions pour dépréciation des matières premières (et fournitures),,Actif,
392,Provisions pour dépréciation des autres approvisionnements,,Actif,
393,Provisions pour dépréciation des en-cours de production de biens,,Actif,
394,Provisions pour dépréciation des en-cours de production de services,,Actif,
395,Provisions pour dépréciation des stocks de produits,,Actif,
397,Provisions pour dépréciation des stocks de marchandises,,Actif,
4,COMPTES DE TIERS,,Actif ou passif,
40,FOURNISSEURS ET COMPTES RATTACHÉS,,Actif ou passif,
400,Fournisseurs et Comptes rattachés,,Actif ou passif,
401,Fournisseurs,,Actif ou passif,
403,Fournisseurs Effets à payer,,Passif,
404,Fournisseurs dimmobilisations,,Actif ou passif,
405,Fournisseurs dimmobilisations Effets à payer,,Passif,
408,Fournisseurs Factures non parvenues,,Passif,
409,Fournisseurs débiteurs,,Actif,
41,CLIENTS ET COMPTES RATTACHÉS,,Actif ou passif,
410,Clients et comptes rattachés,,Actif ou passif,
411,Clients,,Actif ou passif,
413,Clients Effets à recevoir,,Actif,
416,Clients douteux ou litigieux,,Actif,
418,Clients Produits non encore facturés,,Actif,
419,Clients créditeurs,,Passif,
42,PERSONNEL ET COMPTES RATTACHÉS,,Actif ou passif,
421,Personnel Rémunérations dues,,Passif,
422,"Comités dentreprises, détablissement,…",,Actif ou passif,
424,Participation des salariés aux résultats,,Actif,
425,Personnel Avances et acomptes,,Actif,
426,Personnel Dépôts,,Passif,
427,Personnel Oppositions,,Passif,
428,Personnel Charges à payer et produits à recevoir,,Passif,
43,SÉCURITÉ SOCIALE ET AUTRES ORGANISMES SOCIAUX,,Passif,
431,Sécurité sociale,,Passif,
437,Autres organismes sociaux,,Passif,
438,Organismes sociaux Charges à payer et produits à recevoir,,Passif,
44,ÉTAT ET AUTRES COLLECTIVITÉS PUBLIQUES,,Actif,
441,État Subventions à recevoir,,Actif,
442," Contributions, impôts et taxes recouvrés pour le compte de lÉtat ",,Passif,
443,"Opérations particulières avec lÉtat, les collectivités publiques, les organismes internationaux",,Actif ou passif,
444,État Impôts sur les bénéfices,,Actif ou passif,
445,État Taxes sur le chiffre daffaires,,Actif,
446,Obligations cautionnées,,Actif,
447,"Autres impôts, taxes et versements assimilés",,Actif,
448,État Charges à payer et produits à recevoir,,Actif ou passif,
449,Quotas démission à acquérir,,Passif,
45,GROUPE ET ASSOCIÉS,,Actif ou passif,
451,Groupe,,Actif ou passif,
455,Associés Comptes courants,,Actif ou passif,
456,Associés Opérations sur le capital,,Actif,
457,Associés Dividendes à payer,,Passif,
458,Associés Opérations faites en commun et en G.I.E.,,Actif ou passif,
46,DÉBITEURS DIVERS ET CRÉDITEURS DIVERS,,Actif ou passif,
462,Créances sur cessions dimmobilisations,,Actif,
464,Dettes sur acquisitions de valeurs mobilières de placement,,Passif,
465,Créances sur cessions de valeurs mobilières de placement,,Actif,
467,Autres comptes débiteurs ou 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 DATTENTE,,Actif ou passif,
471,à 475 comptes dattente,,Actif ou passif,
476,Différence de conversion Actif,,Actif,
477,Différences de conversion Passif,,Passif,
478,Autres comptes transitoires,,Actif ou passif,
48,COMPTES DE RÉGULARISATION,,Actif ou passif,
481,Charges à répartir sur plusieurs exercices,,Passif,
486,Charges constatées davance,,Actif,
487,Produits constatés davance,,Passif,
488,Comptes de répartition périodique des charges et des produits,,Actif ou passif,
489,Quotas démission alloués par lÉtat,,Actif,
49,PROVISIONS POUR DÉPRÉCIATION DES COMPTES DE TIERS,,Actif ou passif,
491,Provisions pour dépréciation des comptes de clients,,Passif,
495,Provisions pour dépréciation des comptes du groupe et des associés,,Passif,
496,Provisions pour dépréciation des comptes de débiteurs divers,,Passif,
5,COMPTES FINANCIERS,,Actif,
50,VALEURS MOBILIÈRES DE PLACEMENT,,Actif,
501,Parts dans des entreprises liées,,Actif,
502,Actions propres,,Actif,
503,Actions,,Actif,
504,Autres titres conférant un droit de propriété,,Actif,
505,Obligations et bons émis par la société et rachetés par elle,,Actif,
506,Obligations,,Actif,
507,Bons du Trésor et bons de caisse à court terme,,Actif,
508,Autres valeurs mobilières de placement et autres créances assimilées,,Actif,
509,Versements restant à effectuer sur valeurs mobilières de placement non libérées,,Actif,
51,"BANQUES, ÉTABLISSEMENTS FINANCIERS ET ASSIMILÉS",,Actif,
511,Valeurs à lencaissement,,Actif ou passif,Favori
512,Banques,,Actif ou passif,
512A,Compte courant,,Actif ou passif,Favori
514,Chèques postaux,,Actif ou passif,Favori
515,« Caisses » du Trésor et des établissements publics,,Actif ou passif,
516,Sociétés de bourse,,Actif,
517,Autres organismes financiers,,Actif ou passif,
518,Intérêts courus,,Actif ou passif,
519,Concours bancaires courants,,Actif ou passif,
52,INSTRUMENTS DE TRÉSORERIE,,Actif ou passif,
53,CAISSE,,Actif ou passif,
531,Caisse siège social,,Actif ou passif,Favori
532,Caisse succursale (ou usine) A,,Actif ou passif,
533,Caisse succursale (ou usine) B,,Actif ou passif,
54,RÉGIES DAVANCE ET ACCRÉDITIFS,,Actif ou passif,
58,VIREMENTS INTERNES,,Actif ou passif,
59,DÉPRÉCIATION DES COMPTES FINANCIERS,,Actif ou passif,
590,Provisions pour dépréciation des valeurs mobilières de placement,,Passif,
6,COMPTES DE CHARGES,,Charge,
60,ACHATS (SAUF 603),,Charge,
601,Achats stockés Matières premières (et fournitures),,Charge,Favori
602,Achats stockés Autres approvisionnements,,Charge,Favori
604,Achats détudes et prestations de services,,Charge,Favori
605,"Achats de matériel, équipements et travaux",,Charge,Favori
606,Achats non stockés de matière et fournitures,"On peut rajouter des sous-comptes : eau, électricité, etc.",Charge,Favori
607,Achats de marchandises,,Charge,Favori
608,"(Compte réservé, le cas échéant, à la récapitulation des frais accessoires incorporés aux achats)",,Charge,
609,"Rabais, remises et ristournes obtenus sur achats",,Charge,
603,Variations des stocks (approvisionnements et marchandises),,Charge,
61,SERVICES EXTÉRIEURS,,Charge,
611,Sous-traitance générale,,Charge,
612,Redevances de crédit-bail,,Charge,
613,Locations,,Charge,Favori
614,Charges locatives et de copropriété,,Charge,Favori
615,Entretien et réparations,,Charge,
616,Primes dassurances,,Charge,Favori
617,Études et recherches,,Charge,
618,Divers,,Charge,
619,"Rabais, remises et ristournes obtenus sur services extérieurs",,Charge,
62,AUTRES SERVICES EXTÉRIEURS,,Charge,
621,Personnel extérieur à lentreprise,,Charge,
622,Rémunérations dintermédiaires et honoraires,,Charge,
623,"Publicité, publications, relations publiques",,Charge,
624,Transports de biens et transports collectifs du personnel,Ne comprend pas les transports de lexploitant,Charge,
625,"Déplacements, missions et réceptions",,Charge,Favori
626,Frais postaux et de télécommunications,,Charge,Favori
627,Services bancaires et assimilés,,Charge,Favori
628,Divers,,Charge,
629,"Rabais, remises et ristournes obtenus sur autres services extérieurs",,Charge,
63,"IMPÔTS, TAXES ET VERSEMENTS ASSIMILÉS",,Charge,
631,"Impôts, taxes et versements assimilés sur rémunérations (administrations des impôts)",,Charge,
633,"Impôts, taxes et versements assimilés sur rémunérations (autres organismes)",,Charge,
635,"Autres impôts, taxes et versements assimilés (administrations des impôts)",,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,
644,Rémunération du travail de lexploitant,,Charge,Favori
645,Charges de sécurité sociale et de prévoyance,,Charge,Favori
6451,Cotisations à lUrssaf,,Charge,Favori
646,Cotisations sociales personnelles de lexploitant,,Charge,Favori
647,Autres charges sociales,,Charge,
648,Autres charges de personnel,,Charge,
65,AUTRES CHARGES DE GESTION COURANTE,,Charge,
651,"Redevances pour concessions, brevets, licences, marques, procédés, logiciels, droits et valeurs similaires",,Charge,
653,Jetons de présence,,Charge,
654,Pertes sur créances irrécouvrables,,Charge,
655,Quote-part de résultat sur opérations faites en commun,,Charge,
658,Charges diverses de gestion courante,,Charge,
66,CHARGES FINANCIÈRES,,Charge,
661,Charges dintérêts,,Charge,
664,Pertes sur créances liées à des participations,,Charge,
665,Escomptes accordés,,Charge,
666,Pertes de change,,Charge,
667,Charges nettes sur cessions de valeurs mobilières de placement,,Charge,
668,Autres charges financières,,Charge,
67,CHARGES EXCEPTIONNELLES,,Charge,
671,Charges exceptionnelles sur opérations de gestion,,Charge,
672,"(Compte à la disposition des entités pour enregistrer, en cours dexercice, les charges sur exercices antérieurs)",,Charge,
675,Valeurs comptables des éléments dactif cédés,,Charge,
678,Autres charges exceptionnelles,,Charge,
68,DOTATIONS AUX AMORTISSEMENTS ET AUX PROVISIONS,,Charge,
681,Dotations aux amortissements et aux provisions Charges dexploitation,,Charge,
686,Dotations aux amortissements et aux provisions Charges financières,,Charge,
687,Dotations aux amortissements et aux provisions Charges exceptionnelles,,Charge,
69,PARTICIPATION DES SALARIÉS IMPÔTS SUR LES BÉNÉFICES ET ASSIMILÉS,,Charge,
691,Participation des salariés aux résultats,,Charge,
695,Impôts sur les bénéfices,,Charge,
696,Suppléments dimpôt sur les sociétés liés aux distributions,,Charge,
697,Imposition forfaitaire annuelle des sociétés,,Charge,
698,Intégration fiscale,,Charge,
699,Produits Reports en arrière des déficits,,Charge,
7,COMPTES DE PRODUITS,,Produit,
70,"VENTES DE PRODUITS FABRIQUÉS, PRESTATIONS DE SERVICES, MARCHANDISES",,Produit,
701,Ventes de produits finis,,Produit,Favori
702,Ventes de produits intermédiaires,,Produit,Favori
703,Ventes de produits résiduels,,Produit,Favori
704,Travaux,,Produit,Favori
705,Études,,Produit,Favori
706,Prestations de services,,Produit,Favori
707,Ventes de marchandises,,Produit,Favori
708,Produits des activités annexes,,Produit,
709,"Rabais, remises et ristournes accordés par lentreprise",,Produit,
71,PRODUCTION STOCKÉE (OU DÉSTOCKAGE),,Produit,
713,"Variation des stocks (en-cours de production, produits)",,Produit,
72,PRODUCTION IMMOBILISÉE,,Produit,
721,Immobilisations incorporelles,,Produit,
722,Immobilisations corporelles,,Produit,
74,SUBVENTIONS DEXPLOITATION,,Produit,
75,AUTRES PRODUITS DE GESTION COURANTE,,Produit,
751,"Redevances pour concessions, brevets, licences, marques, procédés, logiciels, droits et valeurs similaires",,Produit,
752,Revenus des immeubles non affectés à des activités professionnelles,,Produit,
753,"Jetons de présence et rémunérations dadministrateurs, gérants…",,Produit,
754,Ristournes perçues des coopératives (provenant des excédents),,Produit,
755,Quotes-parts de résultat sur opérations faites en commun,,Produit,
758,Produits divers de gestion courante,,Produit,
76,PRODUITS FINANCIERS,,Produit,
761,PRODUITS DE PARTICIPATIONS,,Produit,
762,Produits des autres immobilisations financières,,Produit,
763,Revenus des autres créances,,Produit,
764,Revenus des valeurs mobilières de placement,,Produit,
765,Escomptes obtenus,,Produit,
766,Gains de change,,Produit,
767,Produits nets sur cessions de valeurs mobilières de placement,,Produit,
768,Autres produits financiers,,Produit,
77,Produits exceptionnels,,Produit,
771,Produits exceptionnels sur opérations de gestion,,Produit,
772,"(Compte à la disposition des entités pour enregistrer, en cours dexercice, les produits sur exercices antérieurs)",,Produit,
775,Produits des cessions déléments dactif,,Produit,
777,Quote-part des subventions dinvestissement virée au résultat de lexercice,,Produit,
778,Autres produits exceptionnels,,Produit,
78,REPRISES SUR AMORTISSEMENTS ET PROVISIONS,,Produit,
781,Reprises sur amortissements et provisions (à inscrire dans les produits dexploitation),,Produit,
786,Reprises sur provisions pour risques (à inscrire dans les produits financiers),,Produit,
787,Reprises sur provisions (à inscrire dans les produits exceptionnels),,Produit,
79,TRANSFERTS DE CHARGES,,Produit,
791,Transferts de charges dexploitation,,Produit,
796,Transferts de charges financières,,Produit,
797,Transferts de charges exceptionnelles,,Produit,
89,COMPTES DE BILAN,,,
890,Bilan d'ouverture,,Actif ou passif,
891,Bilan de clôture,,Actif ou passif,
1 code label description position bookmark
2 1 COMPTES DE CAPITAUX Passif
3 10 CAPITAL ET RÉSERVES Passif
4 101 Capital Passif
5 1011 Capital souscrit -non appelé Passif
6 1012 Capital souscrit -appelé, non versé Passif
7 1013 Capital souscrit - appelé, versé Passif
8 102 Fonds fiduciaires Passif
9 104 Primes liées au capital social Passif
10 105 Écarts de réévaluation Passif
11 106 Réserves Passif
12 1068 Autres réserves Passif
13 107 Écart d’équivalence Passif
14 108 Compte de l’exploitant Passif
15 109 Actionnaires : capital souscrit – non appelé Passif
16 11 REPORT À NOUVEAU (SOLDE CRÉDITEUR OU DÉBITEUR) Passif
17 110 Report à nouveau (solde créditeur) Passif
18 119 Report à nouveau (solde débiteur) Passif
19 12 RÉSULTAT DE L’EXERCICE (BÉNÉFICE OU PERTE) Passif
20 120 Résultat de l’exercice (bénéfice) Passif
21 129 Résultat de l’exercice (perte) Passif
22 13 SUBVENTIONS D’INVESTISSEMENT Passif
23 131 Subventions d’équipement Passif
24 1311 État Passif
25 1312 Régions Passif
26 1313 Départements Passif
27 1314 Communes Passif
28 1315 Collectivités publiques Passif
29 1316 Entreprises publiques Passif
30 1317 Entreprises et organismes privés Passif
31 1318 Autres Passif
32 138 Autres subventions d’investissement Même ventilation que celle du compte 131, à rajouter si nécessaire Passif
33 139 Subventions d’investissement inscrites au compte de résultat Passif
34 1391 Subventions d'équipement Même ventilation que celle du compte 131, à rajouter si nécessaire Passif
35 1398 Autres subventions d’investissement Même ventilation que celle du compte 131, à rajouter si nécessaire Passif
36 14 PROVISIONS RÉGLEMENTÉES Passif
37 142 Provisions réglementées relatives aux immobilisations Passif
38 143 Provisions réglementées relatives aux stocks Passif
39 144 Provisions réglementées relatives aux autres éléments de l’actif Passif
40 145 Amortissements dérogatoires Passif
41 146 Provision spéciale de réévaluation Passif
42 147 Plus-values réinvesties Passif
43 148 Autres provisions réglementées Passif
44 15 PROVISIONS POUR RISQUES ET CHARGES Passif
45 151 Provisions pour risques Passif
46 153 Provisions pour pensions et obligations similaires Passif
47 154 Provisions pour restructurations Passif
48 155 Provisions pour impôts Passif
49 156 Provisions pour renouvellement des immobilisations (entreprises concessionnaires) Passif
50 157 Provisions pour charges à répartir sur plusieurs exercices Passif
51 158 Autres provisions pour charges Passif
52 16 EMPRUNTS ET DETTES ASSIMILÉES Passif
53 161 Emprunts obligataires convertibles Passif
54 163 Autres emprunts obligataires Passif
55 164 Emprunts auprès des établissements de crédit Passif
56 165 Dépôts et cautionnements reçus Passif
57 166 Participation des salariés aux résultats Passif
58 167 Emprunts et dettes assortis de conditions particulières Passif
59 168 Autres emprunts et dettes assimilées Passif
60 169 Primes de remboursement des obligations Passif
61 17 DETTES RATTACHÉES À DES PARTICIPATIONS Passif
62 171 Dettes rattachées à des participations (groupe) Passif
63 174 Dettes rattachées à des participations (hors groupe) Passif
64 178 Dettes rattachées à des sociétés en participation Passif
65 18 COMPTES DE LIAISON DES ÉTABLISSEMENTS ET SOCIÉTÉS EN PARTICIPATION Passif
66 181 Comptes de liaison des établissements Passif
67 186 Biens et prestations de services échangés entre établissements (charges) Passif
68 187 Biens et prestations de services échangés entre établissements (produits) Passif
69 188 Comptes de liaison des sociétés en participation Passif
70 2 COMPTES D’IMMOBILISATIONS Actif
71 20 IMMOBILISATIONS INCORPORELLES Actif
72 201 Frais d’établissement Actif
73 203 Frais de recherche et de développement Actif
74 205 Concessions et droits similaires, brevets, licences, marques, procédés, logiciels, droits et valeurs similaires Actif
75 206 Droit au bail Actif
76 207 Fonds commercial Actif
77 208 Autres immobilisations incorporelles Actif
78 21 IMMOBILISATIONS CORPORELLES Actif
79 211 Terrains Au besoin, créer des sous-comptes 2111 et suivants : Terrains nus, Terrains aménagés, Sous - sols et sursols, Terrains de gisement et Terrains bâtis. Actif
80 212 Agencements et aménagements de terrains (même ventilation que celle du compte 211 (même ventilation que celle du compte 211) Actif
81 213 Constructions Actif
82 214 Constructions sur sol d’autrui (même ventilation que celle du compte 213 Actif
83 215 Installations techniques, matériels et outillage industriels Actif
84 218 Autres immobilisations corporelles Actif
85 22 IMMOBILISATIONS MISES EN CONCESSION Actif
86 23 IMMOBILISATIONS EN COURS Actif
87 231 Immobilisations corporelles en cours Actif
88 232 Immobilisations incorporelles en cours Actif
89 237 Avances et acomptes versés sur immobilisations incorporelles Actif
90 238 Avances et acomptes versés sur commandes d’immobilisations corporelles Actif
91 25 PARTS DANS DES ENTREPRISES LIÉES ET CRÉANCES SUR DES ENTREPRISES LIÉES Actif
92 26 PARTICIPATIONS ET CRÉANCES RATTACHÉES À DES PARTICIPATIONS Actif
93 261 Titres de participation Actif
94 266 Autres formes de participation Actif
95 267 Créances rattachées à des participations Actif
96 268 Créances rattachées à des sociétés en participation Actif
97 269 Versements restant à effectuer sur titres de participation non libérés Actif
98 27 AUTRES IMMOBILISATIONS FINANCIÈRES Actif
99 271 Titres immobilisés autres que les titres immobilisés de l’activité de portefeuille (droit de propriété) Actif
100 272 Titres immobilisés (droit de créance) Actif
101 273 Titres immobilisés de l’activité de portefeuille Actif
102 274 Prêts Actif
103 275 Dépôts et cautionnements versés Actif
104 276 Autres créances immobilisées Actif
105 277 (Actions propres ou parts propres) Actif
106 278 Mali de fusion sur actifs financiers Actif
107 279 Versements restant à effectuer sur titres immobilisés non libérés Actif
108 28 AMORTISSEMENTS DES IMMOBILISATIONS Actif
109 280 Amortissements des immobilisations incorporelles Actif
110 281 Amortissements des immobilisations corporelles Actif
111 282 Amortissements des immobilisations mises en concession Actif
112 29 DÉPRÉCIATIONS DES IMMOBILISATIONS Actif
113 290 Dépréciations des immobilisations incorporelles Actif
114 291 Dépréciations des immobilisations corporelles Même ventilation que celle du compte 21 Actif
115 292 Dépréciations des immobilisations mises en concession Actif
116 293 Dépréciations des immobilisations en cours Actif
117 296 Provisions pour dépréciation des participations et créances rattachées à des participations Actif
118 297 Provisions pour dépréciation des autres immobilisations financières Actif
119 3 COMPTES DE STOCKS ET EN-COURS Actif
120 31 MATIÈRES PREMIÈRES (ET FOURNITURES) Actif
121 311 Matières (ou groupe) A Actif
122 312 Matières (ou groupe) B Actif
123 317 Fournitures A, B, C Actif
124 32 AUTRES APPROVISIONNEMENTS Actif
125 321 Matières consommables Actif
126 322 Fournitures consommables Actif
127 326 Emballages Actif
128 33 EN-COURS DE PRODUCTION DE BIENS Actif
129 331 Produits en cours Actif
130 335 Travaux en cours Actif
131 34 EN-COURS DE PRODUCTION DE SERVICES Actif
132 341 Études en cours Actif
133 345 Prestations de services en cours Actif
134 35 STOCKS DE PRODUITS Actif
135 351 Produits intermédiaires Actif
136 355 Produits finis Actif
137 358 Produits résiduels (ou matières de récupération) Actif
138 37 STOCKS DE MARCHANDISES Actif
139 371 Marchandises (ou groupe) A Actif
140 372 Marchandises (ou groupe) B Actif
141 39 PROVISIONS POUR DÉPRÉCIATION DES STOCKS ET EN-COURS Actif
142 391 Provisions pour dépréciation des matières premières (et fournitures) Actif
143 392 Provisions pour dépréciation des autres approvisionnements Actif
144 393 Provisions pour dépréciation des en-cours de production de biens Actif
145 394 Provisions pour dépréciation des en-cours de production de services Actif
146 395 Provisions pour dépréciation des stocks de produits Actif
147 397 Provisions pour dépréciation des stocks de marchandises Actif
148 4 COMPTES DE TIERS Actif ou passif
149 40 FOURNISSEURS ET COMPTES RATTACHÉS Actif ou passif
150 400 Fournisseurs et Comptes rattachés Actif ou passif
151 401 Fournisseurs Actif ou passif
152 403 Fournisseurs – Effets à payer Passif
153 404 Fournisseurs d’immobilisations Actif ou passif
154 405 Fournisseurs d’immobilisations – Effets à payer Passif
155 408 Fournisseurs – Factures non parvenues Passif
156 409 Fournisseurs débiteurs Actif
157 41 CLIENTS ET COMPTES RATTACHÉS Actif ou passif
158 410 Clients et comptes rattachés Actif ou passif
159 411 Clients Actif ou passif
160 413 Clients – Effets à recevoir Actif
161 416 Clients douteux ou litigieux Actif
162 418 Clients – Produits non encore facturés Actif
163 419 Clients créditeurs Passif
164 42 PERSONNEL ET COMPTES RATTACHÉS Actif ou passif
165 421 Personnel – Rémunérations dues Passif
166 422 Comités d’entreprises, d’établissement,… Actif ou passif
167 424 Participation des salariés aux résultats Actif
168 425 Personnel – Avances et acomptes Actif
169 426 Personnel – Dépôts Passif
170 427 Personnel – Oppositions Passif
171 428 Personnel – Charges à payer et produits à recevoir Passif
172 43 SÉCURITÉ SOCIALE ET AUTRES ORGANISMES SOCIAUX Passif
173 431 Sécurité sociale Passif
174 437 Autres organismes sociaux Passif
175 438 Organismes sociaux – Charges à payer et produits à recevoir Passif
176 44 ÉTAT ET AUTRES COLLECTIVITÉS PUBLIQUES Actif
177 441 État – Subventions à recevoir Actif
178 442 Contributions, impôts et taxes recouvrés pour le compte de l’État Passif
179 443 Opérations particulières avec l’État, les collectivités publiques, les organismes internationaux Actif ou passif
180 444 État – Impôts sur les bénéfices Actif ou passif
181 445 État – Taxes sur le chiffre d’affaires Actif
182 446 Obligations cautionnées Actif
183 447 Autres impôts, taxes et versements assimilés Actif
184 448 État – Charges à payer et produits à recevoir Actif ou passif
185 449 Quotas d’émission à acquérir Passif
186 45 GROUPE ET ASSOCIÉS Actif ou passif
187 451 Groupe Actif ou passif
188 455 Associés – Comptes courants Actif ou passif
189 456 Associés – Opérations sur le capital Actif
190 457 Associés – Dividendes à payer Passif
191 458 Associés – Opérations faites en commun et en G.I.E. Actif ou passif
192 46 DÉBITEURS DIVERS ET CRÉDITEURS DIVERS Actif ou passif
193 462 Créances sur cessions d’immobilisations Actif
194 464 Dettes sur acquisitions de valeurs mobilières de placement Passif
195 465 Créances sur cessions de valeurs mobilières de placement Actif
196 467 Autres comptes débiteurs ou créditeurs Actif ou passif
197 468 Divers – Charges à payer et produits à recevoir Actif ou passif
198 4686 Charges à payer Passif
199 4687 Produits à recevoir Actif
200 47 COMPTES TRANSITOIRES OU D’ATTENTE Actif ou passif
201 471 à 475 comptes d’attente Actif ou passif
202 476 Différence de conversion – Actif Actif
203 477 Différences de conversion – Passif Passif
204 478 Autres comptes transitoires Actif ou passif
205 48 COMPTES DE RÉGULARISATION Actif ou passif
206 481 Charges à répartir sur plusieurs exercices Passif
207 486 Charges constatées d’avance Actif
208 487 Produits constatés d’avance Passif
209 488 Comptes de répartition périodique des charges et des produits Actif ou passif
210 489 Quotas d’émission alloués par l’État Actif
211 49 PROVISIONS POUR DÉPRÉCIATION DES COMPTES DE TIERS Actif ou passif
212 491 Provisions pour dépréciation des comptes de clients Passif
213 495 Provisions pour dépréciation des comptes du groupe et des associés Passif
214 496 Provisions pour dépréciation des comptes de débiteurs divers Passif
215 5 COMPTES FINANCIERS Actif
216 50 VALEURS MOBILIÈRES DE PLACEMENT Actif
217 501 Parts dans des entreprises liées Actif
218 502 Actions propres Actif
219 503 Actions Actif
220 504 Autres titres conférant un droit de propriété Actif
221 505 Obligations et bons émis par la société et rachetés par elle Actif
222 506 Obligations Actif
223 507 Bons du Trésor et bons de caisse à court terme Actif
224 508 Autres valeurs mobilières de placement et autres créances assimilées Actif
225 509 Versements restant à effectuer sur valeurs mobilières de placement non libérées Actif
226 51 BANQUES, ÉTABLISSEMENTS FINANCIERS ET ASSIMILÉS Actif
227 511 Valeurs à l’encaissement Actif ou passif Favori
228 512 Banques Actif ou passif
229 512A Compte courant Actif ou passif Favori
230 514 Chèques postaux Actif ou passif Favori
231 515 « Caisses » du Trésor et des établissements publics Actif ou passif
232 516 Sociétés de bourse Actif
233 517 Autres organismes financiers Actif ou passif
234 518 Intérêts courus Actif ou passif
235 519 Concours bancaires courants Actif ou passif
236 52 INSTRUMENTS DE TRÉSORERIE Actif ou passif
237 53 CAISSE Actif ou passif
238 531 Caisse siège social Actif ou passif Favori
239 532 Caisse succursale (ou usine) A Actif ou passif
240 533 Caisse succursale (ou usine) B Actif ou passif
241 54 RÉGIES D’AVANCE ET ACCRÉDITIFS Actif ou passif
242 58 VIREMENTS INTERNES Actif ou passif
243 59 DÉPRÉCIATION DES COMPTES FINANCIERS Actif ou passif
244 590 Provisions pour dépréciation des valeurs mobilières de placement Passif
245 6 COMPTES DE CHARGES Charge
246 60 ACHATS (SAUF 603) Charge
247 601 Achats stockés – Matières premières (et fournitures) Charge Favori
248 602 Achats stockés – Autres approvisionnements Charge Favori
249 604 Achats d’études et prestations de services Charge Favori
250 605 Achats de matériel, équipements et travaux Charge Favori
251 606 Achats non stockés de matière et fournitures On peut rajouter des sous-comptes : eau, électricité, etc. Charge Favori
252 607 Achats de marchandises Charge Favori
253 608 (Compte réservé, le cas échéant, à la récapitulation des frais accessoires incorporés aux achats) Charge
254 609 Rabais, remises et ristournes obtenus sur achats Charge
255 603 Variations des stocks (approvisionnements et marchandises) Charge
256 61 SERVICES EXTÉRIEURS Charge
257 611 Sous-traitance générale Charge
258 612 Redevances de crédit-bail Charge
259 613 Locations Charge Favori
260 614 Charges locatives et de copropriété Charge Favori
261 615 Entretien et réparations Charge
262 616 Primes d’assurances Charge Favori
263 617 Études et recherches Charge
264 618 Divers Charge
265 619 Rabais, remises et ristournes obtenus sur services extérieurs Charge
266 62 AUTRES SERVICES EXTÉRIEURS Charge
267 621 Personnel extérieur à l’entreprise Charge
268 622 Rémunérations d’intermédiaires et honoraires Charge
269 623 Publicité, publications, relations publiques Charge
270 624 Transports de biens et transports collectifs du personnel Ne comprend pas les transports de l’exploitant Charge
271 625 Déplacements, missions et réceptions Charge Favori
272 626 Frais postaux et de télécommunications Charge Favori
273 627 Services bancaires et assimilés Charge Favori
274 628 Divers Charge
275 629 Rabais, remises et ristournes obtenus sur autres services extérieurs Charge
276 63 IMPÔTS, TAXES ET VERSEMENTS ASSIMILÉS Charge
277 631 Impôts, taxes et versements assimilés sur rémunérations (administrations des impôts) Charge
278 633 Impôts, taxes et versements assimilés sur rémunérations (autres organismes) Charge
279 635 Autres impôts, taxes et versements assimilés (administrations des impôts) Charge
280 637 Autres impôts, taxes et versements assimilés (autres organismes) Charge
281 64 CHARGES DE PERSONNEL Charge
282 641 Rémunérations du personnel Charge
283 644 Rémunération du travail de l’exploitant Charge Favori
284 645 Charges de sécurité sociale et de prévoyance Charge Favori
285 6451 Cotisations à l’Urssaf Charge Favori
286 646 Cotisations sociales personnelles de l’exploitant Charge Favori
287 647 Autres charges sociales Charge
288 648 Autres charges de personnel Charge
289 65 AUTRES CHARGES DE GESTION COURANTE Charge
290 651 Redevances pour concessions, brevets, licences, marques, procédés, logiciels, droits et valeurs similaires Charge
291 653 Jetons de présence Charge
292 654 Pertes sur créances irrécouvrables Charge
293 655 Quote-part de résultat sur opérations faites en commun Charge
294 658 Charges diverses de gestion courante Charge
295 66 CHARGES FINANCIÈRES Charge
296 661 Charges d’intérêts Charge
297 664 Pertes sur créances liées à des participations Charge
298 665 Escomptes accordés Charge
299 666 Pertes de change Charge
300 667 Charges nettes sur cessions de valeurs mobilières de placement Charge
301 668 Autres charges financières Charge
302 67 CHARGES EXCEPTIONNELLES Charge
303 671 Charges exceptionnelles sur opérations de gestion Charge
304 672 (Compte à la disposition des entités pour enregistrer, en cours d’exercice, les charges sur exercices antérieurs) Charge
305 675 Valeurs comptables des éléments d’actif cédés Charge
306 678 Autres charges exceptionnelles Charge
307 68 DOTATIONS AUX AMORTISSEMENTS ET AUX PROVISIONS Charge
308 681 Dotations aux amortissements et aux provisions – Charges d’exploitation Charge
309 686 Dotations aux amortissements et aux provisions – Charges financières Charge
310 687 Dotations aux amortissements et aux provisions – Charges exceptionnelles Charge
311 69 PARTICIPATION DES SALARIÉS – IMPÔTS SUR LES BÉNÉFICES ET ASSIMILÉS Charge
312 691 Participation des salariés aux résultats Charge
313 695 Impôts sur les bénéfices Charge
314 696 Suppléments d’impôt sur les sociétés liés aux distributions Charge
315 697 Imposition forfaitaire annuelle des sociétés Charge
316 698 Intégration fiscale Charge
317 699 Produits – Reports en arrière des déficits Charge
318 7 COMPTES DE PRODUITS Produit
319 70 VENTES DE PRODUITS FABRIQUÉS, PRESTATIONS DE SERVICES, MARCHANDISES Produit
320 701 Ventes de produits finis Produit Favori
321 702 Ventes de produits intermédiaires Produit Favori
322 703 Ventes de produits résiduels Produit Favori
323 704 Travaux Produit Favori
324 705 Études Produit Favori
325 706 Prestations de services Produit Favori
326 707 Ventes de marchandises Produit Favori
327 708 Produits des activités annexes Produit
328 709 Rabais, remises et ristournes accordés par l’entreprise Produit
329 71 PRODUCTION STOCKÉE (OU DÉSTOCKAGE) Produit
330 713 Variation des stocks (en-cours de production, produits) Produit
331 72 PRODUCTION IMMOBILISÉE Produit
332 721 Immobilisations incorporelles Produit
333 722 Immobilisations corporelles Produit
334 74 SUBVENTIONS D’EXPLOITATION Produit
335 75 AUTRES PRODUITS DE GESTION COURANTE Produit
336 751 Redevances pour concessions, brevets, licences, marques, procédés, logiciels, droits et valeurs similaires Produit
337 752 Revenus des immeubles non affectés à des activités professionnelles Produit
338 753 Jetons de présence et rémunérations d’administrateurs, gérants… Produit
339 754 Ristournes perçues des coopératives (provenant des excédents) Produit
340 755 Quotes-parts de résultat sur opérations faites en commun Produit
341 758 Produits divers de gestion courante Produit
342 76 PRODUITS FINANCIERS Produit
343 761 PRODUITS DE PARTICIPATIONS Produit
344 762 Produits des autres immobilisations financières Produit
345 763 Revenus des autres créances Produit
346 764 Revenus des valeurs mobilières de placement Produit
347 765 Escomptes obtenus Produit
348 766 Gains de change Produit
349 767 Produits nets sur cessions de valeurs mobilières de placement Produit
350 768 Autres produits financiers Produit
351 77 Produits exceptionnels Produit
352 771 Produits exceptionnels sur opérations de gestion Produit
353 772 (Compte à la disposition des entités pour enregistrer, en cours d’exercice, les produits sur exercices antérieurs) Produit
354 775 Produits des cessions d’éléments d’actif Produit
355 777 Quote-part des subventions d’investissement virée au résultat de l’exercice Produit
356 778 Autres produits exceptionnels Produit
357 78 REPRISES SUR AMORTISSEMENTS ET PROVISIONS Produit
358 781 Reprises sur amortissements et provisions (à inscrire dans les produits d’exploitation) Produit
359 786 Reprises sur provisions pour risques (à inscrire dans les produits financiers) Produit
360 787 Reprises sur provisions (à inscrire dans les produits exceptionnels) Produit
361 79 TRANSFERTS DE CHARGES Produit
362 791 Transferts de charges d’exploitation Produit
363 796 Transferts de charges financières Produit
364 797 Transferts de charges exceptionnelles Produit
365 89 COMPTES DE BILAN
366 890 Bilan d'ouverture Actif ou passif
367 891 Bilan de clôture Actif ou passif

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

1
src/include/data/schema.sql Symbolic link
View file

@ -0,0 +1 @@
../migrations/1.3/schema.sql

View file

@ -0,0 +1,162 @@
; Ce fichier contient la configuration par défaut des champs des fiches membres.
; La configuration est ensuite enregistrée au format INI dans la table
; config de la base de données.
;
; Syntaxe :
;
; [nom_du_champ] ; Nom unique du champ, ne peut contenir que des lettres et des tirets bas
; type = text
; label = "Super champ trop cool"
; required = true
;
; Description des options possibles pour chaque champ :
;
; type: (défaut: text) OBLIGATOIRE
; certains types gérés par <input type> de HTML5 :
; text, number, date, datetime, url, email, checkbox, file, password, tel
; champs spécifiques :
; - country = sélecteur de pays
; - textarea = texte multi lignes
; - multiple = multiples cases à cocher (jusqu'à 32, binaire)
; - select = un choix parmis plusieurs
; label: OBLIGATOIRE
; Titre du champ
; help:
; Texte d'aide sur les fiches membres
; options[]:
; pour définir les options d'un champ de type select ou multiple
; required:
; true = obligatoire, la fiche membre ne pourra être enregistrée si ce champ est vide
; false = facultatif (défaut)
; user_access_level:
; 2 = modifiable par le membre
; 1 = visible par le membre (défaut)
; 0 = visible uniquement par un admin
; management_access_level:
; 9 = visible par les membres ayant accès en administration
; 2 = visible uniquement par les personnes ayant accès en écriture aux membres
; 1 = visible par les personnes ayant accès en lecture aux membres
; list_table: 'true' si doit être listé par défaut dans la liste des membres
; sql: SQL code for GENERATED columns
; depends[]: list of fields that need to be existing in order to install this field
[numero]
type = number
label = "Numéro de membre"
required = true
list_table = true
default = true
[pronom]
type = "select"
label = "Pronom"
required = false
default = false
list_table = true
options[] = "elle"
options[] = "il"
options[] = "iel"
install_help = "Pour identifier la personne par rapport à son genre"
[nom]
type = text
label = "Nom & prénom"
required = true
list_table = true
default = true
[email]
; ce champ est facultatif et de type 'email'
type = email
label = "Adresse E-Mail"
required = false
default = true
[password]
; ce champ est obligatoirement présent et de type 'password'
; le titre ne peut être modifié
label = "Mot de passe"
type = password
required = false
default = true
[adresse]
type = textarea
label = "Adresse postale"
help = "Indiquer ici le numéro, le type de voie, etc."
default = true
[code_postal]
type = text
label = "Code postal"
default = true
[ville]
type = text
label = "Ville"
list_table = true
default = true
[pays]
type = country
label = "Pays"
default = false
[telephone]
type = tel
label = "Numéro de téléphone"
default = true
[lettre_infos]
type = checkbox
label = "Inscription à la lettre d'information"
install_help = "Case à cocher pour indiquer que le membre souhaite recevoir la lettre d'information de l'association"
default = true
[annee_naissance]
type = year
label = "Année de naissance"
install_help = "Recommandé, plutôt que la date de naissance qui est une information très sensible."
default = false
[age_annee]
type = virtual
label = "Âge"
install_help = "Déterminé en utilisant l'année de naissance"
depends[] = annee_naissance
default = false
sql = "strftime('%Y', date('now')) - annee_naissance"
[date_naissance]
type = date
label = "Date de naissance complète"
default = false
install_help = "Attention, cette information est très sensible, il est déconseillé par le RGPD de la demander aux membres. Il est préférable de demander seulement l'année de naissance."
[age_date]
type = virtual
label = "Âge"
install_help = "Déterminé en utilisant la date de naissance"
depends[] = date_naissance
default = false
sql = "CAST(strftime('%Y.%m%d', date('now')) - strftime('%Y.%m%d', date_naissance) as int)"
[photo]
type = file
label = "Photo"
default = false
[date_inscription]
type = date
label = "Date d'inscription"
help = "Date à laquelle le membre a été inscrit à l'association pour la première fois"
default = true
default_value = "NOW()"
[anciennete]
type = virtual
label = "Ancienneté"
install_help = "Nombre d'années depuis la date d'inscription"
depends[] = date_inscription
default = false
sql = "CAST(strftime('%Y.%m%d', date('now')) - strftime('%Y.%m%d', date_inscription) as INT)"

423
src/include/init.php Normal file
View file

@ -0,0 +1,423 @@
<?php
namespace Paheko;
use KD2\ErrorManager;
use KD2\Security;
use KD2\Form;
use KD2\Translate;
use KD2\DB\EntityManager;
const CONFIG_FILE = 'config.local.php';
require_once __DIR__ . '/lib/KD2/ErrorManager.php';
ErrorManager::enable(ErrorManager::DEVELOPMENT);
ErrorManager::setLogFile(__DIR__ . '/data/error.log');
/*
* Version de Paheko
*/
function paheko_version()
{
if (defined('Paheko\VERSION'))
{
return VERSION;
}
$file = __DIR__ . '/../VERSION';
if (file_exists($file))
{
$version = trim(file_get_contents($file));
}
else
{
$version = 'unknown';
}
define('Paheko\VERSION', $version);
return $version;
}
function paheko_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_FILE)) {
require __DIR__ . '/../' . CONFIG_FILE;
}
// Configuration par défaut, si les constantes ne sont pas définies dans CONFIG_FILE
// (fallback)
if (!defined('Paheko\ROOT'))
{
define('Paheko\ROOT', dirname(__DIR__));
}
\spl_autoload_register(function (string $classname): void {
$classname = ltrim($classname, '\\');
// Plugins
if (substr($classname, 0, 14) == 'Paheko\\Plugin\\')
{
$classname = substr($classname, 14);
$plugin_name = substr($classname, 0, strpos($classname, '\\'));
$filename = str_replace('\\', '/', substr($classname, strpos($classname, '\\')+1));
$path = Plugins::getPath(strtolower($plugin_name));
// Plugin does not exist, just abort
if (!$path) {
return;
}
$path = $path . '/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('Paheko\DATA_ROOT')) {
define('Paheko\DATA_ROOT', ROOT . '/data');
}
if (!defined('Paheko\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('Paheko\WWW_URI', $uri);
unset($uri);
}
$host = null;
if (!defined('Paheko\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/paheko/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('Paheko\WWW_URL') && $host !== null) {
define('Paheko\WWW_URL', \KD2\HTTP::getScheme() . '://' . $host . WWW_URI);
}
static $default_config = [
'CACHE_ROOT' => DATA_ROOT . '/cache',
'SHARED_CACHE_ROOT' => DATA_ROOT . '/cache/shared',
'WEB_CACHE_ROOT' => DATA_ROOT . '/cache/web/%host%',
'DB_FILE' => DATA_ROOT . '/association.sqlite',
'DB_SCHEMA' => ROOT . '/include/data/schema.sql',
'PLUGINS_ROOT' => DATA_ROOT . '/plugins',
'ALLOW_MODIFIED_IMPORT' => true,
'SHOW_ERRORS' => true,
'MAIL_ERRORS' => false,
'ERRORS_REPORT_URL' => null,
'REPORT_USER_EXCEPTIONS' => 0,
'ENABLE_TECH_DETAILS' => true,
'HTTP_LOG_FILE' => null,
'ENABLE_UPGRADES' => true,
'USE_CRON' => false,
'ENABLE_XSENDFILE' => false,
'DISABLE_EMAIL' => false,
'SMTP_HOST' => false,
'SMTP_USER' => null,
'SMTP_PASSWORD' => null,
'SMTP_PORT' => 587,
'SMTP_SECURITY' => 'STARTTLS',
'SMTP_HELO_HOSTNAME' => null,
'MAIL_RETURN_PATH' => null,
'MAIL_BOUNCE_PASSWORD' => null,
'MAIL_SENDER' => null,
'ADMIN_URL' => WWW_URL . 'admin/',
'NTP_SERVER' => 'fr.pool.ntp.org',
'ADMIN_COLOR1' => '#20787a',
'ADMIN_COLOR2' => '#85b9ba',
'ADMIN_BACKGROUND_IMAGE' => WWW_URL . 'admin/static/bg.png',
'FORCE_CUSTOM_COLORS' => false,
'DISABLE_INSTALL_FORM' => false,
'FILE_STORAGE_BACKEND' => 'SQLite',
'FILE_STORAGE_CONFIG' => null,
'FILE_STORAGE_QUOTA' => null,
'FILE_VERSIONING_POLICY' => null,
'FILE_VERSIONING_MAX_SIZE' => null,
'API_USER' => null,
'API_PASSWORD' => null,
'PDF_COMMAND' => 'auto',
'PDF_USAGE_LOG' => null,
'PDFTOTEXT_COMMAND' => null,
'CALC_CONVERT_COMMAND' => null,
'DOCUMENT_THUMBNAIL_COMMANDS' => null,
'SQL_DEBUG' => null,
'SYSTEM_SIGNALS' => [],
'LOCAL_LOGIN' => null,
'LEGAL_HOSTING_DETAILS' => null,
'ALERT_MESSAGE' => null,
'DISABLE_INSTALL_PING' => false,
'WOPI_DISCOVERY_URL' => null,
'SQLITE_JOURNAL_MODE' => 'TRUNCATE',
];
foreach ($default_config as $const => $value)
{
$const = sprintf('Paheko\\%s', $const);
if (!defined($const))
{
define($const, $value);
}
}
// Check SMTP_SECURITY value
if (SMTP_SECURITY) {
$const = '\KD2\SMTP::' . strtoupper(SMTP_SECURITY);
if (!defined($const)) {
throw new \LogicException('Configuration: SMTP_SECURITY n\'a pas une valeur reconnue. Valeurs acceptées: STARTTLS, TLS, SSL, NONE.');
}
}
// Used for private files, just in case WWW_URL is not the same domain as ADMIN_URL
define('Paheko\BASE_URL', str_replace('/admin/', '/', ADMIN_URL));
define('Paheko\ADMIN_URI', preg_replace('!(^https?://[^/]+)!', '', ADMIN_URL));
const HELP_URL = 'https://paheko.cloud/aide?from=%s';
const HELP_PATTERN_URL = 'https://paheko.cloud/%s';
const WEBSITE = 'https://fossil.kd2.org/paheko/';
const PING_URL = 'https://paheko.cloud/ping/';
const PLUGINS_URL = 'https://paheko.cloud/plugins/list.json';
const USER_TEMPLATES_CACHE_ROOT = CACHE_ROOT . '/utemplates';
const STATIC_CACHE_ROOT = CACHE_ROOT . '/static';
const SHARED_USER_TEMPLATES_CACHE_ROOT = SHARED_CACHE_ROOT . '/utemplates';
const SMARTYER_CACHE_ROOT = SHARED_CACHE_ROOT . '/compiled';
// Used to get around some providers misconfiguration issues
if (isset($_SERVER['HTTP_X_OVHREQUEST_ID'])) {
define('Paheko\HOSTING_PROVIDER', 'OVH');
}
else {
define('Paheko\HOSTING_PROVIDER', 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_FILE
if (!ini_get('date.timezone') || ini_get('date.timezone') === 'UTC') {
if (($tz = @date_default_timezone_get()) && $tz !== 'UTC') {
ini_set('date.timezone', $tz);
}
else {
ini_set('date.timezone', 'Europe/Paris');
}
}
class ValidationException extends UserException
{
}
class APIException extends \LogicException
{
}
// activer le gestionnaire d'erreurs/exceptions
ErrorManager::setEnvironment(SHOW_ERRORS ? ErrorManager::DEVELOPMENT : ErrorManager::PRODUCTION | ErrorManager::CLI_DEVELOPMENT);
ErrorManager::setLogFile(DATA_ROOT . '/error.log');
// activer l'envoi de mails si besoin est
if (MAIL_ERRORS) {
ErrorManager::setEmail(MAIL_ERRORS);
}
if (ERRORS_REPORT_URL) {
ErrorManager::setRemoteReporting(ERRORS_REPORT_URL, true);
}
ErrorManager::setContext([
'root_directory' => ROOT,
'paheko_data_root' => DATA_ROOT,
'paheko_version' => paheko_version(),
]);
ErrorManager::setProductionErrorTemplate(defined('Paheko\ERRORS_TEMPLATE') && ERRORS_TEMPLATE ? ERRORS_TEMPLATE : '<!DOCTYPE html><html><head><title>Erreur interne</title>
<style type="text/css">
body {font-family: sans-serif; background: #fff; }
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 -essayer plus tard.</p>
<p>Si vous suspectez un bug dans Paheko, vous pouvez suivre
<a href="https://fossil.kd2.org/paheko/wiki?name=Rapporter+un+bug&p">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><html><head><meta charset="utf-8" /><style type="text/css">
body { font-family: sans-serif; background: #fff; } * { 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></head><body>
<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 Paheko &rarr;" /></p></form></if>
</article>
</section>
');
function user_error(UserException $e)
{
if (REPORT_USER_EXCEPTIONS > 0) {
\Paheko\Form::reportUserException($e);
}
if (PHP_SAPI == 'cli')
{
echo $e->getMessage();
}
else
{
// Flush any previous output, such as module HTML code etc.
@ob_end_clean();
if ($e->getCode() >= 400) {
http_response_code($e->getCode());
}
// Don't use Template class as there might be an error there due do the context (eg. install/upgrade)
$tpl = new \KD2\Smartyer(ROOT . '/templates/error.tpl');
$tpl->setCompiledDir(SMARTYER_CACHE_ROOT);
$tpl->assign('error', $e->getMessage());
$tpl->assign('html_error', $e->getHTMLMessage());
$tpl->assign('admin_url', ADMIN_URL);
$tpl->display();
}
exit;
}
if (REPORT_USER_EXCEPTIONS < 2) {
// Message d'erreur simple pour les erreurs de l'utilisateur
ErrorManager::setCustomExceptionHandler('\Paheko\UserException', '\Paheko\user_error');
}
// Clé secrète utilisée pour chiffrer les tokens CSRF etc.
if (!defined('Paheko\SECRET_KEY'))
{
$key = base64_encode(random_bytes(64));
Install::setLocalConfig('SECRET_KEY', $key);
define('Paheko\SECRET_KEY', $key);
}
// Intégration du secret pour les tokens CSRF
Form::tokenSetSecret(SECRET_KEY);
EntityManager::setGlobalDB(DB::getInstance());
Translate::setLocale('fr_FR');
// This is specific to OVH and other hosting providers who don't set up their servers properly
// see https://www.prestashop.com/forums/topic/393496-prestashop-16-webservice-authentification-on-ovh/
if (!isset($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) && !empty($_SERVER['HTTP_AUTHORIZATION'])) {
@list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6)));
}
/*
* Vérifications pour enclencher le processus d'installation ou de mise à jour
*/
if (!defined('Paheko\INSTALL_PROCESS'))
{
$exists = file_exists(DB_FILE);
if (!$exists) {
if (in_array('install.php', get_included_files())) {
die('Erreur de redirection en boucle : problème de configuration ?');
}
Utils::redirect(ADMIN_URL . 'install.php');
}
$v = DB::getInstance()->version();
if (version_compare($v, paheko_version(), '<')) {
if (!empty($_POST)) {
http_response_code(500);
readfile(ROOT . '/templates/static/upgrade_post.html');
exit;
}
Utils::redirect(ADMIN_URL . 'upgrade.php');
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,338 @@
<?php
/*
This file is part of KD2FW -- <http://dev.kd2.org/>
Copyright (c) 2001-2019 BohwaZ <http://bohwaz.net/>
All rights reserved.
KD2FW 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.
Foobar 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 Foobar. If not, see <https://www.gnu.org/licenses/>.
*/
namespace KD2;
/**
* Cache Cookie
* (C) 2011-2014 BohwaZ
* Inspired by Frank Denis (C) 2011 Public domain
* https://00f.net/2011/01/19/thoughts-on-php-sessions/
*/
class CacheCookie
{
/**
* Name of the cookie
* @var string
*/
protected $name = 'cache';
/**
* Secret key/random hash
* @var string
*/
protected $secret_key = null;
/**
* Digest method for hash_hmac
* @var string
*/
protected $digest_method = 'sha256';
/**
* Delay before expiration when we should renew the cookie
* before it expires (in minutes)
* @var integer
*/
protected $auto_renew = 30;
/**
* Default cookie path
* @var string
*/
protected $path = '/';
/**
* Default cookie domain
* @var string
*/
protected $domain = null;
/**
* Default cookie duration, in minutes
* Will also determine data validity
* @var integer
*/
protected $duration = 0;
/**
* True if the cookie should only be sent over a SSL/TLS connection
* @var boolean
*/
protected $secure = false;
/**
* Start timestamp used to store a shorter timestamp in the cookie
* @var integer
*/
protected $start_timestamp = 1391209200; //2014-02-01 00:00:00
/**
* Cookie content
* @var array
*/
protected $content = null;
/**
* Cookie HTTP only parameter
* @var boolean
*/
protected $httponly = false;
/**
* Create a new CacheCookie instance and setup default parameters
* @param string $name Cookie name
* @param string $secret Secret random hash (should stay the same for at least the cookie duration)
* @param int $duration Cookie duration, in minutes, set to 0 (zero) to make the cookie lasts for the
* whole user agent session (cookie will be deleted when the browser is closed).
* @param string $path Cookie path
* @param string $domain Cookie domain, if left null the current HTTP_HOST or SERVER_NAME will be used
* @param string $secure Set to TRUE if the cookie should only be sent on a secure connection
*/
public function __construct($name = null, $secret = null, $duration = null, $path = null, $domain = null, $secure = false, $httponly = false)
{
if (!is_null($name))
{
$this->name = $name;
}
if (!is_null($secret))
{
$this->secret = $secret;
}
else
{
// Default secret key
$this->secret = \hash('sha256', (isset($_SERVER['DOCUMENT_ROOT']) ? $_SERVER['DOCUMENT_ROOT'] : ''));
}
if (!is_null($duration))
{
$this->duration = (int) $duration;
}
if (!is_null($path))
{
$this->path = $path;
}
if (!is_null($domain))
{
$this->domain = $domain;
}
$this->secure = (bool)$secure;
$this->httponly = (bool)$httponly;
}
public function setAutoRenew($renew)
{
$this->auto_renew = (int) $renew;
}
/**
* Gets the cookie content
* @return array Data contained in the cookie
*/
protected function _getCookie()
{
if (!is_null($this->content))
{
return $this->content;
}
$cookie = null;
$this->content = new \stdClass;
if (!empty($_COOKIE[$this->name]))
{
$cookie = $_COOKIE[$this->name];
}
if (!empty($cookie) && (substr_count($cookie, '|') >= 2))
{
list($digest, $expire, $data) = explode('|', $cookie, 3);
// Check data expiration and integrity
if (!empty($digest) && !empty($data) && !empty($expire)
&& ($expire > round((time() - $this->start_timestamp) / 60))
&& hash_equals($digest, hash_hmac($this->digest_method, $expire . '|' . $data, $this->secret)))
{
if (substr($data, 0, 1) == '{')
{
$this->content = (object) json_decode($data, true);
}
elseif (function_exists('msgpack_unpack'))
{
$this->content = (object) msgpack_unpack($data);
}
// If the cookie will expire soon we try to renew it first
if ($this->auto_renew && ($expire - round((time() - $this->start_timestamp)/60) <= $this->auto_renew))
{
$this->save();
}
}
else
{
// Invalid cookie: just remove it
$this->save();
}
}
return $this->content;
}
/**
* Sends the cookie content to the user-agent
* @return boolean TRUE for success,
* or RuntimeException if the HTTP headers have already been sent
*/
public function save()
{
if (headers_sent())
{
throw new \RuntimeException('Cache cookie can not be saved as headers have '
. 'already been sent to the user agent.');
}
$headers = headers_list(); // List all headers
header_remove(); // remove all headers
$regexp = '/^Set-Cookie\\s*:\\s*' . preg_quote($this->name) . '=/';
foreach ($headers as $header)
{
// Re-add every header except the one for this cookie
if (!preg_match($regexp, $header))
{
header($header, true);
}
}
if (!empty($this->content) && count($this->content) > 0)
{
if (function_exists('msgpack_pack'))
{
$data = msgpack_pack($this->content);
}
else
{
$data = json_encode($this->content);
}
// Store expiration time in minutes
$data = round((time() - $this->start_timestamp + $this->duration*60)/60) . '|' . $data;
$cookie = hash_hmac($this->digest_method, $data, $this->secret) . '|' . $data;
$duration = $this->duration ? time() + $this->duration * 60 : 0;
if (strlen($cookie . $this->path . $duration . $this->domain . $this->name) > 4080)
{
throw new \OverflowException('Cache cookie can not be saved as its size exceeds 4KB.');
}
setcookie($this->name, $cookie, $duration, $this->path, $this->domain, $this->secure, true);
$_COOKIE[$this->name] = $cookie;
}
else
{
setcookie($this->name, '', 1, $this->path, $this->domain, $this->secure, true);
unset($_COOKIE[$this->name]);
}
return true;
}
/**
* Set a key/value pair in the cache cookie
* @param mixed $key Key (integer or string)
* @param mixed $value Value (integer, string, boolean, array, float...)
*/
public function set($key, $value)
{
$this->_getCookie();
if (is_null($value))
{
unset($this->content->$key);
}
else
{
$this->content->$key = $value;
}
return true;
}
/**
* Get data from the cache cookie, if $key is NULL then all the keys will be returned
* @param mixed $key Data key
* @return mixed NULL if the key is not found, or content of the requested key
*/
public function get($key = null)
{
$content = $this->_getCookie();
if (is_null($key))
{
return $content;
}
if (!isset($content->$key))
{
return null;
}
else
{
return $content->$key;
}
}
/**
* Delete the cookie and all its data
* @return boolean TRUE
*/
public function delete()
{
$content = $this->get();
foreach ($content as $key=>$value)
{
$this->set($key, null);
}
return $this->save();
}
/**
* Returns raw cookie data
* @return string cookie content
*/
public function getRawData()
{
if (isset($_COOKIE[$this->name]))
return $_COOKIE[$this->name];
return null;
}
}

View file

@ -0,0 +1,562 @@
<?php
declare(strict_types=1);
/*
This file is part of KD2FW -- <http://dev.kd2.org/>
Copyright (c) 2001-2019 BohwaZ <http://bohwaz.net/>
All rights reserved.
KD2FW 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.
Foobar 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 Foobar. If not, see <https://www.gnu.org/licenses/>.
*/
namespace KD2\DB;
/**
* AbstractEntity: a generic entity that can be extended to build your entities
* Use the EntityManager to persist entities in a database
*
* @author bohwaz
* @license AGPLv3
*/
abstract class AbstractEntity
{
protected $_exists = false;
protected $_modified = [];
protected $_types = [];
static protected $_types_cache = [];
/**
* Default constructor
*/
public function __construct()
{
// Generate types cache
if (empty(self::$_types_cache[static::class]) && empty($this->_types)) {
$r = new \ReflectionClass(static::class);
foreach ($r->getProperties(\ReflectionProperty::IS_PROTECTED) as $p) {
if ($p->name[0] == '_') {
// Skip internal stuff
continue;
}
if (array_key_exists($p->name, $this->_types)) {
$type = $this->_types[$p->name];
}
else {
$t = $p->getType();
if (null === $t) {
throw new \LogicException(sprintf('Property "%s" of entity "%s" has no type', $p->name, static::class));
}
$type = $t->getName();
$type = ($t->allowsNull() ? '?' : '') . $type;
}
$this->_types[$p->name] = $type;
}
}
self::_loadEntityTypesCache($this->_types);
}
static protected function _loadEntityTypesCache(array $types)
{
if (!empty(self::$_types_cache[static::class])) {
return;
}
foreach ($types as $name => $type) {
$nullable = false;
if ($type[0] === '?') {
$type = substr($type, 1);
$nullable = true;
}
$prop = (object) compact('name', 'nullable', 'type');
$prop->boolean = $type === 'bool' || $type === 'boolean';
$prop->integer = $type === 'int' || $type === 'integer';
$prop->float = $type === 'float' || $type === 'double';
$prop->string = $type === 'string';
$prop->array = $type === 'array';
$prop->object = !$prop->boolean && !$prop->integer && !$prop->float && !$prop->string && !$prop->array;
$prop->class = $prop->object ? $type : null;
$prop->stdclass = $prop->class === 'stdClass';
$prop->datetime = $prop->class === 'DateTime' || $prop->class === 'DateTimeInterface';
$prop->date = $prop->class === Date::class || $prop->class === 'date';
self::$_types_cache[static::class][$name] = $prop;
}
}
public function __wakeup(): void
{
if (empty(self::$_types_cache[static::class])) {
self::_loadEntityTypesCache($this->_types);
}
}
/**
* Loads data from an array into the entity properties
* Used for example to load data from a database. This will convert string values to typed properties.
* @param array $data
* @return self
*/
public function load(array $data): self
{
$properties = self::$_types_cache[static::class];
foreach ($data as $key => $value) {
if (!array_key_exists($key, $properties)) {
throw new \RuntimeException(sprintf('"%s" is not a property of the entity "%s"', $key, static::class));
}
}
foreach ($properties as $name => $prop) {
if (!array_key_exists($name, $data)) {
throw new \RuntimeException('Missing key in array: ' . $name);
}
$value = $data[$name];
if (is_int($value) && $prop->boolean) {
$value = (bool) $value;
}
elseif (is_string($value) && !$prop->string) {
$value = $this->transformValue($name, $value);
}
$this->$name = $value;
}
return $this;
}
/**
* Import data from an array of user-supplied values, only keys corresponding to entity properties
* will be used, others will be ignored.
* @param array|null $source Source data array, if none is supplied $_POST will be used
* @return void
*/
public function import(array $source = null): self
{
if (null === $source) {
$source = $_POST;
}
unset($source['id']);
$data = array_intersect_key($source, self::$_types_cache[static::class]);
foreach ($data as $key => $value) {
$prop = self::$_types_cache[static::class][$key];
if ($prop->nullable && is_string($value) && trim($value) === '') {
$value = null;
}
$value = $this->filterUserValue($prop->type, $value, $key);
$this->setFromAnyValue($key, $value);
}
return $this;
}
protected function filterUserValue(string $type, $value, string $key)
{
if (is_null($value)) {
return $value;
}
switch ($type)
{
case 'date':
case Date::class:
$d = new Date($value);
$d->setTime(0, 0, 0);
return $d;
case 'DateTime':
return new \DateTime($value);
case 'int':
return (int) $value;
case 'float':
return (float) $value;
case 'bool':
return (bool) $value;
case 'string':
return trim((string) $value);
}
return $value;
}
protected function assert($test, string $message = null): void
{
if ($test) {
return;
}
if (null === $message) {
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
$caller_class = array_pop($backtrace);
$caller = array_pop($backtrace);
$message = sprintf('Entity assertion fail from class %s on line %d', $caller_class['class'], $caller['line']);
}
throw new \UnexpectedValueException($message);
}
public function selfCheck(): void
{
$this->assert(!isset($this->id) || (is_numeric($this->id) && $this->id > 0));
foreach (self::$_types_cache[static::class] as $prop_name => $prop) {
// Skip ID
if ($prop_name == 'id') {
continue;
}
if (!isset($this->$prop_name) && !$prop->nullable) {
throw new \UnexpectedValueException(sprintf('Entity property "%s" cannot be left NULL', $prop_name));
}
}
}
public function asArray(bool $for_database = false): array
{
$vars = get_object_vars($this);
// Remove internal stuff
foreach ($vars as $key => &$value) {
if ($key[0] == '_') {
unset($vars[$key]);
continue;
}
if (!$for_database) {
continue;
}
$value = $this->getAsString($key);
}
return $vars;
}
public function getAsString(string $key, $value = null)
{
if (!isset($this->$key)) {
return null;
}
$value ??= $this->$key;
switch (gettype($value)) {
case 'object':
if ($value instanceof \stdClass) {
return json_encode($value);
}
elseif ($value instanceof Date) {
return $value->format('Y-m-d');
}
elseif ($value instanceof \DateTimeInterface) {
return $value->format('Y-m-d H:i:s');
}
return (string) $value;
case 'bool':
case 'boolean':
return (int) $value;
case 'array':
return json_encode($value);
case 'int':
case 'integer':
case 'double':
case 'float':
return $value;
default:
return (string) $value;
}
}
/**
* Returns an array containing *OLD* values of modified properties
* (*NEW* value is stored in object)
*
* Note that modified properties are cleared after save()
*/
public function getModifiedProperties(): array
{
return $this->_modified;
}
/**
* @deprecated
*/
public function modifiedProperties(bool $for_database = false): array
{
return array_intersect_key($this->asArray($for_database), $this->_modified);
}
/**
* Returns the *OLD* value of a modified property
*/
public function getModifiedProperty(string $key)
{
return $this->_modified[$key] ?? null;
}
public function clearModifiedProperties(?array $properties = null): void
{
if (null === $properties) {
$this->_modified = [];
return;
}
foreach ($properties as $key) {
unset($this->_modified[$key]);
}
}
public function isModified(?string $property = null): bool
{
if ($property !== null) {
return array_key_exists($property, $this->_modified);
}
else {
return count($this->_modified) > 0;
}
}
public function id(int $id = null): int
{
if (null !== $id) {
$this->id = $id;
}
if (!isset($this->id)) {
throw new \LogicException('This entity does not have an ID yet');
}
return $this->id;
}
public function exists(bool $exists = null): bool
{
if (null !== $exists) {
$this->_exists = $exists;
if ($exists === false) {
unset($this->id);
}
}
return $this->_exists;
}
public function setFromAnyValue(string $key, $value)
{
$this->set($key, $this->transformValue($key, $value));
}
/**
* Transforms the value from loosely typed to be suitable to expected type of a property
* eg. (string)'42' => (int)42
*/
public function transformValue(string $key, $value)
{
$prop = self::$_types_cache[static::class][$key] ?? null;
if (null === $prop) {
throw new \InvalidArgumentException(sprintf('Unknown "%s" property: "%s"', static::class, $key));
}
if (is_string($value) && trim($value) === '' && $prop->nullable) {
$value = null;
}
elseif (($prop->float || $prop->integer) && is_string($value) && is_numeric($value)) {
$value = (int)$value;
}
elseif ($prop->datetime && is_string($value) && strlen($value) === 19 && ($d = \DateTime::createFromFormat('!Y-m-d H:i:s', $value))) {
$value = $d;
}
elseif ($prop->datetime && is_string($value) && strlen($value) === 16 && ($d = \DateTime::createFromFormat('!Y-m-d H:i', $value))) {
$value = $d;
}
elseif ($prop->date && is_string($value) && strlen($value) === 10 && ($d = Date::createFromFormat('!Y-m-d', $value))) {
$value = $d;
}
elseif ($prop->date && is_object($value) && $value instanceof \DateTime && !($value instanceof Date)) {
$value = Date::createFromInterface($value);
}
elseif ($prop->boolean && is_numeric($value) && ($value == 0 || $value == 1)) {
$value = (bool) $value;
}
elseif ($prop->array && is_string($value)) {
$value = json_decode($value, true);
if (null === $value) {
throw new \RuntimeException(sprintf('Cannot decode JSON string for key "%s"', $key));
}
}
elseif ($prop->stdclass && is_string($value)) {
$value = json_decode($value);
if (null === $value) {
throw new \RuntimeException(sprintf('Cannot decode JSON string for key "%s"', $key));
}
}
return $value;
}
public function set(string $key, $value)
{
$prop = self::$_types_cache[static::class][$key] ?? null;
if (null === $prop) {
throw new \InvalidArgumentException(sprintf('Unknown "%s" property: "%s"', static::class, $key));
}
if (isset($this->$key) && is_object($this->$key)) {
$original_value = clone $this->$key;
}
elseif (isset($this->$key)) {
$original_value = $this->$key;
}
else {
$original_value = null;
}
if (null === $value && !$prop->nullable) {
throw new \UnexpectedValueException(sprintf('Unexpected NULL value for "%s"', $key));
}
if ($prop->date && is_object($value) && !($value instanceof Date)) {
$value = Date::createFromInterface($value);
}
if (null !== $value && !$this->_checkValueType($value, $prop)) {
$found_type = $this->_getValueType($value);
if ('object' == $found_type) {
$found_type = get_class($value);
}
throw new \UnexpectedValueException(sprintf('Value of type \'%s\' for property \'%s\' is invalid (expected \'%s\')', $found_type, $key, $prop->type));
}
// Normalize line breaks to \n
if (is_string($value) && (!isset($this->$key) || $this->$key !== $value)) {
$value = str_replace("\r\n", "\n", $value);
$value = str_replace("\r", "\n", $value);
}
$this->$key = $value;
// For storing a modified object, compare its string value, not the object, as DateTime !== DateTime
if (is_object($value) && is_object($original_value)) {
$compare_value = $this->getAsString($key, $original_value);
$value = $this->getAsString($key, $value);
}
else {
$compare_value = $original_value;
}
// Only modify entity if value has changed
if ($value !== $compare_value) {
$this->_modified[$key] = $original_value;
}
}
public function get(string $key)
{
return $this->$key ?? null;
}
public function __set(string $key, $value)
{
$this->set($key, $value);
}
public function __get(string $key)
{
return $this->get($key);
}
public function __isset($key)
{
return property_exists($this, $key) && isset($this->$key);
}
/**
* Make sure the cloned object doesn't have the same ID, it's a brand new entity!
*/
public function __clone()
{
unset($this->id);
$this->_exists = false;
}
protected function _checkValueType($value, \stdClass $prop): bool
{
$type = $this->_getValueType($value);
if ($type !== 'object' && isset($prop->$type) && $prop->$type === true) {
return true;
}
elseif ($prop->date && $value instanceof Date) {
return true;
}
elseif ($prop->datetime && $value instanceof \DateTimeInterface) {
return true;
}
elseif ($prop->stdclass && $value instanceof \stdClass) {
return true;
}
elseif ($prop->class && $value instanceof $prop->class) {
return true;
}
return false;
}
protected function _getValueType($value)
{
$type = gettype($value);
// Type names are not consistent in PHP...
// see https://mlocati.github.io/articles/php-type-hinting.html
$type = $type === 'double' ? 'float': $type;
return $type;
}
// Helpful helpers
public function save(bool $selfcheck = true): bool
{
return EntityManager::getInstance(static::class)->save($this, $selfcheck);
}
public function delete(): bool
{
return EntityManager::getInstance(static::class)->delete($this);
}
}

View file

@ -0,0 +1,407 @@
<?php
declare(strict_types=1);
/*
This file is part of KD2FW -- <http://dev.kd2.org/>
Copyright (c) 2001-2019 BohwaZ <http://bohwaz.net/>
All rights reserved.
KD2FW 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.
Foobar 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 Foobar. If not, see <https://www.gnu.org/licenses/>.
*/
namespace KD2\DB;
/**
* AbstractEntity: a generic entity that can be extended to build your entities
* Use the EntityManager to persist entities in a database
*
* @author bohwaz
* @license AGPLv3
*/
abstract class AbstractEntity
{
protected $id;
protected $_exists = false;
protected $_modified = [];
protected $_types = [];
/**
* Default constructor
*/
public function __construct()
{
// Generate _types array
if (version_compare(PHP_VERSION, '7.4', '>=') && empty($this->_types)) {
$r = new \ReflectionClass(static::class);
foreach ($r->getProperties(\ReflectionProperty::IS_PROTECTED) as $p) {
if ($p->name[0] == '_') {
// Skip internal stuff
continue;
}
if ($p->name == 'id') {
$type = 'int';
}
else {
$t = $p->getType();
if (null === $t) {
throw new \LogicException(sprintf('Property "%s" of entity "%s" has no type', $p->name, static::class));
}
$type = $t->getName();
$type = ($t->allowsNull() ? '?' : '') . $type;
}
$this->_types[$p->name] = $type;
}
}
}
/**
* Loads data from an array into the entity properties
* Used for example to load data from a database. This will convert string values to typed properties.
* @param array $data
* @return void
*/
public function load(array $data): void
{
$properties = array_keys($this->_types);
foreach ($data as $key => $value) {
if (!in_array($key, $properties)) {
throw new \RuntimeException(sprintf('"%s" is not a property of the entity "%s"', $key, static::class));
}
}
foreach ($properties as $key) {
if (!array_key_exists($key, $data)) {
throw new \RuntimeException('Missing key in array: ' . $key);
}
$value = $data[$key];
$this->set($key, $value, true, false);
}
}
/**
* Import data from an array of user-supplied values, only keys corresponding to entity properties
* will be used, others will be ignored.
* @param array|null $source Source data array, if none is supplied $_POST will be used
* @return void
*/
public function import(array $source = null): self
{
if (null === $source) {
$source = $_POST;
}
$data = array_intersect_key($source, $this->_types);
foreach ($data as $key => $value) {
$type = $this->_types[$key];
if (substr($type, 0, 1) == '?') {
$type = substr($type, 1);
}
$value = $this->filterUserValue($type, $value, $key);
$this->set($key, $value, true, true);
}
return $this;
}
protected function filterUserValue(string $type, $value, string $key)
{
if (is_null($value)) {
return $value;
}
switch ($type)
{
case 'date':
return \DateTime::createFromFormat('!Y-m-d', $value);
case 'DateTime':
return new \DateTime($value);
case 'int':
return (int) $value;
case 'bool':
return (bool) $value;
case 'string':
return trim($value);
}
return $value;
}
protected function assert(?bool $test, string $message = null): void
{
if ($test) {
return;
}
if (null === $message) {
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
$caller_class = array_pop($backtrace);
$caller = array_pop($backtrace);
$message = sprintf('Entity assertion fail from class %s on line %d', $caller_class['class'], $caller['line']);
}
throw new \UnexpectedValueException($message);
}
public function selfCheck(): void
{
$this->assert(is_null($this->id) || (is_numeric($this->id) && $this->id > 0));
foreach ($this->_types as $key => $type) {
// Skip ID
if ($key == 'id') {
continue;
}
if (is_null($this->$key) && substr($type, 0, 1) != '?') {
throw new \UnexpectedValueException(sprintf('Entity property "%s" cannot be left null', $key));
}
}
}
public function asArray($for_database = false): array
{
$vars = get_object_vars($this);
// Remove internal stuff
foreach ($vars as $key => &$value) {
if ($key[0] == '_') {
unset($vars[$key]);
continue;
}
if (!$for_database) {
continue;
}
$value = $this->getAsString($key);
}
return $vars;
}
public function getAsString(string $key)
{
if (null === $this->$key) {
return null;
}
$type = $this->_types[$key];
if (substr($type, 0, 1) == '?') {
$type = substr($type, 1);
}
switch ($type) {
// Export dates
case 'date':
$v = clone $this->$key;
$v->setTimezone(new \DateTimeZone('UTC'));
return $v->format('Y-m-d');
case 'DateTime':
$v = clone $this->$key;
$v->setTimezone(new \DateTimeZone('UTC'));
return $v->format('Y-m-d H:i:s');
case 'bool':
return (int) $this->$key;
default:
return $this->$key;
}
}
public function modifiedProperties($for_database = false): array
{
return array_intersect_key($this->asArray($for_database), $this->_modified);
}
public function isModified(): bool
{
return count($this->_modified) > 0;
}
public function id(int $id = null): int
{
if (null !== $id) {
$this->id = $id;
}
if (null === $this->id) {
throw new \LogicException('This entity does not have an ID yet');
}
return $this->id;
}
public function exists(bool $exists = null): bool
{
if (null !== $exists) {
$this->_exists = $exists;
}
return $this->_exists;
}
public function set(string $key, $value, bool $loose = false, bool $check_for_changes = true) {
if (!property_exists($this, $key)) {
throw new \InvalidArgumentException(sprintf('Unknown "%s" property: "%s"', static::class, $key));
}
if (isset($this->$key)) {
$original_value = $this->getAsString($key);
}
else {
$original_value = null;
}
$type = $this->_types[$key];
$nullable = false;
if ($type[0] == '?') {
$nullable = true;
$type = substr($type, 1);
}
if ($loose) {
if (is_string($value) && trim($value) === '' && $nullable) {
$value = null;
}
if ($value !== null) {
if ($type == 'int' && is_string($value) && ctype_digit($value)) {
$value = (int)$value;
}
elseif ($type == 'DateTime' && is_string($value) && strlen($value) === 19 && ($d = \DateTime::createFromFormat('Y-m-d H:i:s-e', $value . '-UTC'))) {
$value = $d;
}
elseif ($type == 'date' && is_string($value) && strlen($value) === 10 && ($d = \DateTime::createFromFormat('!Y-m-d-e', $value . '-UTC'))) {
$value = $d;
}
elseif ($type == 'bool' && is_numeric($value) && ($value == 0 || $value == 1)) {
$value = (bool) $value;
}
}
}
if (!$nullable && null === $value) {
throw new \RuntimeException(sprintf('Unexpected NULL value for "%s"', $key));
}
if (null !== $value && !$this->_checkType($key, $value, $type)) {
$found_type = $this->_getType($value);
if ('object' == $found_type) {
$found_type = get_class($value);
}
throw new \UnexpectedValueException(sprintf('Value of type \'%s\' for property \'%s\' is invalid (expected \'%s\')', $found_type, $key, $type));
}
$this->$key = $value;
if ($check_for_changes && $original_value !== $this->getAsString($key)) {
$this->_modified[$key] = true;
}
}
public function get(string $key)
{
return $this->$key;
}
public function __set(string $key, $value)
{
$this->set($key, $value, false, true);
}
public function __get(string $key)
{
return $this->$key;
}
public function __isset($key)
{
return isset($this->$key);
}
/**
* Make sure the cloned object doesn't have the same ID, it's a brand new entity!
*/
public function __clone()
{
$this->id = null;
$this->_exists = false;
}
protected function _checkType(string $key, $value, string $type): bool
{
if (false !== strpos($type, '|')) {
$types = explode('|', $type);
foreach ($types as $type) {
if ($this->_checkType($key, $value, $type)) {
return true;
}
}
return false;
}
switch ($type) {
case 'date':
return is_object($value) && $value instanceof \DateTimeInterface;
case 'DateTime':
return is_object($value) && $value instanceof \DateTimeInterface;
default:
return $this->_getType($value) == $type;
}
}
protected function _getType($value)
{
$type = gettype($value);
// Type names are not consistent in PHP...
// see https://mlocati.github.io/articles/php-type-hinting.html
$type = strtr($type, ['boolean' => 'bool', 'integer' => 'int', 'double' => 'float']);
if ($type === 'object') {
$type = get_class($value);
}
return $type;
}
// Helpful helpers
public function save(): bool
{
return EntityManager::getInstance(static::class)->save($this);
}
public function delete(): bool
{
return EntityManager::getInstance(static::class)->delete($this);
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,33 @@
<?php
namespace KD2\DB;
use DateTime;
use DateTimeInterface;
use DateTimeZone;
/**
* Just a helper that tells us that the date should be stored as Y-m-d that's all
*/
class Date extends DateTime {
// For PHP 7.4
static public function createFromInterface(DateTimeInterface $object): DateTime
{
$n = new self;
$n->setTimestamp($object->getTimestamp());
$n->setTimezone($object->getTimeZone());
return $n;
}
#[\ReturnTypeWillChange]
static public function createFromFormat($format, $datetime, DateTimeZone $object = null)
{
$v = parent::createFromFormat($format, $datetime, $object);
if (!$v) {
return $v;
}
return self::createFromInterface($v);
}
}

View file

@ -0,0 +1,255 @@
<?php
namespace KD2\DB;
use KD2\DB\DB;
use KD2\DB\SQLite3;
use KD2\DB\AbstractEntity;
use PDO;
class EntityManager
{
protected $class;
protected $db;
static protected $_instances = [];
static protected $_global_db;
/**
* Returns an EntityManager instance linked to a specific Entity class
* @param string $class Entity class name
* @return EntityManager
*/
static public function getInstance(string $class): self
{
// Create a new entity manager for this entity if it does not exist
if (!array_key_exists($class, self::$_instances)) {
// Check that the class is a child of AbstractEntity
if (!is_a($class, AbstractEntity::class, true)) {
throw new \InvalidArgumentException(sprintf('Class "%s" does not extend "%s"', $class, AbstractEntity::class));
}
// The entity manager works with SQL tables, so the entity needs to specify a table
if (!defined($class . '::TABLE')) {
throw new \InvalidArgumentException(sprintf('Class "%s" does not define a TABLE constant', $class));
}
self::$_instances[$class] = new EntityManager($class);
}
return self::$_instances[$class];
}
/**
* Sets the database manager used for all entity managers, unless they have a specific one
* @param DB $db
*/
static public function setGlobalDB(DB $db): void
{
self::$_global_db = $db;
}
/**
* Set local database object used for this entity manager
* @param DB|null $db Set to NULL to use the global manager
*/
public function setDB(?DB $db = null): void
{
$this->db = $db;
}
/**
* Returns the correct database object for this entity manager
*/
public function DB(): DB
{
if (null !== $this->db) {
$db = $this->db;
}
else {
$db = self::$_global_db;
}
if (null === $db) {
throw new \LogicException('No DB object has been set');
}
return $db;
}
protected function __construct(string $class)
{
$this->class = $class;
}
/**
* Returns an Entity according to a query
* @param string $class Entity class name
* @param string $query SQL query
* @param mixed ...$params Optional parameters to be used in the query
* @return null|AbstractEntity
*/
static public function findOne(string $class, string $query, ...$params)
{
return self::getInstance($class)->one($query, ...$params);
}
/**
* Returns an Entity from its ID
* @param string $class Entity class name
* @param int $id Entity ID
* @return null|AbstractEntity
*/
static public function findOneById(string $class, int $id, ?string $table = null)
{
$query = sprintf('SELECT * FROM %s WHERE id = ?;', $table ?? $class::TABLE);
return self::findOne($class, $query, $id);
}
/**
* Formats a SQL query by replacing the table name with the entity table name
* @param string $query SQL query
* @return string
*/
public function formatQuery(string $query): string
{
$class = $this->class;
$query = str_replace('@TABLE', $class::TABLE, $query);
return $query;
}
public function all(string $query, ...$params): array
{
$res = $this->iterate($query, ...$params);
$out = [];
foreach ($res as $row) {
$out[] = $row;
}
return $out;
}
public function allAssoc(string $query, string $key, ...$params): array
{
$res = $this->iterate($query, ...$params);
$out = [];
foreach ($res as $row) {
$out[$row->$key] = $row;
}
return $out;
}
public function iterate(string $query, ...$params): iterable
{
$db = $this->DB();
$query = $this->formatQuery($query);
$res = $db->preparedQuery($query, $params);
if ($db instanceof SQLite3) {
while ($row = $res->fetchArray(\SQLITE3_ASSOC)) {
// If you are getting a row containing only NULL values
// it probably means you are deleting rows before the iteration
// has a chance to fetch it!
$obj = new $this->class;
$obj->exists(true);
$obj->load($row);
yield $obj;
}
$res->finalize();
}
else {
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
$obj = new $this->class;
$obj->exists(true);
$obj->load($row);
yield $obj;
}
}
}
public function one(string $query, ...$params)
{
$db = $this->DB();
$query = $this->formatQuery($query);
$res = $db->preparedQuery($query, $params);
if ($db instanceof SQLite3) {
$row = $res->fetchArray(\SQLITE3_ASSOC);
$res->finalize();
}
else {
$row = $res->fetch(PDO::FETCH_ASSOC);
}
if (false === $row) {
return null;
}
$obj = new $this->class;
$obj->exists(true);
$obj->load($row);
return $obj;
}
public function col(string $query, ...$params)
{
$query = $this->formatQuery($query);
$db = $this->DB();
return $db->firstColumn($query, ...$params);
}
public function save(AbstractEntity $entity, bool $selfcheck = true): bool
{
if ($selfcheck) {
$entity->selfCheck();
}
$db = $this->DB();
if ($entity->exists()) {
if ($entity->isModified()) {
$data = array_intersect_key($entity->asArray(true), $entity->getModifiedProperties());
$return = $db->update($entity::TABLE, $data, $db->where('id', $entity->id()));
}
else {
$return = true;
}
}
else {
$data = $entity->asArray(true);
$data = array_filter($data, static function($v) { return $v !== null; });
$return = $db->insert($entity::TABLE, $data);
if ($return) {
$id = (int) $db->lastInsertId();
if ($id < 1) {
throw new \LogicException('Error inserting entity in DB: invalid ID = ' . $id);
}
$entity->exists(true);
$entity->id($id);
}
}
$entity->clearModifiedProperties();
return $return;
}
public function delete(AbstractEntity $entity): bool
{
$db = $this->DB();
$return = $db->delete($entity::TABLE, $db->where('id', $entity->id()));
if ($return) {
$entity->exists(false);
}
return $return;
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,105 @@
<?php
/*
This file is part of KD2FW -- <http://dev.kd2.org/>
Copyright (c) 2001-2020 BohwaZ <http://bohwaz.net/>
All rights reserved.
KD2FW 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.
Foobar 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 KD2FW. If not, see <https://www.gnu.org/licenses/>.
*/
/**
* DB_SQLite3_Undo: adds the ability to undo/redo any SQL statement to a SQLite3 database
*
* @author bohwaz http://bohwaz.net/
* @license AGPLv3
*/
namespace KD2\DB;
use PDO;
class SQLite3_Undo
{
protected $db;
public function __construct(DB $db)
{
$this->db = $db;
}
public function disable(array $tables)
{
$db = $this->db;
foreach ($tables as $name) {
$sql = 'SELECT name, name FROM sqlite_master WHERE type = \'trigger\' AND name LIKE \'!_%s_log!__t\' ESCAPE \'!\';';
$sql = sprintf($sql, $name);
$triggers = $db->getAssoc($sql);
foreach ($triggers as $trigger)
{
$db->exec(sprintf('DROP TRIGGER %s;', $db->quoteIdentifier($trigger)));
}
}
}
public function enable(array $tables)
{
$db = $this->db;
$db->exec('CREATE TABLE IF NOT EXISTS undolog (
seq INTEGER PRIMARY KEY,
table TEXT NOT NULL,
action TEXT NOT NULL
sql TEXT NOT NULL,
date TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
);');
$query = 'CREATE TRIGGER _%table_log_it AFTER INSERT ON %table BEGIN
DELETE FROM undolog WHERE rowid IN (SELECT rowid FROM undolog LIMIT 500,1000);
INSERT INTO undolog (table, action, sql) VALUES (\'%table\', \'I\', \'DELETE FROM %table WHERE rowid=\'||new.rowid);
END;
CREATE TRIGGER _%table_log_ut AFTER UPDATE ON %table BEGIN
DELETE FROM undolog WHERE rowid IN (SELECT rowid FROM undolog LIMIT 500,1000);
INSERT INTO undolog (table, action, sql) VALUES (\'%table\', \'U\', \'UPDATE %table SET %columns_update WHERE rowid = \'||old.rowid);
END;
CREATE TRIGGER _%table_log_dt BEFORE DELETE ON %table BEGIN
DELETE FROM undolog WHERE rowid IN (SELECT rowid FROM undolog LIMIT 500,1000);
INSERT INTO undolog (table, action, sql) VALUES (\'%table\', \'D\', \'INSERT INTO %table (rowid, %columns_list) VALUES(\'||old.rowid||\', %columns_insert)\');
END;';
foreach ($tables as $table)
{
$columns = $db->getAssoc(sprintf('PRAGMA table_info(%s);', $this->quoteIdentifier($table)));
$columns_insert = [];
$columns_update = [];
foreach ($columns as &$name)
{
$columns_update[] = sprintf('%s = \'||quote(old.%1$s)||\'', $name);
$columns_insert[] = sprintf('\'||quote(old.%s)||\'', $name);
}
$sql = strtr($query, [
'%table' => $table,
'%columns_list' => implode(', ', $columns),
'%columns_update' => implode(', ', $columns_update),
'%columns_insert' => implode(', ', $columns_insert),
]);
$db->exec($sql);
}
}
}

205
src/include/lib/KD2/DNS.php Normal file
View file

@ -0,0 +1,205 @@
<?php
namespace KD2;
class DNS
{
static public function getRecordsFromDomainNS(string $type, string $record): array
{
$ns = dns_get_record($record, \DNS_NS);
if (empty($ns) || empty($ns[0]['target'])) {
return null;
}
$ns = $ns[0]['target'];
return self::getRecordsFrom($ns, $type, $record);
}
/**
* Make a DNS a request to a custom nameserver, this is similar to dns_get_record, but allows you to query any nameserver
* Usage: dns_get_record_from('ns.server.tld', 'A', 'mydomain.tld');
* => ['42.42.42.42']
* @author bohwaz
* @see https://github.com/DaveRandom/LibDNS
* @see https://cabulous.medium.com/dns-message-how-to-read-query-and-response-message-cfebcb4fe817
*/
static public function getRecordsFrom(string $server, string $type, string $record, string $protocol = 'udp'): array
{
// Source: https://github.com/metaregistrar/php-dns-client/blob/master/DNS/dnsData/dnsTypes.php
static $types = [
1 => 'A',
2 => 'NS',
5 => 'CNAME',
6 => 'SOA',
12 => 'PTR',
15 => 'MX',
16 => 'TXT',
28 => 'AAAA',
255 => 'ANY',
];
$typeid = array_search($type, $types, true);
if (!$typeid) {
throw new \InvalidArgumentException('Invalid type');
}
$host = $protocol . '://' . $server;
if (!$socket = @fsockopen($host, 53, $errno, $errstr, 10)) {
throw new \RuntimeException('Failed to open socket to ' . $host);
}
//stream_set_chunk_size($socket, 0xffff);
//stream_set_blocking($socket, false);
$labels = explode('.', $record);
$question_binary = '';
foreach ($labels as $label) {
$question_binary .= pack("C", strlen($label)); // size byte first
$question_binary .= $label; // then the label
}
$question_binary .= pack("C", 0); // end it off
$id = rand(1,255)|(rand(0,255)<<8); // generate the ID
// Set standard codes and flags
$flags = (0x0100 & 0x0300) | 0x0020; // recursion & queryspecmask | authenticated data
$opcode = 0x0000; // opcode
// Build the header
$header = "";
$header .= pack("n", $id);
$header .= pack("n", $opcode | $flags);
$header .= pack("nnnn", 1, 0, 0, 0);
$header .= $question_binary;
$header .= pack("n", $typeid);
$header .= pack("n", 0x0001); // internet class
$headersize = strlen($header);
$headersizebin = pack("n", $headersize);
$header = $headersizebin . $header;
$request_size = fwrite($socket, $header, $headersize);
$rawbuffer = fread($socket, 1);
fclose($socket);
if (strlen($rawbuffer) < 12) {
throw new \UnderflowException("DNS query return buffer too small");
}
$pos = 0;
$read = function ($len) use (&$pos, $rawbuffer) {
$out = substr($rawbuffer, $pos, $len);
$pos += $len;
return $out;
};
$read_name_pos = function ($offset) use ($rawbuffer) {
$out = [];
while (($len = ord(substr($rawbuffer, $offset, 1))) && $len > 0) {
$out[] = substr($rawbuffer, $offset + 1, $len);
$offset += $len + 1;
}
return $out;
};
$read_name = function() use (&$read, $read_name_pos) {
$out = [];
while (($len = ord($read(1))) && $len > 0) {
if ($len >= 64) {
$offset = (($len & 0x3f) << 8) + ord($read(1));
$out = array_merge($out, $read_name_pos($offset));
break;
}
else {
$out[] = $read($len);
}
}
return implode('.', $out);
};
$header = unpack("nid/nfields/nqdcount/nancount/nnscount/narcount", $read(12));
$fields = $header['fields'];
$flags = new \stdClass;
$flags->rcode = $fields & 0xf;
$flags->ra = (($fields >> 7) & 1) === 1;
$flags->rd = (($fields >> 8) & 1) === 1;
$flags->tc = (($fields >> 9) & 1) === 1;
$flags->aa = (($fields >> 10) & 1) === 1;
$flags->opcode = ($fields >> 11) & 0xf;
$flags->qr = (($fields >> 15) & 1) === 1;
if ($flags->tc) {
throw new \OverflowException('The DNS server returned a truncated result for a UDP query');
}
// No answers
if (!$header['ancount']) {
return [];
}
$is_authorative = $flags->aa;
// Question section
if ($header['qdcount']) {
// Skip name
$read_name();
// skip question part
$pos += 4; // 4 => QTYPE + QCLASS
}
$responses = [];
for ($a = 0; $a < $header['ancount']; $a++) {
$read_name(); // Skip name
$ans_header = unpack("ntype/nclass/Nttl/nlength", $read(10));
$t = $types[$ans_header['type']] ?? null;
if ($type != 'ANY' && $t != $type) {
// Skip type that was not requested
$t = null;
}
switch ($t) {
case 'A':
$responses[] = implode(".", unpack("Ca/Cb/Cc/Cd", $read(4)));
break;
case 'AAAA':
$responses[] = implode(':', unpack("H4a/H4b/H4c/H4d/H4e/H4f/H4g/H4h", $read(16)));
break;
case 'MX':
$prio = unpack('nprio', $read(2)); // priority
$responses[$prio['prio']] = $read_name();
break;
case 'NS':
case 'CNAME':
case 'PTR':
$responses[] = $read_name();
break;
case 'TXT':
$responses[] = $read($ans_header['length']);
break;
default:
// Skip
$read($ans_header['length']);
break;
}
}
return $responses;
}
}

View file

@ -0,0 +1,693 @@
<?php
/*
This file is part of KD2FW -- <http://dev.kd2.org/>
Copyright (c) 2001-2019 BohwaZ <http://bohwaz.net/>
All rights reserved.
KD2FW 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.
Foobar 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 Foobar. If not, see <https://www.gnu.org/licenses/>.
*/
namespace KD2;
/**
* Delta algorithm
* ported from the C code of Fossil SCM
* http://www.fossil-scm.org/xfer/doc/trunk/www/delta_format.wiki
* http://www.fossil-scm.org/xfer/doc/trunk/www/delta_encoder_algorithm.wiki
*/
/*
** Copyright (c) 2006 D. Richard Hipp
** Copyright (c) 2013 BohwaZ (PHP port)
**
** Authors contact information:
** drh@hwaci.com
** http://www.hwaci.com/drh/
**
** http://bohwaz.net/
**
*******************************************************************************
**/
class Delta_Hash
{
public $a; /* Hash values */
public $b;
public $i; /* Start of the hash window */
public $z; /* The values that have been hashed */
public function __set($key, $value)
{
if (($key == 'a' || $key == 'b' || $key == 'i') && (!is_int($value) || $value > 2^16)) {
throw new \OutOfBoundsException($key . ' value must be a 16 bits integer');
}
if ($key != 'z')
{
$this->{$key} = $value & 0xffff;
}
else
{
$this->{$key} = $value;
}
}
}
class Delta
{
const NHASH = 16;
public $debug_enabled = false;
protected function debug($msg)
{
echo str_replace("\n", '.', $msg) . "\n";
return;
}
/**
* Emulates C-like 32-bits integer
* @param mixed $number
* @return integer Unsigned integer
*/
protected function u32($number)
{
return $number & 0xffffffff;
}
/**
* Emulates C-like 16-bit integer
* @param mixed $number
* @return mixed Unsigned integer
*/
protected function u16($number)
{
return $number & 0xffff;
}
/*
** Initialize the rolling hash using the first NHASH characters of z[]
*/
protected function hash_init(Delta_Hash &$pHash, $z)
{
$a = $b = 0;
for ($i=0; $i < self::NHASH; $i++) {
$a += ord($z[$i]);
$b += (self::NHASH - $i) * ord($z[$i]);
$pHash->z[$i] = ord($z[$i]);
}
$pHash->a = $a & 0xffff;
$pHash->b = $b & 0xffff;
$pHash->i = 0;
}
/*
** Advance the rolling hash by a single character "c"
*/
protected function hash_next(Delta_Hash &$pHash, $c)
{
$old = $this->u16($pHash->z[$pHash->i]);
$pHash->z[$pHash->i] = $c;
$pHash->i = ($pHash->i+1) & (self::NHASH - 1);
$pHash->a = $pHash->a - $old + $c;
$pHash->b = $pHash->b - self::NHASH * $old + $pHash->a;
}
/*
** Return a 32-bit hash value
*/
protected function hash_32bit(Delta_Hash $pHash)
{
return ($pHash->a & 0xffff) | sprintf('%u', $this->u32(($pHash->b & 0xffff)<<16));
}
/*
** Write an base-64 integer into the given buffer.
*/
protected function putInt($v)
{
static $zDigits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~';
/* 123456789 123456789 123456789 123456789 123456789 123456789 123 */
$zBuf = (string)'';
$pz = '';
if ( $v == 0 ) {
return $pz . '0';
}
for ($i=0; $v>0; $i++, $v>>=6) {
$zBuf[$i] = $zDigits[$v&0x3f];
}
for ($j = $i-1; $j>=0; $j--) {
$pz .= $zBuf[$j];
}
return $pz;
}
/*
** Read bytes from *pz and convert them into a positive integer. When
** finished, leave *pz pointing to the first character past the end of
** the integer. The *pLen parameter holds the length of the string
** in *pz and is decremented once for each character in the integer.
*/
protected function getInt(&$pz, &$pLen)
{
$zValue = array(
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
-1, 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, -1, -1, -1, -1, 36,
-1, 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, -1, -1, -1, 63, -1,
);
foreach ($zValue as &$row)
{
$row = $this->u32($row);
}
$v = 0;
$z = 0;
while ( ($c = $zValue[0x7f&ord($pz[$z++])]) != $this->u32(-1) ) {
$v = ($v<<6) + $c;
}
$z--;
$pz = substr($pz, $z);
$pLen = strlen($pz);
return $v;
}
/*
** Return the number digits in the base-64 representation of a positive integer
*/
protected function digit_count($v)
{
for($i=1, $x=64; $v >= $x; $i++, $x <<= 6){}
return $i;
}
/*
** Compute a 32-bit checksum on the N-byte buffer. Return the result.
*/
protected function checksum($z, $N)
{
$sum0 = $sum1 = $sum2 = $sum3 = (float)0.0;
while ($N >= 16)
{
$sum0 += (ord($z[0]) + ord($z[4]) + ord($z[8]) + ord($z[12]));
$sum1 += (ord($z[1]) + ord($z[5]) + ord($z[9]) + ord($z[13]));
$sum2 += (ord($z[2]) + ord($z[6]) + ord($z[10]) + ord($z[14]));
$sum3 += (ord($z[3]) + ord($z[7]) + ord($z[11]) + ord($z[15]));
$z = substr($z, 16);
$N -= 16;
}
while ($N >= 4) {
$sum0 += ord($z[0]);
$sum1 += ord($z[1]);
$sum2 += ord($z[2]);
$sum3 += ord($z[3]);
$z = substr($z, 4);
$N -= 4;
}
$sum3 += $this->u32($sum2 << 8) + $this->u32($sum1 << 16) + $this->u32($sum0 << 24);
switch ($N) {
case 3: $sum3 += $this->u32(ord($z[2]) << 8);
case 2: $sum3 += $this->u32(ord($z[1]) << 16);
case 1: $sum3 += $this->u32(ord($z[0]) << 24);
default: ;
}
$sum3 = $this->u32($sum3);
return sprintf('%u', $sum3);
}
/*
** Create a new delta.
**
** The delta is written into a preallocated buffer, zDelta, which
** should be at least 60 bytes longer than the target file, zOut.
** The delta string will be NUL-terminated, but it might also contain
** embedded NUL characters if either the zSrc or zOut files are
** binary. This function returns the length of the delta string
** in bytes, excluding the final NUL terminator character.
**
** Output Format:
**
** The delta begins with a base64 number followed by a newline. This
** number is the number of bytes in the TARGET file. Thus, given a
** delta file z, a program can compute the size of the output file
** simply by reading the first line and decoding the base-64 number
** found there. The delta_output_size() routine does exactly this.
**
** After the initial size number, the delta consists of a series of
** literal text segments and commands to copy from the SOURCE file.
** A copy command looks like this:
**
** NNN@MMM,
**
** where NNN is the number of bytes to be copied and MMM is the offset
** into the source file of the first byte (both base-64). If NNN is 0
** it means copy the rest of the input file. Literal text is like this:
**
** NNN:TTTTT
**
** where NNN is the number of bytes of text (base-64) and TTTTT is the text.
**
** The last term is of the form
**
** NNN;
**
** In this case, NNN is a 32-bit bigendian checksum of the output file
** that can be used to verify that the delta applied correctly. All
** numbers are in base-64.
**
** Pure text files generate a pure text delta. Binary files generate a
** delta that may contain some binary data.
**
** Algorithm:
**
** The encoder first builds a hash table to help it find matching
** patterns in the source file. 16-byte chunks of the source file
** sampled at evenly spaced intervals are used to populate the hash
** table.
**
** Next we begin scanning the target file using a sliding 16-byte
** window. The hash of the 16-byte window in the target is used to
** search for a matching section in the source file. When a match
** is found, a copy command is added to the delta. An effort is
** made to extend the matching section to regions that come before
** and after the 16-byte hash window. A copy command is only issued
** if the result would use less space that just quoting the text
** literally. Literal text is added to the delta for sections that
** do not match or which can not be encoded efficiently using copy
** commands.
*/
/**
* Computes the difference between $zSrc and $zOut and returns the delta
* @param string $zSrc Binary content of source file
* @param string $zOut Binary content of target file
* @return string Delta
*/
public function create($zSrc, $zOut)
{
$lenSrc = strlen($zSrc);
$lenOut = strlen($zOut);
$zDelta = '';
$h = new Delta_Hash;
$nHash = 0; /* Number of hash table entries */
$landmark = 0; /* Primary hash table */
$collide = 0; /* Collision chain */
$lastRead = 0xffffffff; /* Last byte of zSrc read by a COPY command */
/* Add the target file size to the beginning of the delta
*/
$zDelta .= $this->putInt($lenOut);
$zDelta .= "\n";
/* If the source file is very small, it means that we have no
** chance of ever doing a copy command. Just output a single
** literal segment for the entire target and exit.
*/
if ($lenSrc <= self::NHASH)
{
$zDelta .= $this->putInt($lenOut);
$zDelta .= ':';
$zDelta .= substr($zOut, 0, $lenOut);
$zDelta .= $this->putInt($this->checksum($zOut, $lenOut));
$zDelta .= ';';
return $zDelta;
}
/* Compute the hash table used to locate matching sections in the
** source file.
*/
$nHash = (int) ($lenSrc / self::NHASH);
$collide = array_fill(0, $nHash * 2 * PHP_INT_SIZE, $this->u32(-1));
$landmark = array_slice($collide, $nHash);
for ($i = 0; $i < $lenSrc - self::NHASH; $i += self::NHASH)
{
$this->hash_init($h, substr($zSrc, $i, self::NHASH));
$hv = $this->hash_32bit($h) % $nHash;
$collide[$i / self::NHASH] = $landmark[$hv];
$landmark[$hv] = $i / self::NHASH;
}
/* Begin scanning the target file and generating copy commands and
** literal sections of the delta.
*/
$base = 0; /* We have already generated everything before zOut[base] */
while ($base + self::NHASH < $lenOut)
{
$bestOfst = 0;
$bestLitsz = 0;
$this->hash_init($h, substr($zOut, $base, self::NHASH));
$i = 0; /* Trying to match a landmark against zOut[base+i] */
$bestCnt = 0;
while (1)
{
$limit = 250;
$hv = $this->hash_32bit($h) % $nHash;
if ($this->debug_enabled) {
$this->debug(sprintf("LOOKING: %4d [%s]", $base+$i, substr($zOut, $base + $i, 16)));
}
$iBlock = $landmark[$hv];
while ($iBlock != $this->u32(-1) && $iBlock >= 0 && ($limit--) > 0)
{
/*
** The hash window has identified a potential match against
** landmark block iBlock. But we need to investigate further.
**
** Look for a region in zOut that matches zSrc. Anchor the search
** at zSrc[iSrc] and zOut[base+i]. Do not include anything prior to
** zOut[base] or after zOut[outLen] nor anything after zSrc[srcLen].
**
** Set cnt equal to the length of the match and set ofst so that
** zSrc[ofst] is the first element of the match. litsz is the number
** of characters between zOut[base] and the beginning of the match.
** sz will be the overhead (in bytes) needed to encode the copy
** command. Only generate copy command if the overhead of the
** copy command is less than the amount of literal text to be copied.
*/
/* Beginning at iSrc, match forwards as far as we can. j counts
** the number of characters that match */
$iSrc = $iBlock * self::NHASH;
for($j = 0, $x = $iSrc, $y = $base + $i; $x < $lenSrc && $y < $lenOut; $j++, $x++, $y++)
{
if ($zSrc[$x] != $zOut[$y])
{
break;
}
}
$j--;
/* Beginning at iSrc-1, match backwards as far as we can. k counts
** the number of characters that match */
for ($k = 1; $k < $iSrc && $k <= $i; $k++)
{
if ($zSrc[$iSrc - $k] != $zOut[$base + $i - $k])
break;
}
$k--;
/* Compute the offset and size of the matching region */
$ofst = $iSrc - $k;
$cnt = $j + $k + 1;
$litsz = $i - $k; /* Number of bytes of literal text before the copy */
if ($this->debug_enabled) {
$this->debug(sprintf("MATCH %d bytes at %d: [%s] litsz=%d", $cnt, $ofst, substr($zSrc, $ofst, 16), $litsz));
}
/* sz will hold the number of bytes needed to encode the "insert"
** command and the copy command, not counting the "insert" text */
$sz = $this->digit_count($i - $k) + $this->digit_count($cnt) + $this->digit_count($ofst) + 3;
if ($cnt >= $sz && $cnt > $bestCnt )
{
/* Remember this match only if it is the best so far and it
** does not increase the file size */
$bestCnt = $cnt;
$bestOfst = $iSrc - $k;
$bestLitsz = $litsz;
if ($this->debug_enabled) {
$this->debug(sprintf("... BEST SO FAR"));
}
}
/* Check the next matching block */
$iBlock = $collide[$iBlock];
}
/* We have a copy command that does not cause the delta to be larger
** than a literal insert. So add the copy command to the delta.
*/
if ($bestCnt > 0)
{
if ($bestLitsz > 0)
{
/* Add an insert command before the copy */
$zDelta .= $this->putInt($bestLitsz);
$zDelta .= ':';
$zDelta .= substr($zOut, $base, $bestLitsz);
$base += $bestLitsz;
if ($this->debug_enabled) {
$this->debug(sprintf("insert %d", $bestLitsz));
}
}
$base += $bestCnt;
$zDelta .= $this->putInt($bestCnt);
$zDelta .= '@';
$zDelta .= $this->putInt($bestOfst);
if ($this->debug_enabled) {
$this->debug(sprintf("copy %d bytes from %d", $bestCnt, $bestOfst));
}
$zDelta .= ',';
if ($bestOfst + $bestCnt - 1 > $lastRead)
{
$lastRead = $bestOfst + $bestCnt - 1;
if ($this->debug_enabled) {
$this->debug(sprintf("lastRead becomes %d", $lastRead));
}
}
$bestCnt = 0;
break;
}
/* If we reach this point, it means no match is found so far */
if ($base + $i + self::NHASH >= $lenOut)
{
/* We have reached the end of the file and have not found any
** matches. Do an "insert" for everything that does not match */
$zDelta .= $this->putInt($lenOut - $base);
$zDelta .= ':';
$zDelta .= substr($zOut, $base, $lenOut - $base);
$base = $lenOut;
break;
}
/* Advance the hash by one character. Keep looking for a match */
$this->hash_next($h, ord($zOut[$base + $i + self::NHASH]));
$i++;
}
}
/* Output a final "insert" record to get all the text at the end of
** the file that does not match anything in the source file.
*/
if ($base < $lenOut)
{
$zDelta .= $this->putInt($lenOut - $base);
$zDelta .= ':';
$zDelta .= substr($zOut, $base, $lenOut - $base);
}
/* Output the final checksum record. */
$zDelta .= $this->putInt($this->checksum($zOut, $lenOut));
$zDelta .= ';';
unset($collide);
return $zDelta;
}
/*
** Return the size (in bytes) of the output from applying
** a delta.
**
** This routine is provided so that an procedure that is able
** to call delta_apply() can learn how much space is required
** for the output and hence allocate nor more space that is really
** needed.
*/
public function outputSize($zDelta)
{
$lenDelta = strlen($zDelta);
$size = $this->getInt($zDelta, $lenDelta);
if (substr($zDelta, 0, 1) != "\n")
{
/* ERROR: size integer not terminated by "\n" */
return -1;
}
return $size;
}
/*
** Apply a delta.
**
** The output buffer should be big enough to hold the whole output
** file and a NUL terminator at the end. The delta_output_size()
** routine will determine this size for you.
**
** The delta string should be null-terminated. But the delta string
** may contain embedded NUL characters (if the input and output are
** binary files) so we also have to pass in the length of the delta in
** the lenDelta parameter.
**
** This function returns the size of the output file in bytes (excluding
** the final NUL terminator character). Except, if the delta string is
** malformed or intended for use with a source file other than zSrc,
** then this routine returns -1.
**
** Refer to the delta_create() documentation above for a description
** of the delta file format.
*/
public function apply($zSrc, $zDelta)
{
$zOut = '';
$lenSrc = strlen($zSrc);
$lenDelta = strlen($zDelta);
$total = 0;
$zOut;
$limit = $this->getInt($zDelta, $lenDelta);
if (substr($zDelta, 0, 1) != "\n")
{
throw new \UnexpectedValueException('size integer not terminated by "\n"');
}
$zDelta = substr($zDelta, 1);
$lenDelta--;
while ($zDelta != '' && $lenDelta > 0)
{
$cnt = $this->getInt($zDelta, $lenDelta);
switch ($zDelta[0])
{
case '@':
{
$zDelta = substr($zDelta, 1);
$lenDelta--;
$ofst = $this->getInt($zDelta, $lenDelta);
if ($lenDelta > 0 && $zDelta[0] != ',' )
{
throw new \RuntimeException("copy command not terminated by ','");
}
$zDelta = substr($zDelta, 1);
$lenDelta--;
if ($this->debug_enabled) {
$this->debug(sprintf("COPY %d from %d\n", $cnt, $ofst));
}
$total += $cnt;
if ($total > $limit)
{
throw new \RuntimeException('copy exceeds output file size');
}
if ($ofst + $cnt > $lenSrc)
{
throw new \RuntimeException('copy extends past end of input');
}
$zOut .= substr($zSrc, $ofst, $cnt);
break;
}
case ':':
{
$zDelta = substr($zDelta, 1);
$lenDelta--;
$total += $cnt;
if ($total > $limit)
{
throw new \RuntimeException('insert command gives an output larger than predicted');
}
if ($this->debug_enabled) {
$this->debug(sprintf("INSERT %d\n", $cnt));
}
if ($cnt > $lenDelta)
{
throw new \RuntimeException('insert count exceeds size of delta');
}
$zOut .= substr($zDelta, 0, $cnt);
$zDelta = substr($zDelta, $cnt);
$lenDelta -= $cnt;
break;
}
case ';':
{
$zDelta = substr($zDelta, 1);
$lenDelta--;
if ($cnt != ($ck = $this->checksum($zOut, $total)))
{
throw new \RuntimeException('bad checksum: '.sprintf("%u", $ck));
}
if ($total != $limit)
{
throw new \RuntimeException('generated size does not match predicted size');
}
return $zOut;
}
default:
{
throw new \RuntimeException('unknown delta operator: ' . sprintf("'%s'", $zDelta[0]));
}
}
}
throw new \RuntimeException('unterminated delta');
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,707 @@
<?php
/*
This file is part of KD2FW -- <http://dev.kd2.org/>
Copyright (c) 2001-2019 BohwaZ <http://bohwaz.net/>
All rights reserved.
KD2FW 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.
Foobar 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 Foobar. If not, see <https://www.gnu.org/licenses/>.
*/
namespace KD2;
/**
* Simple and loosy feed parser
*
* This parser is not using any XML or DOM parsing library
* as a result of this it can parse any kind of feed, even if it
* is invalid or broken.
*
* It will parse and provide most common properties for every item
* and also an array of all the tags found for the item, allowing
* easy extension on specific features (like medias for example).
*
* Copyleft (C) 2012-2013 BohwaZ <http://bohwaz.net/>
*/
class FeedParser
{
/**
* Possible feed mime types
* @var array
*/
protected static $mime_types = array(
'application/atom+xml',
'application/rss+xml',
'application/rdf+xml'
);
/**
* Feed format (rss/atom)
* @var string
*/
public $format = null;
/**
* Feed vendor (netscape/w3c/userland/rss-dev-wg/imc)
* @var string
*/
public $vendor = null;
/**
* Feed spec version (1.0/0.9x/2.0/0.3)
* @var string
*/
public $version = null;
/**
* Items contained in the feed
* @var array
*/
protected $items = array();
/**
* Channel data
* @var string
*/
protected $channel = null;
/**
* Current item, to iterate over items
* @var integer
*/
protected $current_item = 0;
/**
* Returns discovered feeds from web URL
* @param string $url HTML page URL
* @return array List of discovered feeds
*/
static public function discoverFeedsFromURL($url)
{
$feeds = self::discoverFeeds(file_get_contents($url));
if (empty($feeds))
return $feeds;
foreach ($feeds as &$feed)
{
$feed['url'] = self::getRealURL($feed['href'], $url);
}
return $feeds;
}
/**
* Returns a complete URL with scheme and host from an unknown or incomplete URI
* @param string $href Incomplete URI
* @param string $base_url Base URL used to build a complete URL
* @return string Complete URL
*/
static public function getRealURL($href, $base_url)
{
$_href = parse_url($href);
// already an absolute URL
if (!empty($_href['scheme']))
return $href;
$_base = parse_url($base_url);
// protocol-relative URL ie. //bits.wikimedia.org/static/elements/rss.xml
if (substr($href, 0, 2) == '//')
return $_base['scheme'] . ':' . $href;
$url = $_base['scheme'] . '://';
if (!empty($_base['user']))
{
$url .= $_base['user'];
if (!empty($_base['pass']))
$url .= ':' . $_base['pass'];
$url .= '@';
}
$url .= $_base['host'];
// absolute URI
if (preg_match('!^/!', $href))
return $url . $href;
$url .= preg_replace('!/[^/]*$!', '/', $_base['path']);
// query-based URI, eg. ?feed
if (!empty($_href['path']))
return $url . $href;
$url .= preg_replace('!^.*/!', '', $_base['path']);
// relative URI
return $url . $href;
}
/**
* Discover feeds from an HTML string
* @param string $content HTML content
* @param boolean $fallback_discover_content If set to TRUE, it will try to find feeds in <a href... links
* if no feed is found in <link rel... tags.
* @return array List of feeds found
*/
static public function discoverFeeds($content, $fallback_discover_content = false)
{
$feeds = array();
$possible_rels = array('alternate', 'feed', 'alternate feed');
// Standard auto discovery
if (preg_match_all('/<\s*link\s+(.*?)\/?>/is', $content, $links, PREG_SET_ORDER))
{
foreach ($links as $link)
{
$params = self::parseAttributes($link[1]);
if (empty($params['rel']) || empty($params['type']) || empty($params['href']))
continue;
$rel = strtolower($params['rel']);
if (!in_array($rel, $possible_rels))
continue;
$type = strtolower($params['type']);
if (!in_array($type, self::$mime_types))
continue;
$feeds[] = array(
'type' => $type,
'href' => $params['href'],
'title' => isset($params['title']) ? trim(html_entity_decode($params['title'], ENT_COMPAT, '')) : null,
);
}
}
// Discover feed links from page links
elseif ($fallback_discover_content && preg_match_all('/<\s*a\s+(.*?)>(.*?)<\/a>/is', $content, $links, PREG_SET_ORDER))
{
foreach ($links as $link)
{
$params = self::parseAttributes($link[1]);
if (empty($params['href']))
continue;
if (!preg_match('/[^\w\d](?:atom|rss|rdf)[^\w\d]/i', $params['href']))
continue;
$feeds[] = array(
'type' => null,
'href' => $params['href'],
'title' => html_entity_decode(strip_tags($link[2]), ENT_COMPAT, ''),
);
}
}
return $feeds;
}
/**
* Returns a valid UNIX timestamp from a RSS/ATOM date, even broken ones
* From https://github.com/fguillot/picoFeed/blob/master/lib/PicoFeed/Parser.php
* @param string $value Input date, any format
* @return int Unix Timestamp
*/
static public function parseDate($value)
{
// Format => truncate to this length if not null
static $formats = array(
DATE_ATOM => null,
DATE_RSS => null,
DATE_COOKIE => null,
DATE_ISO8601 => null,
DATE_RFC822 => null,
DATE_RFC850 => null,
DATE_RFC1036 => null,
DATE_RFC1123 => null,
DATE_RFC2822 => null,
DATE_RFC3339 => null,
'D, d M Y H:i:s' => 25,
'D, d M Y h:i:s' => 25,
'D M d Y H:i:s' => 24,
'Y-m-d H:i:s' => 19,
'Y-m-d\TH:i:s' => 19,
'd/m/Y H:i:s' => 19,
'D, d M Y' => 16,
'Y-m-d' => 10,
'd-m-Y' => 10,
'm-d-Y' => 10,
'd.m.Y' => 10,
'm.d.Y' => 10,
'd/m/Y' => 10,
'm/d/Y' => 10,
);
if (!$value) {
return time();
}
$value = trim($value);
foreach ($formats as $format => $length) {
$timestamp = self::getValidDate($format, substr($value, 0, $length));
if ($timestamp > 0) return $timestamp;
}
return time();
}
/**
* Creates a valid timestamp from a given date format
* @param string $format Date format
* @param string $value Date string
* @return integer Timestamp
*/
static protected function getValidDate($format, $value)
{
$date = \DateTime::createFromFormat($format, $value);
if ($date !== false) {
$errors = \DateTime::getLastErrors();
if (empty($errors['error_count']) && empty($errors['warning_count'])) return $date->getTimestamp();
}
return 0;
}
/**
* Returns the content of an XML tag, without entities
* @param string $string Raw XML string
* @return string Decoded string
*/
static protected function getXmlContent($string)
{
$string = trim($string);
$string = preg_replace('/^.*<!\[CDATA\[/is', '', $string);
$string = preg_replace('/\]\]>.*$/s', '', $string);
$string = str_replace('&apos;', '&#039;', $string);
$string = html_entity_decode(self::utf8_encode($string), ENT_QUOTES, 'UTF-8');
return $string;
}
static protected function utf8_encode($str)
{
// Check if string is already UTF-8 encoded or not
if (!preg_match('//u', $str))
{
return utf8_encode($str);
}
return $str;
}
/**
* Parses attributes from a XML/HTML tag
* @param string $str String containing all attributes
* @return array List of attributes
*/
static protected function parseAttributes($str)
{
$params = array();
preg_match_all('/(\w[\w\d]*(?::\w[\w\d]*)*)(?:\s*=\s*(?:([\'"])(.*?)\2|([^>\s\'"]+)))?/i', $str, $_params, PREG_SET_ORDER);
if (empty($_params))
{
return $params;
}
foreach ($_params as $_p)
{
$value = isset($_p[4]) ? trim($_p[4]) : (isset($_p[3]) ? trim($_p[3]) : null);
$params[strtolower($_p[1])] = $value ? self::utf8_encode($value) : $value;
}
return $params;
}
/**
* Constructor
*/
public function __construct()
{
}
/**
* Load and parse a feed from an URL
* @param string $url Feed URL
* @return boolean false if feed parsing or loading failed
*/
public function load($url)
{
if (!$this->parse(file_get_contents($url)))
return false;
if (!empty($this->items))
{
foreach ($this->items as &$item)
{
$item->url = self::getRealURL($item->link, $url);
}
}
return true;
}
/**
* Parse a feed from a string
* @param string $content Feed as string
* @return boolean false if parsing failed (or string is empty)
*/
public function parse($content)
{
$this->format = $this->version = $this->vendor = false;
$this->items = array();
$this->channel = null;
if (preg_match('!<feed\s+[^>]*xmlns\s*=\s*["\']?http://www\.w3\.org/2005/Atom["\']?!i', $content))
{
$this->format = 'atom';
$this->version = '1.0';
$this->vendor = 'w3c';
}
elseif (preg_match('!<feed\s+[^>]*version\s*=\s*["\']?0\.3["\']?!i', $content))
{
$this->format = 'atom';
$this->version = '0.3';
$this->vendor = 'imc';
}
// Source: http://web.archive.org/web/20100315092011/http://diveintomark.org/archives/2004/02/04/incompatible-rss
elseif (preg_match('!<rdf:RDF\s+[^>]*http://my\.netscape\.com/rdf/simple/0\.9/!i', $content))
{
$this->format = 'rss';
$this->version = '0.90';
$this->vendor = 'netscape';
}
elseif (preg_match('!http://my\.netscape\.com/publish/formats/rss-0\.91\.dtd!i', $content))
{
$this->format = 'rss';
$this->version = '0.91';
$this->vendor = 'netscape';
}
elseif (preg_match('!<rss\s+[^>]*version\s*=\s*["\']?(0\.9[1234]|2\.0)["\']?!i', $content))
{
$this->format = 'rss';
$this->version = '0.91';
$this->vendor = 'userland';
}
elseif (preg_match('!<rdf:RDF\s+[^>]*http://purl\.org/rss/1\.0/!i', $content))
{
$this->format = 'rss';
$this->version = '1.0';
$this->vendor = 'rss-dev-wg';
}
// Separate items from channel
$pos = $end = false;
if (($items = preg_split('/<\/?(item|entry)(\s+.*?)?>/is', $content, -1, PREG_SPLIT_OFFSET_CAPTURE | PREG_SPLIT_NO_EMPTY))
&& !empty($items[1]))
{
$pos = $items[1][1];
$end = $items[count($items) - 2][1] + strlen($items[count($items) - 2][0]);
unset($items[count($items)-1]);
unset($items[0]);
foreach ($items as $item)
{
if (trim($item[0]) == '')
continue;
$this->items[] = $item[0];
}
unset($items);
}
if ($pos)
{
$start = stripos($content, '<channel');
$this->channel = substr($content, ($start === false ? 0 : $start), $pos - $start);
// Get the start of the channel
if (($start = strpos($this->channel, '>')) !== false)
{
$this->channel = substr($this->channel, $start);
}
$channel_end = strpos($this->channel, '</channel');
// If the channel ends before the items
if ($channel_end !== false)
{
$this->channel = substr($this->channel, 0, $channel_end);
}
// If there is still somethin from the channel after the items
elseif ($end)
{
$channel_end = strpos($content, '</channel');
$last = substr($content, $end, $channel_end - $end);
if (($start = strpos($last, '>')) !== false)
{
$last = substr($last, $start);
}
$this->channel .= $last;
}
$this->parseChannel();
}
if ($this->items)
{
$this->parseItems();
}
// Obviously something went wrong
if (empty($this->items) && empty($this->channel))
{
return false;
}
return true;
}
/**
* Parse channel tags into something useful
* @return void
*/
protected function parseChannel()
{
$channel = new \stdClass;
$channel->title = null;
$channel->description = null;
$channel->link = null;
$channel->date = null;
$channel->raw = $this->channel;
$channel->xml = array();
preg_match_all('!<\s*([\w\d-]+(?::[\w\d-]+)*)\s*(.*?)/?>(?:(.*?)</\1>)?!is', $this->channel, $tags, PREG_SET_ORDER);
foreach ($tags as $_tag)
{
$tag = new \stdClass;
$tag->name = $_tag[1];
$tag->content = isset($_tag[3]) ? self::getXmlContent($_tag[3]) : null;
$tag->attributes = !empty($_tag[2]) ? self::parseAttributes($_tag[2]) : array();
$channel->xml[] = $tag;
$_tag = strtolower($tag->name);
switch ($_tag)
{
case 'title':
case 'description':
$channel->{$_tag} = $tag->content;
break;
case 'dc:date':
case 'pubdate':
case 'modified':
case 'published':
case 'updated':
$channel->date = $tag->content;
break;
case 'link':
if (!empty($channel->link))
break;
if (!empty($tag->attributes['href']))
{
$channel->link = $tag->attributes['href'];
}
else
{
$channel->link = $tag->content;
}
break;
default:
break;
}
}
// Convert the date string to a timestamp
$channel->date = self::parseDate($channel->date);
$this->channel = $channel;
}
/**
* Parse feed items into an array of objects
* @return void
*/
protected function parseItems()
{
foreach ($this->items as $key=>$_item)
{
$item = new \stdClass;
$item->title = null;
$item->description = null;
$item->link = null;
$item->date = null;
$item->content = null;
$item->raw = $_item;
$item->xml = array();
preg_match_all('!<\s*([\w\d-]+(?::[\w\d-]+)*)\s*(.*?)/?>(?:(.*?)</\1>)?!is', $_item, $tags, PREG_SET_ORDER);
foreach ($tags as $_tag)
{
$tag = new \stdClass;
$tag->name = $_tag[1];
$tag->content = isset($_tag[3]) ? self::getXmlContent($_tag[3]) : null;
$tag->attributes = !empty($_tag[2]) ? self::parseAttributes($_tag[2]) : array();
$item->xml[] = $tag;
$_tag = strtolower($tag->name);
switch ($_tag)
{
case 'title':
case 'description':
case 'content':
$item->{$_tag} = $tag->content;
break;
case 'dc:date':
case 'pubdate':
case 'modified':
case 'published':
case 'updated':
case 'issued':
if (!empty($tag->content))
$item->date = $tag->content;
break;
case 'link':
if (!empty($item->link))
break;
if (!empty($tag->attributes['href']))
{
$item->link = $tag->attributes['href'];
}
else
{
$item->link = $tag->content;
}
break;
case 'summary':
$item->description = $tag->content;
case 'content:encoded':
$item->content = $tag->content;
default:
break;
}
}
// Convert the date string to a timestamp
$item->date = self::parseDate($item->date);
if (is_null($item->description) && !is_null($item->content))
$item->description = $item->content;
elseif (!is_null($item->description) && is_null($item->content))
$item->content = $item->description;
$this->items[$key] = $item;
}
}
/**
* Get the channel object
* @return object stdClass object containg channel informations
*/
public function getChannel()
{
if (!$this->channel)
return false;
return $this->channel;
}
/**
* Get the array of items
* @return array An array of stdClass objects
*/
public function getItems()
{
return $this->items;
}
/**
* Calculates the average publication interval between items.
* Useful to know when to check the feed for new stuff.
* @return integer Average publication time (in seconds)
*/
public function getAveragePublicationInterval()
{
$start = null;
if (count($this->items) < 1)
{
return 3600 * 24;
}
$start = $this->items[0]->date;
$end = $this->items[count($this->items) - 1]->date;
$diff = abs($end - $start);
return (int) round($diff / count($this->items));
}
/**
* Get a feed item
* @param integer $key Item number, if omitted it will return the next item in the list
* @return object stdClass object with informations and raw content of the item
*/
public function getItem($key = false)
{
if (!$this->items)
{
return false;
}
if ($key === false)
{
$key = $this->current_item++;
if ($key > count($this->items))
{
$this->reset();
return false;
}
}
if (!array_key_exists($key, $this->items))
return null;
return $this->items[$key];
}
/**
* Reset the iteration counter for getItem()
* @return void
*/
public function reset()
{
$this->current_item = 0;
}
}

View file

@ -0,0 +1,312 @@
<?php
/*
This file is part of KD2FW -- <http://dev.kd2.org/>
Copyright (c) 2001-2019 BohwaZ <http://bohwaz.net/>
All rights reserved.
KD2FW 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.
Foobar 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 Foobar. If not, see <https://www.gnu.org/licenses/>.
*/
namespace KD2;
/**
* Various tools to get informations on files
*/
class FileInfo
{
/**
* Magic numbers, taken from fileinfo package
* Every key contains the mimetype, and the value is an array
* containing magic numbers
* 'image/gif' => ['GIF'] // will match only if the string 'GIF' is found at position 0
* 'application/epub+zip' => ["PK\003\004", 30 => 'mimetypeapplication/epub+zip']
* // will only match if "PK\003\004" is found at position 0 and
* // 'mimetypeapplication/epub+zip' is found at position 30
* @var array
*/
static public $magic_numbers = [
// Images
'image/gif' => [['GIF87a'], ['GIF89a']],
'image/png' => ["\x89PNG"],
'image/jpeg'=> ["\xff\xd8\xff"],
'image/tiff'=> [["\x49\x49\x2A\x00"], ["\x4D\x4D\x00\x2A"]],
'image/bmp' => ['BM'],
'image/vnd.adobe.photoshop' => ['8BPS'],
'image/x-icon' => ["\000\000\001\000"],
'image/xcf' => ['gimp xcf'],
'image/svg+xml' => '/^\s*<\?xml.*?\?>\s*<svg/is',
// Office documents
'application/msword' => [
["\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1", 546 => 'jbjb'],
["\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1", 546 => 'bjbj']
],
'application/x-msoffice' => ["\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1"],
'application/vnd.openxmlformats-officedocument' => ["PK\x03\x04\x14\x00\x06\x00"],
'application/pdf' => ['%PDF-'],
'application/postscript' => [["\004%"], ['%!PS-Adobe-']],
'application/epub+zip' => ["PK\003\004", 30 => 'mimetypeapplication/epub+zip'],
// Open Office 1.x
'application/vnd.sun.xml.writer'
=> ["PK\003\004", 26 => "\x8\0\0\0mimetypeapplication/", 50 => 'vnd.sun.xml.writer'],
'application/vnd.sun.xml.calc'
=> ["PK\003\004", 26 => "\x8\0\0\0mimetypeapplication/", 50 => 'vnd.sun.xml.calc'],
'application/vnd.sun.xml.draw'
=> ["PK\003\004", 26 => "\x8\0\0\0mimetypeapplication/", 50 => 'vnd.sun.xml.draw'],
'application/vnd.sun.xml.impress'
=> ["PK\003\004", 26 => "\x8\0\0\0mimetypeapplication/", 50 => 'vnd.sun.xml.impress'],
'application/vnd.sun.xml.math'
=> ["PK\003\004", 26 => "\x8\0\0\0mimetypeapplication/", 50 => 'vnd.sun.xml.math'],
'application/vnd.sun.xml.base'
=> ["PK\003\004", 26 => "\x8\0\0\0mimetypeapplication/", 50 => 'vnd.sun.xml.base'],
// Open Office 2.x
'application/vnd.oasis.opendocument.text'
=> ["PK\003\004", 26 => "\x8\0\0\0mimetypeapplication/", 50 => 'vnd.oasis.opendocument.text'],
'application/vnd.oasis.opendocument.graphics'
=> ["PK\003\004", 26 => "\x8\0\0\0mimetypeapplication/", 50 => 'vnd.oasis.opendocument.graphics'],
'application/vnd.oasis.opendocument.presentation'
=> ["PK\003\004", 26 => "\x8\0\0\0mimetypeapplication/", 50 => 'vnd.oasis.opendocument.presentation'],
'application/vnd.oasis.opendocument.spreadsheet'
=> ["PK\003\004", 26 => "\x8\0\0\0mimetypeapplication/", 50 => 'vnd.oasis.opendocument.spreadsheet'],
'application/vnd.oasis.opendocument.chart'
=> ["PK\003\004", 26 => "\x8\0\0\0mimetypeapplication/", 50 => 'vnd.oasis.opendocument.chart'],
'application/vnd.oasis.opendocument.formula'
=> ["PK\003\004", 26 => "\x8\0\0\0mimetypeapplication/", 50 => 'vnd.oasis.opendocument.formula'],
'application/vnd.oasis.opendocument.image'
=> ["PK\003\004", 26 => "\x8\0\0\0mimetypeapplication/", 50 => 'vnd.oasis.opendocument.image'],
// Video/audio
'audio/x-ms-asf' => ["\x30\x26\xb2\x75"],
'audio/x-wav' => ['RIFF', 8 => 'WAVE'],
'video/x-msvideo' => [['RIFF', 8 => 'AVI'], ['RIFX']],
'video/quicktime' => [['mdat'], ['moov']],
'video/mpeg' => [["\x1B\x3"], ["\x1B\xA"], ["\x1E\x0"]],
'audio/mpeg' => [["\xff\xfb"], ['ID3']],
'audio/x-pn-realaudio' => ["\x2e\x72\x61\xfd"],
'audio/vnd.rn-realaudio'=> ['.RMF'],
'audio/x-flac' => ['fLaC'],
'application/ogg' => ['OggS'],
'audio/midi' => ['MThd'],
// Text
'text/xml' => ['<?xml'],
'text/rtf' => ['{\\rtf'],
'text/x-php'=> '/<\?php|<\?=/',
'text/html' => '/<!DOCTYPE html|<(?:html|head|title|script|style|table|a href=)/i',
// Others
'application/zip' => ["PK\003\004"],
'application/x-tar' => [257 => "ustar\0\x06"],
'application/x-xz' => ["\xFD7zXZ\x00"],
'application/x-7z-compressed' => ["7z\xBC\xAF\x27\x1C"],
'application/x-gzip' => ["\x1f\x8b"],
'application/x-bzip' => ['BZ0'],
'application/x-bzip2' => ['BZh'],
'application/x-rar' => ['Rar!'],
'application/x-shockwave-flash' => [['FWS'], ['CWS']],
'application/x-sqlite3' => ['SQLite format 3'],
'text/x-shellscript' => ['#!/'],
'application/octet-stream'=>["\177ELF"],
];
/**
* List of extensions for recognized MIME-types
* @var array
*/
static public $mime_extensions = [
// Images
'image/gif' => 'gif',
'image/png' => 'png',
'image/jpeg'=> 'jpg',
'image/tiff'=> 'tif',
'image/bmp' => 'bmp',
'image/vnd.adobe.photoshop' => 'psd',
'image/x-icon' => 'ico',
'image/xcf' => 'xcf',
'image/svg+xml' => 'svg',
// Office documents
'application/msword' => 'doc',
'application/vnd.openxmlformats-officedocument' => 'docx',
'application/pdf' => 'pdf',
'application/postscript' => 'ps',
'application/epub+zip' => 'epub',
// Open Office 1.x
'application/vnd.sun.xml.writer' => 'sxw',
'application/vnd.sun.xml.calc' => 'sxc',
'application/vnd.sun.xml.draw' => 'sxd',
'application/vnd.sun.xml.impress' => 'sxi',
'application/vnd.sun.xml.math' => 'sxf',
// Open Office 2.x
'application/vnd.oasis.opendocument.text' => 'odt',
'application/vnd.oasis.opendocument.graphics' => 'odg',
'application/vnd.oasis.opendocument.presentation'=> 'odp',
'application/vnd.oasis.opendocument.spreadsheet'=> 'ods',
'application/vnd.oasis.opendocument.chart' => 'odc',
'application/vnd.oasis.opendocument.formula' => 'odf',
// Video/audio
'audio/x-ms-asf' => 'asx',
'audio/x-wav' => 'wav',
'video/x-msvideo' => 'avi',
'video/quicktime' => 'mov',
'video/mpeg' => 'mpeg',
'audio/mpeg' => 'mp3',
'audio/x-pn-realaudio' => 'ra',
'audio/vnd.rn-realaudio'=> 'ram',
'audio/x-flac' => 'flac',
'application/ogg' => 'ogg',
'audio/midi' => 'mid',
// Text
'text/xml' => 'xml',
'text/rtf' => 'rtf',
'text/x-php'=> 'php',
'text/html' => 'html',
// Others
'application/zip' => 'zip',
'application/x-tar' => 'tar',
'application/x-xz' => 'xz',
'application/x-7z-compressed' => '7z',
'application/x-gzip' => 'gz',
'application/x-bzip' => 'bz',
'application/x-bzip2' => 'bz2',
'application/x-rar' => 'rar',
'application/x-shockwave-flash' => 'swf',
'application/x-sqlite3' => 'sqlite',
'text/x-shellscript' => 'sh',
'application/octet-stream' => 'exe',
];
/**
* Guesses the MIME type of a file from its content
* @param string $bytes First 1024 bytes (or more) of the file
* @return mixed Returns a string containing the matched MIME type or FALSE if no MIME type matched
*/
static public function guessMimeType($bytes)
{
// try to match for every mimetype
foreach (self::$magic_numbers as $type=>$match)
{
// Regexp match
if (is_string($match))
{
if (self::matchRegexp($match, $bytes))
return $type;
continue;
}
// Multiple matches possible for one type
if (is_array(current($match)))
{
foreach ($match as $_submatch)
{
if (self::matchBytes($_submatch, $bytes))
return $type;
}
continue;
}
// Single match
if (self::matchBytes($match, $bytes))
return $type;
}
return false;
}
/**
* Tries to match a regular expression against the first bytes of the file
* @param string $regexp Regexp to test
* @param string $bytes Binary string of first bytes of the file
* @return boolean TRUE if regexp matches, or else FALSE
*/
static protected function matchRegexp($regexp, $bytes)
{
return preg_match($regexp, $bytes);
}
/**
* Tries to match magic numbers at specified positions
* @param array $magic associative array: (byte position) => matching string
* @param string $bytes Binary string of first bytes
* @return boolean TRUE if magic numbers actually match, or else FALSE
*/
static protected function matchBytes($magic, $bytes)
{
$match = 0;
$max = strlen($bytes);
// Try to match every magic number for this mimetype
foreach ($magic as $pos=>$v)
{
// Content is too short to try matching this mimetype
if ($pos > $max)
{
return false;
}
$len = strlen($v);
// No match: skip to next mimetype
if (substr($bytes, $pos, $len) !== $v)
{
return false;
}
}
return true;
}
/**
* Get a file extension from its MIME-type
* @param string $type MIME-type, eg. audio/flac
* @return string extension, eg. flac
*/
static public function getFileExtensionFromMimeType($type)
{
foreach (self::$mime_extensions as $mime=>$ext)
{
if ($mime === $type)
return $ext;
}
return false;
}
static public function getMimeTypeFromFileExtension($extension)
{
foreach (self::$mime_extensions as $mime=>$ext)
{
if ($extension === $ext)
return $mime;
}
return false;
}
}

View file

@ -0,0 +1,632 @@
<?php
/*
This file is part of KD2FW -- <http://dev.kd2.org/>
Copyright (c) 2001-2019 BohwaZ <http://bohwaz.net/>
All rights reserved.
KD2FW 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.
Foobar 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 Foobar. If not, see <https://www.gnu.org/licenses/>.
*/
namespace KD2;
use KD2\Security;
/**
* Form management helper
* - CSRF protection
* - validate form fields
* - return form fields
*/
class Form
{
/**
* Custom validation rules
* @var array
*/
static protected $custom_validation_rules = [];
/**
* Secret used for tokens
* @var string
*/
static protected $token_secret;
/**
* Sets the secret key used to hash and check the CSRF tokens
* @param string $secret Whatever secret you may like, must be the same for all the user session
* @return boolean true
*/
static public function tokenSetSecret($secret)
{
self::$token_secret = $secret;
return true;
}
/**
* Generate a single use token and return the value
* The token will be HMAC signed and you can use it directly in a HTML form
* @param string $action An action description, if NULL then REQUEST_URI will be used
* @param integer $expire Number of hours before the hash will expire
* @return string HMAC signed token
*/
static public function tokenGenerate($action = null, $expire = 5)
{
if (is_null(self::$token_secret)) {
throw new \RuntimeException('No CSRF token secret has been set.');
}
$user_secret = $_COOKIE['__c'] ?? null;
if (null === $user_secret) {
if (headers_sent()) {
throw new \RuntimeException('Headers have already been sent, cannot generate a token');
}
$user_secret = bin2hex(random_bytes(10));
// Store user secret in a cookie
setcookie('__c', $user_secret, [
'expires' => 0,
'path' => '/',
'secure' => !empty($_SERVER['HTTPS']) ? true : false,
'httponly' => true,
'samesite' => 'Strict',
]);
}
$action = self::tokenAction($action);
$random = random_int(0, PHP_INT_MAX);
$expire = floor(time() / 3600) + $expire;
$value = $expire . $random . $action;
$hash = hash_hmac('sha256', $expire . $random . $action, self::$token_secret . sha1($user_secret));
return $hash . '/' . dechex($expire) . '/' . dechex($random);
}
/**
* Checks a CSRF token
* @param string $action An action description, if NULL then REQUEST_URI will be used
* @param string $value User supplied value, if NULL then $_POST[automatic name] will be used
* @return boolean
*/
static public function tokenCheck($action = null, $value = null)
{
$user_secret = $_COOKIE['__c'] ?? null;
if (!$user_secret) {
return false;
}
$action = self::tokenAction($action);
if (is_null($value))
{
$name = self::tokenFieldName($action);
if (empty($_POST[$name]))
{
return false;
}
$value = $_POST[$name];
}
$value = explode('/', $value, 3);
if (count($value) != 3)
{
return false;
}
$user_hash = $value[0];
$expire = hexdec($value[1]);
$random = hexdec($value[2]);
// Expired token
if ($expire < ceil(time() / 3600))
{
return false;
}
$hash = hash_hmac('sha256', $expire . $random . $action, self::$token_secret . sha1($user_secret));
return hash_equals($hash, $user_hash);
}
/**
* Generates a random field name for the current token action
* @param string $action An action description, if NULL then REQUEST_URI will be used
* @return string
*/
static public function tokenFieldName($action = null)
{
$action = self::tokenAction($action);
return 'ct_' . sha1($action . $_SERVER['DOCUMENT_ROOT'] . $_SERVER['SERVER_NAME']);
}
/**
* Returns the supplied action name or if it is NULL, then the REQUEST_URI
* @param string $action
* @return string
*/
static protected function tokenAction($action = null)
{
// Default action, will work as long as the check is on the same URI as the generation
if (is_null($action) && !empty($_SERVER['REQUEST_URI']))
{
$url = parse_url($_SERVER['REQUEST_URI']);
if (!empty($url['path']))
{
$action = $url['path'];
}
}
return $action;
}
/**
* Returns HTML code to embed a CSRF token in a form
* @param string $action An action description, if NULL then REQUEST_URI will be used
* @return string HTML <input type="hidden" /> element
*/
static public function tokenHTML($action = null)
{
return '<input type="hidden" name="' . self::tokenFieldName($action) . '" value="' . self::tokenGenerate($action) . '" />';
}
/**
* Returns TRUE if the form has this key and it's not NULL
* @param string $key Key to find in the form
* @return boolean
*/
static public function has($key)
{
return isset($_POST[$key]);
}
/**
* Parses rules for form validation
* @param string $str Rule description
* @return array List of rules with parameters
*/
static protected function parseRules($str)
{
if (false !== strpos($str, '|')) {
$a = '\|';
$b = ',';
}
else {
$a = ',';
$b = ':';
}
$str = preg_split('/(?<!\\\\)' . $a . '/', $str);
$rules = [];
foreach ($str as $rule) {
$name = strtok($rule, ':');
$rules[$name] = [];
while (($param = strtok($b)) !== false) {
$rules[$name][] = $param;
}
}
strtok('');
return $rules;
}
/**
* Returns the value for a form field, or NULL
*
* @param string $key Field name
* @return mixed
*/
static public function get($field)
{
if (is_array($field))
{
$out = new \stdClass;
foreach ($field as $key => $value)
{
$name = is_int($key) ? $value : $key;
$out->$name = self::get($name);
if (!is_int($key))
{
$rules = self::parseRules($value);
foreach ($rules as $rule => $params)
{
$out->$name = self::filterField($out->$name, $rule, $params);
}
}
}
return $out;
}
return isset($_POST[$field]) ? $_POST[$field] : null;
}
/**
* @deprecated
*/
static public function filterField($value, $filter, array $params = [])
{
switch ($filter)
{
case 'date':
return new \DateTime($value);
case 'date_format':
return \DateTime::createFromFormat($params[0], $value);
case 'int':
case 'integer':
return (int) $value;
case 'bool':
case 'boolean':
return (bool) $value;
case 'string':
return trim($value);
}
return $value;
}
/**
* Register a custom validation rule
*
* @param string $name Rule name
* @param Callable $callback Callback (must return a boolean)
* @return void
* @deprecated
*/
static public function registerValidationRule($name, Callable $callback)
{
self::$custom_validation_rules[$name] = $callback;
}
/**
* Check a form field against a rule
*
* @param string $key Field name
* @param string $rule_name Rule name
* @param Array $params Parameters of the rule
* @param Array $source Source of the field data
* @param Array $rules Complete list of rules
* @return boolean
* @deprecated
*/
static public function validateRule($key, $rule_name, Array $params = [], Array $source = null, Array $rules = [])
{
$value = isset($source[$key]) ? $source[$key] : null;
switch ($rule_name)
{
case 'required':
if (isset($rules['file']))
{
// Checked in 'file' rule
return true;
}
elseif (is_array($value) || $value instanceof \Countable)
{
return count($value) > 0;
}
elseif (is_string($value))
{
return trim($value) !== '';
}
return !is_null($value);
case 'required_with':
$required = false;
foreach ($params as $condition)
{
if (isset($source[$condition]))
{
$required = true;
break;
}
}
return $required ? self::validateRule($key, 'required', $params, $source) : true;
case 'required_with_all':
$required = 0;
foreach ($params as $condition)
{
if (isset($source[$condition]))
{
$required++;
}
}
return $required == count($params) ? self::validateRule($key, 'required', $params, $source) : true;
case 'required_without':
$required = false;
foreach ($params as $condition)
{
if (!isset($source[$condition]))
{
$required = true;
break;
}
}
return $required ? self::validateRule($key, 'required', $params, $source) : true;
case 'required_without_all':
$required = 0;
foreach ($params as $condition)
{
if (!isset($source[$condition]))
{
$required++;
}
}
return $required == count($params) ? self::validateRule($key, 'required', $params, $source) : true;
case 'required_if':
$required = false;
$if_value = isset($source[$params[0]]) ? $source[$params[0]] : null;
for ($i = 1; $i < count($params); $i++)
{
if ($params[$i] == $if_value)
{
$required = true;
break;
}
}
return $required ? self::validateRule($key, 'required', $params, $source) : true;
case 'required_unless':
$required = true;
$if_value = isset($source[$params[0]]) ? $source[$params[0]] : null;
for ($i = 1; $i < count($params); $i++)
{
if ($params[$i] == $if_value)
{
$required = false;
break;
}
}
return $required ? self::validateRule($key, 'required', $params, $source) : true;
case 'absent':
return $value === null;
}
// Ignore rules for empty fields, except 'required*'
if ($rule_name != 'file' && ($value === null || (is_string($value) && trim($value) === '')))
{
return true;
}
switch ($rule_name)
{
case 'file':
if (!isset($_FILES[$key]) && isset($rules['required']))
{
return false;
}
elseif (!isset($_FILES[$key]))
{
return true;
}
return ($value = $_FILES[$key]) && !empty($value['size']) && !empty($value['tmp_name']) && empty($value['error']);
case 'active_url':
$url = parse_url($value);
return isset($url['host']) && strlen($url['host']) && (checkdnsrr($url['host'], 'A') || checkdnsrr($url['host'], 'AAAA'));
case 'alpha':
return preg_match('/^[\pL\pM]+$/u', $value);
case 'alpha_dash':
return preg_match('/^[\pL\pM\pN_-]+$/u', $value);
case 'alpha_num':
return preg_match('/^[\pL\pM\pN]+$/u', $value);
case 'array':
return is_array($value);
case 'between':
return isset($params[0]) && isset($params[1]) && $value >= $params[0] && $value <= $params[1];
case 'boolean':
case 'bool':
return ($value == 0 || $value == 1);
case 'color':
return preg_match('/^#?[a-f0-9]{6}$/', $value);
case 'confirmed':
$key_c = $key . '_confirmed';
return isset($source[$key_c]) && $value == $source[$key_c];
case 'date':
return is_object($value) ? $value instanceof \DateTimeInterface : (bool) strtotime($value);
case 'date_format':
$date = date_parse_from_format($params[0], $value);
return $date['warning_count'] === 0 && $date['error_count'] === 0;
case 'different':
return isset($params[0]) && isset($source[$params[0]]) && $value != $source[$params[0]];
case 'digits':
return is_numeric($value) && strlen((string) $value) == $params[0];
case 'digits_between':
$len = strlen((string) $value);
return is_numeric($value) && $len >= $params[0] && $len <= $params[0];
case 'email':
// Compatibility with IDN domains
if (function_exists('idn_to_ascii'))
{
$host = substr($value, strpos($value, '@') + 1);
$host = @idn_to_ascii($host); // Silence errors because of PHP 7.2 http://php.net/manual/en/function.idn-to-ascii.php
$value = substr($value, 0, strpos($value, '@')+1) . $host;
}
return filter_var($value, FILTER_VALIDATE_EMAIL) !== false;
case 'gt':
return isset($params[0]) && isset($source[$params[0]]) && $value > $source[$params[0]];
case 'gte':
return isset($params[0]) && isset($source[$params[0]]) && $value >= $source[$params[0]];
case 'in':
return in_array($value, $params);
case 'in_array':
$field = isset($params[0]) && isset($source[$params[0]]) ? $source[$params[0]] : null;
return $field && is_array($field) && in_array($value, $field);
case 'integer':
case 'int':
return is_int($value);
case 'ip':
return filter_var($value, FILTER_VALIDATE_IP) !== false;
case 'json':
return json_decode($value) !== null;
case 'lt':
return isset($params[0]) && isset($source[$params[0]]) && $value < $source[$params[0]];
case 'lte':
return isset($params[0]) && isset($source[$params[0]]) && $value <= $source[$params[0]];
case 'max':
$size = is_array($value) ? count($value) : (isset($rules['string']) ? strlen($value) : $value);
return isset($params[0]) && $size <= $params[0];
case 'min':
$size = is_array($value) ? count($value) : (isset($rules['string']) ? strlen($value) : $value);
return isset($params[0]) && $size >= $params[0];
case 'money':
return preg_match('/^-?(\d+)(?:[.,](\d{1,2}))?$/', $value, $match) && ($match[1]*100 + $match[2]) >= 0;
case 'not_in':
return !in_array($value, $params);
case 'numeric':
return is_numeric($value);
case 'present':
return isset($source[$key]);
case 'regex':
return isset($params[0]) && preg_match($params[0], $value);
case 'same':
return isset($params[0]) && isset($source[$params[0]]) && $source[$params[0]] == $value;
case 'size':
$size = is_array($value) ? count($value) : (is_numeric($value) ? $value : strlen($value));
return isset($params[0]) && $size == (int) $params[0];
case 'string':
return is_string($value);
case 'timezone':
try {
new \DateTimeZone($value);
return true;
}
catch (\Exception $e) {
return false;
}
case 'url':
return filter_var($value, FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED | FILTER_FLAG_HOST_REQUIRED) !== false;
// Dates
case 'after':
return isset($params[0]) && ($date1 = strtotime($value)) && ($date2 = strtotime($params[0])) && $date1 > $date2;
case 'after_or_equal':
return isset($params[0]) && ($date1 = strtotime($value)) && ($date2 = strtotime($params[0])) && $date1 >= $date2;
case 'before':
return isset($params[0]) && ($date1 = strtotime($value)) && ($date2 = strtotime($params[0])) && $date1 < $date2;
case 'before_or_equal':
return isset($params[0]) && ($date1 = strtotime($value)) && ($date2 = strtotime($params[0])) && $date1 <= $date2;
default:
if (isset(self::$custom_validation_rules[$rule_name]))
{
return call_user_func_array(self::$custom_validation_rules[$rule_name], [$key, $params, $value, $source]);
}
throw new \UnexpectedValueException('Invalid rule name: ' . $rule_name);
}
}
/**
* Validate but add CSRF token check to that
*
* @param string $token_action CSRF token action name
* @param Array $all_rules List of rules, eg. 'login' => 'required|string'
* @param Array &$errors List of errors encountered
* @return boolean
* @deprecated
*/
static public function check($token_action, Array $all_rules, Array &$errors = [])
{
if (!self::tokenCheck($token_action))
{
$errors[] = ['rule' => 'csrf'];
return false;
}
return self::validate($all_rules, $errors);
}
/**
* Validate the current form against a set of rules
*
* Most rules from Laravel are implemented.
*
* @link https://laravel.com/docs/5.4/validation#available-validation-rules
* @param Array $all_rules List of rules, eg. 'login' => 'required|string'
* @param Array &$errors Filled with list of errors encountered
* @param Array $source Source of form data, if left empty or NULL,
* $_POST will be used
* @return boolean
* @deprecated
*/
static public function validate(Array $all_rules, Array &$errors = null, Array $source = null)
{
if (is_null($errors))
{
$errors = [];
}
if (is_null($source))
{
$source = $_POST;
}
foreach ($all_rules as $key => $rules)
{
if ($return = self::validateField($key, $rules, $source)) {
$errors[] = $return;
}
}
return count($errors) == 0 ? true : false;
}
/**
* Validate a field against a list of rules
* @param string $key Name of the field
* @param array|string $rules List of rules, either as an associative array of type rule_name => [...parameters] or a string
* @param array $source Source array of user data (eg. $_POST)
* @return array Array containing the first error encountered for the field (as an array), or NULL if no error was found
* @deprecated
*/
static public function validateField(string $key, $rules, array $source): ?array
{
$rules = is_array($rules) ? $rules : self::parseRules($rules);
foreach ($rules as $name => $params)
{
if (!self::validateRule($key, $name, $params, $source, $rules))
{
return ['name' => $key, 'rule' => $name, 'params' => $params];
}
}
return null;
}
}

View file

@ -0,0 +1,137 @@
<?php
namespace KD2;
class Fossil
{
/**
* Length for SHA1
*/
const HNAME_MIN = 40;
protected $db;
protected $url;
public function __construct($repo_file, $url)
{
$this->db = new DB_SQLite3($repo_file, SQLITE3_OPEN_READONLY);
$this->db->createFunction('repo_url', [$this, 'getURL']);
$this->url = $url;
}
public function getURL($uri = '')
{
return $this->url . $uri;
}
public function listUnversioned()
{
return $this->db->getGrouped('SELECT uvid, name, sz AS size, mtime, hash, repo_url(\'uv/\' || name) AS url
FROM unversioned WHERE hash IS NOT NULL ORDER BY mtime DESC;');
}
public function getTicketsStatus()
{
return $this->db->get('SELECT DISTINCT status FROM ticket;');
}
public function getTicketsTypes()
{
return $this->db->get('SELECT DISTINCT type FROM ticket;');
}
public function listTickets(array $filters = [])
{
$query = 'SELECT *, repo_url(\'tktview?name=\' || substr(tkt_uuid, 1, 10)) AS url FROM ticket WHERE 1';
$args = [];
foreach ($filters as $field => $value)
{
$query .= ' AND ' . $field . ' = ?';
$args[] = $value;
}
$query .= ' ORDER BY tkt_mtime DESC;';
return $this->db->get($query, $args);
}
public function bundlePreview($file, $force = false)
{
if (!is_readable($file))
{
throw new \RuntimeException('Cannot read file: ' . $file);
}
try {
$this->db->preparedQuery('ATTACH ? AS b1;', [$file]);
$a = $this->db->prepare('SELECT bcname, bcvalue FROM b1.bconfig LIMIT 1;');
$b = $this->db->prepare('SELECT blobid, uuid, sz, delta, notes, data FROM b1.bblob;');
if (!$a || !$b)
{
return false;
}
} catch (\Exception $e) {
$this->db->exec('DETACH b1;');
throw new \RuntimeException('Not a valid bundle file: ' . $e->getMessage(), 0, $e);
}
/* Only import a bundle that was generated from a repo with the same
** project code, unless the --force flag is true */
if (!$force)
{
$exists = $this->db->firstColumn('SELECT 1 FROM config, bconfig
WHERE config.name = \'project-code\'
AND bconfig.bcname = \'project-code\'
AND config.value = bconfig.bcvalue;');
if (!$exists)
{
$this->db->exec('DETACH b1;');
throw new \RuntimeException('project-code in the bundle does not match the repository project code.');
}
}
/* If the bundle contains deltas with a basis that is external to the
** bundle and those external basis files are missing from the local
** repo, then the delta encodings cannot be decoded and the bundle cannot
** be extracted. */
$missing_deltas = $this->db->firstColumn('SELECT group_concat(substr(delta,1,10), \' \') FROM bblob WHERE typeof(delta) = \'text\' AND length(delta) >= ? AND NOT EXISTS(SELECT 1 FROM blob WHERE uuid = bblob.delta)', self::HNAME_MIN);
if ($missing_deltas)
{
$this->db->exec('DETACH b1;');
throw new \RuntimeException('delta basis artifacts not found in repository: ' . $missing_deltas);
}
$this->db->begin();
$this->db->exec('CREATE TEMP TABLE bix(
blobid INTEGER PRIMARY KEY,
delta INTEGER
);
CREATE INDEX bixdelta ON bix(delta);
INSERT INTO bix(blobid,delta)
SELECT blobid,
CASE WHEN typeof(delta)==\'integer\'
THEN delta ELSE 0 END
FROM bblob
WHERE NOT EXISTS(SELECT 1 FROM blob WHERE uuid=bblob.uuid AND size>=0);
CREATE TEMP TABLE got(rid INTEGER PRIMARY KEY ON CONFLICT IGNORE);');
/*
manifest_crosslink_begin();
bundle_import_elements(0, 0, isPriv);
manifest_crosslink_end(0);
describe_artifacts_to_stdout("IN got", "Imported content:");
*/
$this->db->commit();
// gzuncompress on each delta
$this->db->exec('DETACH b1;');
}
}

View file

@ -0,0 +1,444 @@
<?php
namespace KD2;
use KD2\HTTP;
use KD2\Security;
/**
* FossilInstaller
*
* This is useful to fetch and install .tar.gz (or .zip) updates from a Fossil repository
* using the Unversioned files feature.
*
* This also implements PGP signature verification and can display a summary of changed to the user.
*
* Copyright (C) 2021 BohwaZ <https://bohwaz.net/>
*/
class FossilInstaller
{
const DEFAULT_REGEXP = '/app-(?P<version>.*)\.tar\.gz/';
protected array $releases;
protected string $app_path;
protected string $tmp_path;
protected string $fossil_url;
protected string $release_name_regexp;
protected array $ignored_paths = [];
protected string $gpg_pubkey_file;
public function __construct(string $fossil_repo_url, string $app_path, string $tmp_path, ?string $release_name_regexp = null)
{
$this->fossil_url = $fossil_repo_url;
$this->app_path = $app_path;
$this->tmp_path = $tmp_path;
$this->release_name_regexp = $release_name_regexp;
}
public function __destruct()
{
$this->prune();
}
public function setPublicKeyFile(string $file)
{
$this->gpg_pubkey_file = $file;
}
/**
* Ignore some paths during upgrade
* @param string $path Paths are relative to the installation directory
*/
public function addIgnoredPath(string $path)
{
$this->ignored_paths[] = $path;
}
public function listReleases(): array
{
if (isset($this->releases)) {
return $this->releases;
}
$list = (new HTTP)->GET($this->fossil_url . 'juvlist');
if (!$list) {
return [];
}
$list = json_decode($list);
if (!$list) {
return [];
}
$this->releases = [];
foreach ($list as $item) {
if (!isset($item->name, $item->hash, $item->size, $item->mtime)) {
continue;
}
if (!preg_match($this->release_name_regexp, $item->name, $match)) {
continue;
}
list(, $version) = $match;
$item->signed = false;
$item->stable = preg_match('/alpha|dev|rc|beta/', $version) ? false : true;
$this->releases[$version] = $item;
}
// Add signed information
foreach ($list as $item) {
if (substr($item->name, -4) !== '.asc') {
continue;
}
$name = substr($item->name, 0, -4);
foreach ($this->releases as &$r) {
if ($r->name == $name) {
$r->signed = true;
}
}
}
unset($r);
return $this->releases;
}
public function latest(bool $stable_only = true): ?string
{
$releases = $this->listReleases();
$latest = null;
foreach ($releases as $version => $r) {
if ($stable_only && !$r->stable) {
continue;
}
if (!$latest || version_compare($version, $latest, '>')) {
$latest = $version;
}
}
return $latest;
}
public function download(string $version): string
{
if (!isset($this->releases[$version])) {
throw new \InvalidArgumentException('Unknown release');
}
$release = $this->releases[$version];
$url = sprintf('%suv/%s', $this->fossil_url, $release->name);
$tmpfile = $this->_getTempFilePath($version);
$r = (new HTTP)->GET($url);
if (!$r->fail && $r->body) {
file_put_contents($tmpfile, $r->body);
touch($tmpfile);
}
if (!file_exists($tmpfile)) {
throw new \RuntimeException('Error while downloading file');
}
$can_check_hash = in_array('sha3-256', hash_algos());
if ($can_check_hash && !hash_equals(hash_file('sha3-256', $tmpfile), $release->hash)) {
@unlink($tmpfile);
throw new \RuntimeException('Error while downloading file: invalid hash');
}
return $tmpfile;
}
protected function _getTempFilePath(string $version): string
{
return $this->tmp_path . '/tmp-release-' . sha1($version) . '.tar.gz';
}
public function verify(string $version): ?bool
{
if (!isset($this->releases[$version])) {
throw new \InvalidArgumentException('Unknown release');
}
$tmpfile = $this->_getTempFilePath($version);
if (!file_exists($tmpfile)) {
throw new \LogicException('This release has not been downloaded yet');
}
$release = $this->releases[$version];
$can_check_hash = in_array('sha3-256', hash_algos());
if ($can_check_hash && !hash_equals(hash_file('sha3-256', $tmpfile), $release->hash)) {
@unlink($tmpfile);
throw new \RuntimeException('Error while downloading file: invalid hash');
}
if (!$release->signed) {
return null;
}
if (!Security::canUseEncryption()) {
return null;
}
$url = sprintf('%suv/%s.asc', $this->fossil_url, $release->name);
$r = (new HTTP)->GET($url);
if ($r->fail || !$r->body) {
return null;
}
$key = file_get_contents($this->gpg_pubkey_file);
$data = file_get_contents($tmpfile);
return Security::verifyWithPublicKey($key, $data, $r->body);
}
/**
* Remove old stale downloaded files
* @return void
*/
public function prune(int $delay = 3600 * 24): void
{
$files = self::recursiveList($this->tmp_path, 'tmp-release-*');
$dirs = [];
foreach ($files as $file) {
if (is_dir($file)) {
$dirs[] = $file;
continue;
}
if (!$delay || filemtime($file) < (time() - $delay)) {
@unlink($file);
}
}
// Try to remove directories
foreach ($dirs as $dir) {
@rmdir($dir);
}
}
public function clean(string $version): void
{
$path = $this->_getTempFilePath($version);
self::recursiveDelete(dirname($path), basename($path) . '*');
}
static protected function recursiveDelete(string $path, string $pattern = '*') {
$files = self::recursiveList($path, $pattern);
$dirs = [];
foreach ($files as $file) {
if (is_dir($file)) {
$dirs[] = $file;
continue;
}
@unlink($file);
}
foreach ($dirs as $dir) {
@rmdir($dir);
}
}
public function diff(string $version): \stdClass
{
$this->listReleases();
if (!isset($this->releases[$version])) {
throw new \InvalidArgumentException('Unknown release');
}
$tmpfile = $this->_getTempFilePath($version);
if (!file_exists($tmpfile)) {
throw new \LogicException('This release has not been downloaded yet');
}
$release = $this->releases[$version];
$phar = new \PharData($tmpfile,
\FilesystemIterator::CURRENT_AS_FILEINFO | \FilesystemIterator::KEY_AS_PATHNAME
| \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::UNIX_PATHS);
// List existing files
$existing_files = [];
$l = strlen($this->app_path);
foreach (self::recursiveList($this->app_path) as $path) {
if (is_dir($path)) {
continue;
}
$file = substr($path, $l + 1);
// Skip ignored paths
foreach ($this->ignored_paths as $ignored_path) {
if (0 === strpos($file, $ignored_path)) {
continue(2);
}
}
$existing_files[$file] = $path;
}
// List files
$release_files = [];
$update = [];
// We are always ignoring the first directory level
$parent = $phar->getPathName();
$parent_l = strlen($parent);
foreach (new \RecursiveIteratorIterator($phar) as $path => $file) {
if ($file->isDir()) {
// Skip directories
continue;
}
$relative_path = substr($path, $parent_l + 1);
$release_files[$relative_path] = $path;
$is_ignored = false;
// Skip ignored paths
foreach ($this->ignored_paths as $ignored_path) {
if (0 === strpos($relative_path, $ignored_path)) {
$is_ignored = true;
break;
}
}
$local_path = $this->app_path . DIRECTORY_SEPARATOR . $relative_path;
// Skip if file doesn't exist, it will be marked as to be created
if (!file_exists($local_path)) {
continue;
}
if ($file->getSize() != filesize($local_path)
|| sha1_file($local_path) != sha1_file($path)) {
$update[$relative_path] = $path;
}
elseif ($is_ignored) {
unset($release_files[$relative_path]);
}
}
$create = array_diff_key($release_files, $existing_files);
$delete = array_diff_key($existing_files, $release_files);
ksort($create);
ksort($delete);
ksort($update);
return (object) compact('delete', 'create', 'update');
}
public function upgrade(string $version): void
{
$diff = $this->diff($version);
foreach ($diff->delete as $file => $path) {
@unlink($path);
}
// FIXME: Clean up empty directories
foreach ($diff->create as $file => $source) {
$this->_copy($source, $this->app_path . DIRECTORY_SEPARATOR . $file);
}
foreach ($diff->update as $file => $source) {
$this->_copy($source, $this->app_path . DIRECTORY_SEPARATOR . $file);
if (function_exists('opcache_invalidate')) {
@opcache_invalidate($this->app_path . DIRECTORY_SEPARATOR . $file, true);
}
}
$this->clean($version);
}
protected function _copy(string $source, string $target): bool
{
$dir = dirname($target);
if (!file_exists($dir)) {
mkdir($dir, 0777, true);
}
return copy($source, $target);
}
public function install(string $version)
{
if (!isset($this->releases[$version])) {
throw new \InvalidArgumentException('Unknown release');
}
$tmpfile = $this->_getTempFilePath($version);
$phar = new \PharData($tmpfile, \FilesystemIterator::CURRENT_AS_FILEINFO | \FilesystemIterator::KEY_AS_PATHNAME
| \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::UNIX_PATHS);
// Ignore first level directory
$root_l = strlen($phar->getPathName());
foreach (new \RecursiveIteratorIterator($phar) as $source => $_file) {
$file = substr($source, $root_l + 1);
$this->_copy($source, $this->app_path . DIRECTORY_SEPARATOR . $file);
}
}
public function autoinstall(?string $version = null): void
{
$version ??= $this->latest();
if (!$version) {
return;
}
$this->download($version);
if (isset($this->gpg_pubkey_file)) {
$this->verify($version);
}
$this->install($version);
$this->clean($version);
}
static protected function recursiveList(string $path, string $pattern = '*')
{
$out = [];
$length = strlen($path);
foreach (glob($path . DIRECTORY_SEPARATOR . $pattern, \GLOB_NOSORT) as $subpath) {
$out[] = $subpath;
if (is_dir($subpath)) {
$out = array_merge($out, self::recursiveList($subpath));
}
}
return $out;
}
}

View file

@ -0,0 +1,878 @@
<?php
/*
This file is part of KD2FW -- <http://dev.kd2.org/>
Copyright (c) 2001-2019 BohwaZ <http://bohwaz.net/>
All rights reserved.
KD2FW 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.
Foobar 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 Foobar. If not, see <https://www.gnu.org/licenses/>.
*/
namespace KD2;
/*
Garbage2xhtml lib
Takes a html text and returns something semantic and maybe valid
Copyleft (C) 2006-13 BohwaZ - http://bohwaz.net/
*/
class Garbage_Exception extends \Exception
{
}
class Garbage2xhtml
{
/**
* Secure attributes contents?
* Will check for url scheme and url content in href and src
* It's advised to disable <script> and <style> tags and style attribute
* because they could be used for XSS attacks
*/
public $secure = true;
/**
* Enclose text which is not in any element in <p> tags?
*/
public $enclose_text = true;
/**
* Auto-add <br /> in text blocks?
* Will also break <p> blocks when encountering a double line break.
*
* Example:
* <p>One Two
*
* Three
* Four
* </p>
*
* Will render as:
* <p>One Two</p>
* <p>Three<br />
* Four</p>
*/
public $auto_br = true;
/**
* Text encoding (used for escaping)
*/
public $encoding = 'UTF-8';
/**
* Remove forbidden tags from ouput?
* If true, "<em>" will disappear if it's not in allowed tags.
* If false, "<em>" will become a text node with &lt;em&gt;
*/
public $remove_forbidden_tags = false;
/**
* Remove forbidden tags contents?
* If true "<b>Hello</b>" will become "" if <b> is not allowed
* If false "<b>Hello</b>" will become "Hello"
*/
public $remove_forbidden_tags_content = false;
public $indent = true;
/**
* Core attributes allowed on each element
*/
public $core_attributes = array('lang', 'class', 'id', 'title', 'dir');
/**
* Allowed block tags
*
* 'tag' => true, // Allows core attributes
* 'tag' => false, // Disallow core attributes
* 'tag' => array('allowed attribute 1', 'href', 'src'),
* // Allow core attributes and those specific attributes
*/
public $block_tags = array(
'ul' => true,
'ol' => true,
'li' => true,
'dl' => true,
'p' => true,
'div' => true,
'h1' => true,
'h2' => true,
'h3' => true,
'h4' => true,
'h5' => true,
'h6' => true,
'pre' => true,
'hr' => true,
'address' => true,
'blockquote'=> array('cite'),
'object'=> array('type', 'width', 'height', 'data'),
'iframe'=> array('src', 'width', 'height', 'frameborder', 'scrolling'),
'table' => array('summary'),
'tbody' => true,
'thead' => true,
'tfoot' => true,
'caption' => true,
'colgroup' => array('span'),
'col' => true,
'tr' => true,
'th' => array('colspan', 'rowspan', 'scope', 'headers'),
'td' => array('colspan', 'rowspan', 'headers'),
// XHTML 5
'article' => true,
'aside' => true,
'audio' => array('src', 'controls', 'loop'),
'figure' => true,
'footer' => true,
'header' => true,
'hgroup' => true,
'section' => true,
'video' => array('src', 'controls', 'width', 'height', 'poster'),
);
/**
* Allowed inline elements
*/
public $inline_tags = array(
// 'tag' => array of allowed attributes
'abbr' => array('title'),
'dfn' => true,
'acronym' => array('title'),
'cite' => true,
'q' => array('cite'),
'code' => true,
'kbd' => true,
'samp' => true,
'strong'=> true,
'b' => true,
'i' => true,
'u' => true,
'em' => true,
'del' => true,
'ins' => true,
'sup' => true,
'sub' => true,
'dt' => true,
'dd' => true,
'span' => true,
'br' => false,
'a' => array('href', 'hreflang', 'rel'),
'img' => array('src', 'alt', 'width', 'height'),
'param' => array('name', 'value', 'type'),
// XHTML 5
'mark' => true,
'var' => true,
'time' => array('pubdate', 'datetime'),
'figcaption'=> true,
);
public $allowed_url_schemes = array(
'http' => '://',
'https' => '://',
'ftp' => '://',
'mailto'=> ':',
'xmpp' => ':',
'news' => ':',
'nntp' => '://',
'tel' => ':',
'callto'=> ':',
'ed2k' => '://',
'irc' => '://',
'magnet'=> ':',
'mms' => '://',
'rtsp' => '://',
'sip' => ':',
);
/**
* Tags who need content to be enclosed
*/
public $elements_need_enclose = array('blockquote', 'form', 'address', 'noscript');
/**
* Tags elements who accept <br /> inside
*/
public $elements_allow_break = array('p', 'dd', 'dt', 'li', 'td', 'th', 'div');
/**
* Autoclosing tags (eg. <br />)
*/
public $autoclosing_tags = array('br', 'hr', 'img', 'param');
///////// PRIVATE PROPERTIES
private $opened = array();
private $matches = array();
private $line = 0;
private $check_only = false;
private $allowed_tags = array();
const SPLIT_REGEXP = '!<(/?)([^><]*)>!';
const ATTRIBUTE_REGEXP = '/(?:(?:"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\') | (?>[^"\'=\s]+))+|[=]/x';
public function parse($string)
{
$string = preg_replace('#<!--.*-->#Us', '', $string);
$string = preg_replace('#<!\[CDATA\[.*\]\]>#Us', '', $string);
$string = str_replace(array("\r\n", "\r"), "\n", $string);
$string = preg_replace('!<br\s*/?>!i', '<br />', $string);
$string = trim($string);
$this->resetInternals();
$this->allowed_tags = array_merge($this->inline_tags, $this->block_tags);
$this->matches = preg_split(self::SPLIT_REGEXP, $string, 0, PREG_SPLIT_DELIM_CAPTURE);
unset($string);
$nodes = $this->buildTree();
$this->resetInternals();
return $nodes;
}
/**
* Checks a string validity
*/
public function check($string)
{
$this->check_only = true;
$this->parse($string);
$this->check_only = false;
return true;
}
/**
* Processes a string
*/
public function process($string)
{
$nodes = $this->parse($string);
unset($string);
if ($this->enclose_text)
{
$nodes = $this->encloseChildren($nodes, false);
}
if ($this->auto_br)
{
$nodes = $this->autoLineBreak($nodes);
}
return $this->outputNodes($nodes);
}
/**
* Outputs a string from a nodes array
*/
public function outputNodes($nodes, $level = 0)
{
$out = '';
foreach ($nodes as $node)
{
if (is_array($node))
{
$close = '';
$content = '';
$open = '<'.$node['name'];
foreach ($node['attrs'] as $key=>$value)
{
$open .= ' '.$key.'="'.$value.'"';
}
if ($this->isTagAutoclosing($node['name']))
{
$open .= ' />';
}
else
{
$open .= '>';
$close = '</'.$node['name'].'>';
}
if (!empty($node['children']))
{
$content = $this->outputNodes($node['children'], $level + 1);
}
if ($close && $this->indent !== false && array_key_exists($node['name'], $this->block_tags) && $node['name'] != 'pre')
{
$tag = $this->indentTag($open, $content, $close, $level * ($this->indent === true ? 1 : (int) $this->indent));
}
else
{
$tag = $open . $content . $close;
if ($node['name'] == 'br')
$tag.= "\n";
}
}
else
{
$tag = $node;
}
$out .= $tag;
}
return $out;
}
private function indentTag($open, $content, $close, $indent)
{
$out = "\n";
$out.= str_repeat(' ', $indent);
$out.= $open;
$out.= "\n";
$content = explode("\n", $content);
foreach ($content as $line)
{
if (!trim($line))
continue;
$out.= str_repeat(' ', $indent + ($this->indent === true ? 2 : (int) $this->indent));
$out.= $line . "\n";
}
unset($content);
$out.= str_repeat(' ', $indent);
$out.= $close;
$out.= "\n";
return $out;
}
private function resetInternals()
{
$this->opened = array();
$this->matches = array();
$this->line = 0;
}
/**
* Break line and paragraphs following this rule :
* in a paragraph : one line break = <br />,
* two line breaks = closing paragraph and opening a new one
* in other elements : nl2br
*/
private function autoLineBreak($nodes, $parent = false)
{
$n = array();
$nb_nodes = count($nodes);
$k = 0;
foreach ($nodes as $node)
{
// Text node inside an element allowing for line breaks
if (is_string($node) && trim($node) != '' && in_array($parent, $this->elements_allow_break))
{
$matches = preg_split('!(\n+)!', $node, -1, PREG_SPLIT_DELIM_CAPTURE);
$i = 1;
$max = count($matches);
while (($line = array_shift($matches)) !== null)
{
// Line break
if ($i++ % 2 == 0)
{
if (!empty($n) && ($k < $nb_nodes - 1 || $i < $max))
{
$n[] = array('name' => 'br', 'attrs' => array(), 'children' => array());
}
}
elseif ($line != "")
{
$n[] = $line;
}
}
}
// In paragraphs we'll try to split them each two-line breaks
elseif (is_array($node) && $node['name'] == 'p')
{
$n[] = array('name' => 'p', 'attrs' => $node['attrs'], 'children' => array());
$current_node = count($n) - 1;
// Because we need to work on parent-level we will loop on children here
// (so we don't do recursive calls)
while (($child = array_shift($node['children'])) !== null)
{
// Text node ? try to split it
if (is_string($child))
{
$matches = preg_split('!(\n+)!', $child, -1, PREG_SPLIT_DELIM_CAPTURE);
$i = 0;
$max = count($matches);
while (($line = array_shift($matches)) !== null)
{
if ($i++ % 2)
{
// More than 2 line-breaks then we create a new paragraph and we continue
if (strlen($line) >= 2)
{
$n[] = array('name' => 'p', 'attrs' => $node['attrs'], 'children' => array());
$current_node = count($n) - 1;
$nb_nodes++;
$k++;
}
// Simple line break
// but no line break just after or before end
elseif (!empty($n[$current_node]['children']) && ($i - 1 < $max || $k < $nb_nodes - 1))
{
$n[$current_node]['children'][] = array('name' => 'br', 'attrs' => array(), 'children' => array());
}
}
elseif ($line != "")
{
$n[$current_node]['children'][] = $line;
}
}
}
else
{
$n[$current_node]['children'][] = $child;
}
}
}
else
{
if (!is_string($node) && !empty($node['children']))
{
$node['children'] = $this->autoLineBreak($node['children'], $node['name']);
}
$n[] = $node;
}
$k++;
}
unset($nodes);
return $n;
}
private function getTagAttributes($value, $tag)
{
$attributes = array();
if (array_key_exists($tag, $this->allowed_tags))
{
$tag =& $this->allowed_tags[$tag];
}
elseif (($prefix = strtok($tag, ':')) && array_key_exists($prefix, $this->allowed_tags))
{
$tag =& $this->allowed_tags[$match[0]];
}
strtok('');
$value = preg_replace('!^.*\s+!U', '', $value);
if (preg_match_all(self::ATTRIBUTE_REGEXP, $value, $match))
{
$state = 0;
$name = false;
foreach($match[0] as $value)
{
if ($state == 0)
{
$name = strtolower((string) $value);
$state = 1;
$pass = false;
// Allowed attribute ?
if ($tag && in_array($name, $this->core_attributes))
$pass = true;
elseif (is_array($tag) && in_array($name, $tag))
$pass = true;
elseif (preg_match('!^(?:data-|[a-z0-9-]+:)!', $name, $m))
{
// Allow namespaces and data- (html5) attributes
if ($tag && in_array($m[0], $this->core_attributes))
$pass = true;
elseif (is_array($tag) && in_array($m[0], $tag))
$pass = true;
}
if (!$pass)
{
$name = false;
continue;
}
}
elseif ($state == 1)
{
if ($value != '=' && $name && $this->check_only)
throw new Garbage_Exception("Expecting '=' after $name on line ".$this->line);
$state = 2;
}
elseif ($state == 2)
{
$state = 0;
if (!$name)
continue;
if ($value == '=' && $this->check_only)
throw new Garbage_Exception("Unexpected '=' after $name on line ".$this->line);
if ($value[0] == '"' || $value[0] == "'")
$value = substr($value, 1, -1);
$value = $this->protectAttribute($name, $value);
$attributes[$name] = $value;
}
}
}
return $attributes;
}
private function decodeObfuscated($value)
{
// Don't try to trick me
$value = rawurldecode($value);
$value = html_entity_decode($value, ENT_QUOTES, $this->encoding);
// Convert unicode entities back to ASCII
// unicode entities don't always have a semicolon ending the entity
$value = preg_replace_callback('~&#x0*([0-9a-f]+);?~i',
function($match) { return chr(hexdec($match[1])); },
$value);
$value = preg_replace_callback('~&#0*([0-9]+);?~',
function ($match) { return chr($match[1]); },
$value);
return $value;
}
private function protectAttribute($name, $value)
{
if (!$this->secure)
return $value;
if ($name == 'src' || $name == 'href')
{
$value = self::decodeObfuscated($value);
// parse_url already have some tricks against XSS
$url = parse_url($value);
$value = '';
if (!empty($url['scheme']))
{
$url['scheme'] = strtolower($url['scheme']);
if (!array_key_exists($url['scheme'], $this->allowed_url_schemes))
return '';
$value .= $url['scheme'] . $this->allowed_url_schemes[$url['scheme']];
}
if (!empty($url['host']))
{
$value .= $url['host'];
}
if (!empty($url['path']))
{
$value .= $url['path'];
}
if (!empty($url['query']))
{
// We can't use parse_str and build_http_string to sanitize url here
// Or else we'll get things like ?param1&param2 transformed in ?param1=&param2=
$query = explode('&', $url['query']);
foreach ($query as &$item)
{
$item = explode('=', $item);
if (isset($item[1]))
$item = rawurlencode(rawurldecode($item[0])) . '=' . rawurlencode(rawurldecode($item[1]));
else
$item = rawurlencode(rawurldecode($item[0]));
}
$value .= '?' . $this->escape(implode('&', $query));
}
if (!empty($url['fragment']))
{
$value .= '#' . $url['fragment'];
}
}
else
{
$value = str_replace('&amp;', '&', $value);
$value = $this->cleanEntities($value);
$value = $this->escape($value);
}
return $value;
}
private function getTagName($value)
{
$value = trim($value);
if (preg_match('!^([a-zA-Z0-9-]+)(?:[:]([a-zA-Z0-9-]+))?!', $value, $match))
{
if (!empty($match[2]) && array_key_exists($match[1] . ':', $this->allowed_tags))
return $match[0];
elseif (array_key_exists($match[0], $this->allowed_tags))
return $match[0];
}
return false;
}
private function isTagAutoclosing($tag)
{
if (in_array($tag, $this->autoclosing_tags))
return true;
if (preg_match('!^[a-zA-Z0-9-]+:!', $tag, $match) && in_array($match[0], $this->autoclosing_tags))
return true;
return false;
}
/**
* Build HTML tree
*/
private function buildTree()
{
$i = 0;
$nodes = array();
$closing = false;
$in_forbidden_tag = false;
while (($value = array_shift($this->matches)) !== null)
{
// Line count
$this->line += (int) substr_count($value, "\n");
switch ($i++ % 3)
{
// Text node
case 0:
{
if ($value != "" && !$this->check_only
&& !($in_forbidden_tag && $this->remove_forbidden_tags_content))
{
$nodes[] = $this->escape($value);
}
break;
}
// Next iteration is closing tag (probably ?)
case 1:
{
$closing = ($value == '/');
break;
}
// Tag itself
case 2:
{
$tag = $this->getTagName($value);
// Self-closing tag
if (substr($value, -1) == '/' || $this->isTagAutoclosing($tag))
{
$value = preg_replace('!\s*/$!', '', $value);
// Dismis un-authorized tag
if (!$tag)
{
if ($this->check_only)
throw new Garbage_Exception("Un-authorized tag <$value>");
if (!$this->remove_forbidden_tags)
$nodes[] = '&lt;'.$this->escape($value).' /&gt;';
$in_forbidden_tag = false;
break;
}
if (!$this->check_only)
{
$nodes[] = array(
'name' => $tag,
'attrs' => $this->getTagAttributes($value, $tag),
'children'=> array(),
);
}
}
// Closing tag
else if ($closing)
{
// Dismis un-authorized tag
if (!$tag)
{
if (!$this->remove_forbidden_tags)
$nodes[] = '&lt;/'.$this->escape($value).'&gt;';
break;
}
$open = array_pop($this->opened);
// Uh-oh parse error !
// We could try to just dismiss tag errors or repair dirty HTML but
// it's too complicated. Just write valid xHTML.
if ($value != $open)
{
if ($this->check_only)
throw new Garbage_Exception("Tag <$value> closed, which is not open, on line ".$this->line);
}
return $nodes;
}
// Opening tag
else
{
if (!$tag)
{
if ($this->check_only)
throw new Garbage_Exception("Invalid tag <$value>");
if (!$this->remove_forbidden_tags)
$nodes[] = '&lt;'.$this->escape($value).'&gt;';
$in_forbidden_tag = true;
break;
}
if (!$this->check_only)
{
$node = array(
'name' => $tag,
'attrs' => $this->getTagAttributes($value, $tag),
'children'=> array(),
);
}
$this->opened[] = $tag;
if ($this->check_only)
{
$this->buildTree();
}
else
{
// Build child tree
$node['children'] = $this->buildTree();
// You need to enclose text in paragraphs in some tags
// (Yes, read the XHTML spec)
$node['children'] = $this->encloseChildren($node['children'], $node['name']);
$nodes[] = $node;
}
}
}
}
}
return $nodes;
}
/**
* Enclose sub elements which need to be enclosed
*/
private function encloseChildren($children, $parent)
{
if (!empty($children) && (in_array($parent, $this->elements_need_enclose) || !$parent))
{
$n = array();
$open = false;
while (($child = array_shift($children)) !== NULL)
{
if (is_string($child) || !array_key_exists($child['name'], $this->block_tags))
{
if ($open === false)
{
$open = count($n);
$n[$open] = array('name' => 'p', 'attrs' => array(), 'children' => array());
}
$n[$open]['children'][] = $child;
}
else
{
$open = false;
$n[] = $child;
}
}
$children = $n;
unset($n, $open, $child);
}
return $children;
}
public function escape($str)
{
$out = htmlspecialchars($str, ENT_QUOTES, $this->encoding, false);
if (empty($out) && !empty($str))
{
throw new Garbage_Exception("Encoding error.");
}
return $out;
}
/**
* Clean entities
*/
private function cleanEntities($str)
{
return preg_replace('/&amp;(#[0-9a-fx]+|[a-z]+);/i', '&\\1;', $str);
}
}

View file

@ -0,0 +1,185 @@
<?php
/*
This file is part of KD2FW -- <http://dev.kd2.org/>
Copyright (c) 2001-2019 BohwaZ <http://bohwaz.net/>
All rights reserved.
KD2FW 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.
Foobar 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 Foobar. If not, see <https://www.gnu.org/licenses/>.
*/
namespace KD2\Graphics;
class BarCode
{
const PRITY = [
[1,1,1,1,1,1],
[1,1,0,1,0,0],
[1,1,0,0,1,0],
[1,1,0,0,0,1],
[1,0,1,1,0,0],
[1,0,0,1,1,0],
[1,0,0,0,1,1],
[1,0,1,0,1,0],
[1,0,1,0,0,1],
[1,0,0,1,0,1]
];
const BARTABLE = [
['3211','1123'],
['2221','1222'],
['2122','2212'],
['1411','1141'],
['1132','2311'],
['1231','1321'],
['1114','4111'],
['1312','2131'],
['1213','3121'],
['3112','2113']
];
protected string $code;
public function __construct(string $code)
{
$this->code = preg_replace('/[^\d]/', '', $code);
}
public function get(): string
{
return $this->code;
}
public function verify(): bool
{
if (strlen($this->code) < 13) {
return false;
}
$sum = 0;
$code = str_split($this->code);
$sum = ($code[1] + $code[3] + $code[5] + $code[7] + $code[9] + $code[11]) * 3;
$sum += $code[0] + $code[2] + $code[4] + $code[6] + $code[8] + $code[10];
$sum = 10 - ($sum % 10);
return (string) $sum === $code[12];
}
public function toSVG(string $width = '200px'): string
{
static $guard = [1, 0, 1];
static $center = [0, 1, 0, 1, 0];
$bw = 3; //bar width
$w = $bw * 106;
$h = $bw * 50;
$fs = 8 * $bw; //Font size
$yt = 45 * $bw;
$dx = 2 * $bw; //lengh between bar and text
$x = 7 * $bw;
$y = 2.5 * $bw;
$sb = 35 * $bw;
$lb = 45 * $bw;
$char = $this->code;
$first = substr($char, 0, 1);
$first = (int) $first;
$oe = self::PRITY[$first]; //Old event array for first number
$char = str_split($char);
$out = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>' . PHP_EOL;
$out .= '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">' . PHP_EOL;
$out .= sprintf('<svg viewBox="0 0 %d %d" width="%s" version="1.1" xmlns="http://www.w3.org/2000/svg">', $w, $h, $width) . PHP_EOL;
$xt = $x + $dx - 8 * $bw; //Start point of text drawing
$out .= sprintf(' <text x="%d" y="%d" font-family="monospace" font-size="%s">%s</text>', $xt, $yt, $fs, $char[0]) . PHP_EOL;
// draw the left-most guarding bar
foreach ($guard as $bar) {
if ($bar === 1) {
$out .= sprintf(' <rect x="%d" y="%d" width="%d" height="%d" fill="black" stroke-width="0" />', $x, $y, $bw, $lb) . PHP_EOL;
}
$x = $x + $bw;
}
// draw the left bars
for ($i = 1; $i < 7; $i++) {
$id = $i - 1; //id for Old-event array
$oev = !$oe[$id]; //Old-event value
$val = self::BARTABLE[$char[$i]][$oev];
$xt = $x + $dx;
$out .= sprintf(' <text x="%d" y="%d" font-family="monospace" font-size="%d">%s</text>', $xt, $yt, $fs, $char[$i]) . PHP_EOL;
$val = str_split($val);
for ($j = 0; $j < 4; $j++) {
$num = (int) $val[$j];
$w = $bw * $num;
if ($j % 2) {
$out .= sprintf(' <rect x="%d" y="%d" width="%d" height="%d" fill="black" stroke-width="0" />', $x, $y, $w, $sb) . PHP_EOL;
}
$x = $x + $w;
}
}
// draw the center bar
foreach ($center as $bar) {
if ($bar === 1) {
$out .= sprintf(' <rect x="%d" y="%d" width="%d" height="%d" fill="black" stroke-width="0" />', $x, $y, $bw, $lb) . PHP_EOL;
}
$x = $x + $bw;
}
// Draw the right bars, always in first column
for ($i = 7; $i < 13; $i++) {
$val = self::BARTABLE[$char[$i]][0];
$xt = $x + $dx;
$out .= sprintf(' <text x="%d" y="%d" font-family="monospace" font-size="%d">%s</text>', $xt, $yt, $fs, $char[$i]) . PHP_EOL;
$val = str_split($val);
for ($j = 0; $j < 4; $j++) {
$num = (int) $val[$j];
$w = $bw * $num;
if (!($j % 2)) {
$out .= sprintf(' <rect x="%d" y="%d" width="%d" height="%d" fill="black" stroke-width="0" />', $x, $y, $w, $sb) . PHP_EOL;
}
$x = $x + $w;
}
}
// Draw the ending guard bar
foreach ($guard as $bar) {
if ($bar === 1) {
$out .= sprintf(' <rect x="%d" y="%d" width="%d" height="%d" fill="black" stroke-width="0" />', $x, $y, $bw, $lb) . PHP_EOL;
}
$x = $x + $bw;
}
$out .= '</svg>' . PHP_EOL;
return $out;
}
}

Some files were not shown because too many files have changed in this diff Show more