Revize 851
Přidáno uživatelem Jiří Sviták před více než 13 roky(ů)
freenetis/trunk/kohana/license.txt | ||
---|---|---|
|
||
Freenetis - open source information system for managing community
|
||
based networks. It provides features like payment management, user
|
||
and device management, services management etc.
|
||
Copyright (C) 2008-2011 Tomas Dulik, Michal Kliment, Jiri Svitak,
|
||
Roman Sevcik, Ondrej Fibich, Petr Danek, Marek Rozehnal
|
||
|
||
This program is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU 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 General Public License for more details.
|
||
|
||
You should have received a copy of the GNU General Public License
|
||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
freenetis/trunk/kohana/application/i18n/cs_CZ/texts.php | ||
---|---|---|
'after you\'ve done that, you can continue' => 'Poté, co tak učiníte, můžete pokračovat.',
|
||
'agree' => 'Souhlas',
|
||
'all' => 'Všichni',
|
||
'all accounts now have correct balances, %d accounts had incorrect balances' => 'Všechny účty teď mají správné zůstatky, %d účtů mělo chybné zůstatky.',
|
||
'all ip addresses of member' => 'všem IP adresám člena',
|
||
'all redirected' => 'Všichni přesměrovaní',
|
||
'all transfers' => 'Všechny převody',
|
||
... | ... | |
'back to all subnets' => 'Zpět na seznam podsítí',
|
||
'back to bank account' => 'Zpět na bankovní účet',
|
||
'back to bank accounts' => 'Zpět na bankovní účty',
|
||
'back to bank statement' => 'Zpět na bankovní výpis',
|
||
'back to bank statements' => 'Zpět na bankovní výpisy',
|
||
'back to bank templates' => 'Zpět na bankovní šablony',
|
||
'back to day book' => 'Zpět na účetní deník',
|
||
... | ... | |
'bad variable symbol format' => 'Špatný formát variabilního symbolu.',
|
||
'bad voip number interval format' => 'Špatný formát VoIP čísel',
|
||
'balance' => 'Stav',
|
||
'balance to year' => 'Zůstatek k roku',
|
||
'balance from date' => 'Zůstatek od data',
|
||
'balance to date' => 'Zůstatek do data',
|
||
'bank account' => 'Bankovní účet',
|
||
'bank account id' => 'ID bankovního účtu',
|
||
'bank account name' => 'Název bankovního účtu',
|
||
... | ... | |
'bank info' => 'Údaje platby',
|
||
'bank interest' => 'Bankovní úrok',
|
||
'bank interests' => 'Bankovní úroky',
|
||
'bank statement contains items that were already imported' => 'Bankovní výpis obsahuje položky, které již byly importovány.',
|
||
'bank statement has been successfully deleted' => 'Bankovní výpis byl úspěšně smazán.',
|
||
'bank statement has been successfully updated' => 'Bankovní výpis byl úspěšně upraven.',
|
||
'bank statements' => 'Bankovní výpisy',
|
||
... | ... | |
'entrance date' => 'Datum vstupu',
|
||
'entrance_date' => 'Datum vstupu',
|
||
'entrance fee' => 'Vstupní příspěvek',
|
||
'entrance fee has been successfully deducted' => 'Vstupní příspěvek byl úspěšně stržen.',
|
||
'entrance fee have to be a number' => 'Vstupní příspěvk musí být číslo',
|
||
'entrance fees have been successfully deducted' => 'Vstupní příspěvky byly úspěšně strženy.',
|
||
'entrance fees have been successfully deducted, %d new transfers created' => 'Vstupní příspěvky byly úspěšně strženy, vytvořeno %d nových převodů.',
|
||
'entrance fees have been successfully recalculated, %d transfers deleted, %d new transfers created' => 'Vstupní příspěvek byl úspěšně stržen, smazáno %d převodů, vytvořeno %d nových převodů.',
|
||
'enum type has been successfully added' => 'Výčet byl úspěšně přidán',
|
||
'enum type has been successfully deleted' => 'Výčet byl úspěšně smazán',
|
||
'enum type has been successfully updated' => 'Výčet byl úspěšně aktualizován',
|
||
... | ... | |
'error - wrong arguments' => 'Chyba - špatné argumenty',
|
||
'error - wrong data' => 'Chyba - špatná data',
|
||
'error - amount has to be positive' => 'Chyba - částka musí být kladná.',
|
||
'error - cannot add bank transfer' => 'Chyba - nelze přidat bankovní převod.',
|
||
'error - cannot add message' => 'Chyba - nelze přidat zprávu.',
|
||
'error - cannot assign transfer' => 'Chyba - nelze přiřadit převod.',
|
||
'error - cannot complete registration' => 'Chyba - Nelze dokončit registraci',
|
||
'error - cannot delete bank statement' => 'Chyba - nelze smazat bankovní výpis.',
|
||
'error - cannot load intelligent selection' => 'Chyba - nelze načíst inteligentní výběr',
|
||
... | ... | |
'execution time' => 'Doba provádění',
|
||
'executive counsil' => 'Správní rada',
|
||
'expenditure-earning' => 'Výdej-Příjem',
|
||
'expenses' => 'Výdaje',
|
||
'export of registration' => 'Export přihlášky',
|
||
'export to xls' => 'Exportovat do XLS',
|
||
'export to csv (utf-8)' => 'Exportovat do CSV (utf-8)',
|
||
... | ... | |
'fee or penalty comment' => 'Komentář k poplatku/pokutě',
|
||
'fee type' => 'Typ poplatku',
|
||
'fees' => 'Poplatky',
|
||
'fees have been successfully deducted' => 'Členské příspěvky byly úspěšně strženy.',
|
||
'fees have been successfully recounted' => 'Členské příspěvky byly úspěšně přepočítány.',
|
||
'fees have been successfully deducted, %d new transfers created' => 'Členské příspěvky byly úspěšně strženy, vytvořeno %d nových převodů.',
|
||
'fees have been successfully recalculated, %d deleted transfers, %d created new transfers' => 'Členské příspěvky byly úspěšně přepočítány, smazáno %d převodů, vytvořeno %d nových převodů.',
|
||
'fees have not been set!' => 'Členské příspěvky nebyly nastaveny!',
|
||
'fifth-degree certified engineers' => 'Certifikování technici pátého stupně',
|
||
'file' => 'Soubor',
|
||
... | ... | |
'ignore whitelist' => 'Ignorovat whitelist',
|
||
'import dhcp export from mikrotik' => 'Import exportu DHCP z Mikrotiku',
|
||
'import has been successfully finished' => 'Import byl úspěšně dokončen.',
|
||
'import has failed' => 'Import selhal.',
|
||
'import new invoice' => 'Import nové faktury',
|
||
'import private contact' => 'Importovat soukromé kontakty',
|
||
'import contact from server funanbol' => 'Importovat kontakty ze serveru Funanbol',
|
||
... | ... | |
'in hours' => 'V hodinách',
|
||
'inactive' => 'Neaktivní',
|
||
'inbound' => 'Příchozí',
|
||
'incomes' => 'Příjmy',
|
||
'incoming member payment' => 'Příchozí členské příspěvky',
|
||
'incoming member payment in the period' => 'Příchozí členské příspěvky v období',
|
||
'increase of members' => 'Přírůstek členů',
|
||
... | ... | |
'read-only tariff cannot be deleted' => 'Tarif pouze pro čtení nelze mazat.',
|
||
'read-only tariff cannot be edited' => 'Tarif pouze pro čtení nelze editovat.',
|
||
'really delete this account' => 'Opravdu smazat tento účet',
|
||
'recalculate account balances' => 'Přepočítat zůstatky na účtech',
|
||
'recipient information' => 'Informace o příjemci',
|
||
'received member fees' => 'Přijaté členské příspěvky',
|
||
'received' => 'Přijatá',
|
||
... | ... | |
'specific symbol' => 'Specifický symbol',
|
||
'start amount' => 'Počáteční částka',
|
||
'static ip' => 'Statická IP',
|
||
'statistics' => 'Statistiky',
|
||
'state' => 'Stav',
|
||
'statement' => 'Výpis',
|
||
'statement number' => 'Číslo výpisu',
|
||
... | ... | |
'suffix has to start with slash character and has to end with slash character' => 'Přípona musí začínat lomítkem a musí končit lomítkem.',
|
||
'suggest amount' => 'Navrhovaná částka',
|
||
'sum' => 'Součet',
|
||
'summary' => 'Sumarizace',
|
||
'summary' => 'Shrnutí',
|
||
'supplier' => 'Dodavatel',
|
||
'suppliers account' => 'Účet dodavatelů',
|
||
'surname' => 'Příjmení',
|
freenetis/trunk/kohana/application/i18n/cs_CZ/help.php | ||
---|---|---|
<?php defined('SYSPATH') or die('No direct access allowed.');
|
||
/**
|
||
* This array contains czech help and hints to specific fields in tables and forms.
|
||
* @author Jiri Svitak
|
||
* @license <http://www.gnu.org/licenses/> GNU/GPLv3
|
||
*/
|
||
$lang = array
|
||
(
|
||
'access_to_system' => 'Určuje, zda-li má uživatel možnost přihlásit se do systému Freenetis a zda má možnost využívat služeb Radius serveru napojeného na Freenetis, tedy například VPN, aktivní prvky sítě, volání z VoIP účtu atd.',
|
||
'accounting_system' => 'Účetní osnova je hlavní pomocník pro účetního sdružení. Zobrazuje sumu peněz na účtu z pohledu účetní osnovy. Ve výchozím stavu je to částka za celou dobu fungování sdružení, lze ovšem vyfiltrovat rok, např. 2011, nebo konkrétní měsíc, např. 2011-02.',
|
||
'accounting_system' => 'Účetní osnova je hlavní pomocník pro účetního sdružení. Zobrazuje sumu peněz na účtu z pohledu účetní osnovy. Ve výchozím stavu je to částka za celou dobu fungování sdružení, lze ovšem vyfiltrovat převody za zvolené období, např. od data 2009-01-01 do data 2009-12-31.',
|
||
'add_new_bank_transfer' => 'Umožňuje přidat ručně nový bankovní převod, který ma zdrojový i cílový účet. Typicky jde o fakturu nebo členský příspěvek. V běžném provozu využívejte automatický import výpisů. Ruční přidávání je tu pouze z důvodu, že byla potřeba dát do systému staré platby, které již byly jen v textovém formátu a nebylo možné je parsovat.',
|
||
'add_new_bank_transfer_without_counteraccount' => 'Umožňuje přidat bankovní převod bez protiúčtu, jde typicky o vklad, úrok bance apod. V běžném provozu využívejte automatický import výpisů. Ruční přidávání je tu pouze z důvodu, že byla potřeba dát do systému staré platby, které již nebylo možné parsovat.',
|
||
'add_new_transfer' => 'Zobrazí formulář, který umožňuje hospodáři sdružení přidat libovolný převod mezi dvěma podvojnými účty. Účetní korektnost tohoto zásahu je ovšem v zodpovědnosti účetního.',
|
||
'add_from_account' => 'Umožňuje poslat peníze z účtu na jiný účet. Například člen může poslat peníze na projektový účet na podporu nějakého projektu nebo jinému členovi, např. zaplatit rodičům internet, pokud mají samostatnou přípojku.',
|
||
'application_password' => 'Aplikační heslo slouží uživateli pro přihlášení ke službám, které jsou závislé na Radius serveru, jako například VPN, aktivní prvky sítě atd. Toto heslo je v databázi uloženo v otevřené podobě.',
|
||
... | ... | |
'password' => 'Uživatelské heslo musí obsahovat alespoň 8 znaků a musí obsahovat alespoň jedno písmeno nebo číslici.',
|
||
'payed_to' => 'Datum, do kdy máte zaplaceny členské příspěvky. Včas před tímto datem byste měli zaplatit členské příspěvky. V případě, že jste s kreditem v mínusu, tak zaplaťte co nejdříve, jinak budete zablokováni.',
|
||
'project_subaccounts' => 'Projektový účet 221103 pro účetního představuje jeden účet. Zde jsou ovšem rozepsány všechny projektové podúčty z pohledu Freenetisu. Každý člen má právo vytvořit svůj projekt, který je v souladu se stanovami sdružení, může jít například o nějakou akci nebo školení. Cílem takovéhoto projektového podúčtu je, aby ostatní členové měli možnost zakladateli projektu přispět peníze ze svého kreditního účtu na realizaci projektu.',
|
||
'recount_fees' => 'Pro primární strhávání členských příspěvků používejte funkci pro globální strhávání členských příspěvků v Účetním deníku. Tuto funkci používejte opatrně a to jen v případě, že máte správně strženy všechny členské příspěvky pro všechny členy od založení sdružení až po současné datum. Pak můžete tomuto členovi přepočítat stržení členských příspěvků v případě, že u něj došlo k nutnosti je přepočítat, např. chybné datum vstupu, vznikla nutnost přidat přerušení členství apod.',
|
||
'recount_entrance_fees' => 'Pro primární strhávání vstupních příspěvků používejte funkci pro globální strhávání v účetním deníku. Tuto funkci používejte jen v případě, že došlo k nějakému omylu, například, že měl zaplatit vstupní a pak se ukázalo, že nemusel.',
|
||
'recalculate_account_balances' => 'Primárním zdrojem o stavu financí v systému jsou převody. Zůstatky na účtech byly dříve pokaždé počítány na požádání z převodů. Nyní si každý účet ukládá svůj zůstatek kvůli vyšší rychlosti. Tuto funkci použijete v případě přechodu na verzi systému, která tuto optimalizaci obsahuje.',
|
||
'recalculate_fees' => 'Pro primární strhávání členských příspěvků používejte funkci pro globální strhávání členských příspěvků v Účetním deníku. Tuto funkci používejte opatrně a to jen v případě, že máte správně strženy všechny členské příspěvky pro všechny členy od založení sdružení až po současné datum. Pak můžete tomuto členovi přepočítat stržení členských příspěvků v případě, že u něj došlo k nutnosti je přepočítat, např. chybné datum vstupu, vznikla nutnost přidat přerušení členství apod.',
|
||
'recalculate_entrance_fees' => 'Pro primární strhávání vstupních příspěvků používejte funkci pro globální strhávání v účetním deníku. Tuto funkci používejte jen v případě, že došlo k nějakému omylu, například, že měl zaplatit vstupní a pak se ukázalo, že nemusel.',
|
||
'unidentified_transfers' => 'Neidentifikované platby jsou všechny příchozí bankovní platby, které nebyl náš systém schopen z různých důvodů automaticky rozpoznat. Typicky se jedná o platby s chybným variabilním symbolem. Pokud zde svoji platbu najdete, pak kontaktujte hospodáře sdružení pro její správné přiřazení.',
|
||
'variable_symbol' => 'Variabilní symbol slouží k jednoznačnému určení příchozí platby člena.'
|
||
);
|
freenetis/trunk/kohana/application/models/bank_transfer.php | ||
---|---|---|
CONCAT(dba.account_nr, '/', dba.bank_nr) AS dba_number,
|
||
m2.id AS dba_member_id, m2.name AS dba_member_name,
|
||
t.id, t.origin_id, t.destination_id, t.datetime, t.creation_datetime, t.text, t.amount,
|
||
bt.id AS bt_id, bt.variable_symbol, bt.constant_symbol, bt.specific_symbol
|
||
bt.id AS bt_id, bt.variable_symbol, bt.constant_symbol, bt.specific_symbol, bt.bank_statement_id
|
||
FROM transfers t
|
||
JOIN bank_transfers bt ON t.id = bt.transfer_id
|
||
LEFT JOIN bank_accounts oba ON oba.id = bt.origin_id
|
||
... | ... | |
AND bt.variable_symbol $cond_vs";
|
||
return $this->db->query($q);
|
||
}
|
||
|
||
|
||
}
|
||
|
||
?>
|
freenetis/trunk/kohana/application/models/member.php | ||
---|---|---|
m.id, m.registration, m.name,
|
||
s.street, ap.street_number, t.town, t.quarter,
|
||
m.variable_symbol, a.id AS aid,
|
||
(q2.inbound - q2.outbound) AS balance,
|
||
a.balance,
|
||
m.redirect
|
||
FROM members m
|
||
LEFT JOIN address_points ap ON m.address_point_id = ap.id
|
||
LEFT JOIN streets s ON ap.street_id = s.id
|
||
LEFT JOIN towns t ON ap.town_id = t.id
|
||
LEFT JOIN accounts a ON a.member_id = m.id AND m.id <> 1
|
||
LEFT JOIN
|
||
(
|
||
SELECT q1.id, q1.inbound, IFNULL(SUM(t.amount),0) AS outbound
|
||
FROM
|
||
(
|
||
SELECT a.id, IFNULL(SUM(t.amount),0) AS inbound
|
||
FROM accounts a
|
||
LEFT JOIN transfers t ON t.destination_id = a.id
|
||
GROUP BY a.id
|
||
) q1
|
||
LEFT JOIN transfers t ON t.origin_id = q1.id
|
||
GROUP BY q1.id
|
||
) q2 ON q2.id = a.id
|
||
$where
|
||
ORDER BY $order_by $order_by_direction
|
||
LIMIT $limit_from, $limit_results"
|
freenetis/trunk/kohana/application/models/account.php | ||
---|---|---|
$where .= 'account_attribute_id = '.Account_attribute_Model::$credit;
|
||
else
|
||
$where .= 'account_attribute_id <> '.Account_attribute_Model::$project.
|
||
' AND account_attribute_id <> '.Account_attribute_Model::$credit;
|
||
|
||
$datetime1 = '';
|
||
$datetime2 = '';
|
||
' AND account_attribute_id <> '.Account_attribute_Model::$credit;
|
||
// default datetime of transfers
|
||
$datetime_from_t1 = " AND t1.datetime >= '0000-00-00'";
|
||
$datetime_to_t1 = " AND t1.datetime <= '9999-12-31'";
|
||
$datetime_from_t2 = " AND t2.datetime >= '0000-00-00'";
|
||
$datetime_to_t2 = " AND t2.datetime <= '9999-12-31'";
|
||
foreach ($filter_values as $key => $value)
|
||
{
|
||
if ($key != 'submit' && $key != 'datetime')
|
||
if ($key == 'name')
|
||
{
|
||
$where .= ' AND ';
|
||
if ($key == 'name')
|
||
$where .= "a.name LIKE '%".$value."%' COLLATE utf8_general_ci";
|
||
$where .= "a.name LIKE '%".$value."%' COLLATE utf8_general_ci";
|
||
}
|
||
if ($key == 'datetime')
|
||
if ($key == 'datetime_from')
|
||
{
|
||
$datetime1 = " AND t1.datetime LIKE '%".$value."%' COLLATE utf8_general_ci";
|
||
$datetime2 = " AND t2.datetime LIKE '%".$value."%' COLLATE utf8_general_ci";
|
||
$datetime_from_t1 = " AND t1.datetime >= '$value'";
|
||
$datetime_from_t2 = " AND t2.datetime >= '$value'";
|
||
}
|
||
if ($key == 'datetime_to')
|
||
{
|
||
$datetime_to_t1 = " AND t1.datetime <= '$value'";
|
||
$datetime_to_t2 = " AND t2.datetime <= '$value'";
|
||
}
|
||
}
|
||
// query
|
||
return $this->db->query("
|
||
... | ... | |
IFNULL(SUM(amount), 0) AS outbound
|
||
FROM accounts a
|
||
LEFT JOIN members m ON m.id = a.member_id
|
||
LEFT JOIN transfers t1 ON a.id = t1.origin_id $datetime1
|
||
LEFT JOIN transfers t1 ON a.id = t1.origin_id $datetime_from_t1 $datetime_to_t1
|
||
$where
|
||
GROUP BY a.id
|
||
) q1
|
||
LEFT JOIN transfers t2 ON q1.id = t2.destination_id $datetime2
|
||
$where
|
||
LEFT JOIN transfers t2 ON q1.id = t2.destination_id $datetime_from_t2 $datetime_to_t2
|
||
GROUP BY q1.id
|
||
) q2
|
||
ORDER BY $order_by $order_by_direction
|
||
... | ... | |
' AND account_attribute_id <> '.Account_attribute_Model::$credit;
|
||
foreach ($filter_values as $key => $value)
|
||
{
|
||
if ($key != 'submit' && $key != 'datetime')
|
||
if ($key == 'name')
|
||
{
|
||
$where .= ' AND ';
|
||
if ($key == 'name')
|
||
$where .= "a.name LIKE '%".$value."%' COLLATE utf8_general_ci";
|
||
$where .= "a.name LIKE '%".$value."%' COLLATE utf8_general_ci";
|
||
}
|
||
}
|
||
return $this->db->query("
|
||
... | ... | |
public function get_accounts_to_deduct($date)
|
||
{
|
||
return $this->db->query("
|
||
SELECT a.id, m.entrance_date, m.leaving_date,
|
||
SELECT a.id, a.balance, m.entrance_date, m.leaving_date,
|
||
IF(mf.fee IS NOT NULL, 1, 0) fee_is_set,
|
||
mf.fee,
|
||
mf.readonly AS fee_readonly,
|
||
mf.name AS fee_name
|
||
mf.name AS fee_name,
|
||
IF(t.id IS NULL, 0, t.id) AS transfer_id
|
||
FROM accounts a
|
||
JOIN members m ON a.member_id = m.id
|
||
LEFT JOIN enum_types e ON e.id = m.type
|
||
... | ... | |
ORDER BY member_id, priority) q
|
||
GROUP BY q.member_id
|
||
) mf ON m.id = mf.member_id
|
||
LEFT JOIN transfers t ON t.origin_id = a.id AND t.type = ".Transfer_Model::$deduct_member_fee." AND t.datetime = '$date'
|
||
WHERE m.id <> 1 AND m.entrance_date < '$date'
|
||
AND (m.leaving_date = '0000-00-00'
|
||
OR (m.leaving_date <> '0000-00-00' AND m.leaving_date > '$date'))
|
||
... | ... | |
");
|
||
}
|
||
|
||
/**
|
||
* Function deletes deducting transfers of given account.
|
||
* @author Jiri Svitak
|
||
* @param $account_id
|
||
* @return unknown_type
|
||
*/
|
||
public function delete_deduct_transfers_of_account($account_id)
|
||
{
|
||
$this->db->query("DELETE FROM transfers WHERE type = ".Transfer_Model::$deduct_member_fee."
|
||
AND origin_id = $account_id");
|
||
}
|
||
|
||
/**
|
||
* Gets information important to correctly deduct fees. Used for recounting
|
||
... | ... | |
* @author Jiri Svitak
|
||
* @param unknown_type $account_id
|
||
*/
|
||
function get_account_to_recount_entrance_fees($account_id)
|
||
function get_account_to_recalculate_entrance_fees($account_id)
|
||
{
|
||
return $this->db->query("
|
||
SELECT a.id, m.entrance_fee, m.debt_payment_rate, m.entrance_date, t.id AS transfer_id, t.amount
|
||
SELECT a.id, m.entrance_fee, m.debt_payment_rate, m.entrance_date
|
||
FROM accounts a
|
||
JOIN members m ON a.member_id = m.id AND m.id <> 1
|
||
LEFT JOIN transfers t ON t.origin_id = a.id AND t.type = ".Transfer_Model::$deduct_entrance_fee."
|
||
WHERE a.account_attribute_id = ".Account_attribute_Model::$credit." AND a.id = $account_id
|
||
");
|
||
}
|
||
|
||
|
||
/**
|
||
* Function deletes member fee deducting transfers of given account.
|
||
* @author Jiri Svitak
|
||
* @param $account_id
|
||
* @return unknown_type
|
||
*/
|
||
public function delete_deduct_transfers_of_account($account_id)
|
||
{
|
||
$transfers = ORM::factory('transfer')->where(array('type' => Transfer_Model::$deduct_member_fee,
|
||
'origin_id' => $account_id))->find_all();
|
||
$transfers_count = 0;
|
||
foreach ($transfers as $transfer)
|
||
{
|
||
$transfers_count++;
|
||
if (!$transfer->delete())
|
||
throw new ErrorException();
|
||
}
|
||
// recalculate balance of current credit account
|
||
if (!$this->recalculate_account_balance_of_account($account_id))
|
||
throw new ErrorException();
|
||
// recalculate balance of operating account
|
||
$operating = ORM::factory('account')->where(array('account_attribute_id' => Account_attribute_Model::$operating))->find();
|
||
if (!$this->recalculate_account_balance_of_account($operating->id))
|
||
throw new ErrorException();
|
||
return $transfers_count;
|
||
}
|
||
|
||
/**
|
||
* Function deletes entrance fee deducting transfers of given account.
|
||
* @author Jiri Svitak
|
||
* @param $account_id
|
||
... | ... | |
*/
|
||
public function delete_entrance_deduct_transfers_of_account($account_id)
|
||
{
|
||
$this->db->query("DELETE FROM transfers WHERE type = ".Transfer_Model::$deduct_entrance_fee."
|
||
AND origin_id = $account_id");
|
||
$transfers = ORM::factory('transfer')->where(array('type' => Transfer_Model::$deduct_entrance_fee,
|
||
'origin_id' => $account_id))->find_all();
|
||
$transfers_count = 0;
|
||
foreach ($transfers as $transfer)
|
||
{
|
||
$transfers_count++;
|
||
if (!$transfer->delete())
|
||
throw new ErrorException();
|
||
}
|
||
// recalculate balance of current credit account
|
||
if (!$this->recalculate_account_balance_of_account($account_id))
|
||
throw new ErrorException();
|
||
// recalculate balance of operating account
|
||
$operating = ORM::factory('account')->where(array('account_attribute_id' => Account_attribute_Model::$infrastructure))->find();
|
||
if (!$this->recalculate_account_balance_of_account($operating->id))
|
||
throw new ErrorException();
|
||
return $transfers_count;
|
||
}
|
||
|
||
|
||
... | ... | |
ORDER BY d.buy_date ASC
|
||
");
|
||
}
|
||
|
||
|
||
/**
|
||
* Recalculates all account balances.
|
||
* @author Jiri Svitak
|
||
* @return int count of accounts with corrected balances
|
||
*/
|
||
public function recalculate_account_balances()
|
||
{
|
||
$accounts = $this->db->query("
|
||
SELECT q2.*, (inbound - outbound) AS calculated_balance
|
||
FROM
|
||
(
|
||
SELECT q1.*, IFNULL(SUM(amount), 0) AS inbound
|
||
FROM
|
||
(
|
||
SELECT a.*, IFNULL(SUM(amount), 0) AS outbound
|
||
FROM accounts a
|
||
LEFT JOIN members m ON m.id = a.member_id
|
||
LEFT JOIN transfers t1 ON a.id = t1.origin_id
|
||
GROUP BY a.id
|
||
) q1
|
||
LEFT JOIN transfers t2 ON q1.id = t2.destination_id
|
||
GROUP BY q1.id
|
||
) q2
|
||
");
|
||
// create update sql query
|
||
$sql = "UPDATE accounts SET balance = CASE id ";
|
||
// incorrect balances
|
||
$incorrect_balances = 0;
|
||
// array of ids to change
|
||
$ids = array();
|
||
foreach ($accounts as $account)
|
||
{
|
||
if ($account->balance != $account->calculated_balance)
|
||
{
|
||
$incorrect_balances++;
|
||
$sql .= "WHEN $account->id THEN $account->calculated_balance ";
|
||
$ids[] = $account->id;
|
||
}
|
||
}
|
||
// are there some accounts with incorrect balances? save correct balances
|
||
if ($incorrect_balances > 0)
|
||
{
|
||
$ids_with_commas = implode(',', $ids);
|
||
$sql .= "END WHERE id IN ($ids_with_commas)";
|
||
$db = new Database();
|
||
$db->query($sql);
|
||
}
|
||
return $incorrect_balances;
|
||
}
|
||
|
||
/**
|
||
* Recalculates account balance of single account.
|
||
* @author Jiri Svitak
|
||
* @param <type> $account_id
|
||
*/
|
||
public function recalculate_account_balance_of_account($account_id)
|
||
{
|
||
$account_model = new Account_Model();
|
||
$balance = $account_model->get_account_balance($account_id);
|
||
return $this->db->query("UPDATE accounts SET balance = '$balance' WHERE id = $account_id");
|
||
}
|
||
|
||
}
|
||
|
freenetis/trunk/kohana/application/models/account_attribute.php | ||
---|---|---|
public function get_accounting_system($limit_from = 0, $limit_results = 20, $order_by = 'id', $order_by_direction = 'asc', $filter_values = array())
|
||
{
|
||
$where = '';
|
||
$datetime1 = '';
|
||
$datetime2 = '';
|
||
$datetime_from_t1 = " AND t1.datetime >= '0000-00-00'";
|
||
$datetime_to_t1 = " AND t1.datetime <= '9999-12-31'";
|
||
$datetime_from_t2 = " AND t2.datetime >= '0000-00-00'";
|
||
$datetime_to_t2 = " AND t2.datetime <= '9999-12-31'";
|
||
foreach ($filter_values as $key => $value)
|
||
{
|
||
if ($key == 'name')
|
||
{
|
||
$where = " WHERE aa.name LIKE '%".$value."%' COLLATE utf8_general_ci";
|
||
}
|
||
if ($key == 'datetime')
|
||
if ($key == 'datetime_from')
|
||
{
|
||
$datetime1 = " AND t1.datetime LIKE '%".$value."%' COLLATE utf8_general_ci";
|
||
$datetime2 = " AND t2.datetime LIKE '%".$value."%' COLLATE utf8_general_ci";
|
||
$datetime_from_t1 = " AND t1.datetime >= '$value'";
|
||
$datetime_from_t2 = " AND t2.datetime >= '$value'";
|
||
}
|
||
if ($key == 'datetime_to')
|
||
{
|
||
$datetime_to_t1 = " AND t1.datetime <= '$value'";
|
||
$datetime_to_t2 = " AND t2.datetime <= '$value'";
|
||
}
|
||
}
|
||
// query
|
||
return $this->db->query("
|
||
... | ... | |
(SELECT a.id, a.account_attribute_id
|
||
FROM accounts a
|
||
) q0
|
||
LEFT JOIN transfers t1 ON q0.id = t1.origin_id $datetime1
|
||
LEFT JOIN transfers t1 ON q0.id = t1.origin_id $datetime_from_t1 $datetime_to_t1
|
||
GROUP BY q0.id
|
||
) q1
|
||
LEFT JOIN transfers t2 ON q1.id = t2.destination_id $datetime2
|
||
LEFT JOIN transfers t2 ON q1.id = t2.destination_id $datetime_from_t2 $datetime_to_t2
|
||
GROUP BY q1.id
|
||
) q2
|
||
) q3 ON aa.id = q3.account_attribute_id
|
freenetis/trunk/kohana/application/models/transfer.php | ||
---|---|---|
<?php
|
||
<?php
|
||
class Transfer_Model extends ORM
|
||
{
|
||
protected $belongs_to = array('origin' => 'account', 'destination' => 'account');
|
||
... | ... | |
else
|
||
return NULL;
|
||
}
|
||
|
||
|
||
|
||
|
||
/**
|
||
* @author Jiri Svitak
|
||
* @param <type> $origin_id origin account id
|
||
* @param <type> $destination_id destination account id
|
||
* @param <type> $previous_transfer_id previous transfer id, useful for transfer groups
|
||
* @param <type> $member_id transaction owner id
|
||
* @param <type> $user_id id of user who added transfer
|
||
* @param <type> $type type of transfer, see Transfer_Model
|
||
* @param <type> $datetime accounting datetime of transfer
|
||
* @param <type> $creation_datetime datetime of transfer creation
|
||
* @param <type> $text transfer text
|
||
* @param <type> $amount amount of transfer
|
||
* @throws ErrorException when failed transfer insert, origin or destination account update
|
||
*/
|
||
public static function insert_transfer($origin_id, $destination_id, $previous_transfer_id,
|
||
$member_id, $user_id, $type, $datetime, $creation_datetime, $text, $amount)
|
||
{
|
||
// insert new transfer
|
||
$transfer = new Transfer_Model();
|
||
$transfer->origin_id = $origin_id;
|
||
$transfer->destination_id = $destination_id;
|
||
$transfer->previous_transfer_id = $previous_transfer_id;
|
||
$transfer->member_id = $member_id;
|
||
$transfer->user_id = $user_id;
|
||
$transfer->type = $type;
|
||
$transfer->datetime = $datetime;
|
||
$transfer->creation_datetime = $creation_datetime;
|
||
$transfer->text = $text;
|
||
$transfer->amount = $amount;
|
||
if (!$transfer->save())
|
||
throw new ErrorException();
|
||
// update balance of origin account
|
||
$oa = new Account_Model($origin_id);
|
||
$oa->balance -= $amount;
|
||
if (!$oa->save())
|
||
throw new ErrorException();
|
||
// update balance of destination account
|
||
$da = new Account_Model($destination_id);
|
||
$da->balance += $amount;
|
||
if (!$da->save())
|
||
throw new ErrorException();
|
||
return $transfer->id;
|
||
}
|
||
|
||
/**
|
||
* Edits transfers safely with change of dependent account balance.
|
||
* @author Jiri Svitak
|
||
* @param <type> $id
|
||
* @param <type> $text
|
||
* @param <type> $amount
|
||
*/
|
||
public static function edit_transfer($id, $text, $amount)
|
||
{
|
||
// update transfer
|
||
$transfer = new Transfer_Model($id);
|
||
$transfer->text = $text;
|
||
$transfer->amount = $amount;
|
||
if (!$transfer->save())
|
||
throw new ErrorException();
|
||
// update balance of origin account
|
||
$oa = new Account_Model($transfer->origin_id);
|
||
$oa->balance -= $amount;
|
||
if (!$oa->save())
|
||
throw new ErrorException();
|
||
// update balance of destination account
|
||
$da = new Account_Model($transfer->destination_id);
|
||
$da->balance += $amount;
|
||
if (!$da->save())
|
||
throw new ErrorException();
|
||
}
|
||
|
||
/**
|
||
* Safely deletes transfer.
|
||
* @author Jiri Svitak
|
||
* @param <type> $id
|
||
*/
|
||
public static function delete_transfer($id)
|
||
{
|
||
$transfer = new Transfer_Model($id);
|
||
// update balance of origin account
|
||
$oa = new Account_Model($transfer->origin_id);
|
||
$oa->balance += $transfer->amount;
|
||
if (!$oa->save())
|
||
throw new ErrorException();
|
||
// update balance of destination account
|
||
$da = new Account_Model($transfer->destination_id);
|
||
$da->balance -= $transfer->amount;
|
||
if (!$da->save())
|
||
throw new ErrorException();
|
||
// delete transfer
|
||
if (!$transfer->delete())
|
||
throw new ErrorException();
|
||
}
|
||
}
|
||
|
||
?>
|
freenetis/trunk/kohana/application/controllers/transfers.php | ||
---|---|---|
* Handles double-entry transfers and special actions with transfers like deducting fees etc.
|
||
*
|
||
* @author Jiri Svitak
|
||
* @license GNU/GPL
|
||
* @TODO Several methods use database transaction processing, but it seems that Kohana (?) uses
|
||
* in one run multiple database connections, so these transactions are not fully fuctional (ROLLBACK).
|
||
* @license <http://www.gnu.org/licenses/> GNU/GPLv3
|
||
*
|
||
*/
|
||
class Transfers_Controller extends Controller
|
||
{
|
||
// used for storing id of origin account for callback function
|
||
protected $origin;
|
||
|
||
/**
|
||
* @author Jiri Svitak
|
||
* By default, it redirects user to day book - list of all double-entry transfers.
|
||
... | ... | |
{
|
||
if (!$this->acl_check_view('Accounts_Controller', 'transfers'))
|
||
Controller::error(ACCESS);
|
||
$this->session->del('ssAccount_id');
|
||
// get new selector
|
||
if (is_numeric($this->input->get('record_per_page')))
|
||
$limit_results = (int) $this->input->get('record_per_page');
|
||
... | ... | |
{
|
||
Controller::error(ACCESS);
|
||
}
|
||
$this->session->set('ssAccount_id', $account_id);
|
||
// gets grid settings
|
||
if (is_numeric($this->input->get('record_per_page')))
|
||
$limit_results = (int) $this->input->get('record_per_page');
|
||
... | ... | |
$balance = $inbound = $outbound = 0;
|
||
if (count($transfers) > 0)
|
||
{
|
||
// inbound and outbound amount of money are calculated from transfers of account
|
||
$inbound = $transfers->current()->inbound;
|
||
$outbound = $transfers->current()->outbound;
|
||
$balance = $inbound - $outbound;
|
||
// balance is not calculated, fast redundant value from account itself is used
|
||
$balance = $account->balance;
|
||
}
|
||
// headline
|
||
$headline = url_lang::lang('texts.Transfers of double-entry account');
|
||
... | ... | |
if ($account->account_attribute_id == Account_attribute_Model::$credit)
|
||
{
|
||
if ($this->acl_check_edit('Accounts_Controller', 'transfers'))
|
||
$grid->add_new_button(url_lang::base().'transfers/recount_fees/'.$account->id, url_lang::lang('texts.Recount of member fees'), array('onclick' => 'return potvrd(\''.url_lang::lang('texts.Are you sure you want to recount fees of this member').'\')'), help::hint('recount_fees'));
|
||
$grid->add_new_button(url_lang::base().'transfers/recalculate_fees/'.$account->id, url_lang::lang('texts.Recount of member fees'), array('onclick' => 'return potvrd(\''.url_lang::lang('texts.Are you sure you want to recount fees of this member').'\')'), help::hint('recalculate_fees'));
|
||
if ($this->acl_check_edit('Accounts_Controller', 'transfers'))
|
||
$grid->add_new_button(url_lang::base().'transfers/recount_entrance_fees/'.$account->id, url_lang::lang('texts.Recount of entrance fees'), array('onclick' => 'return potvrd(\''.url_lang::lang('texts.Are you sure you want to recount entrance fees of this member').'\')'), help::hint('recount_entrance_fees'));
|
||
$grid->add_new_button(url_lang::base().'transfers/recalculate_entrance_fees/'.$account->id, url_lang::lang('texts.Recount of entrance fees'), array('onclick' => 'return potvrd(\''.url_lang::lang('texts.Are you sure you want to recount entrance fees of this member').'\')'), help::hint('recalculate_entrance_fees'));
|
||
}
|
||
$grid->order_field('id')->label('ID');
|
||
//$grid->order_field('trans_type')->label(url_lang::lang('texts.Type'))->bool(array(url_lang::lang('texts.Inbound'),url_lang::lang('texts.Outbound')));
|
||
... | ... | |
{
|
||
$form_data[$key] = htmlspecialchars($value);
|
||
}
|
||
$transfer = new Transfer_Model();
|
||
$transfer->origin_id = $form_data['oname'];
|
||
$transfer->destination_id = $form_data['aname'];
|
||
$transfer->user_id = $this->session->get('user_id');
|
||
$transfer->datetime = date('Y-m-d', $form_data['datetime']);
|
||
$transfer->creation_datetime = date('Y-m-d H:i:s');
|
||
$transfer->text = $form_data['text'];
|
||
$transfer->amount = $form_data['amount'];
|
||
if ($transfer->save())
|
||
try
|
||
{
|
||
$this->session->set_flash('message', url_lang::lang('texts.Transfer has been successfully added'));
|
||
url::redirect(url_lang::base().'transfers/show_by_account/'.$origin_account_id);
|
||
$db = new Transfer_Model();
|
||
$db->transaction_start();
|
||
Transfer_Model::insert_transfer($form_data['oname'], $form_data['aname'], null,
|
||
null, $this->session->get('user_id'), null, date('Y-m-d', $form_data['datetime']),
|
||
date('Y-m-d H:i:s'), $form_data['text'], $form_data['amount']);
|
||
$db->transaction_commit();
|
||
$this->session->set_flash('message', url_lang::lang('texts.Transfer has been successfully added.'));
|
||
}
|
||
catch (ErrorException $e)
|
||
{
|
||
$db->transaction_rollback();
|
||
$this->session->set_flash('message', url_lang::lang('texts.Error - cannot add new transfer.'));
|
||
}
|
||
url::redirect(url_lang::base().'transfers/show_by_account/'.$origin_account_id);
|
||
}
|
||
|
||
//if ($this->acl_check_view('Members_Controller','members', $origin_account->member_id))
|
||
... | ... | |
$accounts = $account_model->get_some_doubleentry_account_names();
|
||
$origin_accounts = $accounts;
|
||
$dst_accounts = $accounts;
|
||
|
||
foreach ($dst_accounts as $dst_account)
|
||
{
|
||
$arr_dst_accounts[$dst_account->id] = $dst_account->name.' '.$dst_account->id.' ('.$dst_account->addr.')';
|
||
... | ... | |
{
|
||
$form_data[$key] = htmlspecialchars($value);
|
||
}
|
||
$transfer = new Transfer_Model();
|
||
$transfer->origin_id = $form_data['oname'];
|
||
$transfer->destination_id = $form_data['aname'];
|
||
$transfer->user_id = $this->session->get('user_id');
|
||
$transfer->datetime = date('Y-m-d', $form_data['datetime']);
|
||
$transfer->creation_datetime = date('Y-m-d H:i:s');
|
||
$transfer->text = $form_data['text'];
|
||
$transfer->amount = $form_data['amount'];
|
||
if ($transfer->save())
|
||
try
|
||
{
|
||
$db = new Transfer_Model();
|
||
$db->transaction_start();
|
||
Transfer_Model::insert_transfer($form_data['oname'], $form_data['aname'], null,
|
||
null, $this->session->get('user_id'), null, date('Y-m-d', $form_data['datetime']),
|
||
date('Y-m-d H:i:s'), $form_data['text'], $form_data['amount']);
|
||
$db->transaction_commit();
|
||
$this->session->set_flash('message', url_lang::lang('texts.Transfer has been successfully added.'));
|
||
}
|
||
catch (ErrorException $e)
|
||
{
|
||
$db->transaction_rollback();
|
||
$this->session->set_flash('message', url_lang::lang('texts.Transfer has been successfully added'));
|
||
url::redirect(url_lang::base().'transfers/show_all');
|
||
}
|
||
url::redirect(url_lang::base().'transfers/show_all');
|
||
}
|
||
|
||
$links[] = html::anchor(url_lang::base().'transfers/show_all', url_lang::lang('texts.Back to day book'));
|
||
$headline = url_lang::lang('texts.Add new transfer');
|
||
$view = new View('main');
|
||
... | ... | |
{
|
||
if (!isset($origin_account))
|
||
Controller::warning(PARAMETER);
|
||
|
||
$billing = new Billing();
|
||
|
||
$account= ORM::factory('account')->where('id', $origin_account)->find();
|
||
|
||
if (!$billing->has_driver() || ($billing->get_account($account->member_id) == null))
|
||
Controller::error(RECORD);
|
||
|
||
if (isset($origin_account)) { // transfer from specific account ?
|
||
$this->origin = $origin_account; // save for callback function valid_amount_to_send
|
||
$origin_acc = new Account_Model($origin_account);
|
||
... | ... | |
$origin_acc = new Account_Model(); // yes = create object of all accounts
|
||
$dst_accounts = $origin_accounts = $origin_acc->get_some_doubleentry_account_names();
|
||
}
|
||
|
||
$arr_orig_accounts[$origin_acc->id] =
|
||
"$origin_acc->name - ".url_lang::lang('texts.Account ID')." $origin_acc->name - "
|
||
.url_lang::lang('texts.Member ID')." $origin_acc->member_id";
|
||
|
||
|
||
// form
|
||
$form = new Forge(url_lang::base().'transfers/add_voip/'.$origin_account, '', 'POST', array('id' => 'article_form'));
|
||
$form->set_attr('class', 'form_class')->set_attr('method', 'post');
|
||
... | ... | |
special::required_forge_style($form, ' *', 'required');
|
||
if ($form->validate())
|
||
{
|
||
|
||
// default destination account
|
||
$operating = ORM::factory('account')->where('account_attribute_id', Account_attribute_Model::$operating)->find();
|
||
$text = url_lang::lang('texts.Recharging of VoIP credit');
|
||
|
||
$form_data = $form->as_array();
|
||
foreach($form_data as $key => $value)
|
||
{
|
||
$form_data[$key] = htmlspecialchars($value);
|
||
}
|
||
$transfer = new Transfer_Model();
|
||
$transfer->origin_id = $form_data['oname'];
|
||
$transfer->destination_id = $operating->id;
|
||
$transfer->user_id = $this->session->get('user_id');
|
||
$transfer->type = Transfer_Model::$deduct_voip_unnaccounted_fee;
|
||
$transfer->datetime = date('Y-m-d', $form_data['datetime']);
|
||
$transfer->creation_datetime = date('Y-m-d H:i:s', time());
|
||
$transfer->text = $text;
|
||
$transfer->amount = $form_data['amount'];
|
||
if ($transfer->save())
|
||
try
|
||
{
|
||
$db = new Transfer_Model();
|
||
$db->transaction_start();
|
||
Transfer_Model::insert_transfer($form_data['oname'], $operating->id, null,
|
||
null, $this->session->get('user_id'), Transfer_Model::$deduct_voip_unnaccounted_fee,
|
||
date('Y-m-d', $form_data['datetime']),
|
||
date('Y-m-d H:i:s'), $text, $form_data['amount']);
|
||
$db->transaction_commit();
|
||
$this->session->set_flash('message', url_lang::lang('texts.Transfer has been successfully added.'));
|
||
}
|
||
catch (ErrorException $e)
|
||
{
|
||
$db->transaction_rollback();
|
||
$this->session->set_flash('message', url_lang::lang('texts.Transfer has been successfully added'));
|
||
url::redirect(url_lang::base().'transfers/show_by_account/'.$origin_account);
|
||
}
|
||
url::redirect(url_lang::base().'transfers/show_by_account/'.$origin_account);
|
||
}
|
||
|
||
|
||
if ($this->acl_check_view('Members_Controller','members', $account->member_id))
|
||
$links[] = html::anchor(url_lang::base().'members/show/'.$account->member_id, url_lang::lang('texts.Back to the member'));
|
||
$links[] = html::anchor(url_lang::base().'transfers/show_by_account/'.$origin_account, url_lang::lang('texts.Back to transfers of account'));
|
||
|
||
$headline = url_lang::lang('texts.Add new VoIP transfer');
|
||
$info[] = url_lang::lang('texts.Information').' : '.url_lang::lang('texts.Transfer will be effected within 15 minutes.');
|
||
|
||
$view = new View('main');
|
||
$view->title = $headline;
|
||
$view->content = new View('form');
|
||
... | ... | |
{
|
||
if (!isset($transfer_id))
|
||
Controller::warning(PARAMETER);
|
||
$ssAccount_id = $this->session->get('ssAccount_id');
|
||
// access rights
|
||
if (!$this->acl_check_edit('Accounts_Controller', 'transfers'))
|
||
Controller::error(ACCESS);
|
||
... | ... | |
if($form->validate())
|
||
{
|
||
$form_data = $form->as_array();
|
||
$transfer->text = htmlspecialchars($form_data['text']);
|
||
$transfer->amount = htmlspecialchars($form_data['amount']);
|
||
unset($form_data);
|
||
if ($transfer->save())
|
||
try
|
||
{
|
||
$db = new Transfer_Model();
|
||
$db->transaction_start();
|
||
Transfer_Model::edit_transfer($transfer_id, htmlspecialchars($form_data['text']), htmlspecialchars($form_data['amount']));
|
||
$db->transaction_commit();
|
||
$this->session->set_flash('message', url_lang::lang('texts.Transfer has been successfully updated.'));
|
||
else
|
||
url::redirect(url_lang::base().'transfers/show/'.$transfer_id);
|
||
}
|
||
catch (ErrorException $e)
|
||
{
|
||
$db->transaction_rollback();
|
||
$this->session->set_flash('message', url_lang::lang('texts.Error - cant update transfer.'));
|
||
if ($ssAccount_id)
|
||
url::redirect(url_lang::base().'transfers/show_by_account/'.$ssAccount_id);
|
||
else
|
||
url::redirect(url_lang::base().'transfers/show_all');
|
||
url::redirect(url_lang::base().'transfers/show/'.$transfer_id);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
$headline = url_lang::lang('texts.Editing of transfer');
|
||
$links[] = html::anchor(url_lang::base().'transfers/show_by_account/'.$ssAccount_id, url_lang::lang('texts.Back to transfers of account'));
|
||
$view = new View('main');
|
||
$view->title = $headline;
|
||
$view->content = new View('form');
|
||
$view->content->headline = $headline;
|
||
$view->content->form = $form->html();
|
||
if ($ssAccount_id)
|
||
$view->content->link_back = html::anchor(url_lang::base().'transfers/show_by_account/'.$ssAccount_id, url_lang::lang('texts.Back to transfers of account'));
|
||
else
|
||
$view->content->link_back = html::anchor(url_lang::base().'transfers/show_all', url_lang::lang('texts.Back to day book'));
|
||
$view->content->link_back = implode (' | ', $links);
|
||
$view->render(TRUE);
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Deducts fees of all members in one month. Instead of one transfer per year this function deducts
|
||
* one transfer per month. It is possible to recount member fees by deleting previous
|
||
* member fee transfers and creating new ones.
|
||
* Deducts fees of all members in one month. If deduct transfer for one month and
|
||
* account is found, then it is ignored and skipped.
|
||
* @author Jiri Svitak
|
||
* @return unknown_type
|
||
*/
|
||
... | ... | |
// access rights
|
||
if (!$this->acl_check_new('Accounts_Controller', 'transfers'))
|
||
Controller::error(ACCESS);
|
||
|
||
// content of dropdown for months
|
||
for ($i = 1; $i <= 12; $i++)
|
||
$arr_months[$i] = $i;
|
||
... | ... | |
$form->dropdown('month')->label(url_lang::lang('texts.Month').':')->rules('required')->options($arr_months)->selected($current_month)->callback(array($this, 'valid_default_fee'));
|
||
$form->submit('submit')->value(url_lang::lang('texts.Deduct'));
|
||
special::required_forge_style($form, ' *', 'required');
|
||
|
||
// form validation
|
||
if ($form->validate())
|
||
{
|
||
// access rights
|
||
if (!$this->acl_check_new('Accounts_Controller', 'transfers'))
|
||
Controller::error(ACCESS);
|
||
|
||
$form_data = $form->as_array();
|
||
|
||
foreach($form_data as $key => $value)
|
||
$form_data[$key] = htmlspecialchars($value);
|
||
|
||
// preparation
|
||
$created_transfers_count = 0;
|
||
$total_amount = 0;
|
||
$date = date('Y-m-d', mktime(0, 0, 0, $form_data['month'], 15, $arr_years[$form_data['year']]));
|
||
$creation_datetime = date('Y-m-d H:i:s');
|
||
|
||
$user_id = $this->session->get('user_id');
|
||
// finds default fee
|
||
$fee_model = new Fee_Model();
|
||
$fee = $fee_model->get_default_fee_by_date_type($date, 'regular member fee');
|
||
|
||
if ($fee && $fee->id)
|
||
{
|
||
$default_fee = $fee->fee;
|
||
}
|
||
else
|
||
throw new Kohana_User_Exception(url_lang::lang('texts.Fatal error'), url_lang::lang('texts.Fees have not been set!'));
|
||
|
||
// test if there exist already deduct transfer for given month
|
||
$transfer = ORM::factory('transfer')->
|
||
like(array('type' => Transfer_Model::$deduct_member_fee, 'datetime' => $date))->find_all();
|
||
|
||
if (count($transfer) > 0)
|
||
{
|
||
$this->session->set_flash('message', url_lang::lang('texts.This month has been already deducted!'));
|
||
$this->session->set_flash('message', url_lang::lang('texts.Fees have not been set!'));
|
||
url::redirect(url_lang::base().'transfers/show_all');
|
||
}
|
||
|
||
$operating = ORM::factory('account')->
|
||
where('account_attribute_id', Account_attribute_Model::$operating)->find();
|
||
$text = url_lang::lang('texts.Deduction of member fee');
|
||
$database = new Database();
|
||
$account_model = new Account_Model();
|
||
$accounts = $account_model->get_accounts_to_deduct($date);
|
||
$save_successful = true;
|
||
foreach ($accounts as $account)
|
||
try
|
||
{
|
||
$transfer = new Transfer_Model();
|
||
$transfer->origin_id = $account->id;
|
||
$transfer->destination_id = $operating->id;
|
||
$transfer->user_id = $this->session->get('user_id');
|
||
$transfer->type = Transfer_Model::$deduct_member_fee;
|
||
$transfer->datetime = $date;
|
||
$transfer->creation_datetime = $creation_datetime;
|
||
$transfer->text = $text;
|
||
|
||
if ($account->fee_is_set)
|
||
$db = new Transfer_Model();
|
||
$db->transaction_start();
|
||
// first sql for inserting transfers
|
||
$sql_insert = "INSERT INTO transfers (origin_id, destination_id, previous_transfer_id, member_id, user_id, type, datetime, creation_datetime, text, amount) VALUES ";
|
||
$values = array();
|
||
// second sql for updating accounts
|
||
$sql_update = "UPDATE accounts SET balance = CASE id ";
|
||
$ids = array();
|
||
// main cycle
|
||
foreach ($accounts as $account)
|
||
{
|
||
$transfer->amount = $account->fee;
|
||
$transfer->text = ($account->fee_readonly) ? $text.' - '.url_lang::lang('texts.'.$account->fee_name) : $text.' - '.$account->fee_name;
|
||
// no deduct transfer for this date and account generated? then create one
|
||
if ($account->transfer_id == 0)
|
||
{
|
||
$text = url_lang::lang('texts.Deduction of member fee');
|
||
if ($account->fee_is_set)
|
||
{
|
||
$amount = $account->fee;
|
||
$text = ($account->fee_readonly) ? $text.' - '.url_lang::lang('texts.'.$account->fee_name) : $text.' - '.$account->fee_name;
|
||
}
|
||
else
|
||
{
|
||
$amount = $default_fee;
|
||
}
|
||
// is amount bigger than zero?
|
||
if ($amount > 0)
|
||
{
|
||
// insert
|
||
$values[] = "($account->id, $operating->id, NULL, NULL, $user_id, ".Transfer_Model::$deduct_member_fee.", '$date', '$creation_datetime', '$text', $amount)";
|
||
// update
|
||
$sql_update .= "WHEN $account->id THEN ".($account->balance - $amount)." ";
|
||
$ids[] = $account->id;
|
||
$total_amount += $amount;
|
||
$created_transfers_count++;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
if ($created_transfers_count > 0)
|
||
{
|
||
$transfer->amount = $default_fee;
|
||
$transfer->text = $text;
|
||
// single query for inserting transfers
|
||
$sql_insert .= implode(",", $values);
|
||
if (!$database->query($sql_insert))
|
||
throw new ErrorException();
|
||
// single query for updating credit account balances
|
||
$ids_with_commas = implode(",", $ids);
|
||
$sql_update .= "END WHERE id IN ($ids_with_commas)";
|
||
if (!$database->query($sql_update))
|
||
throw new ErrorException();
|
||
// update also balance of operating account
|
||
if (!$account_model->recalculate_account_balance_of_account($operating->id))
|
||
throw new ErrorException();
|
||
}
|
||
|
||
if (!$transfer->save())
|
||
$save_successful = false;
|
||
|
||
$db->transaction_commit();
|
||
$this->session->set_flash('message', url_lang::lang('texts.Fees have been successfully deducted, %d new transfers created.', $created_transfers_count));
|
||
}
|
||
if ($save_successful)
|
||
catch(ErrorException $e)
|
||
{
|
||
$this->session->set_flash('message', url_lang::lang('texts.Fees have been successfully deducted.'));
|
||
}
|
||
else
|
||
{
|
||
$db->transaction_rollback();
|
||
$this->session->set_flash('message', url_lang::lang('texts.Error - some fees have not been deducted.'));
|
||
}
|
||
url::redirect(url_lang::base().'transfers/show_all');
|
||
... | ... | |
}
|
||
|
||
/**
|
||
* Function recounts wrong deducted fees of given account of member.
|
||
* Function recalculates wrong deducted fees of given account of member.
|
||
* @author Jiri Svitak
|
||
* @return unknown_type
|
||
*/
|
||
function recount_fees($account_id = 0)
|
||
function recalculate_fees($account_id = 0)
|
||
{
|
||
// access control
|
||
if (!$this->acl_check_new('Accounts_Controller', 'transfers'))
|
||
Controller::error(ACCESS);
|
||
|
||
$account = new Account_Model($account_id);
|
||
|
||
// account doesn't exist
|
||
if (!$account->id)
|
||
Controller::error(RECORD);
|
||
|
||
// finds default fee
|
||
$fee_model = new Fee_Model();
|
||
|
||
$transfer = new Transfer_Model();
|
||
|
||
// finds member's entrance date
|
||
$entrance_date = date_parse($account->member->entrance_date);
|
||
|
||
$year = $entrance_date['year'];
|
||
$month = $entrance_date['month'];
|
||
$day = $entrance_date['day'];
|
||
|
||
// round entrance date
|
||
if ($day >= 15)
|
||
if ($day > 15)
|
||
{
|
||
$month++;
|
||
|
||
if ($month > 12)
|
||
{
|
||
$year++;
|
||
$month = 1;
|
||
}
|
||
}
|
||
|
||
// finds member's leaving date
|
||
if ($account->member->leaving_date != '0000-00-00')
|
||
{
|
||
$max_date = date_parse($account->member->leaving_date);
|
||
}
|
||
else
|
||
{
|
||
// find datetime of las deduct fee
|
||
$last_datetime = $transfer->find_last_transfer_datetime_by_type(Transfer_Model::$deduct_member_fee);
|
||
|
||
// find datetime of last deduct fee
|
||
$transfer_model = new Transfer_Model();
|
||
$last_datetime = $transfer_model->find_last_transfer_datetime_by_type(Transfer_Model::$deduct_member_fee);
|
||
if ($last_datetime)
|
||
$max_date = date_parse($last_datetime);
|
||
else
|
||
$max_date = date_parse(date('Y-m-d'));
|
||
}
|
||
|
||
$max_day = $max_date['day'];
|
||
$max_month = $max_date['month'];
|
||
$max_year = $max_date['year'];
|
||
|
||
// round max date
|
||
if ($max_day >= 15)
|
||
if ($max_day > 15)
|
||
{
|
||
$max_month++;
|
||
|
||
if ($max_month > 12)
|
||
{
|
||
$max_year++;
|
||
$max_month = 1;
|
||
}
|
||
}
|
||
|
||
// finds operating account
|
||
$operating = ORM::factory('account')->
|
||
where('account_attribute_id', Account_attribute_Model::$operating)->find();
|
||
|
||
// text of transfers
|
||
$text = url_lang::lang('texts.Deduction of member fee');
|
||
|
||
// creation datetime of transfers
|
||
$creation_datetime = date('Y-m-d H:i:s');
|
||
|
||
// deleting of old deduct transfer of member
|
||
$account->delete_deduct_transfers_of_account($account_id);
|
||
$save_successful = true;
|
||
|
||
$max_date = date('Y-m-d', mktime(0, 0, 0, $max_month, 15, $max_year));
|
||
|
||
while (($date = date('Y-m-d', mktime(0, 0, 0, $month, 15, $year))) < $max_date)
|
||
try
|
||
{
|
||
// finds default regular member fee for this month
|
||
$fee = $fee_model->get_default_fee_by_date_type($date, 'regular member fee');
|
||
|
||
if ($fee && $fee->id)
|
||
$default_fee = $fee->fee;
|
||
else
|
||
throw new Kohana_User_Exception(url_lang::lang('texts.Fatal error'), url_lang::lang('texts.Fees have not been set!'));
|
||
|
||
// creating new deduct transfer
|
||
$transfer->clear();
|
||
$transfer->origin_id = $account->id;
|
||
$transfer->destination_id = $operating->id;
|
||
$transfer->user_id = $this->session->get('user_id');
|
||
$transfer->type = Transfer_Model::$deduct_member_fee;
|
||
$transfer->datetime = $date;
|
||
$transfer->creation_datetime = $creation_datetime;
|
||
|
||
// finds regular member fee for this member and this month
|
||
$fee = $fee_model->get_fee_by_member_date_type($account->member_id, $date, 'regular member fee');
|
||
|
||
// it exists
|
||
if ($fee && $fee->id)
|
||
$db = new Transfer_Model();
|
||
$db->transaction_start();
|
||
// deleting old deduct transfer of member
|
||
$deleted_transfers_count = $account->delete_deduct_transfers_of_account($account_id);
|
||
$created_transfers_count = 0;
|
||
$max_date = date('Y-m-d', mktime(0, 0, 0, $max_month, 15, $max_year));
|
||
while (($date = date('Y-m-d', mktime(0, 0, 0, $month, 15, $year))) <= $max_date)
|
||
{
|
||
$transfer->amount = $fee->fee;
|
||
|
||
// translate only read-only fee names
|
||
$transfer->text = ($fee->readonly) ? $text.' - '.url_lang::lang('texts.'.$fee->name) : $text.' - '.$fee->name;
|
||
$text = url_lang::lang('texts.Deduction of member fee');
|
||
// finds default regular member fee for this month
|
||
$fee = $fee_model->get_default_fee_by_date_type($date, 'regular member fee');
|
||
if ($fee && $fee->id)
|
||
$default_fee = $fee->fee;
|
||
else
|
||
throw new ErrorException(url_lang::lang('texts.Fatal error'), url_lang::lang('texts.Fees have not been set!'));
|
||
// finds regular member fee for this member and this month
|
||
$fee = $fee_model->get_fee_by_member_date_type($account->member_id, $date, 'regular member fee');
|
||
// it exists
|
||
if ($fee && $fee->id)
|
||
{
|
||
$amount = $fee->fee;
|
||
// translate only read-only fee names
|
||
$text = ($fee->readonly) ? $text.' - '.url_lang::lang('texts.'.$fee->name) : $text.' - '.$fee->name;
|
||
}
|
||
// it doesn't exist - uses default fee
|
||
else
|
||
{
|
||
$amount = $default_fee;
|
||
}
|
||
if ($amount > 0)
|
||
{
|
||
$created_transfers_count++;
|
||
Transfer_Model::insert_transfer($account->id, $operating->id, null, null,
|
||
$this->session->get('user_id'), Transfer_Model::$deduct_member_fee,
|
||
$date, $creation_datetime, $text, $amount);
|
||
}
|
||
// iterate to next month
|
||
$month++;
|
||
if ($month == 13)
|
||
{
|
||
$month = 1;
|
||
$year++;
|
||
}
|
||
}
|
||
// it doesn't exist - uses default fee
|
||
else
|
||
{
|
||
$transfer->amount = $default_fee;
|
||
$transfer->text = $text;
|
||
}
|
||
|
||
if (!$transfer->save())
|
||
$save_successful = false;
|
||
|
||
$year += floor($month/12);
|
||
$month %= 12;
|
||
$month++;
|
||
$db->transaction_commit();
|
||
$this->session->set_flash('message', url_lang::lang('texts.Fees have been successfully recalculated, %d deleted transfers, %d created new transfers.', array(0 => $deleted_transfers_count, 1=> $created_transfers_count)));
|
||
}
|
||
|
||
if ($save_successful)
|
||
$this->session->set_flash('message', url_lang::lang('texts.Fees have been successfully recounted.'));
|
||
else
|
||
catch (ErrorException $e)
|
||
{
|
||
$db->transaction_rollback();
|
||
$this->session->set_flash('message', url_lang::lang('texts.Error - some fees have not been recounted.'));
|
||
|
||
}
|
||
url::redirect(url_lang::base().'transfers/show_by_account/'.$account_id);
|
||
}
|
||
|
||
... | ... | |
if (!$this->acl_check_new('Accounts_Controller', 'transfers'))
|
||
Controller::error(ACCESS);
|
||
// preparation
|
||
$created_transfers_count = 0;
|
||
$creation_datetime = date('Y-m-d H:i:s');
|
||
//$current_date = date::get_middle_of_month(date('Y-m-d'));
|
||
$current_date = date('Y-m-d');
|
||
... | ... | |
$transfer_model = new Transfer_Model();
|
||
// gets all credit accounts, tries to find also existing transfer
|
||
$credit_accounts = $account_model->get_accounts_to_deduct_entrance_fees();
|
||
// large amount of database inserts, transaction processing is necessary
|
||
$db = new Database();
|
||
$db->query("START TRANSACTION;");
|
||
$save_successful = true;
|
||
foreach($credit_accounts as $ca)
|
||
try
|
||
{
|
||
// if member's entrance fee is 0, then no transfer is generated
|
||
if ($ca->entrance_fee == 0)
|
||
continue;
|
||
// are there some deduct transfers?
|
||
if (empty($ca->transfer_id))
|
||
$db = new Transfer_Model();
|
||
$db->transaction_start();
|
||
foreach($credit_accounts as $ca)
|
||
{
|
||
// no deduct entrance fee transfer means that nothing is already paid
|
||
$already_paid = 0;
|
||
$latest_date = '0001-01-01';
|
||
}
|
||
else
|
||
{
|
||
// some transfers already exist, then their total amount is calculated
|
||
$eftransfers = $transfer_model->get_entrance_fee_transfers_of_account($ca->id);
|
||
$already_paid = $eftransfers->current()->total_amount;
|
||
$latest_date = $eftransfers->current()->datetime;
|
||
$latest_date = substr($latest_date, 0, strpos($latest_date, ' '));
|
||
}
|
||
// is already whole entrance fee paid?
|
||
if ($already_paid >= $ca->entrance_fee)
|
||
continue;
|
||
// entrance fee is not wholy paid, calculate debt
|
||
$debt = $ca->entrance_fee - $already_paid;
|
||
// entrance date of current member
|
||
$entrance = date_parse($ca->entrance_date);
|
||
$eyear = $entrance['year'];
|
||
$emonth = $entrance['month'];
|
||
$eday = $entrance['day'];
|
||
if ($eday > 15)
|
||
$emonth++;
|
||
if ($emonth == 13)
|
||
{
|
||
$emonth = 1;
|
||
$eyear++;
|
||
}
|
||
// getting boundary date - 15th day in the month
|
||
$date = date('Y-m-d', mktime(0, 0, 0, $emonth, 15, $eyear));
|
||
// while debt is greater than zero and date of instalment is lower than current date
|
||
while ($debt > 0 && $date < $current_date)
|
||
{
|
||
// is debt still greater than one monthly instalment?
|
||
if ($debt > $ca->debt_payment_rate)
|
||
// if member's entrance fee is 0, then no transfer is generated
|
||
if ($ca->entrance_fee == 0)
|
||
continue;
|
||
// are there some deduct transfers?
|
||
if (empty($ca->transfer_id))
|
||
{
|
||
// one monthly instalment is deducted
|
||
$amount = $ca->debt_payment_rate;
|
||
// if debt pay rate is zero, then whole amount of debt is deducted
|
||
if ($amount <= 0)
|
||
$amount = $debt;
|
||
// no deduct entrance fee transfer means that nothing is already paid
|
||
$already_paid = 0;
|
||
$latest_date = '0001-01-01';
|
||
}
|
||
else
|
||
{
|
||
// rest of the debt is deducted
|
||
$amount = $debt;
|
||
// some transfers already exist, then their total amount is calculated
|
||
$eftransfers = $transfer_model->get_entrance_fee_transfers_of_account($ca->id);
|
||
$already_paid = $eftransfers->current()->total_amount;
|
||
$latest_date = $eftransfers->current()->datetime;
|
||
$latest_date = substr($latest_date, 0, strpos($latest_date, ' '));
|
||
}
|
||
// only one transfer per month - older transfers cannot be duplicated
|
||
if ($date > $latest_date)
|
||
{
|
||
// decrease amount of debt due to size of one instalment
|
||
$debt -= $amount;
|
||
// create new transfer
|
||
$transfer = new Transfer_Model();
|
||
$transfer->origin_id = $ca->id;
|
||
$transfer->destination_id = $infrastructure->id;
|
||
$transfer->user_id = $this->session->get('user_id');
|
||
$transfer->type = Transfer_Model::$deduct_entrance_fee;
|
||
$transfer->datetime = $date;
|
||
$transfer->creation_datetime = $creation_datetime;
|
||
$transfer->text = url_lang::lang('texts.Entrance fee');
|
||
$transfer->amount = $amount;
|
||
if (!$transfer->save())
|
||
$save_successful = false;
|
||
}
|
||
// iterate to next month
|
||
$emonth++;
|
||
// is already whole entrance fee paid?
|
||
if ($already_paid >= $ca->entrance_fee)
|
||
continue;
|
||
// entrance fee is not wholy paid, calculate debt
|
||
$debt = $ca->entrance_fee - $already_paid;
|
||
// entrance date of current member
|
||
$entrance = date_parse($ca->entrance_date);
|
||
$eyear = $entrance['year'];
|
||
$emonth = $entrance['month'];
|
||
$eday = $entrance['day'];
|
||
if ($eday > 15)
|
||
$emonth++;
|
||
if ($emonth == 13)
|
||
{
|
||
$emonth = 1;
|
||
$eyear++;
|
||
$eyear++;
|
||
}
|
||
// getting boundary date - 15th day in the month
|
||
$date = date('Y-m-d', mktime(0, 0, 0, $emonth, 15, $eyear));
|
||
$date = date('Y-m-d', mktime(0, 0, 0, $emonth, 15, $eyear));
|
||
// while debt is greater than zero and date of instalment is lower than current date
|
||
while ($debt > 0 && $date < $current_date)
|
||
{
|
||
// is debt still greater than one monthly instalment?
|
||
if ($debt > $ca->debt_payment_rate)
|
||
{
|
||
// one monthly instalment is deducted
|
||
$amount = $ca->debt_payment_rate;
|
||
// if debt pay rate is zero, then whole amount of debt is deducted
|
||
if ($amount <= 0)
|
||
$amount = $debt;
|
||
}
|
||
else
|
||
{
|
||
// rest of the debt is deducted
|
||
$amount = $debt;
|
||
}
|
||
// only one transfer per month - older transfers cannot be duplicated
|
||
if ($date > $latest_date)
|
||
{
|
||
// decrease amount of debt due to size of one instalment
|
||
$debt -= $amount;
|
||
// create new transfer
|
||
Transfer_Model::insert_transfer($ca->id, $infrastructure->id, null, null,
|
||
$this->session->get('user_id'), Transfer_Model::$deduct_entrance_fee,
|
||
$date, $creation_datetime, url_lang::lang('texts.Entrance fee'), $amount);
|
||
$created_transfers_count++;
|
||
}
|
||
// iterate to next month
|
||
$emonth++;
|
||
if ($emonth == 13)
|
||
{
|
||
$emonth = 1;
|
||
$eyear++;
|
||
}
|
||
// getting boundary date - 15th day in the month
|
||
$date = date('Y-m-d', mktime(0, 0, 0, $emonth, 15, $eyear));
|
||
}
|
||
}
|
||
$db->transaction_commit();
|
||
$this->session->set_flash('message', url_lang::lang('texts.Entrance fees have been successfully deducted, %d new transfers created.', $created_transfers_count));
|
||
}
|
||
if ($save_successful)
|
||
catch(ErrorException $e)
|
||
{
|
||
$db->query("COMMIT;");
|
||
$this->session->set_flash('message', url_lang::lang('texts.Entrance fees have been successfully deducted.'));
|
||
}
|
||
else
|
||
{
|
||
$db->query("ROLLBACK;");
|
||
$db->transaction_rollback();
|
||
$this->session->set_flash('message', url_lang::lang('texts.Error - cant deduct entrance fee.'));
|
||
}
|
||
url::redirect(url_lang::base().'transfers/show_all');
|
||
}
|
||
|
||
/**
|
||
* Recounts transfer of one member credit account. Used only in special cases, like changing entrance date.
|
||
* Recounts transfer of one member credit account.
|
||
* Used only in special cases, like changing entrance date.
|
||
* @author Jiri Svitak
|
||
* @param $account_id
|
||
*/
|
||
function recount_entrance_fees($account_id)
|
||
function recalculate_entrance_fees($account_id)
|
||
{
|
||
// access rights
|
||
if (!$this->acl_check_new('Accounts_Controller', 'transfers'))
|
||
... | ... | |
$account_model = new Account_Model($account_id);
|
||
if ($account_model->id == 0)
|
||
Controller::error(RECORD);
|
Také k dispozici: Unified diff
Zacleneni transakcniho zpracovani financnich prevodu vcetne dalsich vylepseni a rychlostni optimalizaci financi do hlavni vetve. Pridan i licencni soubor GNU/GPLv3.