Compare commits

...

3 Commits

14 changed files with 214 additions and 58 deletions

View File

@ -89,6 +89,7 @@ $form->runIf(f('save') && !$form->hasErrors(),
'reglee' => f('reglee') == 1?1:0,
'archivee' => f('archivee') == 1?1:0,
'moyen_paiement' => f('moyen_paiement'),
'nom_contact' => f('nom_contact'),
'toto' => 0
];
$data['type_facture'] = f('type');
@ -113,8 +114,12 @@ $form->runIf(f('save') && !$form->hasErrors(),
unset($data['toto']);
if (! isset($data['contenu'])) {
throw new UserException("Aucune désignation ni aucun prix saisi !!");
}
}
}
if (f('type') == FACT) {
$data['numero_commande'] = f('numero_commande');
$data['reference_acheteur'] = f('reference_acheteur');
}
}
elseif ( f('type') == CERFA )
{
$data['moyen_paiement'] = f('moyen_paiement_cerfa');
@ -276,6 +281,9 @@ else
$doc['date_emission'] = f('date_emission') ?: $f->date_emission;
$doc['date_echeance'] = f('date_echeance')?: $f->date_echeance; // Smarty m'a saoulé pour utiliser form_field|date_fr:---
$doc['nom_contact'] = $f->nom_contact;
$doc['numero_commande'] = $f->numero_commande;
$doc['reference_acheteur'] = $f->reference_acheteur;
/* modif DD -- CERFA -------------------------------------- */
if ( $f->type_facture == CERFA ) {
$doc['total'] = $f->total;
@ -336,6 +344,7 @@ $tpl->assign('date', $date->format('d/m/Y'));
$tpl->assign(compact('liste', 'radio', 'step', 'designations', 'prix', 'from_user', 'identite', 'csrf_key', 'doc'));
$tpl->assign('users', toArray($db->get('SELECT id, '.$identite.' FROM users WHERE id_category != -2 NOT IN (SELECT id FROM users_categories WHERE hidden = 1) ORDER BY ' .$identite. ';'), 'id', " "));
$tpl->assign('clients', $db->getAssoc('SELECT id, nom FROM plugin_facturation_clients;'));
$tpl->assign('contacts', $db->getAssoc('SELECT id, nom_contact FROM plugin_facturation_clients;'));
$tpl->assign('require_number', $require_number);
$tpl->assign('number_pattern', PATTERNS_LIST[$plugin->getConfig('pattern')]);

View File

@ -17,27 +17,29 @@ if (!$c)
}
$form->runIf(f('save') && !$form->hasErrors(),
function () use ($client, $id, $form)
{
try
{
$r = $client->edit($id,[
'nom' => f('nom'),
'adresse' => f('adresse'),
'code_postal' => f('code_postal'),
'ville' => f('ville'),
'siret' => f('siret'),
'telephone' => f('telephone'),
'email' => f('email')
]);
function () use ($client, $id, $form)
{
try
{
$r = $client->edit($id,[
'nom' => f('nom'),
'adresse' => f('adresse'),
'code_postal' => f('code_postal'),
'ville' => f('ville'),
'siret' => f('siret'),
'telephone' => f('telephone'),
'email' => f('email'),
'nom_contact' => f('nom_contact'),
'note' => f('note')
]);
$r ? Utils::redirect(PLUGIN_ADMIN_URL . 'client.php?id='.(int)$id):'';
}
catch (UserException $e)
{
$form->addError($e->getMessage());
}
}, 'edit_client');
$r ? Utils::redirect(PLUGIN_ADMIN_URL . 'client.php?id='.(int)$id):'';
}
catch (UserException $e)
{
$form->addError($e->getMessage());
}
}, 'edit_client');
$tpl->assign('client', $c);

View File

@ -18,7 +18,9 @@ $form->runIf(f('add') && !$form->hasErrors(),
'ville' => f('ville'),
'siret' => f('siret'),
'telephone' => f('telephone'),
'email' => f('email')
'email' => f('email'),
'nom_contact' => f('nom_contact'),
'note' => f('note')
]);
$id ? Utils::redirect(PLUGIN_ADMIN_URL . 'client.php?id='.(int)$id):'';

View File

@ -128,12 +128,17 @@ if ($f->type_facture != CERFA)
$receveur =
$txtdest.'<br>'.
'<b>'.$nom_client.'</b><br>'.
(($t = $f->nom_contact)?"Contact : $t<br>":'').
$c->adresse."<br>".
$c->code_postal.' '.$c->ville."<br>".
(($t = $c->siret)?"SIREN/SIRET : " . implode(' ', str_split($t, 3)) . "<br>":'').
(($t = $c->email)?"Email : $t<br>":'').
(($t = $c->telephone)?"Tel : $t<br>":'');
if ($f->type_facture == FACT) {
$receveur .=
(($t = $f->numero_commande)?"Commande N° : $t<br>":'').
(($t = $f->reference_acheteur)?"Référence : $t<br>":'');
}
$total = Utils::money_format($f->total, ',', ' ');
// Devis et facture
@ -203,11 +208,11 @@ EOF;
</footer>
EOF;
if ($f->type_facture == DEVIS) {
echo <<<EOF
if ($f->type_facture == DEVIS) {
echo <<<EOF
<p><b>Bon pour accord, date et signature<b></p>
EOF;
}
}
$content = ob_get_clean();

View File

@ -10,7 +10,10 @@ CREATE TABLE IF NOT EXISTS plugin_facturation_factures (
archivee INTEGER DEFAULT 0, -- bool
moyen_paiement TEXT NOT NULL,
contenu TEXT NOT NULL,
total INTEGER DEFAULT 0
total INTEGER DEFAULT 0,
nom_contact TEXT,
numero_commande TEXT,
reference_acheteur TEXT
-- FOREIGN KEY(moyen_paiement) REFERENCES compta_moyens_paiement(code)
);
@ -24,7 +27,9 @@ CREATE TABLE IF NOT EXISTS plugin_facturation_clients (
siret TEXT,
date_creation TEXT NOT NULL DEFAULT CURRENT_DATE CHECK (date(date_creation) IS NOT NULL AND date(date_creation) = date_creation), -- Date d\'inscription
telephone TEXT,
email TEXT
email TEXT,
nom_contact TEXT,
note TEXT
);

View File

