initial commit
This commit is contained in:
commit
5ebc506921
975 changed files with 154341 additions and 0 deletions
62
tools/categories_as_projects.sh
Executable file
62
tools/categories_as_projects.sh
Executable file
|
|
@ -0,0 +1,62 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Ce script permet de convertir les anciennes catégories en projets
|
||||
# et d'affecter ces projets aux écritures.
|
||||
#
|
||||
# - Création de nouveaux comptes de projets
|
||||
# - Affectation des lignes des écritures à ces nouvelles écritures
|
||||
#
|
||||
# Le premier argument doit être l'ancienne base de données (version 0.9.8)
|
||||
# Le second argument doit être la nouvelle base de données (1.0)
|
||||
#
|
||||
# Évidemment ça ne marche que si la BDD 1.0 est une mise à jour de la BDD de la 0.9.8 !
|
||||
# Sinon ça sera tout mélangé !
|
||||
|
||||
if [ ! -f "$1" ] || [ ! -f "$2" ]; then
|
||||
echo "Usage: $0 OLD_DATABASE NEW_DATABASE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sqlite3 "$1" <<EOF
|
||||
CREATE TEMP TABLE projects_categories (id, code, label, description);
|
||||
|
||||
INSERT INTO projects_categories SELECT id, NULL, intitule, description FROM compta_categories;
|
||||
|
||||
UPDATE projects_categories SET code = printf('99%03d', rowid);
|
||||
|
||||
--SELECT code, label FROM projects_categories;
|
||||
--SELECT id, (SELECT code FROM projects_categories WHERE id = id_categorie) FROM compta_journal WHERE id_categorie IS NOT NULL;
|
||||
|
||||
CREATE TEMP TABLE projects_transactions (id, code, account_id);
|
||||
|
||||
INSERT INTO projects_transactions
|
||||
SELECT
|
||||
id,
|
||||
(SELECT code FROM projects_categories WHERE id = id_categorie),
|
||||
NULL
|
||||
FROM compta_journal
|
||||
WHERE id_categorie IS NOT NULL;
|
||||
|
||||
ATTACH '${2}' AS new;
|
||||
|
||||
BEGIN;
|
||||
|
||||
INSERT INTO new.acc_accounts (id_chart, code, label, description, position, type, user)
|
||||
SELECT
|
||||
(SELECT id FROM acc_charts WHERE code = 'PCGA1999'),
|
||||
code,
|
||||
label,
|
||||
description,
|
||||
0,
|
||||
7, -- type
|
||||
1
|
||||
FROM projects_categories;
|
||||
|
||||
UPDATE projects_transactions AS t SET account_id = (SELECT id FROM new.acc_accounts a WHERE a.code = t.code);
|
||||
|
||||
UPDATE new.acc_transactions_lines AS l
|
||||
SET
|
||||
id_analytical = (SELECT account_id FROM projects_transactions t WHERE t.id = l.id_transaction);
|
||||
|
||||
COMMIT;
|
||||
EOF
|
||||
593
tools/construire_plan_comptable.php
Normal file
593
tools/construire_plan_comptable.php
Normal file
|
|
@ -0,0 +1,593 @@
|
|||
<?php
|
||||
|
||||
namespace Garradin;
|
||||
|
||||
require __DIR__ . '/../src/include/class.compta_comptes.php';
|
||||
require __DIR__ . '/../src/include/lib.utils.php';
|
||||
|
||||
$plan = <<<EOF_PLAN
|
||||
Classe 1 — Comptes de capitaux (Fonds propres, emprunts et dettes assimilés)
|
||||
|
||||
10 FONDS ASSOCIATIFS ET RÉSERVES
|
||||
|
||||
102 Fonds associatif sans droit de reprise
|
||||
|
||||
1021 Valeur du patrimoine intégré
|
||||
1022 Fonds statutaire
|
||||
1024 Apports sans droit de reprise
|
||||
|
||||
103 Fonds associatif avec droit de reprise
|
||||
|
||||
1034 Apports avec droit de reprise
|
||||
|
||||
105 Écarts de réévaluation
|
||||
|
||||
106 Réserves
|
||||
|
||||
1063 Réserves statutaires ou contractuelles
|
||||
1064 Réserves réglementées
|
||||
1068 Autres réserves (dont réserves pour projet associatif)
|
||||
|
||||
11 REPORT À NOUVEAU
|
||||
|
||||
110 Report à nouveau (Solde créditeur)
|
||||
119 Report à nouveau (Solde débiteur)
|
||||
|
||||
12 RÉSULTAT NET DE L'EXERCICE
|
||||
|
||||
120 Résultat de l'exercice (excédent)
|
||||
129 Résultat de l'exercice (déficit)
|
||||
|
||||
13 SUBVENTIONS D'INVESTISSEMENT AFFECTÉES A DES BIENS NON RENOUVELABLES
|
||||
|
||||
131 Subventions d'investissement (renouvelables)
|
||||
139 Subventions d'investissement inscrites au compte de résultat
|
||||
|
||||
14 PROVISIONS REGLEMENTÉES
|
||||
|
||||
15 PROVISIONS
|
||||
|
||||
151 Provisions pour risques
|
||||
|
||||
157 Provisions pour charges à répartir sur plusieurs exercices
|
||||
|
||||
158 Autres provisions pour charges
|
||||
|
||||
|
||||
16 EMPRUNTS ET DETTES ASSIMILÉES
|
||||
|
||||
164 Emprunts auprès des établissements de crédits
|
||||
|
||||
165 Dépôts et cautionnements reçus
|
||||
|
||||
167 Emprunts et dettes assorties de conditions particulières
|
||||
|
||||
168 Autres emprunts et dettes assimilés
|
||||
|
||||
17 DETTES RATTACHÉES À DES PARTICIPATIONS
|
||||
|
||||
18 COMPTES DE LIAISON DES ÉTABLISSEMENTS
|
||||
|
||||
181 Apports permanents entre siège social et établissements
|
||||
185 Biens et prestations de services échangés entre établissements et siège social
|
||||
186 Biens et prestations de services échangés entre établissements (charges)
|
||||
187 Biens et prestations de services échangés entre établissements (produits)
|
||||
|
||||
19 FONDS DÉDIÉS
|
||||
|
||||
194 Fonds dédiés sur subventions de fonctionnement
|
||||
195 Fonds dédiés sur dons manuels affectés
|
||||
197 Fonds dédiés sur legs et donations affectés
|
||||
198 Excédent disponible après affectation au projet associatif
|
||||
199 Reprise des fonds affectés au projet associatif
|
||||
|
||||
Classe 2 — Comptes d'immobilisations
|
||||
|
||||
20 IMMOBILISATIONS INCORPORELLES
|
||||
|
||||
200 Immobilisations incorporelles
|
||||
|
||||
21 IMMOBILISATIONS CORPORELLES
|
||||
|
||||
210 Investissements
|
||||
|
||||
22 IMMOBILISATIONS GREVÉES DE DROITS
|
||||
|
||||
228 Immobilisations grevées de droits
|
||||
229 Droits des propriétaires
|
||||
|
||||
23 IMMOBILISATIONS EN COURS
|
||||
|
||||
231 Immobilisations corporelles en cours
|
||||
238 Avances et acomptes versés sur commande d'immobilisations corporelles
|
||||
|
||||
26 PARTICIPATIONS ET CRÉANCES RATTACHÉES A DES PARTICIPATIONS
|
||||
|
||||
261 Titres de participation
|
||||
|
||||
27 AUTRES IMMOBILISATIONS FINANCIÈRES
|
||||
|
||||
270 Participations financières
|
||||
275 Dépôts et cautionnements versés
|
||||
|
||||
28 AMORTISSEMENTS DES IMMOBILISATIONS
|
||||
|
||||
280 Amortissements des immobilisations incorporelles
|
||||
281 Amortissements des immobilisations corporelles
|
||||
|
||||
29 DÉPRÉCIATION DES IMMOBILISATIONS
|
||||
|
||||
290 Dépréciation des immobilisations incorporelles
|
||||
291 Dépréciation des immobilisations corporelles
|
||||
|
||||
Classe 3 — Comptes de stocks
|
||||
|
||||
31 MATIERES PREMIERES ET FOURNITURES
|
||||
|
||||
311 Matières
|
||||
317 Fournitures
|
||||
|
||||
32 AUTRES APPROVISIONNEMENTS
|
||||
|
||||
321 Matières consommables
|
||||
322 Fournitures consommables
|
||||
|
||||
33 EN-COURS DE PRODUCTION DE BIENS
|
||||
|
||||
331 Produits en cours
|
||||
335 Travaux en cours
|
||||
|
||||
34 EN-COURS DE PRODUCTION DE SERVICES
|
||||
|
||||
35 STOCKS DE PRODUITS
|
||||
|
||||
351 Produits intermédiaires
|
||||
355 Produits finis
|
||||
358 Produits résiduels
|
||||
|
||||
3581 Déchets
|
||||
3585 Rebuts
|
||||
3586 Matière de récupération
|
||||
|
||||
37 STOCKS DE MARCHANDISES
|
||||
|
||||
370 Autres stocks de marchandises
|
||||
|
||||
39 PROVISIONS POUR DEPRECIATION DES STOCKS ET EN-COURS
|
||||
|
||||
391 Provisions pour dépréciation des matières premières et fournitures
|
||||
|
||||
Classe 4 — Comptes de tiers
|
||||
|
||||
40 FOURNISSEURS ET COMPTES RATTACHÉS [PASSIF]
|
||||
|
||||
401 Fournisseurs [PASSIF]
|
||||
|
||||
4010 Autres fournisseurs [PASSIF]
|
||||
|
||||
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]
|
||||
|
||||
419 Avances aux usagers [PASSIF]
|
||||
|
||||
42 PERSONNEL ET COMPTES RATTACHÉS [PASSIF]
|
||||
|
||||
421 Personnel - Rémunérations dues [PASSIF]
|
||||
4210 Autres membres du personnel [PASSIF]
|
||||
425 Personnel - Avances et acomptes [ACTIF]
|
||||
428 Personnel - Charges à payer et produits à recevoir [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 [PASSIF]
|
||||
|
||||
4382 Charges sociales sur congés à payer [PASSIF]
|
||||
4386 Autres charges à payer [PASSIF]
|
||||
4387 Produits à recevoir [ACTIF]
|
||||
|
||||
439 Avances auprès des organismes sociaux [PASSIF]
|
||||
|
||||
44 ÉTAT ET AUTRES COLLECTIVITÉS PUBLIQUES [ACTIF]
|
||||
|
||||
441 État - Subventions à recevoir [ACTIF]
|
||||
|
||||
4411 Subventions d'investissement [ACTIF]
|
||||
4417 Subventions d'exploitation [ACTIF]
|
||||
4418 Subventions d'équilibre [ACTIF]
|
||||
4419 Avances sur subventions [ACTIF]
|
||||
|
||||
442 État - Impôts et taxes recouvrables sur des tiers [PASSIF]
|
||||
444 État - Impôts sur les bénéfices [ACTIF]
|
||||
445 État - Taxes sur le chiffre d'affaires [ACTIF]
|
||||
|
||||
4455 Taxes sur le chiffre d'affaires à décaisser [ACTIF]
|
||||
|
||||
44551 TVA à décaisser [ACTIF]
|
||||
44558 Taxes assimilées à la TVA [ACTIF]
|
||||
|
||||
4456 Taxes sur le chiffre d'affaires déductibles [ACTIF]
|
||||
|
||||
44562 TVA sur immobilisations [ACTIF]
|
||||
44566 TVA sur autres biens et services [ACTIF]
|
||||
|
||||
4457 Taxes sur le chiffre d'affaires collectées par l'association [ACTIF]
|
||||
4458 Taxes sur le chiffre d'affaires à régulariser ou en attente [ACTIF]
|
||||
|
||||
44581 Acomptes - Régime simplifié d'imposition [ACTIF]
|
||||
44582 Acomptes - Régime du forfait [ACTIF]
|
||||
44583 Remboursement de taxes sur le chiffre d'affaires demandé [ACTIF]
|
||||
44584 TVA récupérée d'avance [ACTIF]
|
||||
44586 Taxes sur le chiffre d'affaires sur factures non parvenues [ACTIF]
|
||||
44587 Taxes sur le chiffre d'affaires sur factures à établir [ACTIF]
|
||||
|
||||
447 Autres impôts, taxes et versements assimilés [PASSIF]
|
||||
|
||||
4471 Autres impôts, taxes et versements assimilés sur rémunérations (Administration des impôts) [PASSIF]
|
||||
|
||||
44711 Taxe sur les salaires [PASSIF]
|
||||
44713 Participation des employeurs à la formation professionnelle continue [PASSIF]
|
||||
44714 Cotisation par défaut d'investissement obligatoire dans la construction [PASSIF]
|
||||
44718 Autres impôts, taxes et versements assimilés [PASSIF]
|
||||
|
||||
4473 Autres impôts, taxes et versements assimilés sur rémunérations (Autres organismes) [PASSIF]
|
||||
|
||||
44733 Participation des employeurs à la formation professionnelle continue [PASSIF]
|
||||
44734 Participation des employeurs à l'effort de construction (versements à fonds perdus) [PASSIF]
|
||||
|
||||
4475 Autres impôts, taxes et versements assimilés (Administration des impôts) [PASSIF]
|
||||
4477 Autres impôts, taxes et versements assimilés (Autres organismes) [PASSIF]
|
||||
|
||||
448 État - Charges à payer et produits à recevoir [PASSIF]
|
||||
|
||||
4482 Charges fiscales sur congés à payer [PASSIF]
|
||||
4486 Autres charges à payer [PASSIF]
|
||||
4487 Produits à recevoir [ACTIF]
|
||||
|
||||
449 Avances auprès de l'état et des collectivités publiques [PASSIF]
|
||||
|
||||
45 CONFÉDÉRATION, FÉDÉRATION, UNIONS ET ASSOCIATIONS AFFILIÉES
|
||||
|
||||
451 Confédération, fédération et associations affiliées - Compte courant
|
||||
455 Sociétaires - Comptes courants
|
||||
|
||||
46 DÉBITEURS DIVERS ET CRÉDITEURS DIVERS
|
||||
|
||||
467 Autres comptes débiteurs et créditeurs
|
||||
468 Divers - Charges à payer et produits à recevoir
|
||||
|
||||
4686 Charges à payer [PASSIF]
|
||||
4687 Produits à recevoir [ACTIF]
|
||||
|
||||
47 COMPTES TRANSITOIRES OU D'ATTENTE
|
||||
|
||||
471 Recettes à classer [PASSIF]
|
||||
472 Dépenses à classer et à régulariser [ACTIF]
|
||||
|
||||
48 COMPTES DE RÉGULARISATION
|
||||
|
||||
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]
|
||||
|
||||
Classe 5 — Comptes financiers
|
||||
|
||||
50 VALEURS MOBILIÈRES DE PLACEMENT
|
||||
|
||||
51 BANQUES, ÉTABLISSEMENTS FINANCIERS ET ASSIMILÉS
|
||||
|
||||
512 Banques
|
||||
|
||||
53 CAISSE
|
||||
|
||||
530 Caisse
|
||||
|
||||
54 RÉGIES D'AVANCES ET ACCRÉDITIFS
|
||||
|
||||
58 VIREMENTS INTERNES
|
||||
|
||||
59 PROVISIONS POUR DÉPRÉCIATION DES COMPTES FINANCIERS
|
||||
|
||||
Classe 6 — Comptes de charges
|
||||
|
||||
60 ACHATS
|
||||
|
||||
601 Achats stockés - Matières premières et fournitures
|
||||
|
||||
602 Achats stockés - Autres approvisionnements
|
||||
|
||||
604 Achat d'études et prestations de services
|
||||
|
||||
606 Achats non stockés de matières et fournitures
|
||||
|
||||
6061 Fournitures non stockables (eau, énergie...)
|
||||
|
||||
6063 Fournitures d'entretien et de petit équipement
|
||||
6064 Fournitures administratives
|
||||
6068 Autres matières et fournitures
|
||||
|
||||
607 Achats de marchandises
|
||||
|
||||
61 SERVICES EXTÉRIEURS
|
||||
|
||||
611 Sous-traitance générale
|
||||
612 Redevances de crédit-bail
|
||||
|
||||
613 Locations
|
||||
|
||||
614 Charges locatives et de co-propriété
|
||||
615 Entretiens et réparations
|
||||
|
||||
616 Primes d'assurance
|
||||
|
||||
618 Divers
|
||||
|
||||
62 AUTRES SERVICES EXTÉRIEURS
|
||||
|
||||
621 Personnel extérieur à l'association
|
||||
|
||||
622 Rémunérations d'intermédiaires et honoraires
|
||||
|
||||
6226 Honoraires
|
||||
6227 Frais d'actes et de contentieux
|
||||
6228 Divers
|
||||
|
||||
623 Publicité, publications, relations publiques
|
||||
|
||||
624 Transports de biens et transports collectifs du personnel
|
||||
|
||||
625 Déplacements, missions et réceptions
|
||||
|
||||
626 Frais postaux et de télécommunications
|
||||
|
||||
627 Services bancaires et assimilés
|
||||
|
||||
628 Divers
|
||||
|
||||
63 IMPÔTS, TAXES ET VERSEMENTS ASSIMILÉS
|
||||
|
||||
631 Impôts, taxes et versements assimilés sur rémunérations (Administration des impôts)
|
||||
|
||||
6311 Taxes sur les salaires
|
||||
6313 Participations des employeurs à la formation professionnelle continue
|
||||
|
||||
635 Autres impôts, taxes et versements assimilés (Administration des impôts)
|
||||
|
||||
6351 Impôts directs (sauf impôts sur les bénéfices)
|
||||
6353 Impôts indirects
|
||||
|
||||
637 Autres impôts, taxes et versements assimilés (Autres organismes)
|
||||
|
||||
64 CHARGES DE PERSONNEL
|
||||
|
||||
641 Rémunérations du personnel
|
||||
|
||||
643 Rémunérations du personnel artistique et assimilés
|
||||
|
||||
645 Charges de sécurité sociale et de prévoyance
|
||||
|
||||
647 Autres charges sociales
|
||||
|
||||
648 Autres charges de personnel
|
||||
|
||||
65 AUTRES CHARGES DE GESTION COURANTE
|
||||
|
||||
658 Charges diverses de gestion courante
|
||||
|
||||
66 CHARGES FINANCIÈRES
|
||||
|
||||
661 Charges d'intérêts
|
||||
|
||||
67 CHARGES EXCEPTIONNELLES
|
||||
|
||||
671 Charges exceptionnelles sur opérations de gestion
|
||||
|
||||
6713 Dons, libéralités
|
||||
|
||||
678 Autres charges exceptionnelles
|
||||
|
||||
6788 Charges exceptionnelles diverses
|
||||
|
||||
68 DOTATIONS AUX AMORTISSEMENTS, DÉPRÉCIATIONS, PROVISIONS ET ENGAGEMENTS
|
||||
|
||||
681 Dotations aux amortissements, dépréciations et provisions - Charges d'exploitation
|
||||
|
||||
6811 Dotations aux amortissements des immobilisations incorporelles et corporelles
|
||||
|
||||
68111 Immobilisations incorporelles
|
||||
68112 Immobilisations corporelles
|
||||
|
||||
686 Dotations aux amortissements, dépréciations et provisions - Charges financières
|
||||
|
||||
69 PARTICIPATION DES SALARIÉS - IMPÔTS SUR LES BÉNÉFICES ET ASSIMILÉS
|
||||
|
||||
695 Impôts sur les sociétés (y compris impôts sur les sociétés des personnes morales non lucratives)
|
||||
|
||||
Classe 7 — Comptes de produits
|
||||
|
||||
70 VENTES DE PRODUITS FINIS, PRESTATIONS DE SERVICES, MARCHANDISES
|
||||
|
||||
701 Ventes de produits finis
|
||||
706 Prestations de services
|
||||
707 Ventes de marchandises
|
||||
708 Produits des activités annexes
|
||||
|
||||
|
||||
71 PRODUCTION STOCKÉE (OU DÉSTOCKAGE)
|
||||
72 PRODUCTION IMMOBILISÉE
|
||||
|
||||
74 SUBVENTIONS D'EXPLOITATION
|
||||
|
||||
740 Subventions reçues
|
||||
|
||||
75 AUTRES PRODUITS DE GESTION COURANTE
|
||||
|
||||
754 Collectes
|
||||
756 Cotisations
|
||||
758 Produits divers de gestion courante
|
||||
|
||||
7587 Ventes de dons en nature
|
||||
7588 Autres produits de la générosité du public
|
||||
|
||||
76 PRODUITS FINANCIERS
|
||||
|
||||
760 Produits financiers
|
||||
|
||||
77 PRODUITS EXCEPTIONNELS
|
||||
|
||||
771 Produits exceptionnels sur opérations de gestion
|
||||
|
||||
7713 Libéralités reçues
|
||||
7715 Subventions d'équilibre
|
||||
|
||||
775 Produits des cessions d'éléments d'actifs
|
||||
|
||||
778 Autres produits exceptionnels
|
||||
|
||||
7780 Manifestations diverses
|
||||
7788 Produits exceptionnels divers
|
||||
|
||||
|
||||
78 REPRISES SUR AMORTISSEMENTS ET PROVISIONS
|
||||
|
||||
79 TRANSFERT DE CHARGES
|
||||
|
||||
791 Transferts de charges d'exploitation
|
||||
796 Transferts de charges financières
|
||||
797 Transferts de charges exceptionnels
|
||||
|
||||
Classe 8 — Contributions bénévoles en nature
|
||||
|
||||
86 RÉPARTITION PAR NATURE DE CHARGES
|
||||
|
||||
861 Mise à dispositions gratuites de biens
|
||||
862 Prestations
|
||||
864 Personnel bénévole
|
||||
|
||||
87 RÉPARTITION PAR NATURE DE RESSOURCES
|
||||
|
||||
870 Bénévolat
|
||||
871 Prestations en nature
|
||||
875 Dons en nature
|
||||
|
||||
Classe 9 — Comptes analytiques
|
||||
|
||||
EOF_PLAN;
|
||||
|
||||
$plan = preg_replace("/\r/", '', $plan);
|
||||
$plan = preg_replace("/\n{2,}/", "\n", $plan);
|
||||
$src = explode("\n", $plan);
|
||||
$plan = array();
|
||||
|
||||
foreach ($src as $line)
|
||||
{
|
||||
$line = trim($line);
|
||||
if (preg_match('!^(\d+)\s+(.+)$!', $line, $match))
|
||||
{
|
||||
$code = (int)$match[1];
|
||||
$nom = trim($match[2]);
|
||||
$parent = (int)substr($match[1], 0, -1);
|
||||
}
|
||||
elseif (preg_match('!^Classe (\d+)\s+.*$!', $line, $match))
|
||||
{
|
||||
$code = (int)$match[1];
|
||||
$nom = trim($match[0]);
|
||||
$parent = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "$line\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
if (preg_match('/^(.+?)\s+\[(ACTIF|PASSIF)\]\s*$/', $nom, $match))
|
||||
{
|
||||
$position = ($match[2] == 'PASSIF') ? Compta_Comptes::PASSIF : Compta_Comptes::ACTIF;
|
||||
$nom = $match[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
$position = false;
|
||||
}
|
||||
|
||||
$classe = substr((string)$code, 0, 1);
|
||||
|
||||
if ($classe == 1)
|
||||
{
|
||||
$position = Compta_Comptes::PASSIF;
|
||||
}
|
||||
elseif ($classe == 2 || $classe == 3 || $classe == 5)
|
||||
{
|
||||
$position = Compta_Comptes::ACTIF;
|
||||
}
|
||||
// Comptes de classe 4, c'est compliqué là
|
||||
elseif ($classe == 4)
|
||||
{
|
||||
if ($position === false)
|
||||
{
|
||||
$position = Compta_Comptes::PASSIF | Compta_Comptes::ACTIF;
|
||||
}
|
||||
}
|
||||
elseif ($classe == 6)
|
||||
{
|
||||
$position = Compta_Comptes::CHARGE;
|
||||
}
|
||||
elseif ($classe == 7)
|
||||
{
|
||||
$position = Compta_Comptes::PRODUIT;
|
||||
}
|
||||
elseif ($classe == 8)
|
||||
{
|
||||
if (substr($code, 0, 2) == 86)
|
||||
{
|
||||
$position = Compta_Comptes::CHARGE;
|
||||
}
|
||||
elseif (substr($code, 0, 2) == 87)
|
||||
{
|
||||
$position = Compta_Comptes::PRODUIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
$position = Compta_Comptes::CHARGE | Compta_Comptes::PRODUIT;
|
||||
}
|
||||
}
|
||||
elseif ($classe == 9)
|
||||
{
|
||||
$position = Compta_Comptes::CHARGE | Compta_Comptes::PRODUIT;
|
||||
}
|
||||
|
||||
$plan[$code] = array(
|
||||
'code' => $code,
|
||||
'nom' => $nom,
|
||||
'parent' => $parent,
|
||||
'position' => $position,
|
||||
);
|
||||
}
|
||||
|
||||
$json = json_encode($plan, JSON_PRETTY_PRINT);
|
||||
file_put_contents(__DIR__ . '/../src/include/data/plan_comptable.json', $json);
|
||||
|
||||
die("OK\n");
|
||||
|
||||
?>
|
||||
109
tools/doc_md_to_html.php
Normal file
109
tools/doc_md_to_html.php
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
<?php
|
||||
|
||||
use KD2\HTML\Markdown;
|
||||
use KD2\HTML\Markdown_Extensions;
|
||||
|
||||
require_once __DIR__ . '/../src/include/lib/KD2/HTML/Markdown.php';
|
||||
require_once __DIR__ . '/../src/include/lib/KD2/HTML/Markdown_Extensions.php';
|
||||
|
||||
$md = new Markdown;
|
||||
|
||||
// Allow extra tags for Markdown quickref
|
||||
$extra_tags = [
|
||||
'blockquote' => null,
|
||||
'pre' => null,
|
||||
'br' => null,
|
||||
'h1' => null,
|
||||
'h2' => null,
|
||||
'h3' => null,
|
||||
'h4' => null,
|
||||
'h5' => null,
|
||||
'h6' => null,
|
||||
'ul' => null,
|
||||
'ol' => null,
|
||||
'li' => null,
|
||||
'table' => null,
|
||||
'thead' => null,
|
||||
'tbody' => null,
|
||||
'tr' => null,
|
||||
'th' => null,
|
||||
'td' => null,
|
||||
'hr' => null,
|
||||
'div' => ['style'],
|
||||
];
|
||||
|
||||
Markdown_Extensions::register($md);
|
||||
|
||||
foreach (glob(__DIR__ . '/../doc/admin/*.md') as $file) {
|
||||
if (basename($file) == 'markdown_quickref.md') {
|
||||
$md->allowed_inline_tags = array_merge($md->allowed_inline_tags, $extra_tags);
|
||||
}
|
||||
else {
|
||||
$md->allowed_inline_tags = $md::DEFAULT_INLINE_TAGS;
|
||||
}
|
||||
|
||||
$t = file_get_contents($file);
|
||||
|
||||
if (preg_match('/^Title: (.*)/', $t, $match)) {
|
||||
$t = substr($t, strlen($match[0]));
|
||||
}
|
||||
|
||||
$t = $md->text($t);
|
||||
$t = preg_replace('!(<a\s+[^>]+external[^>]+)>!', '$1 target="_blank">', $t);
|
||||
|
||||
$title = $match[1] ?? $file;
|
||||
|
||||
$out = '<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>' . htmlspecialchars($title) . '</title>
|
||||
<meta charset="utf-8" />
|
||||
<style type="text/css">
|
||||
body, form, p, div, hr, fieldset, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6 {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
body {
|
||||
font-family: "Trebuchet MS", Arial, Helvetica, Sans-serif;
|
||||
padding: .8em;
|
||||
background: #eee;
|
||||
}
|
||||
.web-content .nav ul {
|
||||
list-style-type: none;
|
||||
margin: -.8em;
|
||||
margin-bottom: 1em;
|
||||
padding: 1em;
|
||||
background: #ddd;
|
||||
border-bottom: 1px solid #999;
|
||||
text-align: center;
|
||||
}
|
||||
.web-content .boutons ul {
|
||||
list-style-type: none;
|
||||
background: #ccc;
|
||||
padding: .5em;
|
||||
margin: 0;
|
||||
}
|
||||
.web-content .nav li, .web-content .boutons li {
|
||||
display: inline-block;
|
||||
margin: 0 1em;
|
||||
}
|
||||
.web-content .nav a, .web-content .boutons a {
|
||||
display: inline-block;
|
||||
background: #fff;
|
||||
color: darkblue;
|
||||
border-radius: .2em;
|
||||
padding: .3em .5em;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
.web-content .nav strong a {
|
||||
color: darkred;
|
||||
box-shadow: 0px 0px 5px orange;
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" type="text/css" href="../../../content.css" />
|
||||
</head>
|
||||
<body><div class="web-content">' . $t . '</div></body></html>';
|
||||
|
||||
$dest = __DIR__ . '/../src/www/admin/static/doc/' . str_replace('.md', '.html', basename($file));
|
||||
file_put_contents($dest, $out);
|
||||
}
|
||||
164
tools/extract-credit-mutuel-csv.php
Normal file
164
tools/extract-credit-mutuel-csv.php
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
<?php
|
||||
/**
|
||||
* Extracteur de données des relevés de compte du Crédit Mutuel
|
||||
* à destination de Garradin (ou autre logiciel de compta)
|
||||
*
|
||||
* https://garradin.eu/
|
||||
*
|
||||
* Ce script prend en argument un répertoire contenant des extraits
|
||||
* de compte en PDF (ou un seul extrait de compte) et crée un fichier
|
||||
* CSV importable directement dans Garradin.
|
||||
*
|
||||
* Ce script requiert d'avoir installé Tabula (Java) :
|
||||
* https://github.com/tabulapdf/tabula-java
|
||||
*
|
||||
* Copyright (C) 2020 BohwaZ - licence AGPLv3
|
||||
*/
|
||||
|
||||
// Ajuster cette constante en fonction du chemin où vous avez placé
|
||||
// le JAR de Tabula
|
||||
const TABULA_PATH = 'tabula.jar';
|
||||
|
||||
if (empty($argv[1]) || empty($argv[2])) {
|
||||
printf("Usage: %s REPERTOIRE_OU_FICHIER FICHIER_SORTIE_CSV\n", $argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$path = $argv[1];
|
||||
$dest = $argv[2];
|
||||
|
||||
if (!is_readable($path)) {
|
||||
die("Ne peut lire le répertoire\n");
|
||||
}
|
||||
|
||||
$path = rtrim($path, '/');
|
||||
|
||||
$header = null;
|
||||
$sum_header = null;
|
||||
$out = [];
|
||||
$i = 0;
|
||||
|
||||
if (is_file($path)) {
|
||||
$files = [$path];
|
||||
}
|
||||
else {
|
||||
$files = glob($path . '/*.pdf');
|
||||
}
|
||||
|
||||
// Lecture du CSV
|
||||
foreach ($files as $file) {
|
||||
printf("Lecture de %s…" . PHP_EOL, $file);
|
||||
|
||||
$csv = shell_exec(sprintf('java -jar %s -g -l -p all %s', TABULA_PATH, escapeshellarg($file)));
|
||||
|
||||
$csv = explode("\n", $csv);
|
||||
|
||||
/*
|
||||
Date
|
||||
Date valeur
|
||||
Opération
|
||||
Débit EUROS
|
||||
Crédit EUROS
|
||||
*/
|
||||
foreach ($csv as $line) {
|
||||
$row = str_getcsv($line);
|
||||
|
||||
if (count($row) < 2) {
|
||||
echo "Saut ligne vide\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
if (preg_match('!^Solde.*(?:AU\s+(\d+/\d+/\d+))!i', trim($row[0]), $match)) {
|
||||
if (null === $sum_header) {
|
||||
$row = [$match[1], null, $row[0], null, $row[2]];
|
||||
$out[$i++] = $row;
|
||||
$sum_header = $row;
|
||||
continue;
|
||||
}
|
||||
|
||||
echo "Saut solde : ";
|
||||
echo implode(', ', $row);
|
||||
echo PHP_EOL;
|
||||
continue;
|
||||
}
|
||||
elseif (preg_match('!^(?:Solde|Total|Réf\s+:.*SOLDE)!i', trim($row[0]))) {
|
||||
echo "Saut solde : ";
|
||||
echo implode(', ', $row);
|
||||
echo PHP_EOL;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (null === $header) {
|
||||
echo "Saut entête\n";
|
||||
$header = $row;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($header === $row) {
|
||||
echo "Saut répétition entête\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
if (count($row) !== count($header)) {
|
||||
echo "Ligne incohérente\n";
|
||||
var_dump($row); exit;
|
||||
}
|
||||
|
||||
foreach ($row as &$cell) {
|
||||
$cell = preg_replace('/\s\s+/', ' ', $cell);
|
||||
}
|
||||
|
||||
unset($cell);
|
||||
|
||||
if (empty($row[0])) {
|
||||
$out[$i - 1][2] .= PHP_EOL . $row[2];
|
||||
continue;
|
||||
}
|
||||
|
||||
$out[$i++] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
// Création du CSV de sortie
|
||||
$fp = fopen($dest, 'w');
|
||||
|
||||
fputcsv($fp, ['Numéro d\'écriture', 'Date', 'Libellé', 'Compte de débit', 'Compte de crédit', 'Montant', 'Numéro pièce comptable', 'Référence paiement', 'Notes']);
|
||||
|
||||
foreach ($out as $line) {
|
||||
$label = $line[2];
|
||||
$notes = null;
|
||||
$ref = null;
|
||||
|
||||
if (false !== ($pos = strpos($label, "\n"))) {
|
||||
$notes = trim(substr($label, $pos));
|
||||
$label = trim(substr($label, 0, $pos));
|
||||
}
|
||||
|
||||
if (preg_match('/^VRST (REF.*)/', $label, $match)) {
|
||||
$label = 'Versement espèces';
|
||||
$ref = $match[1];
|
||||
}
|
||||
elseif (preg_match('/^REM CHQ (REF.*)/', $label, $match)) {
|
||||
$label = 'Remise de chèques';
|
||||
$ref = $match[1];
|
||||
}
|
||||
elseif (preg_match('/^FACTURE (SGT.*)/', $label, $match)) {
|
||||
$label = 'Frais bancaires Crédit Mutuel';
|
||||
$ref = $match[1];
|
||||
}
|
||||
elseif (preg_match('/^CHEQUE (\d+)/', $label, $match)) {
|
||||
$label = 'Chèque ' . $match[1];
|
||||
$ref = $match[1];
|
||||
}
|
||||
elseif (preg_match('/^VIR ROZO/', $label) && preg_match('/(REP\d+-\d+)/s', $notes, $match)) {
|
||||
$label = 'Virement Rozo';
|
||||
$ref = $match[1];
|
||||
}
|
||||
|
||||
$amount = !empty($line[4]) ? $line[4] : '-' . $line[3];
|
||||
$amount = str_replace('.', '', $amount);
|
||||
|
||||
fputcsv($fp, ['', $line[0], $label, '', '', $amount, '', $ref, $notes]);
|
||||
}
|
||||
|
||||
fclose($fp);
|
||||
163
tools/extract-paypal-csv.php
Normal file
163
tools/extract-paypal-csv.php
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
<?php
|
||||
/**
|
||||
* Extracteur de données des relevés de compte Paypal
|
||||
* à destination de Garradin (ou autre logiciel de compta)
|
||||
*
|
||||
* https://garradin.eu/
|
||||
*
|
||||
* Ce script prend en argument un fichier CSV exporté de Paypal
|
||||
* https://business.paypal.com/merchantdata/reportHome?reportType=DLOG
|
||||
* et produit un import exploitable dans Garradin
|
||||
*
|
||||
* Copyright (C) 2020 BohwaZ - licence AGPLv3
|
||||
*/
|
||||
|
||||
if (empty($argv[1]) || empty($argv[2])) {
|
||||
printf("Usage: %s FICHIER_PAYPAL_CSV FICHIER_SORTIE_CSV\n", $argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$path = $argv[1];
|
||||
$dest = $argv[2];
|
||||
|
||||
if (!is_readable($path)) {
|
||||
die("Ne peut lire le répertoire\n");
|
||||
}
|
||||
|
||||
$path = rtrim($path, '/');
|
||||
|
||||
$header = null;
|
||||
$sum_header = null;
|
||||
$out = [];
|
||||
$i = 0;
|
||||
|
||||
if (!is_file($path)) {
|
||||
die("Le fichier Paypal est invalide\n");
|
||||
}
|
||||
|
||||
// Lecture du CSV
|
||||
printf("Lecture de %s…" . PHP_EOL, $path);
|
||||
|
||||
/*
|
||||
Date
|
||||
Heure
|
||||
Fuseau horaire
|
||||
Nom
|
||||
Type
|
||||
État
|
||||
Devise
|
||||
Avant commission
|
||||
Commission
|
||||
Net
|
||||
De l'adresse email
|
||||
À l'adresse email
|
||||
Numéro de transaction
|
||||
Adresse de livraison
|
||||
État de l'adresse
|
||||
Titre de l'objet
|
||||
Numéro de l'objet
|
||||
Montant des frais d'expédition et de traitement
|
||||
Montant de l'assurance
|
||||
TVA
|
||||
Nom de l'option 1
|
||||
Valeur de l'option 1
|
||||
Nom de l'option 2
|
||||
Valeur de l'option 2
|
||||
Numéro de la transaction de référence
|
||||
Numéro de facture
|
||||
Numéro de client
|
||||
Quantité
|
||||
Numéro de reçu
|
||||
Solde
|
||||
Adresse
|
||||
Adresse (suite)/District/Quartier
|
||||
Ville
|
||||
État/Province/Région/Comté/Territoire/Préfecture/République
|
||||
Code postal
|
||||
Pays
|
||||
Numéro de téléphone du contact
|
||||
Objet
|
||||
Remarque
|
||||
Indicatif pays
|
||||
Impact sur le solde
|
||||
*/
|
||||
|
||||
$header = null;
|
||||
|
||||
$bom = "\xef\xbb\xbf";
|
||||
|
||||
// Read file from beginning.
|
||||
$fp = fopen($path, 'r');
|
||||
|
||||
// Progress file pointer and get first 3 characters to compare to the BOM string.
|
||||
if (fgets($fp, 4) !== $bom) {
|
||||
// BOM not found - rewind pointer to start of file.
|
||||
rewind($fp);
|
||||
}
|
||||
|
||||
$l = 0;
|
||||
|
||||
static $required = ['Date', 'Nom', 'Type', 'Commission', 'Net', 'Objet', 'Remarque', 'Numéro de transaction'];
|
||||
|
||||
while (!feof($fp)) {
|
||||
$l++;
|
||||
$row = fgetcsv($fp);
|
||||
|
||||
if (!$row) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (null === $header) {
|
||||
$header = $row;
|
||||
continue;
|
||||
}
|
||||
|
||||
$c = (object) array_combine($header, $row);
|
||||
|
||||
foreach ($required as $key) {
|
||||
if (!isset($c->$key)) {
|
||||
printf('Colonne "%s" manquante sur ligne %d' . PHP_EOL, $key, $l);
|
||||
continue(2);
|
||||
}
|
||||
}
|
||||
|
||||
$out[] = $c;
|
||||
}
|
||||
|
||||
fclose($fp);
|
||||
|
||||
// Création du CSV de sortie
|
||||
$fp = fopen($dest, 'w');
|
||||
|
||||
fputcsv($fp, ['Numéro d\'écriture', 'Date', 'Libellé', 'Compte de débit', 'Compte de crédit', 'Montant', 'Numéro pièce comptable', 'Référence paiement', 'Notes']);
|
||||
|
||||
static $notes_keys = ['Nom', 'Objet', 'Remarque'];
|
||||
|
||||
foreach ($out as $c) {
|
||||
$label = $c->Type;
|
||||
|
||||
if ($c->Nom) {
|
||||
$label = $c->Nom . ' - ' . $label;
|
||||
}
|
||||
|
||||
$notes = '';
|
||||
$ref = $c->{'Numéro de transaction'};
|
||||
|
||||
foreach ($notes_keys as $k) {
|
||||
if ($c->{$k}) {
|
||||
$notes .= $c->{$k} . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
$notes = trim($notes);
|
||||
|
||||
if ($c->Commission != '0,00') {
|
||||
$amount = preg_replace('/\s+/U', '', $c->Commission);
|
||||
fputcsv($fp, ['', $c->Date, 'Commission PayPal sur transaction', '', '', $amount, '', $ref, $notes]);
|
||||
}
|
||||
|
||||
$amount = preg_replace('/[\s ]+/U', '', $c->{'Avant commission'});
|
||||
fputcsv($fp, ['', $c->Date, $label, '', '', $amount, '', $ref, $notes]);
|
||||
}
|
||||
|
||||
fclose($fp);
|
||||
122
tools/factory/config.local.php
Normal file
122
tools/factory/config.local.php
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
<?php
|
||||
|
||||
namespace Paheko;
|
||||
|
||||
/**
|
||||
* Ce fichier permet de configurer Paheko pour une utilisation
|
||||
* avec plusieurs associations, mais une seule copie du code source.
|
||||
* (aussi appelé installation multi-sites, ferme ou usine)
|
||||
*
|
||||
* Voir la doc : https://fossil.kd2.org/paheko/wiki?name=Multi-sites
|
||||
*
|
||||
* N'oubliez pas d'installer également le script cron.sh fournit
|
||||
* pour lancer les rappels automatiques et sauvegardes.
|
||||
*
|
||||
* Si cela ne suffit pas à vos besoins, contactez-nous :
|
||||
* https://paheko.cloud/contact
|
||||
* pour une aide spécifique à votre installation.
|
||||
*/
|
||||
|
||||
// Décommenter cette ligne si vous n'utilisez pas NFS,
|
||||
// pour rendre les bases de données plus rapides.
|
||||
//
|
||||
// Si vous utilisez NFS, décommenter cette ligne risque
|
||||
// de provoquer des corruptions de base de données !
|
||||
#const SQLITE_JOURNAL_MODE = 'WAL';
|
||||
|
||||
// Nom de domaine parent des associations hébergées
|
||||
// Exemple : si vos associations sont hébergées en clubdetennis.paheko.cloud,
|
||||
// indiquer ici 'paheko.cloud'
|
||||
const FACTORY_DOMAIN = 'monsite.tld';
|
||||
|
||||
// Répertoire où seront stockées les données des utilisateurs
|
||||
// Dans ce répertoire, un sous-répertoire sera créé pour chaque compte
|
||||
// Ainsi 'clubdetennis.paheko.cloud' sera dans le répertoire courant (__DIR__),
|
||||
// sous-répertoire 'users' et dans celui-ci, sous-répertoire 'clubdetennis'
|
||||
//
|
||||
// Pour chaque utilisateur il faudra créer le sous-répertoire en premier lieu
|
||||
// (eg. mkdir .../users/clubdetennis)
|
||||
const FACTORY_USER_DIRECTORY = __DIR__ . '/users';
|
||||
|
||||
// Envoyer les erreurs PHP par mail à l'adresse de l'administrateur système
|
||||
// (mettre à null pour ne pas recevoir d'erreurs)
|
||||
const MAIL_ERRORS = 'administrateur@monsite.tld';
|
||||
|
||||
// IMPORTANT !
|
||||
// Modifier pour indiquer une valeur aléatoire de plus de 30 caractères
|
||||
const SECRET_KEY = 'Indiquer ici une valeur aléatoire !';
|
||||
|
||||
// Quota de stockage de documents (en octets)
|
||||
// Définit la taille de stockage disponible pour chaque association pour ses documents
|
||||
const FILE_STORAGE_QUOTA = 1 * 1024 * 1024 * 1024; // 1 Go
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Réglages conseillés, normalement il n'y a rien à modifier ici
|
||||
|
||||
// Indiquer que l'on va utiliser cron pour lancer les tâches à exécuter (envoi de rappels de cotisation)
|
||||
const USE_CRON = true;
|
||||
|
||||
// Cache partagé
|
||||
const SHARED_CACHE_ROOT = __DIR__ . '/cache/shared';
|
||||
|
||||
// Cache web partagé
|
||||
const WEB_CACHE_ROOT = __DIR__ . '/cache/web/%host%';
|
||||
|
||||
// Désactiver le log des erreurs PHP visible dans l'interface (sécurité)
|
||||
const ENABLE_TECH_DETAILS = false;
|
||||
|
||||
// Désactiver les mises à jour depuis l'interface web
|
||||
// Pour être sûr que seul l'admin sys puisse faire des mises à jour
|
||||
const ENABLE_UPGRADES = false;
|
||||
|
||||
// Ne pas afficher les erreurs de code PHP
|
||||
const SHOW_ERRORS = false;
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Code 'magique' qui va configurer Paheko selon les réglages
|
||||
|
||||
$login = null;
|
||||
|
||||
// Un sous-domaine ne peut pas faire plus de 63 caractères
|
||||
$login_regexp = '([a-z0-9_-]{1,63})';
|
||||
$domain_regexp = sprintf('/^%s\.%s$/', $login_regexp, preg_quote(FACTORY_DOMAIN, '/'));
|
||||
|
||||
if (isset($_SERVER['SERVER_NAME']) && preg_match($domain_regexp, $_SERVER['SERVER_NAME'], $match)) {
|
||||
$login = $match[1];
|
||||
}
|
||||
elseif (PHP_SAPI == 'cli' && !empty($_SERVER['PAHEKO_FACTORY_USER']) && preg_match('/^' . $login_regexp . '$/', $_SERVER['PAHEKO_FACTORY_USER'])) {
|
||||
$login = $_SERVER['PAHEKO_FACTORY_USER'];
|
||||
}
|
||||
else {
|
||||
// Login invalide ou non fourni
|
||||
http_response_code(404);
|
||||
die('<h1>Page non trouvée</h1>');
|
||||
}
|
||||
|
||||
$user_data_dir = rtrim(FACTORY_USER_DIRECTORY, '/') . '/' . $login;
|
||||
|
||||
if (!is_dir($user_data_dir)) {
|
||||
http_response_code(404);
|
||||
die("<h1>Cette association n'existe pas.</h1>");
|
||||
}
|
||||
|
||||
// Définir le dossier où sont stockés les données
|
||||
define('Paheko\DATA_ROOT', $user_data_dir);
|
||||
|
||||
// Définir l'URL
|
||||
define('Paheko\WWW_URL', 'https://' . $login . '.' . FACTORY_DOMAIN . '/');
|
||||
define('Paheko\WWW_URI', '/');
|
||||
|
||||
// Créer le lien symbolique vers le cache partagé des pages du site web
|
||||
$web_cache_public = __DIR__ . '/www/.cache';
|
||||
|
||||
if (!file_exists($web_cache_public)) {
|
||||
$web_cache_root = dirname(WEB_CACHE_ROOT);
|
||||
|
||||
if (!@symlink($web_cache_root, $web_cache_public)) {
|
||||
echo "<h2>Impossible de créer le lien symbolique pour le cache web partagé</h2>";
|
||||
echo "<p>Vous pouvez exécuter la commande suivante :</p>";
|
||||
printf("<pre>ln -s %s %s</pre>", $web_cache_root, $web_cache_public);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
14
tools/factory/factory_cron.sh
Executable file
14
tools/factory/factory_cron.sh
Executable file
|
|
@ -0,0 +1,14 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Répertoire où sont stockées les données des utilisateurs
|
||||
# veiller à ce que ce soit le même que dans config.local.php
|
||||
FACTORY_USER_DIRECTORY="users"
|
||||
|
||||
# Chemin vers le script cron.php de Paheko
|
||||
PAHEKO_CRON_SCRIPT="scripts/cron.php"
|
||||
|
||||
for user in $(cd ${FACTORY_USER_DIRECTORY} && ls -1d */)
|
||||
do
|
||||
PAHEKO_FACTORY_USER=$(basename "$user") php $PAHEKO_CRON_SCRIPT
|
||||
echo $PAHEKO_FACTORY_USER
|
||||
done
|
||||
14
tools/factory/factory_cron_emails.sh
Normal file
14
tools/factory/factory_cron_emails.sh
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Répertoire où sont stockées les données des utilisateurs
|
||||
# veiller à ce que ce soit le même que dans config.local.php
|
||||
FACTORY_USER_DIRECTORY="users"
|
||||
|
||||
# Chemin vers le script emails.php de Paheko
|
||||
PAHEKO_CRON_SCRIPT="scripts/emails.php"
|
||||
|
||||
for user in $(cd ${FACTORY_USER_DIRECTORY} && ls -1d */)
|
||||
do
|
||||
PAHEKO_FACTORY_USER=$(basename "$user") php $PAHEKO_CRON_SCRIPT
|
||||
echo $PAHEKO_FACTORY_USER
|
||||
done
|
||||
14
tools/factory/factory_upgrade.sh
Normal file
14
tools/factory/factory_upgrade.sh
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Répertoire où sont stockées les données des utilisateurs
|
||||
# veiller à ce que ce soit le même que dans config.local.php
|
||||
FACTORY_USER_DIRECTORY="users"
|
||||
|
||||
# Chemin vers le script upgrade.php de Paheko
|
||||
PAHEKO_UPGRADE_SCRIPT="scripts/cron.php"
|
||||
|
||||
for user in $(cd ${FACTORY_USER_DIRECTORY} && ls -1d */)
|
||||
do
|
||||
PAHEKO_FACTORY_USER=$(basename "$user")
|
||||
php $PAHEKO_UPGRADE_SCRIPT
|
||||
done
|
||||
74
tools/fossil-verify.sh
Executable file
74
tools/fossil-verify.sh
Executable file
|
|
@ -0,0 +1,74 @@
|
|||
#!/bin/bash
|
||||
|
||||
REPO="$1"
|
||||
|
||||
if [ ! -f "$1/manifest" ]
|
||||
then
|
||||
echo "Missing manifest, maybe you didn't specify a repository path,"
|
||||
echo "or you didn't enable the manifest? (fossil settings manifest on)"
|
||||
echo "Usage: $0 FOSSIL_REPOSITORY_PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
gpg --verify "$1/manifest" 2> /dev/null
|
||||
|
||||
if [ $? != 0 ]
|
||||
then
|
||||
echo "Manifest signature failed to verify"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
TMPFILE=$(mktemp)
|
||||
|
||||
while IFS= read -r LINE
|
||||
do
|
||||
if [ "${LINE:0:2}" != "F " ]
|
||||
then
|
||||
echo "$LINE" >> $TMPFILE
|
||||
continue
|
||||
fi
|
||||
|
||||
# Split string by spaces
|
||||
PARTS=($LINE)
|
||||
|
||||
FILE_ENCODED="${PARTS[1]}"
|
||||
FILE="${PARTS[1]//\\s/ }"
|
||||
HASH="${PARTS[2]}"
|
||||
|
||||
if [ "${#HASH}" = 40 ]
|
||||
then
|
||||
NEW_HASH=$(sha1sum "$1/$FILE" | awk '{print $1}')
|
||||
else
|
||||
NEW_HASH=$(openssl dgst -sha3-256 -binary "$1/$FILE" | xxd -p -c 100)
|
||||
fi
|
||||
|
||||
if [ "$HASH" != "$NEW_HASH" ]
|
||||
then
|
||||
echo "Local file has changed"
|
||||
echo "$FILE"
|
||||
echo "Manifest hash: $HASH"
|
||||
echo "Local file hash: $NEW_HASH"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
PARTS[2]="$HASH"
|
||||
|
||||
# join parts in a new string
|
||||
NEW_LINE="$(printf " %s" "${PARTS[@]}")"
|
||||
NEW_LINE="${NEW_LINE:1}"
|
||||
|
||||
echo "$NEW_LINE" >> $TMPFILE
|
||||
done < "$1/manifest"
|
||||
|
||||
gpg --verify $TMPFILE 2>/dev/null
|
||||
|
||||
if [ $? != 0 ]
|
||||
then
|
||||
echo "Something has changed between manifest and check?!"
|
||||
diff "$1/manifest" $TMPFILE
|
||||
rm -f $TMPFILE
|
||||
exit 2
|
||||
fi
|
||||
|
||||
rm -f $TMPFILE
|
||||
exit 0
|
||||
191
tools/make_installer.php
Normal file
191
tools/make_installer.php
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
<?php
|
||||
|
||||
$includes = [
|
||||
'##KD2' => [
|
||||
__DIR__ . '/../src/include/lib/KD2/Security.php',
|
||||
__DIR__ . '/../src/include/lib/KD2/HTTP.php',
|
||||
__DIR__ . '/../src/include/lib/KD2/FossilInstaller.php',
|
||||
],
|
||||
];
|
||||
|
||||
$template = <<<'EOF'
|
||||
<?php
|
||||
|
||||
// Copier ce fichier dans un nouveau répertoire vide
|
||||
// Et s'y rendre avec un navigateur web :-)
|
||||
|
||||
|
||||
namespace KD2 {
|
||||
##KD2
|
||||
}
|
||||
|
||||
namespace {
|
||||
const WEBSITE = 'https://fossil.kd2.org/paheko/';
|
||||
const INSTALL_DIR = __DIR__ . '/.install';
|
||||
|
||||
echo '
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<style type="text/css">
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
h2, p {
|
||||
margin: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
div {
|
||||
position: relative;
|
||||
border: 1px solid #999;
|
||||
max-width: 500px;
|
||||
padding: 1em;
|
||||
border-radius: .5em;
|
||||
}
|
||||
.spinner h2::after {
|
||||
display: block;
|
||||
content: " ";
|
||||
margin: 1rem auto;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border: 5px solid #000;
|
||||
border-radius: 50%;
|
||||
border-top-color: #999;
|
||||
animation: spin 1s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes spin { to { transform: rotate(360deg); } }
|
||||
</style>';
|
||||
|
||||
function exception_error_handler($severity, $message, $file, $line) {
|
||||
if (!(error_reporting() & $severity)) {
|
||||
return;
|
||||
}
|
||||
throw new ErrorException($message, 0, $severity, $file, $line);
|
||||
}
|
||||
|
||||
function mini_exception_handler($e) {
|
||||
printf('
|
||||
<div style="padding: 1rem;
|
||||
background: #fee;
|
||||
border: 2px solid darkred;"><h2>%s</h2>
|
||||
<h3>in %s:%d</h3>
|
||||
<pre>%s</pre>
|
||||
</div>',
|
||||
$e->getMessage(), $e->getFile(), $e->getLine(), (string) $e);
|
||||
}
|
||||
|
||||
set_error_handler("exception_error_handler");
|
||||
|
||||
set_exception_handler('mini_exception_handler');
|
||||
|
||||
if (!version_compare(phpversion(), '7.4', '>=')) {
|
||||
throw new \Exception('PHP 7.4 ou supérieur requis. PHP version ' . phpversion() . ' installée.');
|
||||
}
|
||||
|
||||
if (!class_exists('SQLite3')) {
|
||||
throw new \Exception('Le module de base de données SQLite3 n\'est pas disponible.');
|
||||
}
|
||||
|
||||
$v = \SQLite3::version();
|
||||
|
||||
if (!version_compare($v['versionString'], '3.16', '>=')) {
|
||||
throw new \Exception('SQLite3 version 3.16 ou supérieur requise. Version installée : ' . $v['versionString']);
|
||||
}
|
||||
|
||||
$step = $_GET['step'] ?? null;
|
||||
$error = null;
|
||||
|
||||
@mkdir(INSTALL_DIR);
|
||||
$i = new KD2\FossilInstaller(WEBSITE, __DIR__, INSTALL_DIR, '!^paheko-(.*)\.tar\.gz$!');
|
||||
|
||||
if ($step == 'download') {
|
||||
$latest = $i->latest();
|
||||
|
||||
if (!$latest) {
|
||||
die('</head><h1>Aucune version à télécharger n\'a été trouvée.</h1>');
|
||||
}
|
||||
|
||||
$i->download($latest);
|
||||
$next = 'install';
|
||||
}
|
||||
elseif ($step == 'install') {
|
||||
$latest = $i->latest();
|
||||
|
||||
if (!$latest) {
|
||||
die('</head><h1>Aucune version à télécharger n\'a été trouvée.</h1>');
|
||||
}
|
||||
|
||||
$i->install($latest);
|
||||
$i->clean($latest);
|
||||
|
||||
if (class_exists('\OCP\AppFramework\Controller')) {
|
||||
$next = 'nc' . time();
|
||||
}
|
||||
else {
|
||||
$next = null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$next = 'download';
|
||||
}
|
||||
|
||||
echo $next ? '<meta http-equiv="refresh" content="0;url=?step='.$next.'" />' : '';
|
||||
|
||||
echo '
|
||||
</head>';
|
||||
|
||||
if ($step == 'download') {
|
||||
echo '
|
||||
<div class="spinner">
|
||||
<h2>Décompression en cours…</h2>
|
||||
</div>';
|
||||
}
|
||||
elseif ($step == 'install') {
|
||||
echo '<div>
|
||||
<h2>Installation réussie</h2>
|
||||
<p>Configurez désormais votre sous-domaine pour pointer sur le sous-répertoire <strong>www</strong> de cette installation.</p>
|
||||
<p><a href="' . WEBSITE . '">Consultez la documentation pour plus d\'infos</a></p>
|
||||
</div>';
|
||||
}
|
||||
else {
|
||||
echo '
|
||||
<div class="spinner">
|
||||
<h2>Téléchargement en cours…</h2>
|
||||
</div>';
|
||||
}
|
||||
|
||||
echo '
|
||||
</body>
|
||||
</html>
|
||||
';
|
||||
|
||||
if ($step == 'install') {
|
||||
$i->prune(0);
|
||||
@rmdir(INSTALL_DIR);
|
||||
@unlink(__FILE__);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
EOF;
|
||||
|
||||
foreach ($includes as $tag => $files) {
|
||||
$source = [];
|
||||
|
||||
foreach ($files as $file) {
|
||||
$content = file_get_contents($file);
|
||||
$content = preg_replace('!^(?:<\?php|namespace |use ).*$!m', '', $content);
|
||||
$content = preg_replace("!^!m", "\t$0", $content);
|
||||
$content = preg_replace("!^\t$!m", '', $content);
|
||||
$content = trim($content);
|
||||
$source[] = $content;
|
||||
}
|
||||
|
||||
$source = implode("\n\n", $source);
|
||||
|
||||
$template = str_replace($tag, $source, $template);
|
||||
}
|
||||
|
||||
echo $template;
|
||||
98
tools/plugin_check_0.8.php
Normal file
98
tools/plugin_check_0.8.php
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
<?php
|
||||
|
||||
if (empty($argv[1]))
|
||||
{
|
||||
echo sprintf('Usage: %s PLUGIN_DIRECTORY' . PHP_EOL, $argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
assert_options(ASSERT_ACTIVE, true);
|
||||
assert_options(ASSERT_BAIL, true);
|
||||
|
||||
$dir = rtrim($argv[1], '/\\') . DIRECTORY_SEPARATOR;
|
||||
|
||||
assert(is_readable($dir), 'Le répertoire du plugin n\'est pas lisible');
|
||||
assert(is_dir($dir), sprintf('%s n\'est pas un répertoire', $dir));
|
||||
assert(file_exists($dir . 'garradin_plugin.ini'), sprintf('%s n\'est pas un répertoire de plugin Garradin', $dir));
|
||||
|
||||
$dir_iterator = new RecursiveDirectoryIterator(substr($dir, 0, -1), FilesystemIterator::SKIP_DOTS);
|
||||
$iterator = new RecursiveIteratorIterator($dir_iterator, RecursiveIteratorIterator::SELF_FIRST);
|
||||
https://fossil.kd2.org/garradin-plugins/timeline
|
||||
$base = realpath($dir);
|
||||
|
||||
foreach ($iterator as $file)
|
||||
{
|
||||
if ($file->isDir())
|
||||
{
|
||||
// Skip directories
|
||||
continue;
|
||||
}
|
||||
|
||||
$source = str_replace($base, '', $file->getRealPath());
|
||||
|
||||
if ($file->getExtension() == 'php')
|
||||
{
|
||||
check_php($file->getRealPath(), $source);
|
||||
}
|
||||
elseif ($file->getExtension() == 'tpl')
|
||||
{
|
||||
check_smarty($file->getRealPath(), $source);
|
||||
}
|
||||
}
|
||||
|
||||
function check_php($file, $source)
|
||||
{
|
||||
static $deprecated_php_functions = [
|
||||
'->simpleQuerySingle',
|
||||
'->queryFetchAssocKey',
|
||||
'->queryFetchAssoc',
|
||||
'->queryFetch',
|
||||
'->simpleStatementFetchAssocKey',
|
||||
'->simpleStatementFetchAssoc',
|
||||
'->simpleStatementFetch',
|
||||
'->simpleStatement',
|
||||
'->escapeString',
|
||||
'->simpleExec',
|
||||
'->simpleUpdate',
|
||||
'->simpleInsert',
|
||||
'utils::get(',
|
||||
'utils::post(',
|
||||
'utils::CRSF',
|
||||
];
|
||||
|
||||
$content = file_get_contents($file);
|
||||
|
||||
foreach ($deprecated_php_functions as $func)
|
||||
{
|
||||
if (stripos($content, $func) !== false)
|
||||
{
|
||||
fputs(STDERR, sprintf('ERROR: %s: la fonction %s a été supprimée de Garradin.', $source, $func) . PHP_EOL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function check_smarty($file, $source)
|
||||
{
|
||||
$content = file_get_contents($file);
|
||||
|
||||
if (preg_match('/\{.*`.*\}/sU', $content))
|
||||
{
|
||||
fputs(STDERR, sprintf('ERROR: %s: la syntaxe `$variable` est invalide dans Smartyer, utiliser le modifieur |args:$variable', $source) . PHP_EOL);
|
||||
}
|
||||
|
||||
if (preg_match('/\{\s*(section|php|switch|insert|capture)/', $content, $match))
|
||||
{
|
||||
fputs(STDERR, sprintf('ERROR: %s: le bloc "%s" est absent dans Smartyer', $source, $match[1]) . PHP_EOL);
|
||||
}
|
||||
|
||||
if (preg_match('/(\$smarty\.|\$tpl\.|\$templatelite\.)/', $content, $match))
|
||||
{
|
||||
fputs(STDERR, sprintf('ERROR: %s: les variables "%s" sont absentes dans Smartyer', $source, $match[1]) . PHP_EOL);
|
||||
}
|
||||
|
||||
if (preg_match('/\{.*\|escape/sU', $content))
|
||||
{
|
||||
fputs(STDERR, sprintf('SUGGESTION: %s: le modifieur |escape n\'est plus nécessaire (escaping automatique)', $source) . PHP_EOL);
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue