Projekt

Obecné

Profil

« Předchozí | Další » 

Revize 428

Přidáno uživatelem Jiří Sviták před asi 15 roky(ů)

Upravz menu. Problem s CSV vypisy, vypada to, ze neni mozne pouzivat sablony, ale je nutne pro kazdy druh vypisu napsat vlastni importovaci funkci. Vsechny importovaci funkce presunuty z accounts do controlleru import.

Zobrazit rozdíly:

freenetis/trunk/kohana/application/controllers/members.php
if ($this->acl_check_new(get_class($this), 'members'))
$grid->add_new_button(url_lang::base().'members/add', url_lang::lang('texts.Add new member'));
if ($this->acl_check_edit('Members_Controller', 'registration'))
$grid->add_new_button(url_lang::base().'members/registration', url_lang::lang('texts.Edit registrations'));
if ($this->acl_check_view(get_class($this), 'members'))
{
// xls export of members, works fine in OpenOffice,
freenetis/trunk/kohana/application/controllers/transfers.php
$view->content = new View('form');
$view->content->headline = $headline;
$view->content->form = $form->html();
$view->content->message = $this->session->get_once('message');
//$view->content->message = $this->session->get_once('message');
$view->content->link_back = html::anchor(url_lang::base().'transfers/show_all',url_lang::lang('texts.Back to day book'));
$view->footer = new View('base/footer');
$view->render(TRUE);
freenetis/trunk/kohana/application/controllers/bank_accounts.php
$baa_grid->field('account_number')->label(url_lang::lang('texts.Account number'));
$baa_grid->field('mname')->label(url_lang::lang('texts.Member name'));
$baa_grid->action_field('id')->label(url_lang::lang('texts.Transfers'))->url(url_lang::base().'bank_transfers/show_by_bank_account')->action(url_lang::lang('texts.Show'));
$baa_grid->action_field('id')->label(url_lang::lang('texts.Import'))->url(url_lang::base().'accounts/upload_bank_file')->action(url_lang::lang('texts.Import'));
$baa_grid->action_field('id')->label(url_lang::lang('texts.Import'))->url(url_lang::base().'import/upload_bank_file')->action(url_lang::lang('texts.Import'));
$baa_grid->datasource($baa);
// bank accounts except association's
freenetis/trunk/kohana/application/controllers/import.php
<?php
class Duplicity_Exception extends Exception
{
public $duplicity;
public function __construct($duplicity=NULL) {$this->duplicity=$duplicity;}
}
class Import_Controller extends Controller
{
// static constants of bank listing types
private static $html_ebanka = 1;
private static $csv_postovni_sporitelna = 2;
// private variables for accounts
private $acc_model;
private $bank_acc_model;
private $member_model;
private $fee_model;
private $parsed_acc;
private $bank_interests;
private $bank_fees;
private $suppliers;
private $operating;
private $member_fees;
// private variables for transfers
private $t;
private $bt;
/**
* @var object $parsed_bank_acc obsahuje data o parsovaném bank. účtu (z tabluky bank_accounts)
* Používá se v callback funkci store_transfer
*/
protected $parsed_bank_acc = NULL;
protected $time_now;
protected $stats;
// automatic redirect
function index()
{
url::redirect(url::base());
}
/**
* Function uploads bank files.
* @param $id
* @return unknown_type
*/
public function upload_bank_file($id = null)
{
if (!isset($id))
Controller::warning(PARAMETER);
if (!$this->acl_check_new('Accounts_Controller', 'bank_transfers'))
Controller::error(ACCESS);
$bank_acc_model=new Bank_account_Model($id);
if ($bank_acc_model->id == 0)
Controller::error(RECORD);
// file types of bank listings
$types = array();
$types[self::$html_ebanka] = 'HTML eBanka';
$types[self::$csv_postovni_sporitelna] = 'CSV Postovni sporitelna';
// csv templates
/*
$template_model = new Bank_template_Model();
$templates = $template_model->find_all();
foreach ($templates as $template)
{
$arr_templates[$template->id] = $template->template_name;
}
*/
// form
$form = new Forge(url_lang::base()."import/upload_bank_file/$id", '','POST',array('id' => 'article_form'));
$form->set_attr('class', 'form_class')->set_attr('method', 'post');
$form->dropdown('type')->label(url_lang::lang('texts.File type'))->options($types)->rules('required');
//$form->dropdown('csv_template')->label(url_lang::lang('texts.CSV file template'))->options($arr_templates);
$form->upload('listing', TRUE)->label(url_lang::lang('texts.File with bank transfer listing'))->rules('required');
$form->submit(url_lang::lang('texts.Submit'));
special::required_forge_style($form, ' *', 'required');
// validation
if($form->validate())
{
$form_data = $form->as_array();
switch($form_data['type'])
{
case self::$html_ebanka:
$this->parse_ebank_account(null, $form->listing->value);
break;
case self::$csv_postovni_sporitelna:
//$this->parse_csv_file($id, $form_data['csv_template'], $form->listing->value);
$this->parse_csv_postovni_sporitelna($id, $form->listing->value);
break;
default:
break;
}
}
else
{
$title = url_lang::lang('texts.Upload bank transfers listing');
$view = new View('template');
$view->header = new View('base/header');
$view->header->title = $title;
$view->header->menu = Controller::render_menu();
$view->content = new View('form');
$view->content->form = $form->html();
$view->content->link_back = html::anchor(url_lang::base().'bank_accounts/show_all', url_lang::lang('texts.Back to bank accounts'));
$view->content->headline = $title;
$view->footer = new View('base/footer');
$view->render(TRUE);
}
}
/**
* Imports data from table which contains annual statement to database structure of freenetis.
* Not functional yet.
* @author Jiri Svitak
* Function prepares import of listing file. Certain double-entry accounts are created.
* @return unknown_type
*/
public function run()
private function init_import($bank_account_id = null)
{
$db = new Database();
$stat = $db->get('2006');
for ($i = 0; $i < count($stat); $i++)
$this->time_now = date("Y-m-d H:i:s");
$this->t = new Transfer_Model();
$this->bt = new Bank_transfer_Model();
$this->member_model = new Member_Model();
$this->acc_model = new Account_Model();
$this->bank_acc_model = new Bank_account_Model();
$this->fee_model = new Fee_Model();
$this->parsed_bank_acc = new Bank_account_Model($bank_account_id);
$this->parsed_acc = $this->parsed_bank_acc->get_related_account_by_attribute_id(Account_attribute_Model::$bank);
if ($this->parsed_acc===FALSE)
{
// tohle by normálně nemělo nastat.
// může se to stát pouze pokud někdo smaže vazbu bank. účet sdružení
// s podvojným účtem přes tabulku accounts_bank_accounts
throw new Kohana_User_Exception('Kritická chyba', 'V tabulce accounts_bank_accounts chybí vazba bankovního a podvojného účtu sdružení');
}
$bank_interests = $this->parsed_bank_acc->get_related_account_by_attribute_id(Account_attribute_Model::$bank_interests);
if ($bank_interests===FALSE)
{ // pokud ucet uroku neexistuje, pak si jej vytvorime
$bank_interests = Account_Model::create(Account_attribute_Model::$bank_interests, "Úroky z $parsed_acc->name", 1);
$bank_interests->add_bank_account($this->parsed_bank_acc);
}
$bank_fees = $this->parsed_bank_acc->get_related_account_by_attribute_id(Account_attribute_Model::$bank_fees);
if ($bank_fees===FALSE) { // pokud ucet poplatku neexistuje, pak jej vytvorime
$bank_fees = Account_Model::create(Account_attribute_Model::$bank_fees, "Poplatky z $parsed_acc->name", 1);
$bank_fees->add_bank_account($this->parsed_bank_acc);
}
$this->suppliers = ORM::factory('account')->find_by_account_attribute_id(Account_attribute_Model::$suppliers);
$this->member_fees = ORM::factory('account')->find_by_account_attribute_id(Account_attribute_Model::$member_fees);
$this->operating = ORM::factory('account')->find_by_account_attribute_id(Account_attribute_Model::$operating);
if (!$this->suppliers->id || !$this->member_fees->id || !$this->operating->id)
throw new Kohana_User_Exception('Kritická chyba', 'V DB chybí účet member_fees, suppliers nebo operating');
}
/**
* Function parses csv file with bank listing.
* It uses predefined bank template to identify columns in csv file.
* @author Jiri Svitak
* @param $bank_account_id
* @param $bank_template_id
* @return unknown_type
*/
/*
private function parse_csv_file($bank_account_id = null, $bank_template_id = null, $url = "")
{
if (!isset($bank_account_id) || !isset($bank_template_id) || $url == "")
Controller::warning(PARAMETER);
$bank_account = new Bank_account_Model($bank_account_id);
$bank_template = new Bank_template_Model($bank_template_id);
if ($bank_account->id == 0 || $bank_template->id == 0)
Controller::error(RECORD);
// preparation
//$this->init_import();
$first = true;
$template = $bank_template->as_array();
// associatiove array - keys are template column names and values are column numbers in csv file
$headers = array();
$items = array();
// file to import
$file = fopen($url, 'r');
while (($line = fgetcsv($file, 0, $bank_template->item_separator, $bank_template->string_separator)) !== false)
{
if ($stat[$i]->varsym != null)
// column headers
if ($first)
{
$ba = $db->select('bank_nr')->from('bank_accounts')->where('bank_nr', $stat[$i]->protiucet)->get();
if ($ba->count() == 0)
// goes through every header of csv file
for ($i = 0; $i < count($line); $i++)
{
$acc = new Account_Model();
$acc->member_id = 'null';
$acc->name = $stat[$i]->osoba;
$acc->type = 'bank';
$acc->start_amount = '0';
$acc->comment = '';
$acc->save();
$bacc = new Bank_Account_Model();
$bacc->account_id = $acc->id;
$bacc->account_nr = $stat[$i]->protiucet;
$bacc->bank_nr = $stat[$i]->kod_banky;
$bacc->save();
}
$mt = new Money_transfer_Model();
$mt->origin_id = $acc->id;
$mt->destination_id = '1';
$mt->timestamp = $stat[$i]->datum_platby;
$mt->text = $stat[$i]->text;
$mt->amount = $stat[$i]->castka;
$mt->save();
$mtbi = new Money_transfer_bank_info_Model();
$mtbi->transfer_id = $mt->id;
$mtbi->variable_symbol = $stat[$i]->varsym;
$mtbi->save();
// goes through every header specified by template
foreach ($template as $key => $value)
{
if (trim($value) == trim($line[$i]))
{
$headers[$key] = $i;
}
}
}
$first = false;
}
echo 'line '.($i+1). ' saved';
// import of line
else
{
// loads the items array with proper values
for ($i = 0; $i < count($line); $i++)
{
foreach ($headers as $key => $value)
{
if ($value == $i)
$items[$key] = $line[$i];
}
}
print_r($items);
echo '<br>';
}
}
fclose($file);
die();
}
*/
/**
* Function parses csv bank listing file of czech bank Postovni sporitelna.
* @param $bank_account_id
* @param $url
* @return unknown_type
*/
private function parse_csv_postovni_sporitelna($bank_account_id = null, $url = "")
{
if (!isset($bank_account_id) || $url == "")
Controller::warning(PARAMETER);
$bank_account = new Bank_account_Model($bank_account_id);
if ($bank_account->id == 0)
Controller::error(RECORD);
echo "Memory usage: ".($mem=memory_get_usage()). "<p>\n";
echo "parse - start: ".($start=microtime(true))."<p>\n";
// preparation
$this->init_import($bank_account_id);
$data = new StdClass();
$first = true;
// file to import
$file = fopen($url, 'r');
while (($line = fgetcsv($file, 0, ';', '"')) !== false)
{
if ($first)
{
$first = false;
continue;
}
$data->amount = (double)$line[13];
$data->comment = $line[23];
$data->variable_symbol = $line[15];
$data->specific_symbol = $line[16];
$data->constant_symbol = $line[17];
// counteraccount
$data->account_nr = (int)$line[10];
$data->account_bank_nr = (int)$line[11];
$data->name = $line[21];
$datetime = explode('.', trim($line[20]));
$data->date_time = $datetime[2].'-'.$datetime[1].'-'.$datetime[0];
// vydej
if ($line[14] == 1)
{
// poplatek
if (trim($line[21]) == 'Zuctovanipoplatku')
{
}
}
// prijem
else
{
$this->member_model->clear();
$member = $this->member_model;
$vs = trim($data->variable_symbol);
if ($data->amount > 0 && !empty($vs))
{
// členský příspěvek: uvedl člen u teto platby jako variabilni symbol (VS) svůj telefon ?
$member = $this->member_model->find_member_by_phone($vs);
if ($member === FALSE )
{ // find_member_by_phone vrací false, pokud nic nenajde
// ne? zkusime, zda jako VS nezadal svoje member_id + crc16(member_id)
// $member=$member_model->get_member_by_crc_id($vs); // this function has bugs!!! needs rewrite!!!
$member = $this->member_model;
}
// pokud se to nepovedlo, pak $member->id nastavíme na null
} // else { // platba přijaté faktury - majitele účtu najdeme dle VS na faktuře, až budeme mít modul přijatých faktur}
// ***Tady si vytvorime instanci účtu clena (nebo dodavatele) z prave nacteneho vypisu:
$bank_acc = $this->bank_acc_model->find_by_account_nr_and_bank_nr($data->account_nr, $data->account_bank_nr);
if (!$bank_acc->id) { // bank. ucet clena neexistuje, tak si ho vytvorime
$bank_acc->clear();
$bank_acc->member_id = $member->id;
$bank_acc->name = $data->name;
$bank_acc->account_nr = $data->account_nr;
$bank_acc->bank_nr = $data->account_bank_nr;
$bank_acc->save();
$this->stats->new_bank_accounts++;
// $bank_acc->add_account($member_fees); //tuto vazbu bych tvořil jen pokud bych chtěl evidovat pohyby na bank. účtech členů
}
// členský příspěvek - vytvoříme:
// - podvojnou transakci z 684000 na 221000
// - bankovní transakci z bank. účtu člena na bank. účet sdružení
$id = $this->create_transfers($this->member_fees, $this->parsed_acc, $data->amount,
$bank_acc, $this->parsed_bank_acc, $data, $member->id);
if ($member->id)
{ // našli jsme plátce?
// **** převedeme peníze členovi na jeho účet s kreditem
// ten účet ale musíme najít nebo vytvořit:
$credit_acc = $this->acc_model->find_by_member_id_and_account_attribute_id(
$member->id, Account_attribute_Model::$credit);
if (!$credit_acc->id)
{
$credit_acc->clear();
$credit_acc->account_attribute_id = Account_attribute_Model::$credit;
$credit_acc->member_id = $member->id;
$credit_acc->name = $member->name;
$credit_acc->save();
}
$this->create_transfer($this->parsed_acc, $this->acc_model,
$data->amount, $data->date_time, "Přiřazení platby", $member->id, $id);
// **** teď se podíváme, jestli v té době sdružení účtovalo poplatek za zpracování platby:
$fee = $fee_model->get_by_date_type($data->date_time, 'transfer fee');
if (is_object($fee) && $fee->id) // ano? Pak poplatek strhneme z účtu
$this->create_transfer($credit_acc, $this->operating,
$fee->fee, $data->date_time, "Transakční poplatek",
$member->id, $id);
} // if (is_object($member) && $member->id)
$this->stats->member_fees_nr++;
$this->stats->member_fees+=$data->amount;
}
//print_r($line);
}
fclose($file);
echo html::anchor(url_lang::base().'bank_accounts/show_all', url_lang::lang('texts.Back to bank accounts'));
}
/**
* @author Tomas Dulik
* Funkce store_transfers_ebanka se používá jako callback funkce pro Parser_Ebanka.
* Třída Parser_Ebanka tuto funkci volá s každou načtenou položkou výpisu.
* Jednotlivé položky se pak uvnitř této funkce ukládají do databáze.
* Viz http://wiki.freenetis.slfree.net/index.php/Soubor:Hospodareni.pdf
*
* @param data - objekt s následujícími položkami:
* parsed_acc_nr => 184932848 //cislo parsovaneho uctu
* parsed_acc_bank_nr=> 2400 //cislo banky parsovaneho uctu
* number => 1 //cislo vypisu
* date_time => 2008-03-25 05:40 //datum a cas
* comment => Rozpis polozek uveden v soupisu prevodu
* name => CESKA POSTA, S.P.
* account_nr => 160987123
* account_bank_nr = 0300
* type => Příchozí platba
* variable_symbol => 9081000001
* constant_symbol => 998
* specific_symbol => 9876543210
* amount => 720.00
* fee => -6.90
*
*/
public function store_transfer_ebanka($data) {
/** zde jsou statické objekty, jejichž instance tvořím jen jednou u importu prvního řádku
* výpisu (šetříme paměť...)
* */
static $acc_model, $bank_acc_model, $member_model, $fee_model, $parsed_acc;
static $bank_interests, $bank_fees, $time_deposits_interests, $time_deposits;
static $suppliers, $operating, $member_fees, $cash;
static $first_pass=true;
$this->stats->linenr++;
if ($first_pass) { // dostavame prvni radek vypisu?
$this->stats=new stdClass();
$this->time_now=date("Y-m-d H:i:s");
$member_model=new Member_Model(); // vytvorime vsechny instance, ktere potrebujeme i pro dalsi radky
$acc_model=new Account_Model();
$bank_acc_model=new Bank_account_Model();
$fee_model=new Fee_Model();
$ebank_nrs=array("2400", "5500");
if (!isset($this->parsed_bank_acc)) { // mame jiz parsovany ucet v DB? (tato promenna bude nastavena pouze pokud se parsuje ucet zvoleny v gridu uzivatelem)
// parsovany ucet dopredu nezname. Je v parsovanem vypisu? (je, pokud to neni transparentni vypis ebanky)
if (isset($data->parsed_acc_nr) && isset($data->parsed_acc_bank_nr)) {
if (in_array($data->parsed_acc_bank_nr, $ebank_nrs))
$bank_nr="5500 (2400)"; // u ebanky probehla zmena kodu banky...
else $bank_nr=$data->parsed_acc_bank_nr;
$this->parsed_bank_acc=ORM::factory('bank_account')->find_by_account_nr_and_bank_nr(
$data->parsed_acc_nr, $bank_nr);
if (!$this->parsed_bank_acc->id) { // parsovany ucet zatim neexistuje?
// tak si ho vytvorime
$acc_name="$data->parsed_acc_nr/$bank_nr";
$parsed_acc = Account_Model::create(Account_attribute_Model::$bank,
$acc_name, 1);
$this->parsed_bank_acc=Bank_account_Model::create($acc_name, $data->parsed_acc_nr,
$bank_nr, 1);
$parsed_acc->add_bank_account($this->parsed_bank_acc);
}
} else { // if (isset($data->parsed_acc_nr) ... ve výpisu není číslo parsovaného účtu = kritická chyba
$this->session->set_flash('message', url_lang::lang('texts.The parsed account is unknown.'));
return;
}
} else // if (!isset($this->parsed_bank_acc))) - parsovany ucet je v DB, tak zkontroluj, jestli vypis neni z jineho uctu:
if (isset($data->parsed_acc_nr) && isset($data->parsed_acc_bank_nr) &&
! ($data->parsed_acc_nr == $this->parsed_bank_acc->account_nr && // cisla uctu odpovidaji
($data->parsed_acc_bank_nr == $this->parsed_bank_acc->bank_nr || // cisla bank odpovidaji nebo
in_array($data->parsed_acc_bank_nr, $ebank_nrs) && // jsou obe 2400 nebo 5500
in_array($this->parsed_bank_acc->bank_nr, $ebank_nrs)
))) throw new Kohana_User_Exception('Chyba', 'Importovaný výpis není z vybraného účtu!');
// @todo tato chyba nema byt Exception, ale normalni hlášení
if (!isset($parsed_acc)) {
$parsed_acc = $this->parsed_bank_acc->get_related_account_by_attribute_id(
Account_attribute_Model::$bank);
if ($parsed_acc===FALSE)
// tohle by normálně nemělo nastat.
// může se to stát pouze pokud někdo smaže vazbu bank. účet sdružení
// s podvojným účtem přes tabulku accounts_bank_accounts
throw new Kohana_User_Exception('Kritická chyba', 'V tabulce accounts_bank_accounts chybí vazba bankovního a podvojného účtu sdružení');
}
// Teď potřebujeme najít nebo vytvořit speciální podvojné účty k parsovanému bank. učtu:
$spec_accounts=array(
"bank_interests" => "Úroky z $parsed_acc->name",
"time_deposits_interests" => "Úroky z termín. vkladů $parsed_acc->name",
"time_deposits" => "Termínované vklady $parsed_acc->name",
"bank_fees" => "Poplatky z $parsed_acc->name"
);
foreach ($spec_accounts as $accnt=>$name) {
$spec_acc=$this->parsed_bank_acc->get_related_account_by_attribute_id(
Account_attribute_Model::$$accnt);
if ($spec_acc===FALSE) { // pokud spec. ucet neexistuje, pak si jej vytvorime
$spec_acc=Account_Model::create(Account_attribute_Model::$$accnt, $name, 1);
$spec_acc->add_bank_account($this->parsed_bank_acc);
}
$$accnt=$spec_acc;
}
$suppliers=ORM::factory('account')->find_by_account_attribute_id(Account_attribute_Model::$suppliers);
$member_fees=ORM::factory('account')->find_by_account_attribute_id(Account_attribute_Model::$member_fees);
$operating=ORM::factory('account')->find_by_account_attribute_id(Account_attribute_Model::$operating);
$cash=ORM::factory('account')->find_by_account_attribute_id(Account_attribute_Model::$cash);
if (!$suppliers->id || !$member_fees->id || !$operating->id)
throw new Kohana_User_Exception('Kritická chyba', 'V DB chybí účet member_fees, suppliers nebo operating');
$first_pass=FALSE;
}
if (!empty($data->fee)) {
$fee=abs($data->fee);
$this->stats->bank_fees+=$fee;
$this->stats->bank_fees_nr++;
}
// ********************** Tak a jdeme tvořit transakce *********************
$vs=trim($data->variable_symbol);
if (empty($data->amount)) {
// ****** Bankovní poplatky: ebanka má v řádku výpisu pouze poplatek, ale castka==0
// vytvoříme transakci "bankovní poplatek z 221000 (bank. účty) na 549001 (bank. poplatky)
//a bankovní transakci z parsovaného účtu na null. Přiřadíme ji sdružení (member_id=1).
if (empty($data->comment)) $data->comment=$data->type;
$this->create_transfers($parsed_acc, $bank_fees, $fee,
$this->parsed_bank_acc, null, $data, 1);
} else // castka je nenulova:
if (empty($data->fee) && stripos($data->type, "rok") !== FALSE) {
// ***** úroky u ebanky: amount!=0, fee==0, type je "Úrok", "Kladný úrok", "Převedení úroku po kapitalizaci TV"
// Vytvoříme transakci z 644000 nebo 655000 (uroky) na 221000
// a bankovní transakci z null na parsovaný účet. Přiřadíme ji sdružení (member_id=1)
if (empty($vs)) // běžný úrok? (644000)
$this->create_transfers($interests, $parsed_acc, $data->amount,
null, $this->parsed_bank_acc, $data, 1);
else // úrok z termínovaného vkladu (655000)
$this->create_transfers($time_deposit_interests, $parsed_acc, $data->amount,
null, $this->parsed_bank_acc, $data, 1);
$this->stats->interests += $data->amount;
$this->stats->interests_nr++;
} else {
// ****** nejběžnější případ:
// - členský příspěvek, platba faktury dodavatelum, termín. vklad, výběr hotovosti ******
// Nejdriv zkusím najít majitele bankovního protiúčtu
$ks=trim($data->constant_symbol);
$term_vklad = ($ks == "968");
$member_model->clear();
$member=$member_model;
if ($term_vklad) $member->id=1; // term. vklad vždy způsobuje samo sdružení
//u ostatních typů transakcí zkusíme najít původce:
else if ($data->amount>0 && !empty($vs)) {
// členský příspěvek nebo příjem z faktury odběrateli
// @todo zpracování jiných typů VS u člen. příspěvků (např. ID+CRC16)
// uvedl člen u teto platby jako variabilni symbol (VS) svůj telefon ?
$member=$member_model->find_member_by_phone($vs);
if ($member===FALSE ) { // find_member_by_phone vrací false, pokud nic nenajde
// ne? zkusime, zda jako VS nezadal svoje member_id + crc16(member_id)
// $member=$member_model->get_member_by_crc_id($vs); // this function has bugs!!! needs rewrite!!!
$member=$member_model;
$this->stats->unasigned++;
}
}
// else { // platba přijaté faktury - majitele účtu najdeme dle VS na faktuře, až budeme mít modul přijatých faktur}
// ***Tady si vytvorime instanci účtu clena (nebo dodavatele) z prave nacteneho vypisu:
$bank_acc=$bank_acc_model->find_by_account_nr_and_bank_nr($data->account_nr, $data->account_bank_nr);
if (!$bank_acc->id) { // bank. ucet clena neexistuje, tak si ho vytvorime
$bank_acc->clear();
$bank_acc->member_id = $member->id;
$bank_acc->name = $data->name;
$bank_acc->account_nr = $data->account_nr;
$bank_acc->bank_nr = $data->account_bank_nr;
$bank_acc->save();
$this->stats->new_bank_accounts++;
// $bank_acc->add_account($member_fees); //tuto vazbu bych tvořil jen pokud bych chtěl evidovat pohyby na bank. účtech členů
}
if ($data->amount<0) {
$amount=abs($data->amount);
if ($term_vklad) { // převod peněz na účet term. vkladu
$id=$this->create_transfers($parsed_acc, $time_deposits, $amount,
$this->parsed_bank_acc, $bank_acc, $data, $member->id, null);
$this->stats->time_deposits_drawn+=$amount;
$this->stats->time_deposits_drawn_nr++;
} else {
if (stripos($data->type, "hotovost") !== FALSE) { // výběr do pokladny ?
$id=$this->create_transfers($parsed_acc, $cash, $amount,
$this->parsed_bank_acc, null, $data, $member->id, null);
$this->stats->cash_drawn+=$amount;
$this->stats->cash_drawn_nr++;
} else {
// úhrada faktury - z 221000 (bank. účet) na 321000 (dodavatelé)
if (!$member->id && $bank_acc->member_id) // pokud se předtím nepodařilo najít majitele dle VS
$member = $member_model->find($bank_acc->member_id); // zkusím ho vzít odsud
$id=$this->create_transfers($parsed_acc, $suppliers, $amount,
$this->parsed_bank_acc, $bank_acc, $data, $member->id);
$this->stats->invoices+=$amount;
$this->stats->invoices_nr++;
}
} // if ($term_vklad) ... else
if (!empty($fee)) {
// je tam bankovní poplatek - vytvoříme:
// - podvojnou transakci z 221000 (bank. účty) na 549001 (bank. poplatky)
// - bankovní transakci z parsovaného účtu na null
$data->comment = "Bank. poplatek". (!empty($data->comment) ? " ($data->comment)":"");
$this->create_transfers($parsed_acc, $bank_fees, $fee,
$this->parsed_bank_acc, null, $data, $member->id, $id);
}
} else { // $data->amount > 0
if ($term_vklad) { // převod peněz na účet term. vkladu
$id=$this->create_transfers($parsed_acc, $time_deposits, $amount,
$this->parsed_bank_acc, $bank_acc, $data, $member->id, null);
$this->stats->time_deposits_drawn+=$amount;
$this->stats->time_deposits_drawn_nr++;
} else {
// členský příspěvek - vytvoříme:
// - podvojnou transakci z 684000 na 221000
// - bankovní transakci z bank. účtu člena na bank. účet sdružení
$id=$this->create_transfers($member_fees, $parsed_acc, $data->amount,
$bank_acc, $this->parsed_bank_acc, $data, $member->id);
if (!empty($fee)) {
// bankovní poplatek - vytvoříme:
// - podvojnou transakci z 221000 (bank. účty) na 549001 (bank. poplatky)
// - bankovní transakci z parsovaného účtu na null
$data->comment = "Bank. poplatek". (!empty($data->comment) ? " ($data->comment)":"");
$this->create_transfers($parsed_acc, $bank_fees, $fee,
$this->parsed_bank_acc, null, $data, $member->id, $id);
// naše správní rada si vymyslela, že poplatek budeme dotovat z operačního účtu
// (pokud máte ve správní radě rozumnější lidi, tak tento řádek zakomentujte :-)
$this->create_transfer($operating, $parsed_acc,
abs($data->fee), $data->date_time, "Bank. poplatek hrazený sdružením",
$member->id, $id);
}
if ($member->id) { // původce je známý?
// **** převedeme peníze členovi na jeho účet s kreditem
// ten účet ale musíme najít nebo vytvořit:
$credit_acc=$acc_model->find_by_member_id_and_account_attribute_id(
$member->id, Account_attribute_Model::$credit);
if (!$credit_acc->id) {
$credit_acc->clear();
$credit_acc->account_attribute_id = Account_attribute_Model::$credit;
$credit_acc->member_id = $member->id;
/**
* @todo Jirka pri tvorbe uctu jako jmeno uctu pouziva
* prijmeni jmeno majitele. To se mi tady nechce programovat,
* protoze se jen tezko muze stat, ze by kreditni ucet neexistoval
*/
$credit_acc->name = $member->name;
$credit_acc->save();
}
$this->create_transfer($parsed_acc, $acc_model,
$data->amount, $data->date_time, "Přiřazení platby",
$member->id, $id);
// **** teď se podíváme, jestli v té době sdružení účtovalo poplatek za zpracování platby:
$fee=$fee_model->get_by_date_type($data->date_time, 'transfer fee');
if (is_object($fee) && $fee->id) // ano? Pak poplatek strhneme z účtu
$this->create_transfer($credit_acc, $operating,
$fee->fee, $data->date_time, "Transakční poplatek",
$member->id, $id);
} // if (is_object($member) && $member->id)
$this->stats->member_fees_nr++;
$this->stats->member_fees+=$data->amount;
} // if ($term_vklad) ... else {
} // else { // $data->amount > 0
} // else { // ****** castka!=0 && poplatek !=0
}
private function create_transfer($src, $dst, $amount, $datetime, $text,
$member_id=null, $prev_id=null) {
static $transfer; // static variable saves a little bit of memory & time
if (!isset($transfer)) $transfer=new Transfer_Model();
$transfer->clear();
$transfer->amount = $amount;
$transfer->datetime = $datetime;
$transfer->creation_datetime=$this->time_now;
$transfer->origin_id = $src->id;
$transfer->destination_id = $dst->id;
$transfer->text= $text;
$transfer->previous_transfer_id = $prev_id;
$transfer->member_id = $member_id;
$transfer->save();
return $transfer->id;
}
private function create_transfers($src_acc, $dst_acc, $amount,
$src_bank_acc, $dst_bank_acc, $data,
$member_id=null, $prev_id=null) {
static $transfer; // static variable saves a little bit of memory & time
static $bank_transfer;
if (!isset($transfer)) {
$transfer=new Transfer_Model();
$bank_transfer=new Bank_transfer_Model();
}
// nejdriv zkontroluj, jestli uz tuto transakci nemame od minuleho importu
$dups=$bank_transfer->get_duplicities($data);
if ($dups->count() > 0) throw new Duplicity_Exception($dups);
$transfer->clear();
$transfer->amount = $amount;
$transfer->datetime = $data->date_time;
$transfer->creation_datetime=$this->time_now;
$transfer->origin_id = $src_acc->id;
$transfer->destination_id = $dst_acc->id;
$transfer->text= $data->comment;
$transfer->previous_transfer_id=$prev_id;
$transfer->member_id = $member_id;
$transfer->save();
$bank_transfer->clear();
$bank_transfer->transfer_id = $transfer->id;
$bank_transfer->origin_id = isset($src_bank_acc)? $src_bank_acc->id : null;
$bank_transfer->destination_id = isset($dst_bank_acc)? $dst_bank_acc->id : null;
$bank_transfer->variable_symbol = $data->variable_symbol;
$bank_transfer->constant_symbol = $data->constant_symbol;
$bank_transfer->specific_symbol = $data->specific_symbol;
$bank_transfer->save();
return $transfer->id;
}
/**
* @author Tomas Dulik
* @param $url - URL containing the file to parse
* @param $account_id - ID of the account whose data will be parsed.
* @return void
*/
public function parse_ebank_account($bank_account_id=NULL, $url="") {
$parser=new Parser_Ebanka();
echo "Memory usage=".($mem=memory_get_usage()). "<p>\n";
echo"parse - start: ".($start=microtime(true))."<p>\n";
//$parser->set_callback(array($this, "print_row"));
$parser->set_callback(array($this, "store_transfer_ebanka"));
// pokud z gridu dostáváme $account_id, pak si ho uložíme pro potřeby callback funkce
if (isset($bank_account_id))
$this->parsed_bank_acc=new Bank_account_Model($bank_account_id);
//print_r ($parser);
// $parser->parse("c:/txt/unart/ucto/vypisy/2007/09.html");
//$parser->parse("http://www.rb.cz/firemni-finance/transparentni-ucty/?root=firemni-finance&item1=transparentni-ucty&tr_acc=vypis&account_number=184932848");
if (empty($url)) $url="/var/www/freenetis-import/08.html.htm";
try {
$parser->parse($url);
} catch (Duplicity_Exception $ex) {
// v případě duplicity commitujeme vše do výskytu duplicity a hned skončíme
echo "Končíme, právě importovaný záznam má již v databázi duplicitní záznam:<br/>\n";
echo "<table border=1>";
$first=true; $header="";
foreach ($ex->duplicity as $dup) {
echo "<tr>\n"; $data="";
foreach ($dup as $key=>$val) {
if ($first)
$header.="<th>$key</th>";
$data.="<td>$val</td>";
}
if ($first) {
echo $header;
echo "</tr>\n";
$first=false;
}
echo $data;
echo "</tr>\n";
}
}
//$parser->parse("http://localhost/2007.html");
//$parser->parse("c:/txt/unart/ucto/vypisy/2007/2007.html");
echo "<table border=1>\n";
foreach ($this->stats as $key=>$value)
echo "<tr><td>$key</td><td>$value</td></tr>";
echo "</table>\n";
if (!isset($this->stats->invoices)) $this->stats->invoices=0;
if (!isset($this->stats->interests)) $this->stats->interests=0;
if (!isset($this->stats->bank_fees)) $this->stats->bank_fees=0;
if (!isset($this->stats->member_fees)) $this->stats->member_fees=0;
echo "Bank. poplatky = ". $this->stats->bank_fees;
echo "<br/>\nVýdaje = ". ($this->stats->bank_fees + $this->stats->invoices);
echo "<br/>\nPříjmy = ". ($this->stats->interests + $this->stats->member_fees);
echo "<br/>\nMemory usage=".(memory_get_usage()-$mem)."<p>\n";
echo"parse - end: ".(microtime(true)-$start)."<p>\n";
//print_r($this);
//die("OK");
echo html::anchor(url_lang::base().'bank_accounts/show_all', url_lang::lang('texts.Back to bank accounts'));
}
}
?>
freenetis/trunk/kohana/application/controllers/accounts.php
<?php
class Duplicity_Exception extends Exception {
public $duplicity;
public function __construct($duplicity=NULL) {$this->duplicity=$duplicity;}
}
class Accounts_Controller extends Controller
{
// private variables for importing bank listings
// accounts
private $acc_model;
private $bank_acc_model;
private $member_model;
private $fee_model;
private $parsed_acc;
private $bank_interests;
private $bank_fees;
private $suppliers;
private $operating;
private $member_fees;
// all created transfers in database should have the same time
private $current_time;
/**
* @var object $parsed_bank_acc obsahuje data o parsovaném bank. účtu (z tabluky bank_accounts)
* Používá se v callback funkci store_transfer
*/
protected $parsed_bank_acc = NULL;
protected $time_now;
protected $stats;
function index()
{
url::redirect(url_lang::base().'accounts/show_all');
......
$view->render(TRUE);
}
} // end of edit function
/**
* @author Jiri Svitak
* Deletes account. It shouldn't be used. Accounts cannot be deleted.
* @param $acc_id
* @return unknown_type
*/
function delete($acc_id = NULL)
{
/*
// access rights
if (!$this->acl_check_delete('Accounts_Controller', 'accounts'))
Controller::error(ACCESS);
if (isset($acc_id))
Controller::warning(PARAMETER);
$model_account = new Account_Model($acc_id);
$owner = $model_account->member_id;
$model_account->delete();
$this->session->set_flash('message', url_lang::lang('texts.Acount deleted.'));
url::redirect(url_lang::base().'members/show/'.(int)$owner);
*/
} // end of delete function
/**
* Function uploads bank files.
* @param $id
* @return unknown_type
*/
public function upload_bank_file($id = null)
{
if (!isset($id))
Controller::warning(PARAMETER);
if (!$this->acl_check_new('Accounts_Controller', 'bank_transfers'))
Controller::error(ACCESS);
$bank_acc_model=new Bank_account_Model($id);
if ($bank_acc_model->id == 0)
Controller::error(RECORD);
// file types of bank listings
$types = array();
$types[1] = 'CSV';
$types[2] = 'HTML eBanka';
// csv templates
$template_model = new Bank_template_Model();
$templates = $template_model->find_all();
foreach ($templates as $template)
{
$arr_templates[$template->id] = $template->template_name;
}
// form
$form = new Forge(url_lang::base()."accounts/upload_bank_file/$id", '','POST',array('id' => 'article_form'));
$form->set_attr('class', 'form_class')->set_attr('method', 'post');
$form->dropdown('type')->label(url_lang::lang('texts.File type'))->options($types)->rules('required');
$form->dropdown('csv_template')->label(url_lang::lang('texts.CSV file template'))->options($arr_templates);
$form->upload('listing', TRUE)->label(url_lang::lang('texts.File with bank transfer listing'))->rules('required');
$form->submit(url_lang::lang('texts.Submit'));
special::required_forge_style($form, ' *', 'required');
// validation
if($form->validate())
{
$form_data = $form->as_array();
if ($form_data['type'] == 2)
{
$this->parse_ebank_account(null, $form->listing->value);
}
else
{
$this->parse_csv_file($id, $form_data['csv_template'], $form->listing->value);
}
}
else
{
$title = url_lang::lang('texts.Upload bank transfers listing');
$view = new View('template');
$view->header = new View('base/header');
$view->header->title = $title;
$view->header->menu = Controller::render_menu();
$view->content = new View('form');
$view->content->form = $form->html();
$view->content->link_back = html::anchor(url_lang::base().'bank_accounts/show_all', url_lang::lang('texts.Back to bank accounts'));
$view->content->headline = $title;
$view->footer = new View('base/footer');
$view->render(TRUE);
}
}
/**
* @author Jiri Svitak
* Function prepares import of listing file. Certain double-entry accounts are created.
* @return unknown_type
*/
private function init_import()
{
$this->member_model = new Member_Model();
$this->acc_model = new Account_Model();
$this->bank_acc_model = new Bank_account_Model();
$this->fee_model = new Fee_Model();
$this->suppliers = ORM::factory('account')->find_by_account_attribute_id(Account_attribute_Model::$suppliers);
$this->member_fees = ORM::factory('account')->find_by_account_attribute_id(Account_attribute_Model::$member_fees);
$this->operating = ORM::factory('account')->find_by_account_attribute_id(Account_attribute_Model::$operating);
if (!$suppliers->id || !$member_fees->id || !$operating->id)
throw new Kohana_User_Exception('Kritická chyba', 'V DB chybí účet member_fees, suppliers nebo operating');
}
/**
* @author Jiri Svitak
* Function parses csv file with bank listing.
* It uses predefined bank template to identify columns in csv file.
* @param $bank_account_id
* @param $bank_template_id
* @return unknown_type
*/
private function parse_csv_file($bank_account_id = null, $bank_template_id = null, $url = "")
{
if (!isset($bank_account_id) || !isset($bank_template_id) || $url == "")
Controller::warning(PARAMETER);
$bank_account = new Bank_account_Model($bank_account_id);
$bank_template = new Bank_template_Model($bank_template_id);
if ($bank_account->id == 0 || $bank_template->id == 0)
Controller::error(RECORD);
// preparation
//$this->init_import();
$first = true;
$template = $bank_template->as_array();
// associatiove array - keys are template column names and values are column numbers in csv file
$headers = array();
$items = array();
// file to import
$file = fopen($url, 'r');
while (($line = fgetcsv($file, 0, $bank_template->item_separator, $bank_template->string_separator)) !== false)
{
// column headers
if ($first)
{
// goes through every header of csv file
for ($i = 0; $i < count($line); $i++)
{
// goes through every header specified by template
foreach ($template as $key => $value)
{
if (trim($value) == trim($line[$i]))
{
$headers[$key] = $i;
}
}
}
$first = false;
}
// import of line
else
{
// loads the items array with proper values
for ($i = 0; $i < count($line); $i++)
{
foreach ($headers as $key => $value)
{
if ($value == $i)
$items[$key] = $line[$i];
}
}
print_r($items);
echo '<br>';
}
}
fclose($file);
die();
}
/**
* @author Tomas Dulik
* Funkce store_transfers_ebanka se používá jako callback funkce pro Parser_Ebanka.
* Třída Parser_Ebanka tuto funkci volá s každou načtenou položkou výpisu.
* Jednotlivé položky se pak uvnitř této funkce ukládají do databáze.
* Viz http://wiki.freenetis.slfree.net/index.php/Soubor:Hospodareni.pdf
*
* @param data - objekt s následujícími položkami:
* parsed_acc_nr => 184932848 //cislo parsovaneho uctu
* parsed_acc_bank_nr=> 2400 //cislo banky parsovaneho uctu
* number => 1 //cislo vypisu
* date_time => 2008-03-25 05:40 //datum a cas
* comment => Rozpis polozek uveden v soupisu prevodu
* name => CESKA POSTA, S.P.
* account_nr => 160987123
* account_bank_nr = 0300
* type => Příchozí platba
* variable_symbol => 9081000001
* constant_symbol => 998
* specific_symbol => 9876543210
* amount => 720.00
* fee => -6.90
*
*/
public function store_transfer_ebanka($data) {
/** zde jsou statické objekty, jejichž instance tvořím jen jednou u importu prvního řádku
* výpisu (šetříme paměť...)
* */
static $acc_model, $bank_acc_model, $member_model, $fee_model, $parsed_acc;
static $bank_interests, $bank_fees, $time_deposits_interests, $time_deposits;
static $suppliers, $operating, $member_fees, $cash;
static $first_pass=true;
$this->stats->linenr++;
if ($first_pass) { // dostavame prvni radek vypisu?
$this->stats=new stdClass();
$this->time_now=date("Y-m-d H:i:s");
$member_model=new Member_Model(); // vytvorime vsechny instance, ktere potrebujeme i pro dalsi radky
$acc_model=new Account_Model();
$bank_acc_model=new Bank_account_Model();
$fee_model=new Fee_Model();
$ebank_nrs=array("2400", "5500");
if (!isset($this->parsed_bank_acc)) { // mame jiz parsovany ucet v DB? (tato promenna bude nastavena pouze pokud se parsuje ucet zvoleny v gridu uzivatelem)
// parsovany ucet dopredu nezname. Je v parsovanem vypisu? (je, pokud to neni transparentni vypis ebanky)
if (isset($data->parsed_acc_nr) && isset($data->parsed_acc_bank_nr)) {
if (in_array($data->parsed_acc_bank_nr, $ebank_nrs))
$bank_nr="5500 (2400)"; // u ebanky probehla zmena kodu banky...
else $bank_nr=$data->parsed_acc_bank_nr;
$this->parsed_bank_acc=ORM::factory('bank_account')->find_by_account_nr_and_bank_nr(
$data->parsed_acc_nr, $bank_nr);
if (!$this->parsed_bank_acc->id) { // parsovany ucet zatim neexistuje?
// tak si ho vytvorime
$acc_name="$data->parsed_acc_nr/$bank_nr";
$parsed_acc = Account_Model::create(Account_attribute_Model::$bank,
$acc_name, 1);
$this->parsed_bank_acc=Bank_account_Model::create($acc_name, $data->parsed_acc_nr,
$bank_nr, 1);
$parsed_acc->add_bank_account($this->parsed_bank_acc);
}
} else { // if (isset($data->parsed_acc_nr) ... ve výpisu není číslo parsovaného účtu = kritická chyba
$this->session->set_flash('message', url_lang::lang('texts.The parsed account is unknown.'));
return;
}
} else // if (!isset($this->parsed_bank_acc))) - parsovany ucet je v DB, tak zkontroluj, jestli vypis neni z jineho uctu:
if (isset($data->parsed_acc_nr) && isset($data->parsed_acc_bank_nr) &&
! ($data->parsed_acc_nr == $this->parsed_bank_acc->account_nr && // cisla uctu odpovidaji
($data->parsed_acc_bank_nr == $this->parsed_bank_acc->bank_nr || // cisla bank odpovidaji nebo
in_array($data->parsed_acc_bank_nr, $ebank_nrs) && // jsou obe 2400 nebo 5500
in_array($this->parsed_bank_acc->bank_nr, $ebank_nrs)
))) throw new Kohana_User_Exception('Chyba', 'Importovaný výpis není z vybraného účtu!');
// @todo tato chyba nema byt Exception, ale normalni hlášení
if (!isset($parsed_acc)) {
$parsed_acc = $this->parsed_bank_acc->get_related_account_by_attribute_id(
Account_attribute_Model::$bank);
if ($parsed_acc===FALSE)
// tohle by normálně nemělo nastat.
// může se to stát pouze pokud někdo smaže vazbu bank. účet sdružení
// s podvojným účtem přes tabulku accounts_bank_accounts
throw new Kohana_User_Exception('Kritická chyba', 'V tabulce accounts_bank_accounts chybí vazba bankovního a podvojného účtu sdružení');
}
// Teď potřebujeme najít nebo vytvořit speciální podvojné účty k parsovanému bank. učtu:
$spec_accounts=array(
"bank_interests" => "Úroky z $parsed_acc->name",
"time_deposits_interests" => "Úroky z termín. vkladů $parsed_acc->name",
"time_deposits" => "Termínované vklady $parsed_acc->name",
"bank_fees" => "Poplatky z $parsed_acc->name"
);
foreach ($spec_accounts as $accnt=>$name) {
$spec_acc=$this->parsed_bank_acc->get_related_account_by_attribute_id(
Account_attribute_Model::$$accnt);
if ($spec_acc===FALSE) { // pokud spec. ucet neexistuje, pak si jej vytvorime
$spec_acc=Account_Model::create(Account_attribute_Model::$$accnt, $name, 1);
$spec_acc->add_bank_account($this->parsed_bank_acc);
}
$$accnt=$spec_acc;
}
$suppliers=ORM::factory('account')->find_by_account_attribute_id(Account_attribute_Model::$suppliers);
$member_fees=ORM::factory('account')->find_by_account_attribute_id(Account_attribute_Model::$member_fees);
$operating=ORM::factory('account')->find_by_account_attribute_id(Account_attribute_Model::$operating);
$cash=ORM::factory('account')->find_by_account_attribute_id(Account_attribute_Model::$cash);
if (!$suppliers->id || !$member_fees->id || !$operating->id)
throw new Kohana_User_Exception('Kritická chyba', 'V DB chybí účet member_fees, suppliers nebo operating');
$first_pass=FALSE;
}
if (!empty($data->fee)) {
$fee=abs($data->fee);
$this->stats->bank_fees+=$fee;
$this->stats->bank_fees_nr++;
}
// ********************** Tak a jdeme tvořit transakce *********************
$vs=trim($data->variable_symbol);
if (empty($data->amount)) {
// ****** Bankovní poplatky: ebanka má v řádku výpisu pouze poplatek, ale castka==0
// vytvoříme transakci "bankovní poplatek z 221000 (bank. účty) na 549001 (bank. poplatky)
//a bankovní transakci z parsovaného účtu na null. Přiřadíme ji sdružení (member_id=1).
if (empty($data->comment)) $data->comment=$data->type;
$this->create_transfers($parsed_acc, $bank_fees, $fee,
$this->parsed_bank_acc, null, $data, 1);
} else // castka je nenulova:
if (empty($data->fee) && stripos($data->type, "rok") !== FALSE) {
// ***** úroky u ebanky: amount!=0, fee==0, type je "Úrok", "Kladný úrok", "Převedení úroku po kapitalizaci TV"
// Vytvoříme transakci z 644000 nebo 655000 (uroky) na 221000
// a bankovní transakci z null na parsovaný účet. Přiřadíme ji sdružení (member_id=1)
if (empty($vs)) // běžný úrok? (644000)
$this->create_transfers($interests, $parsed_acc, $data->amount,
null, $this->parsed_bank_acc, $data, 1);
else // úrok z termínovaného vkladu (655000)
$this->create_transfers($time_deposit_interests, $parsed_acc, $data->amount,
null, $this->parsed_bank_acc, $data, 1);
$this->stats->interests += $data->amount;
$this->stats->interests_nr++;
} else {
// ****** nejběžnější případ:
// - členský příspěvek, platba faktury dodavatelum, termín. vklad, výběr hotovosti ******
// Nejdriv zkusím najít majitele bankovního protiúčtu
$ks=trim($data->constant_symbol);
$term_vklad = ($ks == "968");
$member_model->clear();
$member=$member_model;
if ($term_vklad) $member->id=1; // term. vklad vždy způsobuje samo sdružení
//u ostatních typů transakcí zkusíme najít původce:
else if ($data->amount>0 && !empty($vs)) {
// členský příspěvek nebo příjem z faktury odběrateli
// @todo zpracování jiných typů VS u člen. příspěvků (např. ID+CRC16)
// uvedl člen u teto platby jako variabilni symbol (VS) svůj telefon ?
$member=$member_model->find_member_by_phone($vs);
if ($member===FALSE ) { // find_member_by_phone vrací false, pokud nic nenajde
// ne? zkusime, zda jako VS nezadal svoje member_id + crc16(member_id)
// $member=$member_model->get_member_by_crc_id($vs); // this function has bugs!!! needs rewrite!!!
$member=$member_model;
$this->stats->unasigned++;
}
}
// else { // platba přijaté faktury - majitele účtu najdeme dle VS na faktuře, až budeme mít modul přijatých faktur}
// ***Tady si vytvorime instanci účtu clena (nebo dodavatele) z prave nacteneho vypisu:
$bank_acc=$bank_acc_model->find_by_account_nr_and_bank_nr($data->account_nr, $data->account_bank_nr);
if (!$bank_acc->id) { // bank. ucet clena neexistuje, tak si ho vytvorime
$bank_acc->clear();
$bank_acc->member_id = $member->id;
$bank_acc->name = $data->name;
$bank_acc->account_nr = $data->account_nr;
$bank_acc->bank_nr = $data->account_bank_nr;
$bank_acc->save();
$this->stats->new_bank_accounts++;
// $bank_acc->add_account($member_fees); //tuto vazbu bych tvořil jen pokud bych chtěl evidovat pohyby na bank. účtech členů
}
if ($data->amount<0) {
$amount=abs($data->amount);
if ($term_vklad) { // převod peněz na účet term. vkladu
$id=$this->create_transfers($parsed_acc, $time_deposits, $amount,
$this->parsed_bank_acc, $bank_acc, $data, $member->id, null);
$this->stats->time_deposits_drawn+=$amount;
$this->stats->time_deposits_drawn_nr++;
} else {
if (stripos($data->type, "hotovost") !== FALSE) { // výběr do pokladny ?
$id=$this->create_transfers($parsed_acc, $cash, $amount,
$this->parsed_bank_acc, null, $data, $member->id, null);
$this->stats->cash_drawn+=$amount;
$this->stats->cash_drawn_nr++;
} else {
// úhrada faktury - z 221000 (bank. účet) na 321000 (dodavatelé)
if (!$member->id && $bank_acc->member_id) // pokud se předtím nepodařilo najít majitele dle VS
$member = $member_model->find($bank_acc->member_id); // zkusím ho vzít odsud
$id=$this->create_transfers($parsed_acc, $suppliers, $amount,
$this->parsed_bank_acc, $bank_acc, $data, $member->id);
$this->stats->invoices+=$amount;
$this->stats->invoices_nr++;
}
} // if ($term_vklad) ... else
if (!empty($fee)) {
// je tam bankovní poplatek - vytvoříme:
// - podvojnou transakci z 221000 (bank. účty) na 549001 (bank. poplatky)
// - bankovní transakci z parsovaného účtu na null
$data->comment = "Bank. poplatek". (!empty($data->comment) ? " ($data->comment)":"");
$this->create_transfers($parsed_acc, $bank_fees, $fee,
$this->parsed_bank_acc, null, $data, $member->id, $id);
}
} else { // $data->amount > 0
if ($term_vklad) { // převod peněz na účet term. vkladu
$id=$this->create_transfers($parsed_acc, $time_deposits, $amount,
$this->parsed_bank_acc, $bank_acc, $data, $member->id, null);
$this->stats->time_deposits_drawn+=$amount;
$this->stats->time_deposits_drawn_nr++;
} else {
// členský příspěvek - vytvoříme:
// - podvojnou transakci z 684000 na 221000
// - bankovní transakci z bank. účtu člena na bank. účet sdružení
$id=$this->create_transfers($member_fees, $parsed_acc, $data->amount,
$bank_acc, $this->parsed_bank_acc, $data, $member->id);
if (!empty($fee)) {
// bankovní poplatek - vytvoříme:
// - podvojnou transakci z 221000 (bank. účty) na 549001 (bank. poplatky)
// - bankovní transakci z parsovaného účtu na null
$data->comment = "Bank. poplatek". (!empty($data->comment) ? " ($data->comment)":"");
$this->create_transfers($parsed_acc, $bank_fees, $fee,
$this->parsed_bank_acc, null, $data, $member->id, $id);
// naše správní rada si vymyslela, že poplatek budeme dotovat z operačního účtu
// (pokud máte ve správní radě rozumnější lidi, tak tento řádek zakomentujte :-)
$this->create_transfer($operating, $parsed_acc,
abs($data->fee), $data->date_time, "Bank. poplatek hrazený sdružením",
$member->id, $id);
}
if ($member->id) { // původce je známý?
// **** převedeme peníze členovi na jeho účet s kreditem
// ten účet ale musíme najít nebo vytvořit:
$credit_acc=$acc_model->find_by_member_id_and_account_attribute_id(
$member->id, Account_attribute_Model::$credit);
if (!$credit_acc->id) {
$credit_acc->clear();
$credit_acc->account_attribute_id = Account_attribute_Model::$credit;
$credit_acc->member_id = $member->id;
/**
* @todo Jirka pri tvorbe uctu jako jmeno uctu pouziva
* prijmeni jmeno majitele. To se mi tady nechce programovat,
* protoze se jen tezko muze stat, ze by kreditni ucet neexistoval
*/
$credit_acc->name = $member->name;
$credit_acc->save();
}
$this->create_transfer($parsed_acc, $acc_model,
$data->amount, $data->date_time, "Přiřazení platby",
$member->id, $id);
// **** teď se podíváme, jestli v té době sdružení účtovalo poplatek za zpracování platby:
$fee=$fee_model->get_by_date_type($data->date_time, 'transfer fee');
if (is_object($fee) && $fee->id) // ano? Pak poplatek strhneme z účtu
$this->create_transfer($credit_acc, $operating,
$fee->fee, $data->date_time, "Transakční poplatek",
$member->id, $id);
} // if (is_object($member) && $member->id)
$this->stats->member_fees_nr++;
$this->stats->member_fees+=$data->amount;
} // if ($term_vklad) ... else {
} // else { // $data->amount > 0
} // else { // ****** castka!=0 && poplatek !=0
}
private function create_transfer($src, $dst, $amount, $datetime, $text,
$member_id=null, $prev_id=null) {
static $transfer; // static variable saves a little bit of memory & time
if (!isset($transfer)) $transfer=new Transfer_Model();
$transfer->clear();
$transfer->amount = $amount;
$transfer->datetime = $datetime;
$transfer->creation_datetime=$this->time_now;
$transfer->origin_id = $src->id;
$transfer->destination_id = $dst->id;
$transfer->text= $text;
$transfer->previous_transfer_id = $prev_id;
$transfer->member_id = $member_id;
$transfer->save();
return $transfer->id;
}
private function create_transfers($src_acc, $dst_acc, $amount,
$src_bank_acc, $dst_bank_acc, $data,
$member_id=null, $prev_id=null) {
static $transfer; // static variable saves a little bit of memory & time
static $bank_transfer;
if (!isset($transfer)) {
$transfer=new Transfer_Model();
$bank_transfer=new Bank_transfer_Model();
}
// nejdriv zkontroluj, jestli uz tuto transakci nemame od minuleho importu
$dups=$bank_transfer->get_duplicities($data);
if ($dups->count() > 0) throw new Duplicity_Exception($dups);
$transfer->clear();
$transfer->amount = $amount;
$transfer->datetime = $data->date_time;
$transfer->creation_datetime=$this->time_now;
$transfer->origin_id = $src_acc->id;
$transfer->destination_id = $dst_acc->id;
$transfer->text= $data->comment;
$transfer->previous_transfer_id=$prev_id;
$transfer->member_id = $member_id;
$transfer->save();
$bank_transfer->clear();
$bank_transfer->transfer_id = $transfer->id;
$bank_transfer->origin_id = isset($src_bank_acc)? $src_bank_acc->id : null;
$bank_transfer->destination_id = isset($dst_bank_acc)? $dst_bank_acc->id : null;
$bank_transfer->variable_symbol = $data->variable_symbol;
$bank_transfer->constant_symbol = $data->constant_symbol;
$bank_transfer->specific_symbol = $data->specific_symbol;
$bank_transfer->save();
return $transfer->id;
}
/**
* @author Tomas Dulik
* @param $url - URL containing the file to parse
* @param $account_id - ID of the account whose data will be parsed.
* @return void
*/
public function parse_ebank_account($bank_account_id=NULL, $url="") {
$parser=new Parser_Ebanka();
echo "Memory usage=".($mem=memory_get_usage()). "<p>\n";
echo"parse - start: ".($start=microtime(true))."<p>\n";
//$parser->set_callback(array($this, "print_row"));
$parser->set_callback(array($this, "store_transfer_ebanka"));
// pokud z gridu dostáváme $account_id, pak si ho uložíme pro potřeby callback funkce
if (isset($bank_account_id))
$this->parsed_bank_acc=new Bank_account_Model($bank_account_id);
//print_r ($parser);
// $parser->parse("c:/txt/unart/ucto/vypisy/2007/09.html");
//$parser->parse("http://www.rb.cz/firemni-finance/transparentni-ucty/?root=firemni-finance&item1=transparentni-ucty&tr_acc=vypis&account_number=184932848");
if (empty($url)) $url="/var/www/freenetis-import/08.html.htm";
try {
$parser->parse($url);
} catch (Duplicity_Exception $ex) {
// v případě duplicity commitujeme vše do výskytu duplicity a hned skončíme
echo "Končíme, právě importovaný záznam má již v databázi duplicitní záznam:<br/>\n";
echo "<table border=1>";
$first=true; $header="";
foreach ($ex->duplicity as $dup) {
echo "<tr>\n"; $data="";
foreach ($dup as $key=>$val) {
if ($first)
$header.="<th>$key</th>";
$data.="<td>$val</td>";
}
if ($first) {
echo $header;
echo "</tr>\n";
$first=false;
}
echo $data;
echo "</tr>\n";
}
}
//$parser->parse("http://localhost/2007.html");
//$parser->parse("c:/txt/unart/ucto/vypisy/2007/2007.html");
echo "<table border=1>\n";
foreach ($this->stats as $key=>$value)
echo "<tr><td>$key</td><td>$value</td></tr>";
echo "</table>\n";
if (!isset($this->stats->invoices)) $this->stats->invoices=0;
if (!isset($this->stats->interests)) $this->stats->interests=0;
if (!isset($this->stats->bank_fees)) $this->stats->bank_fees=0;
if (!isset($this->stats->member_fees)) $this->stats->member_fees=0;
echo "Bank. poplatky = ". $this->stats->bank_fees;
echo "<br/>\nVýdaje = ". ($this->stats->bank_fees + $this->stats->invoices);
echo "<br/>\nPříjmy = ". ($this->stats->interests + $this->stats->member_fees);
echo "<br/>\nMemory usage=".(memory_get_usage()-$mem)."<p>\n";
echo"parse - end: ".(microtime(true)-$start)."<p>\n";
//print_r($this);
//die("OK");
echo html::anchor(url_lang::base().'bank_accounts/show_all', url_lang::lang('texts.Back to bank accounts'));
}
}
?>
freenetis/trunk/kohana/application/libraries/MY_Controller.php
$acc_menu .= '<li>'.html::anchor(url_lang::base().'bank_accounts/show_all', url_lang::lang('texts.Bank accounts')).'</li>
<li>'.html::anchor(url_lang::base().'accounts/show_all', url_lang::lang('texts.Double-entry accounts')).'</li>
<li>'.html::anchor(url_lang::base().'transfers/show_all', url_lang::lang('texts.Day book')).'</li>
<li>'.html::anchor(url_lang::base().'accounts/cash_flow', url_lang::lang('texts.Cash flow')).'</li>
<li>'.html::anchor(url_lang::base().'invoices', url_lang::lang('texts.Invoices')).'</li>';
if ($acc_menu != '') $myMenu .= '<li class="transfer"><h2>'.url_lang::lang('texts.Finances').'</h2>
<ul>
......
<ul>
<li>'.html::anchor(url_lang::base().'members', url_lang::lang('texts.Members')).'</li>
<li>'.html::anchor(url_lang::base().'users', url_lang::lang('texts.Users')).'</li>';
if ($this->acl_check_2D('menu', 'registration_admin')) $myMenu .= '<li>'.html::anchor(url_lang::base().'members/registration', url_lang::lang('texts.Edit registrations')).'</li>';
$myMenu .= '</ul>
</li>';
freenetis/trunk/kohana/application/views/bank_transfers/show_by_bank_account.php
<td><?php echo $ba->account_nr ?></td>
</tr>
<tr>
<th><?php echo url_lang::lang('texts.Bank number')?></th>
<th><?php echo url_lang::lang('texts.Bank code')?></th>
<td><?php echo $ba->bank_nr ?></td>
</tr>
</table>

Také k dispozici: Unified diff