Revize 974
Přidáno uživatelem Michal Kliment před více než 13 roky(ů)
freenetis/branches/testing/application/models/account.php | ||
---|---|---|
|
||
}
|
||
|
||
?>
|
||
?>
|
freenetis/branches/testing/application/controllers/transfers.php | ||
---|---|---|
*
|
||
* @author Jiri Svitak
|
||
* @license <http://www.gnu.org/licenses/> GNU/GPLv3
|
||
*
|
||
*
|
||
*/
|
||
class Transfers_Controller extends Controller
|
||
{
|
||
... | ... | |
{
|
||
url::redirect(url_lang::base().'transfers/show_all');
|
||
}
|
||
|
||
|
||
/**
|
||
* It shows all double-entry transfers. They are shown in day book.
|
||
* It shows all double-entry transfers. They are shown in day book.
|
||
* @author Jiri Svitak
|
||
* @param $limit_results
|
||
* @param $order_by
|
||
... | ... | |
$order_by = 'id';
|
||
if (strtolower($order_by_direction) != 'asc' && strtolower($order_by_direction) != 'desc')
|
||
$order_by_direction = 'desc';
|
||
// there are two groups of transfers
|
||
$arr_groups[Transfer_Model::$all_transfers] = url_lang::lang('texts.All transfers');
|
||
$arr_groups[Transfer_Model::$without_inner] = url_lang::lang('texts.Without inner transfers');
|
||
// there are two groups of transfers
|
||
$arr_groups[Transfer_Model::$all_transfers] = url_lang::lang('texts.All transfers');
|
||
$arr_groups[Transfer_Model::$without_inner] = url_lang::lang('texts.Without inner transfers');
|
||
// creates fields for filtering
|
||
$filter=new Table_Form(url_lang::base()."transfers/show_all", "get", array(
|
||
new Table_Form_Item('text', 'oa_name', 'Origin account'),
|
||
... | ... | |
new Table_Form_Item('text', 'amount', 'Amount'),
|
||
"tr",
|
||
new Table_Form_Item('text', 'text', 'Text'),
|
||
new Table_Form_Item('select', 'group', 'Group', $arr_groups),
|
||
new Table_Form_Item('select', 'group', 'Group', $arr_groups),
|
||
"tr",
|
||
"td", new Table_Form_Item('submit', 'submit', 'Filter')
|
||
)
|
||
... | ... | |
$model_transfer = new Transfer_Model();
|
||
$total_transfers = $model_transfer->count_all_transfers($filter->values());
|
||
if (($sql_offset = ($page - 1) * $limit_results) > $total_transfers)
|
||
$sql_offset = 0;
|
||
$sql_offset = 0;
|
||
$alltransfers = $model_transfer->get_all_transfers($sql_offset, (int)$limit_results, $order_by, $order_by_direction, $filter->values());
|
||
$headline = url_lang::lang('texts.Day book');
|
||
$grid = new Grid(url_lang::base().'transfers', null, array(
|
||
... | ... | |
$view->render(TRUE);
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* It shows transfers of credit account.
|
||
* @author Jiri Svitak
|
||
... | ... | |
if (count($filter_values) == 0)
|
||
$filter_values['type'] = Transfer_Model::$inbound_and_outbound;
|
||
// transfers on account
|
||
$transfer_model = new Transfer_Model();
|
||
$total_transfers = $transfer_model->count_transfers($account_id, $filter_values);
|
||
$transfer_model = new Transfer_Model();
|
||
$total_transfers = $transfer_model->count_transfers($account_id, $filter_values);
|
||
if (($sql_offset = ($page - 1) * $limit_results) > $total_transfers)
|
||
$sql_offset = 0;
|
||
$sql_offset = 0;
|
||
$transfers = $transfer_model->get_transfers($account_id, $sql_offset, (int)$limit_results, $order_by, $order_by_direction, $filter_values);
|
||
// total amount of inbound and outbound transfers and total balance
|
||
$balance = $inbound = $outbound = 0;
|
||
... | ... | |
$view->content->transfers_grid = $transfers_grid;
|
||
if ($this->acl_check_view ('Members_Controller','comment',$account->member_id))
|
||
$view->content->comments_grid = $comments_grid;
|
||
$view->content->message = $this->session->get_once('message');
|
||
$view->content->message = $this->session->get_once('message');
|
||
$view->render(TRUE);
|
||
} // end of show_by_account function
|
||
|
||
|
||
} // end of show_by_account function
|
||
|
||
|
||
/**
|
||
* Function shows information of transfer including previous transfer if exists.
|
||
* @author Jiri Svitak
|
||
... | ... | |
elseif ($da->member_id != 1)
|
||
$member_id = $da->member_id;
|
||
else
|
||
$member_id = 1;
|
||
$member_id = 1;
|
||
if (!$this->acl_check_view('Accounts_Controller', 'transfers', $member_id))
|
||
Controller::error(ACCESS);
|
||
// transfers dependent on this transfer, if this transfer is member fee payment
|
||
... | ... | |
$view->content->message = $this->session->get_once('message');
|
||
$view->render(TRUE);
|
||
}
|
||
|
||
|
||
/**
|
||
* Adds transfers from single origin account.
|
||
* @todo set of accounts choosen by account_attribute_id, must be done by ajax
|
||
... | ... | |
{
|
||
if (!isset($origin_account_id) || !is_numeric($origin_account_id))
|
||
Controller::warning(PARAMETER);
|
||
// save for callback function valid_amount_to_send
|
||
$this->origin = $origin_account_id;
|
||
// save for callback function valid_amount_to_send
|
||
$this->origin = $origin_account_id;
|
||
$origin_account = new Account_Model($origin_account_id);
|
||
if ($origin_account->id == 0)
|
||
Controller::error(RECORD);
|
||
if (!$this->acl_check_new('Accounts_Controller', 'transfers', $origin_account->member_id))
|
||
Controller::error(ACCESS);
|
||
// destination account, instead of origin one
|
||
$dst_account_model = new Account_Model();
|
||
$dst_account_model = new Account_Model();
|
||
$dst_accounts = $dst_account_model->get_some_doubleentry_account_names($origin_account_id);
|
||
foreach ($dst_accounts as $dst_account)
|
||
{ // convert the object into array (used for HTML select list)
|
||
{ // convert the object into array (used for HTML select list)
|
||
$arr_dst_accounts[$dst_account->id] = $dst_account->name.' '.$dst_account->id.' ('.$dst_account->addr.')';
|
||
//"$dst_account->name, $dst_account->addr - ".url_lang::lang('texts.Account ID')." $dst_account->id - "
|
||
//.url_lang::lang('texts.Member ID')." $dst_account->member_id - "
|
||
... | ... | |
}
|
||
asort($arr_dst_accounts, SORT_LOCALE_STRING);
|
||
// default destination account
|
||
$operating = ORM::factory('account')->where('account_attribute_id', Account_attribute_Model::$operating)->find();
|
||
$operating = ORM::factory('account')->where('account_attribute_id', Account_attribute_Model::$operating)->find();
|
||
// array with only one origin account
|
||
$arr_orig_accounts[$origin_account->id] = $origin_account->name.' '.$origin_account->id;
|
||
// account attributes for types of accounts
|
||
... | ... | |
//$form->dropdown('')->label(url_lang::lang('texts.Account type').':')->options($arr_attributes);
|
||
$form->dropdown('oname')->label(url_lang::lang('texts.Origin account (account name, account ID)').':')->options($arr_orig_accounts)->rules('required');
|
||
// destination account
|
||
$form->group('')->label(url_lang::lang('texts.Destination account'));
|
||
$form->group('')->label(url_lang::lang('texts.Destination account'));
|
||
$form->dropdown('account_type')->label(url_lang::lang('texts.Account type').':')->options($arr_attributes);
|
||
$form->dropdown('aname')->label(url_lang::lang('texts.Destination account (account name, account ID)').':')->options($arr_dst_accounts)->rules('required')->selected($operating->id);
|
||
// other information
|
||
$form->group('')->label(url_lang::lang('texts.Transfer'));
|
||
$form->group('')->label(url_lang::lang('texts.Transfer'));
|
||
$form->date('datetime')->label(url_lang::lang('texts.Date and time').':')->years(date('Y')-20, date('Y'))->rules('required');
|
||
$form->input('amount')->label(url_lang::lang('texts.Amount').':')->rules('required|valid_numeric')->callback(array($this, 'valid_amount_to_send'));
|
||
$form->input('text')->label(url_lang::lang('texts.Text').':')->rules('required');
|
||
$form->submit('submit')->value(url_lang::lang('texts.Send'));
|
||
special::required_forge_style($form, ' *', 'required');
|
||
special::required_forge_style($form, ' *', 'required');
|
||
if ($form->validate())
|
||
{
|
||
$form_data = $form->as_array();
|
||
$form_data = $form->as_array();
|
||
foreach($form_data as $key => $value)
|
||
{
|
||
$form_data[$key] = htmlspecialchars($value);
|
||
... | ... | |
}
|
||
url::redirect(url_lang::base().'transfers/show_by_account/'.$origin_account_id);
|
||
}
|
||
|
||
|
||
//if ($this->acl_check_view('Members_Controller','members', $origin_account->member_id))
|
||
// $links[] = html::anchor(url_lang::base().'members/show/'.$origin_account->member_id, url_lang::lang('texts.Back to the member'));
|
||
|
||
|
||
//$links[] = html::anchor(url_lang::base().'transfers/show_by_account/'.$origin_account_id, url_lang::lang('texts.Back to account transfers'));
|
||
|
||
$breadcrumbs = array();
|
||
... | ... | |
$view->content->headline = $headline;
|
||
$view->content->form = $form->html();
|
||
$view->content->link_back = '';
|
||
$view->render(TRUE);
|
||
$view->render(TRUE);
|
||
}
|
||
|
||
|
||
/**
|
||
* Function adds transfers from one arbitrary account to another arbitrary account.
|
||
* @todo set of accounts choosen by account_attribute_id, must be done by ajax
|
||
... | ... | |
function add()
|
||
{
|
||
if (!$this->acl_check_new('Accounts_Controller', 'transfers'))
|
||
Controller::error(ACCESS);
|
||
Controller::error(ACCESS);
|
||
$account_model = new Account_Model();
|
||
$accounts = $account_model->get_some_doubleentry_account_names();
|
||
$origin_accounts = $accounts;
|
||
... | ... | |
{
|
||
$arr_dst_accounts[$dst_account->id] = $dst_account->name.' '.$dst_account->id.' ('.$dst_account->addr.')';
|
||
}
|
||
asort($arr_dst_accounts);
|
||
asort($arr_dst_accounts);
|
||
// array origin accounts for dropdown
|
||
$arr_orig_accounts = $arr_dst_accounts;
|
||
$arr_orig_accounts = $arr_dst_accounts;
|
||
// default destination account
|
||
$operating = ORM::factory('account')->where('account_attribute_id', Account_attribute_Model::$operating)->find();
|
||
// account attributes for types of accounts
|
||
... | ... | |
//$form->dropdown('')->label(url_lang::lang('texts.Account type').':')->options($arr_attributes);
|
||
$form->dropdown('oname')->label(url_lang::lang('texts.Origin account (account name, account ID)').':')->options($arr_orig_accounts)->rules('required');
|
||
// destination account
|
||
$form->group('')->label(url_lang::lang('texts.Destination account'));
|
||
$form->group('')->label(url_lang::lang('texts.Destination account'));
|
||
//$form->dropdown('')->label(url_lang::lang('texts.Account type').':')->options($arr_attributes);
|
||
$form->dropdown('aname')->label(url_lang::lang('texts.Destination account (account name, account ID)').':')->options($arr_dst_accounts)->rules('required')->selected($operating->id);
|
||
// other information
|
||
$form->group('')->label(url_lang::lang('texts.Transfer'));
|
||
$form->group('')->label(url_lang::lang('texts.Transfer'));
|
||
$form->date('datetime')->label(url_lang::lang('texts.Date and time').':')->years(date('Y')-20, date('Y'))->rules('required');
|
||
// no amount on origin account is required, this arbitrary transfers should only admin or accountant of association who knows what is he doing
|
||
$form->input('amount')->label(url_lang::lang('texts.Amount').':')->rules('required|valid_numeric')->callback(array($this, 'valid_amount'));//->callback(array($this, 'valid_amount_to_send'));
|
||
$form->input('text')->label(url_lang::lang('texts.Text').':')->rules('required');
|
||
$form->submit('submit')->value(url_lang::lang('texts.Send'));
|
||
special::required_forge_style($form, ' *', 'required');
|
||
special::required_forge_style($form, ' *', 'required');
|
||
if ($form->validate())
|
||
{
|
||
$form_data = $form->as_array();
|
||
$form_data = $form->as_array();
|
||
foreach($form_data as $key => $value)
|
||
{
|
||
$form_data[$key] = htmlspecialchars($value);
|
||
... | ... | |
}
|
||
|
||
/**
|
||
* Function edits double-entry transfers. They should not be edited.
|
||
* Wrong transfer should be solved by new transfer.
|
||
* Function edits double-entry transfers. They should not be edited.
|
||
* Wrong transfer should be solved by new transfer.
|
||
* @author Jiri Svitak
|
||
* @param $transfer_id
|
||
* @return unknown_type
|
||
... | ... | |
{
|
||
if (!isset($transfer_id))
|
||
Controller::warning(PARAMETER);
|
||
// access rights
|
||
// access rights
|
||
if (!$this->acl_check_edit('Accounts_Controller', 'transfers'))
|
||
Controller::error(ACCESS);
|
||
$transfer = new Transfer_Model($transfer_id);
|
||
$form = new Forge(url_lang::base().'transfers/edit/'.$transfer_id, '', 'POST', array('id' => 'article_form'));
|
||
$form->set_attr('class', 'form_class')->set_attr('method', 'post');
|
||
$form->group('')->label(url_lang::lang('texts.Basic information'));
|
||
$form->input('text')->label(url_lang::lang('texts.Text').':')->rules('required|length[3,50]')->value($transfer->text);
|
||
$form->input('text')->label(url_lang::lang('texts.Text').':')->rules('required|length[3,50]')->value($transfer->text);
|
||
$form->input('amount')->label(url_lang::lang('texts.Amount').':')->rules('required')->value($transfer->amount)->callback(array($this, 'valid_amount'));
|
||
$form->submit('submit')->value(url_lang::lang('texts.Edit'));
|
||
special::required_forge_style($form, ' *', 'required');
|
||
... | ... | |
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.'));
|
||
url::redirect(url_lang::base().'transfers/show/'.$transfer_id);
|
||
url::redirect(url_lang::base().'transfers/show/'.$transfer_id);
|
||
}
|
||
catch (Exception $e)
|
||
{
|
||
... | ... | |
}
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* Deducts fees of all members in one month. If deduct transfer for one month and
|
||
* account is found, then it is ignored and skipped.
|
||
... | ... | |
$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
|
||
// form validation
|
||
if ($form->validate())
|
||
{
|
||
// access rights
|
||
... | ... | |
$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');
|
||
url::redirect(url_lang::base().'transfers/show_all');
|
||
}
|
||
else
|
||
{
|
||
... | ... | |
$view->content->form = $form->html();
|
||
$view->content->link_back = html::anchor(url_lang::base().'transfers/show_all',url_lang::lang('texts.Back to day book'));
|
||
$view->render(TRUE);
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
... | ... | |
{
|
||
$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');
|
||
}
|
||
url::redirect(url_lang::base().'transfers/show_all');
|
||
}
|
||
|
||
|
||
/**
|
||
* Recounts transfer of one member credit account.
|
||
* Used only in special cases, like changing entrance date.
|
||
... | ... | |
if ($ca->entrance_fee == 0)
|
||
{
|
||
$this->session->set_flash('message', url_lang::lang('texts.Entrance fees have been successfully recalculated, %d transfers deleted, %d new transfers created.', array(1=>$deleted_transfers_count, 2=>$created_transfers_count)));
|
||
url::redirect(url_lang::base().'transfers/show_by_account/'.$account_id);
|
||
url::redirect(url_lang::base().'transfers/show_by_account/'.$account_id);
|
||
}
|
||
// entrance fee is not wholy paid, calculate debt
|
||
$debt = $ca->entrance_fee;
|
||
... | ... | |
{
|
||
$db->transaction_rollback();
|
||
$this->session->set_flash('message', url_lang::lang('texts.Error - cant deduct entrance fee.'));
|
||
}
|
||
url::redirect(url_lang::base().'transfers/show_by_account/'.$account_id);
|
||
}
|
||
url::redirect(url_lang::base().'transfers/show_by_account/'.$account_id);
|
||
}
|
||
|
||
|
||
/**
|
||
* Deducts repayments of devices. Special devices, like wifi clients can be sold by association.
|
||
* This mechanism enables repayments of these devices in case that member has not enough money to
|
||
... | ... | |
{
|
||
$db->transaction_rollback();
|
||
$this->session->set_flash('message', url_lang::lang('texts.Error - cant deduct device fee.'));
|
||
}
|
||
url::redirect(url_lang::base().'transfers/show_all');
|
||
}
|
||
url::redirect(url_lang::base().'transfers/show_all');
|
||
}
|
||
|
||
|
||
/**
|
||
* Function adds member fee payment by cash.
|
||
* @author Jiri Svitak
|
||
... | ... | |
if (!$this->acl_check_new('Accounts_Controller', 'transfers'))
|
||
Controller::error(ACCESS);
|
||
$credit = ORM::factory('account')->where(array('member_id' => $member_id,
|
||
'account_attribute_id' => Account_attribute_Model::$credit))->find();
|
||
'account_attribute_id' => Account_attribute_Model::$credit))->find();
|
||
$accounts[$credit->id] = $credit->name;
|
||
// check if there is fee for payment, then new amount is calculated
|
||
$fee_model = new Fee_Model();
|
||
$fee_model = new Fee_Model();
|
||
$fee = $fee_model->get_by_date_type(date('Y-m-d'), 'transfer fee');
|
||
if (is_object($fee) && $fee->id)
|
||
$transfer_fee = $fee->fee;
|
||
else
|
||
$transfer_fee = 0;
|
||
// form
|
||
// form
|
||
$form = new Forge(url_lang::base().'transfers/add_member_fee_payment_by_cash/'.$member_id, '', 'POST', array('id' => 'article_form'));
|
||
$form->set_attr('class', 'form_class')->set_attr('method', 'post');
|
||
$form->group('')->label(url_lang::lang('texts.Transfer'));
|
||
... | ... | |
$form->input('transfer_fee')->label(url_lang::lang('texts.Amount').':')->value($transfer_fee)->rules('valid_numeric')->callback(array($this, 'valid_fee'));
|
||
$form->input('fee_text')->label(url_lang::lang('texts.Text').':')->value(url_lang::lang('texts.Transfer fee'));
|
||
$form->submit('submit')->value(url_lang::lang('texts.Add'));
|
||
special::required_forge_style($form, ' *', 'required');
|
||
special::required_forge_style($form, ' *', 'required');
|
||
if ($form->validate())
|
||
{
|
||
$form_data = $form->as_array();
|
||
$form_data = $form->as_array();
|
||
foreach($form_data as $key => $value)
|
||
{
|
||
$form_data[$key] = htmlspecialchars($value);
|
||
... | ... | |
//$links[] = html::anchor(url_lang::base().'members/show/'.$member_id, url_lang::lang('texts.Back to the member'));
|
||
//$links[] = html::anchor(url_lang::base().'transfers/show_by_account/'.$credit->id, url_lang::lang('texts.Back to transfers of member'));
|
||
//$view->content->link_back = implode(' | ', $links);
|
||
$view->render(TRUE);
|
||
$view->render(TRUE);
|
||
}
|
||
|
||
|
||
}
|
||
|
||
|
||
/**
|
||
* Function validates amount of money to send from double-entry account.
|
||
* @param $input
|
||
... | ... | |
$account_model = new Account_Model();
|
||
if ($input->value <= 0)
|
||
{
|
||
$input->add_error('required', url_lang::lang('texts.Error - amount has to be positive.'));
|
||
$input->add_error('required', url_lang::lang('texts.Error - amount has to be positive.'));
|
||
}
|
||
else if (!$this->acl_check_new('Accounts_Controller', 'transfers') && $account_model->get_account_balance($this->origin) < $input->value)
|
||
{
|
||
$input->add_error('required', url_lang::lang('texts.Error - not enough money on origin account.'));
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Function validates amount of money in editing.
|
||
* @param $input
|
||
... | ... | |
$input->add_error('required', url_lang::lang('texts.Error - amount has to be positive.'));
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Function validates number of months in function deduct_fees.
|
||
* @param $input
|
||
... | ... | |
$year = $this->input->post('year');
|
||
$month = $this->input->post('month');
|
||
$date = date('Y-m-d', mktime(0, 0, 0, $month, 15, $year));
|
||
|
||
|
||
// finds default fee
|
||
$fee_model = new Fee_Model();
|
||
$fee = $fee_model->get_default_fee_by_date_type($date, 'regular member fee');
|
||
... | ... | |
$input->add_error('required', url_lang::lang('texts.For this month and year is not set default fee.'));
|
||
}
|
||
}
|
||
|
||
|
||
}
|
||
?>
|
freenetis/branches/testing/application/controllers/comments.php | ||
---|---|---|
// bad parameter
|
||
if (!$comments_thread_id || !is_numeric($comments_thread_id))
|
||
Controller::warning(PARAMETER);
|
||
|
||
|
||
$comments_thread = new Comments_thread_Model($comments_thread_id);
|
||
|
||
// comment thread doesn't exist
|
||
... | ... | |
if (!$this->acl_check_view ('Members_Controller','comment',$parent->member_id))
|
||
Controller::error (ACCESS);
|
||
|
||
$link_back_url = url_lang::base().'transfers/show_by_account/'.$parent->id;
|
||
if (url::slice(url_lang::uri(Path::instance()->previous()->current()),0,1) == 'comments_threads')
|
||
Path::instance()->previous();
|
||
|
||
//$link_back_url = url_lang::base().'transfers/show_by_account/'.$parent->id;
|
||
$link_back_url = Path::instance()->current();
|
||
|
||
$breadcrumbs[] = html::anchor (url_lang::base().'members/show_all', url_lang::lang('texts.Members'));
|
||
$breadcrumbs[] = html::anchor(url_lang::base().'members/show/'.$parent->member_id,"ID ".$parent->member->id." - ".$parent->member->name);
|
||
$breadcrumbs[] = html::anchor ($link_back_url, url_lang::lang('texts.Transfers'));
|
||
... | ... | |
// access control
|
||
if (!$this->acl_check_view ('Members_Controller','comment',$parent->member_id))
|
||
Controller::error (ACCESS);
|
||
|
||
|
||
$link_back_url = url_lang::base().'transfers/show_by_account/'.$parent->id;
|
||
break;
|
||
case 'job':
|
||
... | ... | |
|
||
}
|
||
|
||
?>
|
||
?>
|
freenetis/branches/testing/application/views/members_show.php | ||
---|---|---|
<br />
|
||
|
||
<?php echo (isset($message)) ? '<div class="message">'.$message.'</div>' : ''; ?>
|
||
|
||
|
||
<?php echo $member_links ?>
|
||
|
||
<br />
|
||
... | ... | |
<h3><?php echo url_lang::lang('texts.Users')?></h3>
|
||
<?php echo $users_grid ?>
|
||
<br />
|
||
|
||
<h3><?php echo url_lang::lang('texts.VoIP')?></h3>
|
||
|
||
<h3><?php echo url_lang::lang('texts.VoIP')?></h3>
|
||
<?php echo $voip_grid ?>
|
||
<br />
|
||
|
Také k dispozici: Unified diff
Nezmergovalo se to vsechno, druhy pokus...