@ -17,7 +17,9 @@ class Client
'ville',
'siret',
'telephone',
'email'
'email',
'nom_contact',
'note'
];
private $config = [
@ -40,7 +42,7 @@ class Client
{
$data[$key] = trim($data[$key]);
if($data[$key] == '' && ($key != 'siret' && $key != 'telephone' && $key != 'email'))
if($data[$key] == '' && ! in_array($key, ['siret', 'telephone', 'email', 'nom_contact', 'note']))
{
throw new UserException('Le champs '.$key.' doit être renseigné.');
}
@ -136,6 +138,12 @@ class Client
'email' => [
'label' => 'E-Mail',
],
'nom_contact' => [
'label' => 'Contact',
],
'note' => [
'label' => 'Note',
],
'nb_documents' => [
'label' => 'Nombre de documents',
'select' => '(SELECT COUNT(*) FROM plugin_facturation_factures WHERE receveur_id = c.id)',

View File

@ -30,7 +30,10 @@ class Facture
'archivee',
'moyen_paiement',
'contenu',
'total'
'total',
'nom_contact',
'numero_commande',
'reference_acheteur'
];
public $types = [
@ -65,7 +68,7 @@ class Facture
if(!is_array($data) && null !== $data){
$datas[$k] = trim($data);
}
if ($datas[$k] === '' && $k != 'numero')
if ($datas[$k] === '' && ! in_array($k, ['numero', 'nom_contact', 'numero_commande', 'reference_acheteur']))
{
throw new UserException("La valeur de $k est vide");
}

View File

@ -1,8 +1,8 @@
name="Facturation"
description="Permet d'éditer des factures, devis et reçus à ses membres ainsi qu'à une base de clients supplémentaire."
description="Permet d'éditer des factures et devis à ses membres ainsi qu'à une base de clients supplémentaire."
author="zou ; adapté par jce"
url="https://git.roflcopter.fr/lesanges/paheko-plugin-facturation"
version="0.12"
version="0.15"
menu=true
restrict_section="accounting"
restrict_level="read"

View File

@ -30,7 +30,7 @@
<dd class="help">
{if $require_number}
Chaque document doit comporter un numéro unique délivré chronologiquement et de façon continue. Il faut que le système adopté par l'association garantisse que deux factures émises la même année ne peuvent pas porter le même numéro.
Chaque document doit comporter un numéro unique délivré chronologiquement et de façon continue. Il faut que le système adopté par l'association garantisse que deux factures émises la même année ne puissent pas porter le même numéro.
{else}
Laisser vide pour qu'un numéro soit automatiquement affecté au format <code>{$number_pattern}</code>.
{/if}
@ -57,7 +57,7 @@
</fieldset>
<fieldset data-types="t0 t1 t2">
<legend>Client</legend>
<legend>Destinataire</legend>
<dl>
<dt><label>Document adressé à :</label></dt>
@ -70,18 +70,30 @@
</dl>
<dl class="type_membre">
{input type="select" name="membre" label="Membre" options=$users required=1 source=$doc}
{input type="select" name="membre" label="Membre" options=$users required=1 source=$doc default_empty="— Choisir un membre —"}
</dl>
{if !empty($clients)}
<dl class="type_client">
{input type="select" name="client" label="Client" options=$clients required=1 class="type_client" source=$doc}
{input type="select" name="client" label="Client" options=$clients required=1 class="type_client" source=$doc default_empty="— Choisir un client —"}
</dl>
{else}
<input type="hidden" name="base_receveur" value="membre" />
{/if}
</fieldset>
<fieldset data-types="t0 t1">
<legend>Autres informations</legend>
{input type="text" name="nom_contact" label="Nom du contact" source=$doc}
<div class="hidden">
{input type="select" name="contact_list" options=$contacts}
</div>
<div data-types="t1">
{input type="text" name="numero_commande" label="Numéro de commande" source=$doc}
{input type="text" name="reference_acheteur" label="Référence acheteur" source=$doc}
</div>
</fieldset>
<fieldset data-types="t0 t1">
<legend>Contenu</legend>

View File

@ -51,6 +51,18 @@
}
}
function modifierContact(client, idlist, idcontact)
{
let contactlist = document.querySelector(idlist);
let options = contactlist.querySelectorAll('option');
for (i=0; i < options.length; ++i) {
if (options[i].value == client.value) {
break;
}
}
document.querySelector(idcontact).value = options[i].textContent;
}
const form = document.querySelector('#f_numero_facture').form;
changeTypeSaisie(form.base_receveur.value);
@ -63,6 +75,11 @@
};
}
const selclient = document.querySelector('#f_client');
selclient.addEventListener("change", () => {
modifierContact(selclient, '#f_contact_list', '#f_nom_contact');
});
} ());

View File

@ -48,6 +48,24 @@
{/if}
</dd>
<dt>Nom du contact</dt>
<dd>
{if empty($client.nom_contact)}
<em>(Non renseigné)</em>
{else}
{$client.nom_contact}
{/if}
</dd>
<dt>Note</dt>
<dd>
{if empty($client.note)}
<em>(Non renseigné)</em>
{else}
{$client.note}
{/if}
</dd>
<dt>Date d'ajout</dt>
<dd>{$client.date_creation|date:'d/m/Y'}</dd>

View File

@ -14,6 +14,8 @@
{input type="text" name="siret" label="SIREN/SIRET" source=$client}
{input type="tel" name="telephone" label="Téléphone" source=$client}
{input type="email" name="email" label="Adresse e-mail" source=$client}
{input type="text" name="nom_contact" label="Nom du contact" source=$client}
{input type="textarea" cols="60" rows="3" name="note" label="Note" source=$client}
</dl>
</fieldset>

View File

@ -61,6 +61,8 @@
{input type="text" name="siret" label="SIREN/SIRET"}
{input type="tel" name="telephone" label="Téléphone"}
{input type="email" name="email" label="Adresse e-mail"}
{input type="text" name="nom_contact" label="Nom contact"}
{input type="textarea" cols="60" rows="3" name="note" label="Note"}
</dl>
</fieldset>

View File

@ -6,7 +6,7 @@ use Paheko\Entities\Files\File;
$db = DB::getInstance();
$old_version = $plugin->oldVersion();
error_log("upgrade::version = " . $old_version);
error_log("upgrade:: à partir de la version = " . $old_version);
// 0.2.0 - Stock le contenu en json plutôt qu'en serialized
if (version_compare($old_version, '0.2.0', '<'))
@ -74,7 +74,7 @@ if (version_compare($old_version, '0.4.0', '<'))
ALTER TABLE plugin_facturation_factures_tmp RENAME TO plugin_facturation_factures;
EOT
);
);
}
@ -111,7 +111,7 @@ if (version_compare($old_version, '0.6.0', '<'))
DROP TABLE plugin_facturation_factures;
ALTER TABLE plugin_facturation_factures_tmp RENAME TO plugin_facturation_factures;
EOT
);
);
$factures = $facture->listAll();
foreach($factures as $k=>$f)
@ -119,13 +119,13 @@ EOT
foreach($f->contenu as $line => $content)
{
// Petit bug qui peut arriver avec des contenus mal enregistrés en db
if (is_int($content))
{
continue;
}
if (is_int($content))
{
continue;
}
$contenu[] = ['designation' => $content['designation'],
'prix' => (int) ($content['prix'] * 100) ];
'prix' => (int) ($content['prix'] * 100) ];
}
$f->contenu = $contenu;
@ -251,3 +251,74 @@ if (version_compare($old_version, '0.12', '<'))
EOT
);
}
// version 0.15
// Ajout champs note et contact à la table clients
// Ajout divers champs à la table factures
if (version_compare($old_version, '0.15', '<'))
{
$db->exec(<<<EOT
CREATE TABLE IF NOT EXISTS plugin_facturation_clients_tmp
(
id INTEGER PRIMARY KEY,
nom TEXT NOT NULL,
adresse TEXT NOT NULL,
code_postal TEXT NOT NULL,
ville TEXT NOT NULL,
siret TEXT,
date_creation TEXT NOT NULL DEFAULT CURRENT_DATE CHECK (date(date_creation) IS NOT NULL AND date(date_creation) = date_creation),
telephone TEXT,
email TEXT,
nom_contact TEXT,
note TEXT
);
EOT
);
// copier les clients dans la table temporaire
$sql = 'SELECT * FROM plugin_facturation_clients';
foreach ($db->iterate($sql) as $client)
{
$db->insert('plugin_facturation_clients_tmp', $client);
}
// remplacer l'ancienne table par la nouvelle
$db->exec(<<<EOT
DROP TABLE plugin_facturation_clients;
ALTER TABLE plugin_facturation_clients_tmp RENAME TO plugin_facturation_clients;
EOT
);
$db->exec(<<<EOT
CREATE TABLE IF NOT EXISTS plugin_facturation_factures_tmp(
id INTEGER PRIMARY KEY,
type_facture INTEGER NOT NULL DEFAULT 0,
numero TEXT NOT NULL UNIQUE,
receveur_membre INTEGER NOT NULL, -- bool
receveur_id INTEGER NOT NULL,
date_emission TEXT NOT NULL, -- CHECK (date(date_emission) IS NOT NULL AND date(date_emission) = date_emission),
date_echeance TEXT NOT NULL, -- CHECK (date(date_echeance) IS NOT NULL AND date(date_echeance) = date_echeance),
reglee INTEGER DEFAULT 0, -- bool
archivee INTEGER DEFAULT 0, -- bool
moyen_paiement TEXT NOT NULL,
contenu TEXT NOT NULL,
total INTEGER DEFAULT 0,
nom_contact TEXT,
numero_commande TEXT,
reference_acheteur TEXT
);
EOT
);
// copier les factures dans la table temporaire
$sql = 'SELECT * FROM plugin_facturation_factures';
foreach ($db->iterate($sql) as $facture)
{
$db->insert('plugin_facturation_factures_tmp', $facture);
}
// remplacer l'ancienne table par la nouvelle
$db->exec(<<<EOT
DROP TABLE plugin_facturation_factures;
ALTER TABLE plugin_facturation_factures_tmp RENAME TO plugin_facturation_factures;
EOT
);
}