redesign for mulituser
change validation concept (client and server) using entities
This commit is contained in:
@@ -30,7 +30,12 @@ class Email extends BaseConfig
|
|||||||
/**
|
/**
|
||||||
* SMTP Server Hostname
|
* SMTP Server Hostname
|
||||||
*/
|
*/
|
||||||
public string $SMTPHost ="web110.dogado.de";
|
public string $SMTPHost = 'web110.dogado.de';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Which SMTP authentication method to use: login, plain
|
||||||
|
*/
|
||||||
|
public string $SMTPAuthMethod = 'login';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SMTP Username
|
* SMTP Username
|
||||||
|
|||||||
@@ -4,30 +4,37 @@ use CodeIgniter\Router\RouteCollection;
|
|||||||
|
|
||||||
/** @var RouteCollection $routes */
|
/** @var RouteCollection $routes */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// We get a performance increase by specifying the default
|
// We get a performance increase by specifying the default
|
||||||
// route since we don't have to scan directories.
|
// route since we don't have to scan directories.
|
||||||
$routes->get('/', 'Home::overview');
|
$routes->get('/', 'Home::overview');
|
||||||
$routes->get('Ajax/(:segment)', 'Ajax::$1');
|
|
||||||
$routes->post('Ajax/(:segment)', 'Ajax::$1');
|
//ajax requests for Tableview
|
||||||
$routes->get('newBill', 'Home::newBill');
|
$routes->get('viewInvoice/(:any)', 'FormHandler::viewInvoice/$1');
|
||||||
$routes->get('newTransfer', 'Home::newTransfer');
|
$routes->post('edit', 'FormHandler::editForm');
|
||||||
$routes->get('newScheduled', 'Home::newScheduled/0');
|
|
||||||
$routes->get('newScheduledTransfer', 'Home::newScheduled/1');
|
$routes->get('newScheduled', 'Scheduled::new/0');
|
||||||
|
$routes->get('newScheduledTransfer', 'Scheduled::new/1');
|
||||||
|
$routes->get('editScheduled/(:num)', 'Scheduled::edit/$1');
|
||||||
|
$routes->get('getScheduledData', 'Scheduled::getTabData');
|
||||||
|
$routes->post('deleteScheduled', 'Scheduled::delete');
|
||||||
|
$routes->get('syncScheduled', 'Scheduled::sync');
|
||||||
|
$routes->get('viewScheduled', 'Scheduled::viewScheduled');
|
||||||
|
|
||||||
|
|
||||||
$routes->post('newBill', 'Home::attemptNewBilling');
|
$routes->get('getOverviewData', 'Bills::getOverviewData');
|
||||||
$routes->post('editAccount', 'Home::attemptEditAccount');
|
$routes->get('getAccountsBalance', 'Bills::getAccountsBalance');
|
||||||
$routes->get('editBill/(:num)', 'Home::editBill/$1');
|
$routes->get('getToDosData', 'Bills::getToDosData');
|
||||||
$routes->get('editScheduled/(:num)', 'Home::editScheduled/$1');
|
$routes->post('getActivitiesData', 'Bills::getActivitiesData');
|
||||||
$routes->get('syncScheduled', 'Home::syncScheduled');
|
$routes->get('newBill', 'Bills::edit/0');
|
||||||
|
$routes->get('newTransfer', 'Bills::edit/0/1');
|
||||||
|
$routes->get('editBill/(:num)', 'Bills::edit/$1');
|
||||||
|
$routes->get('viewActivities', 'Bills::viewActivities');
|
||||||
|
$routes->post('deleteBill', 'Bills::delete');
|
||||||
|
|
||||||
|
$routes->post('editAccount', 'Accounts::attemptEditAccount');
|
||||||
|
$routes->match(['GET', 'POST'],'viewAccounts', 'Accounts::index');
|
||||||
|
|
||||||
|
|
||||||
$routes->get('viewAccounts', 'Home::viewAccountsTree');
|
|
||||||
$routes->get('viewActivities', 'Home::viewAccountActivities');
|
|
||||||
$routes->get('viewScheduled', 'Home::viewScheduled');
|
|
||||||
$routes->get('viewBill/(:any)', 'Home::viewBill/$1');
|
|
||||||
$routes->get('viewChart', 'Charts::getData/0');
|
$routes->get('viewChart', 'Charts::getData/0');
|
||||||
$routes->get('viewChart/(:num)', 'Charts::getData/$1');
|
$routes->get('viewChart/(:num)', 'Charts::getData/$1');
|
||||||
|
|
||||||
|
|||||||
44
app/Controllers/Accounts.php
Normal file
44
app/Controllers/Accounts.php
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<?php namespace App\Controllers;
|
||||||
|
|
||||||
|
use CodeIgniter\Session\Session;
|
||||||
|
use App\Models\mAccounts;
|
||||||
|
use Config\App;
|
||||||
|
|
||||||
|
class Accounts extends BaseController {
|
||||||
|
private \App\Models\mAccounts $accounts;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
$this->accounts = new mAccounts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function index(){
|
||||||
|
if ($this->request->is('post')) {
|
||||||
|
return $this->editAccount();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return $this->viewAccountsTree();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function viewAccountsTree($data = array()){
|
||||||
|
helper('form');
|
||||||
|
$data = array_merge($data,$this->accounts->getTreeData());
|
||||||
|
$data['ddlist'] = $this->accounts->getDropDownList( 'all', false,true );
|
||||||
|
return view('accountstree',$data);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function editAccount(){
|
||||||
|
$rules = [
|
||||||
|
'description' => 'required',
|
||||||
|
];
|
||||||
|
if (! $this->validate($rules)) {
|
||||||
|
return $this->viewAccountsTree(['errors'=>$this->validator->getErrors()]);
|
||||||
|
}
|
||||||
|
$saveDB = array();
|
||||||
|
if ($this->accounts->saveAccount($this->request->getPost()))
|
||||||
|
$saveDB = ['mode'=>'alert-success','message'=>'Erfolgreich gespeichert'];
|
||||||
|
else
|
||||||
|
$saveDB = ['mode'=>'alert-danger','message'=>'Speichern fehlgeschlagen'];
|
||||||
|
|
||||||
|
return $this->viewAccountsTree(['saveDB'=>$saveDB]);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Controllers;
|
|
||||||
use App\Models\mBills;
|
|
||||||
use CodeIgniter\Session\Session;
|
|
||||||
|
|
||||||
|
|
||||||
class Ajax extends BaseController
|
|
||||||
{
|
|
||||||
|
|
||||||
protected $session;
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$this->session = service('session');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getTabelData(){
|
|
||||||
if (!$this->request->isAJAX()) return;
|
|
||||||
$billing = model('App\Models\mBills');
|
|
||||||
$start = $this->request->getPost('datum_start')??session('datum_start');
|
|
||||||
$ende = $this->request->getPost('datum_ende')??session('datum_ende');
|
|
||||||
$src = intval($this->request->getPost('source')) ?? 0;
|
|
||||||
$_SESSION['datum_start'] = $start;
|
|
||||||
$_SESSION['datum_ende'] = $ende;
|
|
||||||
$_SESSION['source'] = $src;
|
|
||||||
$result = $billing->getEntriesDet($start,$ende,$src);
|
|
||||||
return json_encode($result);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAccountsBalance(){
|
|
||||||
if (!$this->request->isAJAX()) return;
|
|
||||||
$billing = model('App\Models\mBills');
|
|
||||||
return json_encode($billing->getAccountsBalance());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getScheduledData(){
|
|
||||||
if (!$this->request->isAJAX()) return;
|
|
||||||
$scheduled = model('App\Models\mScheduled');
|
|
||||||
return json_encode($scheduled->getEntries());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getToDosData(){
|
|
||||||
if (!$this->request->isAJAX()) return;
|
|
||||||
$billing = model('App\Models\mBills');
|
|
||||||
return json_encode($billing->getToDos());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getOverviewData(){
|
|
||||||
if (!$this->request->isAJAX()) return;
|
|
||||||
$billing = model('App\Models\mBills');
|
|
||||||
$result = $billing->getEntries();
|
|
||||||
return json_encode($result);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function deleteBill(){
|
|
||||||
if (!$this->request->isAJAX()) return;
|
|
||||||
$bills = model('App\Models\mBills');
|
|
||||||
$bills->deleteEntry($this->request->getPost('id'));
|
|
||||||
return json_encode(["result"=>"done"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function deleteScheduled(){
|
|
||||||
if (!$this->request->isAJAX()) return;
|
|
||||||
$scheduled = model('App\Models\mScheduled');
|
|
||||||
$scheduled->delete($this->request->getPost('id'));
|
|
||||||
return json_encode(["result"=>"done"]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
||||||
90
app/Controllers/Bills.php
Normal file
90
app/Controllers/Bills.php
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
<?php namespace App\Controllers;
|
||||||
|
|
||||||
|
use App\Models\mAccounts;
|
||||||
|
|
||||||
|
use function PHPUnit\Framework\logicalXor;
|
||||||
|
use App\Models\mBills;
|
||||||
|
use CodeIgniter\API\ResponseTrait;
|
||||||
|
include_once (dirname(__FILE__) . "/FormHandler.php");
|
||||||
|
|
||||||
|
class Bills extends FormHandler {
|
||||||
|
|
||||||
|
use ResponseTrait;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public function edit(int $id, bool $transfer=false){
|
||||||
|
if ($id == 0){ // erstellen eines leeren Formular
|
||||||
|
log_message('debug','Bills::edit: new bill');
|
||||||
|
$eBooking = new \App\Entities\eBooking();
|
||||||
|
$eBooking->transfer = $transfer;
|
||||||
|
$eBooking->scheduled = false;
|
||||||
|
$data = $eBooking->getNew();
|
||||||
|
} else {
|
||||||
|
$billModel = model(mBills::class);
|
||||||
|
$bill = $billModel->find($id); /* @var \App\Entity\eBooking $bill */
|
||||||
|
$bill->datum = date( "Y-m-d", strtotime( $bill->datum ));
|
||||||
|
$data = $bill->fillDetails();
|
||||||
|
log_message('debug','Bills::edit:ID:'.$id.'; Data: '.json_encode($bill->toArray()));
|
||||||
|
}
|
||||||
|
return $this->viewBill($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function viewActivities(){
|
||||||
|
$accounts = model('App\Models\mAccounts'); /* @var \App\Models\mAccounts $accounts */
|
||||||
|
$data = array();
|
||||||
|
$data['source'] = 0;
|
||||||
|
$data['start'] = session('datum_start') ?? date("Y-m-d", strtotime( "- 2 weeks", strtotime( "now" ) ));
|
||||||
|
$data['ende'] = session('datum_ende') ?? date("Y-m-d", strtotime( "now" ) );
|
||||||
|
$data['source'] = session('source') ?? 0;
|
||||||
|
$data['sourcelist'] = $accounts->getDropDownList( 'all', true );
|
||||||
|
return view('activities', $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getOverviewData(){
|
||||||
|
if (!$this->request->isAJAX()) return;
|
||||||
|
$billing = model('App\Models\mBills');
|
||||||
|
$result = $billing->getEntries(10);
|
||||||
|
return json_encode($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getActivitiesData(){
|
||||||
|
if (!$this->request->isAJAX()) return;
|
||||||
|
$billing = model('App\Models\mBills');
|
||||||
|
$start = $this->request->getPost('datum_start')??session('datum_start');
|
||||||
|
$ende = $this->request->getPost('datum_ende')??session('datum_ende');
|
||||||
|
$src = intval($this->request->getPost('source'));
|
||||||
|
$_SESSION['datum_start'] = $start;
|
||||||
|
$_SESSION['datum_ende'] = $ende;
|
||||||
|
$_SESSION['source'] = $src;
|
||||||
|
$result = $billing->getEntriesDet($start,$ende,$src);
|
||||||
|
return json_encode($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete(){
|
||||||
|
if ($this->request->is('post')) {
|
||||||
|
if (!ctype_digit($this->request->getPost("id"))) return $this->failForbidden("Ungültige ID");
|
||||||
|
log_message('debug',"delete id: ".$this->request->getPost("id"));
|
||||||
|
$billModel = model(mBills::class);
|
||||||
|
$result = $billModel->deleteEntry(intval($this->request->getPost("id")));
|
||||||
|
if ($result !== true)
|
||||||
|
return $this->fail("Database error ".$result);
|
||||||
|
else
|
||||||
|
return $this->respondDeleted(['url'=>session('redirect_url') ?? site_url('/'),'ID'=>$this->request->getPost("id")]);
|
||||||
|
}
|
||||||
|
return $this->failUnauthorized("Schäm Dich");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getToDosData(){
|
||||||
|
if (!$this->request->isAJAX()) return;
|
||||||
|
$billing = model('App\Models\mBills');
|
||||||
|
return json_encode($billing->getToDos());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAccountsBalance(){
|
||||||
|
if (!$this->request->isAJAX()) return;
|
||||||
|
$billing = model('App\Models\mBills');
|
||||||
|
return json_encode($billing->getAccountsBalance());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,26 +10,32 @@ class Charts extends BaseController {
|
|||||||
$this->db = \Config\Database::connect();
|
$this->db = \Config\Database::connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getData($id){
|
public function getData(int $id){
|
||||||
if ($id == 0)
|
if ($id == 0)
|
||||||
return $this->getAllData();
|
return $this->getAllData();
|
||||||
else
|
else
|
||||||
return $this->getDetailData($id);
|
return $this->getDetailData($id);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getDetailData($id){
|
private function getDetailData(int $id){
|
||||||
|
$accounts = model('App\Models\mAccounts'); /* @var \App\Models\mAccounts $accounts */
|
||||||
|
$bills = model('App\Models\mBills'); /* @var \App\Models\mBills $bills */
|
||||||
|
$billDet = model('App\Models\mBillDetails'); /* @var \App\Models\mBills $billDet */
|
||||||
|
$accTable = $accounts->getTable();
|
||||||
|
$billTable = $bills->getTable();
|
||||||
|
$billDetTable = $billDet->getTable();
|
||||||
$jetzt = date('Y-m-01');
|
$jetzt = date('Y-m-01');
|
||||||
$query = <<<EOD
|
$query = <<<EOD
|
||||||
SELECT
|
SELECT
|
||||||
SUM(subamount)*(-1) AS Amount,
|
SUM(subamount)*(-1) AS Amount,
|
||||||
description,account_id as id
|
description,account_id as id
|
||||||
FROM
|
FROM
|
||||||
finanzen.budget_billdetails, finanzen.budget_bills,finanzen.budget_accounts
|
$billDetTable, $billTable,$accTable
|
||||||
WHERE
|
WHERE
|
||||||
datum >= '$jetzt'
|
datum >= '$jetzt'
|
||||||
AND (datum < '$jetzt'::date + interval '1 month')
|
AND (datum < '$jetzt'::date + interval '1 month')
|
||||||
AND budget_bills.id = bill_id
|
AND $billTable.id = bill_id
|
||||||
AND account_id = finanzen.budget_accounts.id
|
AND account_id = $accTable.id
|
||||||
AND (account_id IN (
|
AND (account_id IN (
|
||||||
WITH RECURSIVE subordinates AS (
|
WITH RECURSIVE subordinates AS (
|
||||||
SELECT
|
SELECT
|
||||||
@@ -37,7 +43,7 @@ class Charts extends BaseController {
|
|||||||
parent_id,
|
parent_id,
|
||||||
description
|
description
|
||||||
FROM
|
FROM
|
||||||
finanzen.budget_accounts
|
$accTable
|
||||||
WHERE
|
WHERE
|
||||||
id = $id
|
id = $id
|
||||||
UNION
|
UNION
|
||||||
@@ -46,7 +52,7 @@ class Charts extends BaseController {
|
|||||||
e.parent_id,
|
e.parent_id,
|
||||||
e.description
|
e.description
|
||||||
FROM
|
FROM
|
||||||
finanzen.budget_accounts e
|
$accTable e
|
||||||
INNER JOIN subordinates s ON s.id = e.parent_id)
|
INNER JOIN subordinates s ON s.id = e.parent_id)
|
||||||
SELECT
|
SELECT
|
||||||
id
|
id
|
||||||
@@ -72,16 +78,24 @@ class Charts extends BaseController {
|
|||||||
return view("charts/monthly", $data);
|
return view("charts/monthly", $data);
|
||||||
}
|
}
|
||||||
private function getAllData(){
|
private function getAllData(){
|
||||||
|
$accounts = model('App\Models\mAccounts'); /* @var \App\Models\mAccounts $accounts */
|
||||||
|
$bills = model('App\Models\mBills'); /* @var \App\Models\mBills $bills */
|
||||||
|
$billDet = model('App\Models\mBillDetails'); /* @var \App\Models\mBills $billDet */
|
||||||
|
$accTable = $accounts->getTable();
|
||||||
|
$billTable = $bills->getTable();
|
||||||
|
$billDetTable = $billDet->getTable();
|
||||||
$jetzt = date('Y-m-01');
|
$jetzt = date('Y-m-01');
|
||||||
$query = <<<EOD
|
$query = <<<EOD
|
||||||
SELECT * FROM (
|
SELECT * FROM (
|
||||||
SELECT id, description,sum(amount)as summe FROM (SELECT id,description from finanzen.budget_accounts WHERE parent_id=0 AND type='output' AND LKZ is null) as w,
|
SELECT id, description,sum(amount)as summe FROM (SELECT id,description from $accTable WHERE parent_id=0 AND account=false AND deleted_at is null) as w,
|
||||||
LATERAL
|
LATERAL
|
||||||
(SELECT ABS(SUM(subamount)) as amount
|
(SELECT ABS(SUM(subamount)) as amount
|
||||||
FROM finanzen.budget_billdetails, finanzen.budget_bills
|
FROM $billDetTable, $billTable
|
||||||
WHERE datum >= '$jetzt'
|
WHERE datum >= '$jetzt'
|
||||||
AND budget_bills.id = bill_id
|
AND $billTable.deleted_at is null
|
||||||
AND (account_id IN
|
AND $billDetTable.deleted_at is null
|
||||||
|
AND $billTable.id = $billDetTable.bill_id
|
||||||
|
AND (account_id IN
|
||||||
(
|
(
|
||||||
WITH RECURSIVE subordinates AS (
|
WITH RECURSIVE subordinates AS (
|
||||||
SELECT
|
SELECT
|
||||||
@@ -89,7 +103,7 @@ class Charts extends BaseController {
|
|||||||
parent_id,
|
parent_id,
|
||||||
description
|
description
|
||||||
FROM
|
FROM
|
||||||
finanzen.budget_accounts
|
$accTable
|
||||||
WHERE
|
WHERE
|
||||||
id = w.id
|
id = w.id
|
||||||
UNION
|
UNION
|
||||||
@@ -98,7 +112,7 @@ class Charts extends BaseController {
|
|||||||
e.parent_id,
|
e.parent_id,
|
||||||
e.description
|
e.description
|
||||||
FROM
|
FROM
|
||||||
finanzen.budget_accounts e
|
$accTable e
|
||||||
INNER JOIN subordinates s ON s.id = e.parent_id)
|
INNER JOIN subordinates s ON s.id = e.parent_id)
|
||||||
SELECT
|
SELECT
|
||||||
id
|
id
|
||||||
@@ -109,6 +123,7 @@ class Charts extends BaseController {
|
|||||||
EOD;
|
EOD;
|
||||||
$data = array();
|
$data = array();
|
||||||
$result = $this->db->query($query);
|
$result = $this->db->query($query);
|
||||||
|
log_message('debug','Charts::getAllData: '.$this->db->getLastQuery());
|
||||||
foreach ($result->getResult() as $row) {
|
foreach ($result->getResult() as $row) {
|
||||||
$werte[] = $row->summe;
|
$werte[] = $row->summe;
|
||||||
$ids[] = $row->id;
|
$ids[] = $row->id;
|
||||||
|
|||||||
195
app/Controllers/FormHandler.php
Normal file
195
app/Controllers/FormHandler.php
Normal file
@@ -0,0 +1,195 @@
|
|||||||
|
<?php namespace App\Controllers;
|
||||||
|
|
||||||
|
use App\Models\mAccounts;
|
||||||
|
|
||||||
|
use function PHPUnit\Framework\logicalXor;
|
||||||
|
use App\Models\mBills;
|
||||||
|
|
||||||
|
|
||||||
|
class FormHandler extends BaseController {
|
||||||
|
|
||||||
|
public function editForm(){
|
||||||
|
if ($this->request->is('post')) {
|
||||||
|
log_message('debug','Bills::edit: post data: '.json_encode($this->request->getPost()));
|
||||||
|
return $this->checkBillForm();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return $this->viewBill($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prüft ob Kategorie vorhanden wenn ein Betrag eingegeben wurde, ohne Betrag und ohne Kategorie wird die Zeile ignoriert bzw. gelöscht
|
||||||
|
*/
|
||||||
|
public function _ruleBookingLineAcc($value, array $data, ?string &$error, string $field){
|
||||||
|
log_message('debug',"Bills::_ruleBookingLineAcc Typ von übergegeben Wert".gettype($value));
|
||||||
|
$index = explode('.', $field)[1];
|
||||||
|
if ($value > 0) return true;
|
||||||
|
|
||||||
|
if ($index == 0)
|
||||||
|
$error = "Kategorie fehlt";
|
||||||
|
else if ((is_numeric($data['input'][$index]) && (round($data['input'][$index],2) > 0.0)) || (is_numeric($data['output'][$index]) && (round($data['output'][$index]) > 0.0)))
|
||||||
|
$error = "Kategorie in Zeile " . $index . " fehlt";
|
||||||
|
|
||||||
|
return empty($error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prüft ob Teilbetrag vorhanden wenn eine Kategorie ausgewählt wurde, ohne Betrag und ohne Kategorie wird die Zeile ignoriert bzw. gelöscht
|
||||||
|
* auch wird geprüft dass nur Input oder Output einen Wert enthält, soll im Javascript gemacht werden wenn ordentlich läuft
|
||||||
|
*/
|
||||||
|
public function _ruleBookingLineAmount(string $value, array $data, ?string &$error, string $field){
|
||||||
|
log_message('debug',"Bills::_ruleBookingLineAmount Typ von übergegeben Wert ".gettype($value));
|
||||||
|
$index = explode('.', $field)[1];
|
||||||
|
if ((is_numeric($data['input'][$index]) && (round($data['input'][$index],2) > 0.0)) xor
|
||||||
|
(is_numeric($data['output'][$index]) && (round($data['output'][$index],2) > 0.0)))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if ((is_numeric($data['input'][$index]) && (round($data['input'][$index],2) > 0.0)) && (is_numeric($data['output'][$index]) && (round($data['output'][$index],2) > 0.0)))
|
||||||
|
$error = "Systemfehler: Nur Input oder Output darf einen Wert haben";
|
||||||
|
|
||||||
|
else if (($index == 0) && (count($data['input'])==1))
|
||||||
|
$error = "Betrag fehlt";
|
||||||
|
else if (is_numeric($data['account_id'][$index]) && ($data['account_id'][$index] > 0))
|
||||||
|
$error = "Betrag in Zeile " . $index+1 . " fehlt";
|
||||||
|
|
||||||
|
return empty($error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rechnet nach ob der Virtuelle Gesamtbetrag (berechnet javascript) stimmt
|
||||||
|
*/
|
||||||
|
public function _ruleCalcAmount(string $value, array $data, ?string &$error, string $field){
|
||||||
|
$subamounts = 0.0;
|
||||||
|
foreach ($data['input'] as $i => $inp){
|
||||||
|
$subamounts = $subamounts + round(floatval($inp),2) - round(floatval($data['output'][$i]),2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (round($value,2) == round($subamounts,2))
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
$error = "Systemfehler: Amount Client ". floatval($value) . " ungleich Server Amount ". floatval($subamounts) ." Kalkulation; Diff = ".floatval($value)-floatval($subamounts);
|
||||||
|
|
||||||
|
|
||||||
|
return empty($error);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function _ruleCalcTotal(string $value, array $data, ?string &$error, string $field){
|
||||||
|
log_message('debug',"Bills::_ruleCalcTotal In: ".$data['total_in']."; Out: ".$data['total_out']);
|
||||||
|
|
||||||
|
if ((is_numeric($data['total_in']) && (round($data['total_in'],2) > 0.0)) && (is_numeric($data['total_out']) && (round($data['total_out'],2) > 0.0))) {
|
||||||
|
$error = "Systemfehler: Gesamtbetrag darf nur Input oder Output sein";
|
||||||
|
// } else if ((!is_numeric($data['total_in'])) && (!is_numeric($data['total_out']))) {
|
||||||
|
// $error = "Systemfehler: Gesamtbetrag muss angegeben sein";
|
||||||
|
} else {
|
||||||
|
$total = round(floatval($data['total_in'])-floatval($data['total_out']),2);
|
||||||
|
if (($total !== round(floatval($data['amount']),2)) && (round(floatval($data['openamount']),2) == 0.0))
|
||||||
|
$error = "Systemfehler: Gesamtbetrag entspricht nicht Teilbeträgen";
|
||||||
|
}
|
||||||
|
log_message('debug',"Bills::_ruleCalcTotal Ergebnis ".$error);
|
||||||
|
return empty($error);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function checkBillForm(){
|
||||||
|
$rules = [
|
||||||
|
'id'=>['required','is_natural'],
|
||||||
|
'source_id' => ['label'=>'Konto','rules'=>['required','greater_than[0]'],'errors'=>['greater_than'=>'Konto fehlt']],
|
||||||
|
'datum' => 'required',
|
||||||
|
'scheduled' => 'required',
|
||||||
|
'transfer' => 'required',
|
||||||
|
'sid.*' => ['label'=>'BuchungszeileID','rules'=>['required','is_natural']],
|
||||||
|
'receiver' => ['label'=>'Empfänger','rules'=>['required','max_length[120]'],'errors'=>['required'=>'Empfänger fehlt']],
|
||||||
|
'account_id.*' => [[$this,'_ruleBookingLineAcc']],
|
||||||
|
'input.*' => [[$this,'_ruleBookingLineAmount']],
|
||||||
|
'comment.*' => ['label'=>'Kommentar','rules'=>['max_length[150]']],
|
||||||
|
'output.*' => ['permit_empty','numeric'],
|
||||||
|
'amount' => ['required', 'numeric', [$this,'_ruleCalcAmount']],
|
||||||
|
'billfile' => ['max_size[billfile,10000]','mime_in[billfile,application/pdf,image/jpg,image/jpeg]'],
|
||||||
|
'removeBillFile' => ['max_length[50]'],
|
||||||
|
'validate' => ['required'],
|
||||||
|
'scheduledNum' =>['required_with[scheduled]','permit_empty','numeric'],
|
||||||
|
'scheduledType' =>['required_with[scheduled]','permit_empty','in_list[week,month,year]']
|
||||||
|
];
|
||||||
|
if ( 1 < count($this->request->getPost('sid')) ) {
|
||||||
|
$rules['openamount'] = ['rules'=>['numeric','equals[0.00]'], 'errors'=>['equals'=>'Restbetrag muss 0 sein']];
|
||||||
|
$rules['total_in'] = [[$this,'_ruleCalcTotal']];
|
||||||
|
$rules['total_out'] = ['required_without[total_in]','permit_empty','numeric'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $this->request->getPost();// filter getPost by array_keys($rules) but indexed rules not working
|
||||||
|
log_message('debug','Bills::checkBillForm: Form Data: '.json_encode($data));
|
||||||
|
|
||||||
|
if (! $this->validateData($data, $rules)){
|
||||||
|
log_message('debug','Bills::checkBillForm: validation failed: '.json_encode($data));
|
||||||
|
log_message('debug','Bills::checkBillForm: validation failed: '.json_encode($this->validator->getErrors()));
|
||||||
|
$eBooking = new \App\Entities\eBooking($data);
|
||||||
|
return $this->viewBill($eBooking, $this->validator->getErrors());
|
||||||
|
// return redirect()->back()->withInput()->with('errors', $validation->getErrors());
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
log_message('debug','Bills::checkBillForm: validation success: '.json_encode($this->validator->getValidated()));
|
||||||
|
$eBooking = new \App\Entities\eBooking($this->validator->getValidated());
|
||||||
|
if ($data['scheduled'] == "0"){
|
||||||
|
$file = $this->request->getFile('billfile');
|
||||||
|
if ($file) {
|
||||||
|
if (! $file->isValid() && ($file->getError() != UPLOAD_ERR_NO_FILE)) {
|
||||||
|
throw new \RuntimeException($file->getErrorString() . '(' . $file->getError() . ')');
|
||||||
|
}
|
||||||
|
$eBooking->setInvoice($file);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $eBooking->saveIt();
|
||||||
|
if (true !== $result) // show error of database
|
||||||
|
$this->viewBill($eBooking, $result);
|
||||||
|
|
||||||
|
$redirectURL = session('redirect_url') ?? site_url('/');
|
||||||
|
unset($_SESSION['redirect_url']);
|
||||||
|
return redirect()->to($redirectURL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function viewBill(\App\Entities\eBooking $fdata, $errors = NULL){
|
||||||
|
helper('form');
|
||||||
|
log_message('debug','Bills::viewBill: fdata: '.json_encode($fdata->toArray()));
|
||||||
|
|
||||||
|
$data['booking'] = $fdata->getFormData();
|
||||||
|
|
||||||
|
$data['validation'] = $errors;
|
||||||
|
return view('newBill', $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function viewInvoice(string $filename) {
|
||||||
|
$filePath= WRITEPATH . '/uploads/'.auth()->user()->preFixDB;
|
||||||
|
$file = new \CodeIgniter\Files\File($filePath."/".$filename);
|
||||||
|
log_message('debug',$file->getMimeType());
|
||||||
|
if ($file->getMimeType() == 'application/pdf')
|
||||||
|
$this->viewPdf($filename);
|
||||||
|
else{
|
||||||
|
$imginfo = getimagesize($filePath."/".$filename);
|
||||||
|
header("Content-type: {$imginfo['mime']}");
|
||||||
|
readfile($filePath."/".$filename);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
// return view('viewBillImg', ['filename'=>'writable/uploads/'.$filename]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private function viewPdf(string $filename) {
|
||||||
|
// $view = \Config\Services::renderer();
|
||||||
|
log_message('debug',$filename);
|
||||||
|
$filePath= WRITEPATH . '/uploads/'.auth()->user()->preFixDB;
|
||||||
|
header("Cache-Control: maxage=1");
|
||||||
|
header("Pragma: public");
|
||||||
|
header('Content-type:application/pdf');
|
||||||
|
header('Content-disposition: inline; filename="'.$filename.'"');
|
||||||
|
header('content-Transfer-Encoding:binary');
|
||||||
|
header('Content-Length:' .filesize($filePath."/".$filename));
|
||||||
|
if (($pdf =file_get_contents($filePath."/".$filename)) === false)
|
||||||
|
print $filePath."/".$filename;
|
||||||
|
else
|
||||||
|
print $pdf;
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,352 +1,28 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Controllers;
|
namespace App\Controllers;
|
||||||
use App\Models\mBills;
|
|
||||||
use App\Models\mAccounts;
|
use App\Models\mAccounts;
|
||||||
|
use App\Models\mBills;
|
||||||
use CodeIgniter\Session\Session;
|
use CodeIgniter\Session\Session;
|
||||||
use CodeIgniter\Files\File;
|
use CodeIgniter\Files\File;
|
||||||
use CodeIgniter\I18n\Time;
|
use CodeIgniter\I18n\Time;
|
||||||
|
|
||||||
class Home extends BaseController
|
class Home extends BaseController {
|
||||||
{
|
|
||||||
|
|
||||||
private $accounts;
|
|
||||||
/**
|
/**
|
||||||
* @var Session
|
* @var Session
|
||||||
*/
|
*/
|
||||||
protected $session;
|
protected $session;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct() {
|
||||||
{
|
|
||||||
$this->session = service('session');
|
$this->session = service('session');
|
||||||
$this->accounts = model('App\Models\mAccounts');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function overview()
|
public function overview() {
|
||||||
{
|
$accounts = model('App\Models\mAccounts'); /* @var \App\Models\mAccounts $accounts */
|
||||||
|
$bills = model('App\Models\mBills'); /* @var \App\Models\mBills $bills */
|
||||||
|
$billDet = model('App\Models\mBillDetails'); /* @var \App\Models\mBills $billDet */
|
||||||
|
$scheduled = model('App\Models\mScheduled'); /* @var \App\Models\mScheduled $scheduled */
|
||||||
return view('table');
|
return view('table');
|
||||||
}
|
}
|
||||||
|
|
||||||
private function checkDDPList(&$arr, $ele){
|
|
||||||
|
|
||||||
if (!array_key_exists($ele, $arr)){
|
|
||||||
$arr[$ele] = $this->accounts->getDropDownEntry($ele);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function checkDDSList($arr, $par, $ele){
|
|
||||||
if (!array_key_exists($par, $arr)){
|
|
||||||
$ret = array();
|
|
||||||
if ($ele > 0)
|
|
||||||
$ret[$ele] = $this->accounts->getDropDownEntry($ele);
|
|
||||||
else
|
|
||||||
$ret[0] = '-----';
|
|
||||||
return $ret;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
return $arr[$par];
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private function loadFormDefaults(){
|
|
||||||
$data['id'] = 0;
|
|
||||||
$data['source'] = 0;
|
|
||||||
$data['datum'] ='';
|
|
||||||
$data['renummer'] = false;
|
|
||||||
$data['multi'] = false;
|
|
||||||
$data['transfer'] = false;
|
|
||||||
$data['receiver'] = '';
|
|
||||||
$data['total_in'] = '';
|
|
||||||
$data['total_out'] = '';
|
|
||||||
$data['validate'] = false;
|
|
||||||
$data['scheduled'] = false;
|
|
||||||
$data['scheduledNum'] = 0;
|
|
||||||
$data['scheduledType'] = 0;
|
|
||||||
for ($i=0;$i<10;$i++){
|
|
||||||
$data['sid'][$i] = 0;
|
|
||||||
$data['category_parent'][$i] = 0;
|
|
||||||
$data['category'][$i] = 0;
|
|
||||||
$data['input'][$i] = '';
|
|
||||||
$data['output'][$i] = '';
|
|
||||||
$data['comment'][$i] = '';
|
|
||||||
}
|
|
||||||
return $data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Legt eine neue Terminbuchung an
|
|
||||||
* @param bool $transfer ob Terminbuchung vom Typ Transfer ist
|
|
||||||
* @return char gibt die View zurück
|
|
||||||
**/
|
|
||||||
public function newScheduled($transfer = 0){
|
|
||||||
$data = $this->loadFormDefaults();
|
|
||||||
$data['transfer'] = (bool)$transfer;
|
|
||||||
return $this->newBill($data,NULL,true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function newTransfer(){
|
|
||||||
$data = $this->loadFormDefaults();
|
|
||||||
$data['transfer'] = true;
|
|
||||||
return $this->newBill($data,NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function newBill($data = NULL, $errors = NULL,$scheduled = false){
|
|
||||||
helper('form');
|
|
||||||
$data = $data ?? $this->loadFormDefaults();
|
|
||||||
$data['isScheduled'] = $scheduled;
|
|
||||||
$data['validation'] = $errors;
|
|
||||||
|
|
||||||
$srclist = $this->accounts->getDropDownList( 'Acc', TRUE );
|
|
||||||
$this->checkDDPList($srclist,$data['source']);
|
|
||||||
$data['sourcelist'] = $srclist;
|
|
||||||
$data['scheduled'] = array('NumList' => array('1'=>'1','2'=>'2','3'=>'3','4'=>'4','5'=>'5','6'=>'6'),
|
|
||||||
'TypeList' => array('week'=>'Woche(n)','month'=>'Monat(e)','year'=>'Jahr(e)'),
|
|
||||||
'style' => 'class="form-select"');
|
|
||||||
if ($data['transfer'])
|
|
||||||
$categories = $this->accounts->getDropDownLists( 'Acc', TRUE );
|
|
||||||
else
|
|
||||||
$categories = $this->accounts->getDropDownLists( 'InOut', TRUE );
|
|
||||||
|
|
||||||
// $data['catparentlist'] = $categories['parent'];
|
|
||||||
// if (!array_key_exists('catparent', $data))
|
|
||||||
// $data['catparent'] = $this->accounts->getParent($data['cat']);
|
|
||||||
// $this->checkDDPList($data['catparentlist'],$data['catparent']);
|
|
||||||
|
|
||||||
// $data['catlist'] = $this->checkDDSList((array)$categories['subs'],$data['catparent'],$data['cat']);
|
|
||||||
|
|
||||||
$data['subsparent'] = array();
|
|
||||||
$data['subscategory'] = array();
|
|
||||||
for ($i=0;$i<10;$i++){
|
|
||||||
$data['subsparent'][$i] = $categories['parent'];
|
|
||||||
$data['category_parent'][$i] = $data['category_parent'][$i] ?? 0;
|
|
||||||
$this->checkDDPList($data['subsparent'][$i],$data['category_parent'][$i]);
|
|
||||||
$data['subscategory'][$i] = $this->checkDDSList((array)$categories['subs'],$data['category_parent'][$i],$data['category'][$i]??0);
|
|
||||||
}
|
|
||||||
$data['subsdata'] = json_encode($categories['subs']);
|
|
||||||
return view('newBill', $data);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function customValidation(&$errors){
|
|
||||||
$result = true;
|
|
||||||
// if ( "on" == $this->request->getPost('multi') )
|
|
||||||
// {
|
|
||||||
for ($i=0;$i<10;$i++){
|
|
||||||
$inp = $this->request->getPost("input[$i]");
|
|
||||||
$outp = $this->request->getPost("output[$i]");
|
|
||||||
$cat = $this->request->getPost("category[$i]");
|
|
||||||
if ((is_numeric($inp) && $inp > 0.0) || (is_numeric($outp) && $outp > 0.0)){
|
|
||||||
if ($cat == 0){
|
|
||||||
$result &= false;
|
|
||||||
$errors['Kategorie']="Kategorie [$i] fehlt oder ungültig";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($cat > 0){
|
|
||||||
$errors['log2'] = "cat recognized";
|
|
||||||
if (!((is_numeric($inp) && ($inp > 0.0)) || (is_numeric($outp) && ($outp > 0.0)))){
|
|
||||||
$errors['Betrag']="Betrag [$i] fehlt oder ungültig";
|
|
||||||
$result &= false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// }
|
|
||||||
// else{
|
|
||||||
// if ((is_numeric($this->request->getPost('total_in')) && $this->request->getPost('total_in') > 0.0) || (is_numeric($this->request->getPost('total_out')) && $this->request->getPost('total_out') > 0.0)){
|
|
||||||
// return true;
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// $errors['Betrag']="Betrag fehlt oder ungültig";
|
|
||||||
// }
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function viewBill(string $filename) {
|
|
||||||
$filePath= WRITEPATH . '/uploads';
|
|
||||||
$file = new \CodeIgniter\Files\File($filePath."/".$filename);
|
|
||||||
log_message('debug',$file->getMimeType());
|
|
||||||
if ($file->getMimeType() == 'application/pdf')
|
|
||||||
$this->viewPdf($filename);
|
|
||||||
else{
|
|
||||||
$imginfo = getimagesize($filePath."/".$filename);
|
|
||||||
header("Content-type: {$imginfo['mime']}");
|
|
||||||
readfile($filePath."/".$filename);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
// return view('viewBillImg', ['filename'=>'writable/uploads/'.$filename]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function viewPdf(string $filename) {
|
|
||||||
$view = \Config\Services::renderer();
|
|
||||||
log_message('debug',$filename);
|
|
||||||
$filePath= WRITEPATH . '/uploads';
|
|
||||||
header("Cache-Control: maxage=1");
|
|
||||||
header("Pragma: public");
|
|
||||||
header('Content-type:application/pdf');
|
|
||||||
header('Content-disposition: inline; filename="'.$filename.'"');
|
|
||||||
header('content-Transfer-Encoding:binary');
|
|
||||||
header('Content-Length:' .filesize($filePath."/".$filename));
|
|
||||||
if (($pdf =file_get_contents($filePath."/".$filename)) === false)
|
|
||||||
print $filePath."/".$filename;
|
|
||||||
else
|
|
||||||
print $pdf;
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function attemptNewBilling()
|
|
||||||
{
|
|
||||||
helper('form');
|
|
||||||
$uploading = false;
|
|
||||||
$rules = [
|
|
||||||
'source' => 'required|greater_than[0]',
|
|
||||||
'datum' => 'required',
|
|
||||||
'category.0' => 'required|greater_than[0]'
|
|
||||||
// 'totalamount'=>'required|numeric'
|
|
||||||
];
|
|
||||||
$errors = [ // Errors
|
|
||||||
'source' => ['required' => 'Konto fehlt','greater_than' => 'Konto fehlt'],
|
|
||||||
'datum' => ['required' => 'Datum fehlt']];
|
|
||||||
// 'totalamount' => ['required' => 'Betrag fehlt','numeric' => 'Betrag muss eine Zahl sein']];
|
|
||||||
if ( 'on' == $this->request->getPost('multi') ) {
|
|
||||||
$rules['openamount'] = 'equals[0]';
|
|
||||||
$errors['openamount'] = ['equals' => 'Betrag muss 0 sein'];
|
|
||||||
}
|
|
||||||
$fehler= array();
|
|
||||||
$valid = $this->customValidation($fehler);
|
|
||||||
$file = $this->request->getFile('billfile');
|
|
||||||
if ($file) {
|
|
||||||
if (! $file->isValid() && ($file->getError() != UPLOAD_ERR_NO_FILE)) {
|
|
||||||
throw new \RuntimeException($file->getErrorString() . '(' . $file->getError() . ')');
|
|
||||||
} else if ($file->isValid()) {
|
|
||||||
$rules['billfile'] = ['uploaded[billfile]','max_size[billfile,10000]','mime_in[billfile,application/pdf,image/jpg,image/jpeg]'];
|
|
||||||
$errors['billfile'] = ['uploaded'=>'Fehler beim Upload','max_size' => 'Zu Groß', 'mime_in' => "Ungültiger Datentyp"];
|
|
||||||
$uploading = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((! $this->validate($rules,$errors)) || (!$valid)){
|
|
||||||
return $this->newBill($this->request->getPost(), array_merge($this->validator->getErrors(),$fehler),$this->request->getPost('scheduled'));
|
|
||||||
// return redirect()->back()->withInput()->with('errors', $validation->getErrors());
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
$data = $this->request->getPost();
|
|
||||||
log_message('debug',print_r($data,true));
|
|
||||||
|
|
||||||
if ($this->request->getPost('scheduled') =="0"){
|
|
||||||
$bills = model('App\Models\mBills');
|
|
||||||
if ($this->request->getPost('removeBillFile')){
|
|
||||||
$bills->deleteBillFile($data['id']);
|
|
||||||
unlink(WRITEPATH . 'uploads/'.$this->request->getPost('removeBillFile'));
|
|
||||||
}
|
|
||||||
$billId = $bills->saveBill($data);
|
|
||||||
|
|
||||||
if ($uploading){
|
|
||||||
$date = Time::parse($data['datum']);
|
|
||||||
$file->move(WRITEPATH . 'uploads',$date->toLocalizedString('yyyyMMdd')." ".$data['receiver']." ".$billId.".".$file->guessExtension());
|
|
||||||
log_message('debug', $file->getName());
|
|
||||||
$bills->storeBillFile($billId, $file->getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
$redirectURL = session('redirect_url') ?? site_url('/');
|
|
||||||
unset($_SESSION['redirect_url']);
|
|
||||||
return redirect()->to($redirectURL);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
$scheduled = model('App\Models\mScheduled');
|
|
||||||
$scheduled->saveBill($data);
|
|
||||||
}
|
|
||||||
$this->response->redirect(site_url('/'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function editBill($id){
|
|
||||||
$bills = model('App\Models\mBills');
|
|
||||||
$data = $this->loadFormDefaults();
|
|
||||||
$result = $bills->getEntry($id, $data, $this->accounts);
|
|
||||||
return $this->newBill($result);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function editScheduled($id){
|
|
||||||
$scheduled = model('App\Models\mScheduled');
|
|
||||||
$entry = $scheduled->getEntry($id);
|
|
||||||
// $bill = array_merge($this->loadFormDefaults(),(array)json_decode($entry['data']));
|
|
||||||
// $bill['datum'] = $entry['next_date'];
|
|
||||||
return $this->newBill($entry,NULL,true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function deleteScheduled($id){
|
|
||||||
$scheduled = model('App\Models\mScheduled');
|
|
||||||
$entry = $scheduled->getEntry($id);
|
|
||||||
// $bill = array_merge($this->loadFormDefaults(),(array)json_decode($entry['data']));
|
|
||||||
// $bill['datum'] = $entry['next_date'];
|
|
||||||
return $this->newBill($entry,NULL,true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function syncScheduled(){
|
|
||||||
if (!$this->request->isAJAX()) return;
|
|
||||||
$scheduled = model('App\Models\mScheduled');
|
|
||||||
$schedules = $scheduled->findAll();
|
|
||||||
$result = array();
|
|
||||||
$line = "";
|
|
||||||
foreach ( $schedules as $schedule )
|
|
||||||
{
|
|
||||||
$cur_date = $schedule['next_date'];
|
|
||||||
while ( strtotime( $cur_date ) <= strtotime( "now" ) )
|
|
||||||
{
|
|
||||||
$line .= " $cur_date - ";
|
|
||||||
$bill = array_merge($this->loadFormDefaults(),(array)json_decode($schedule['data']));
|
|
||||||
//echo "Hugo:".$schedule['id'];
|
|
||||||
$bill['id']=0; // to generate a new booking
|
|
||||||
$bill['datum'] = $cur_date;
|
|
||||||
$bill['type'] = $bill['transfer']?'transfer':'multiple';
|
|
||||||
$line .= $bill['receiver'];
|
|
||||||
$bills = model('App\Models\mBills');
|
|
||||||
$bills->saveBill($bill);
|
|
||||||
$cur_date = $scheduled->calcNextDate( $cur_date, $bill['scheduledNum'], $bill['scheduledType']);
|
|
||||||
$line .= " - $cur_date <br/>";
|
|
||||||
//log_message('debug','BudgetScheduled:process data: '.logArray($booking->getData()));
|
|
||||||
$scheduled->update($schedule['id'], ['next_date'=>$cur_date ]);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $line;
|
|
||||||
//$this->showTableBookings();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function viewAccountsTree(){
|
|
||||||
helper('form');
|
|
||||||
$data = $this->accounts->getTreeData();
|
|
||||||
$data['ddlist'] = $this->accounts->getDropDownList( 'all', false,true );
|
|
||||||
return view('accountstree',$data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function attemptEditAccount(){
|
|
||||||
$rules = [
|
|
||||||
'description' => 'required',
|
|
||||||
'type' => 'required',
|
|
||||||
];
|
|
||||||
if (! $this->validate($rules))
|
|
||||||
{
|
|
||||||
return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
|
|
||||||
}
|
|
||||||
$this->accounts->saveAccount($this->request->getPost());
|
|
||||||
// $this->accounts = model('App\Models\mAccounts', false);
|
|
||||||
return $this->viewAccountsTree();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public function viewAccountActivities(){
|
|
||||||
helper('form');
|
|
||||||
$data = array();
|
|
||||||
$data['source'] = 0;
|
|
||||||
$data['start'] = session('datum_start') ?? date("d.m.Y", strtotime( "- 2 weeks", strtotime( "now" ) ));
|
|
||||||
$data['ende'] = session('datum_ende') ?? date("d.m.Y", strtotime( "now" ) );
|
|
||||||
$data['source'] = session('source') ?? 0;
|
|
||||||
$data['sourcelist'] = $this->accounts->getDropDownList( 'all', TRUE );
|
|
||||||
return view('activities', $data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function viewScheduled(){
|
|
||||||
helper('form');
|
|
||||||
return view('scheduled');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
83
app/Controllers/Scheduled.php
Normal file
83
app/Controllers/Scheduled.php
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controllers;
|
||||||
|
use App\Models\mScheduled;
|
||||||
|
use CodeIgniter\Session\Session;
|
||||||
|
use CodeIgniter\API\ResponseTrait;
|
||||||
|
include_once (dirname(__FILE__) . "/FormHandler.php");
|
||||||
|
|
||||||
|
class Scheduled extends FormHandler {
|
||||||
|
use ResponseTrait;
|
||||||
|
/**
|
||||||
|
* @var Session
|
||||||
|
*/
|
||||||
|
protected $session;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
$this->session = service('session');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function new(bool $transfer=false){
|
||||||
|
//log_message('debug','Bills::new');
|
||||||
|
$eBooking = new \App\Entities\eBooking();
|
||||||
|
$eBooking->transfer = $transfer;
|
||||||
|
$eBooking->scheduled = true;
|
||||||
|
$eBooking = $eBooking->getNew();
|
||||||
|
return $this->viewBill($eBooking);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function edit(int $id){
|
||||||
|
$scheduled = model('App\Models\mScheduled');
|
||||||
|
$entry = $scheduled->getEntry($id);
|
||||||
|
$eBooking = new \App\Entities\eBooking($entry);
|
||||||
|
return $this->viewBill($eBooking);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sync(){
|
||||||
|
if (!$this->request->isAJAX()) return;
|
||||||
|
$scheduled = model('App\Models\mScheduled');
|
||||||
|
$schedules = $scheduled->findAll();
|
||||||
|
$lines = "";
|
||||||
|
foreach ( $schedules as $schedule ) {
|
||||||
|
$cur_date = $schedule['next_date'];
|
||||||
|
while ( strtotime( $cur_date ) <= strtotime( "now" ) ) {
|
||||||
|
$data = (array)json_decode($schedule['data']);
|
||||||
|
$data['id'] = 0; // to generate a new booking (overwrite id of scheduled DB)
|
||||||
|
$data['scheduled'] = false;
|
||||||
|
$eBooking = new \App\Entities\eBooking($data);
|
||||||
|
$eBooking->datum = $cur_date;
|
||||||
|
$lines .= " $cur_date - $eBooking->receiver <br/>";
|
||||||
|
$eBooking->saveIt();
|
||||||
|
$cur_date = $scheduled->calcNextDate( $cur_date, $data['scheduledNum'], $data['scheduledType']);
|
||||||
|
}
|
||||||
|
$scheduled->update($schedule['id'], ['next_date'=>$cur_date ]);
|
||||||
|
}
|
||||||
|
return $lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function viewScheduled(){
|
||||||
|
helper('form');
|
||||||
|
return view('scheduled');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete(){
|
||||||
|
if ($this->request->is('post')) {
|
||||||
|
log_message('debug',"delete id: ".$this->request->getPost("id"));
|
||||||
|
if (!ctype_digit($this->request->getPost("id"))) return $this->failForbidden("Ungültige ID");
|
||||||
|
$schmodel = model(mScheduled::class);
|
||||||
|
$result = $schmodel->delete(intval($this->request->getPost("id")));
|
||||||
|
if ($result !== true)
|
||||||
|
return $this->fail("Database error ".$result);
|
||||||
|
else
|
||||||
|
return $this->respondDeleted(['url'=>session('redirect_url') ?? site_url('/'),'ID'=>$this->request->getPost("id")]);
|
||||||
|
}
|
||||||
|
return $this->failUnauthorized("Schäm Dich");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTabData(){
|
||||||
|
if (!$this->request->isAJAX()) return;
|
||||||
|
$scheduled = model('App\Models\mScheduled');
|
||||||
|
return json_encode($scheduled->getEntries());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
194
app/Entities/eBooking.php
Normal file
194
app/Entities/eBooking.php
Normal file
@@ -0,0 +1,194 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Entities;
|
||||||
|
|
||||||
|
use App\Models\mBills;
|
||||||
|
use App\Models\mBillDetails;
|
||||||
|
use App\Models\mScheduled;
|
||||||
|
use CodeIgniter\Entity\Entity;
|
||||||
|
use CodeIgniter\I18n\Time;
|
||||||
|
|
||||||
|
class eBooking extends Entity{
|
||||||
|
protected $file = null; /* @var \CodeIgniter\HTTP\Files\UploadedFile|null $file */
|
||||||
|
protected $attributes =[
|
||||||
|
'id' => 0,
|
||||||
|
'datum' => '',
|
||||||
|
'source_id' => 0,
|
||||||
|
'receiver' => '',
|
||||||
|
'amount' => null,
|
||||||
|
'validate' => false,
|
||||||
|
'transfer' => false,
|
||||||
|
'scheduled' => false,
|
||||||
|
'details' => [],
|
||||||
|
'deleted_at' => null,
|
||||||
|
'rechnung' => null,
|
||||||
|
'scheduledNum' => null,
|
||||||
|
'scheduledType' => null
|
||||||
|
];
|
||||||
|
|
||||||
|
public function fillDetails(){
|
||||||
|
$billD = model(mBillDetails::class);
|
||||||
|
$accounts = model('App\Models\mAccounts'); /* @var \App\Models\mAccounts $accounts */
|
||||||
|
$this->attributes['details'] = $billD->where('bill_id',$this->attributes['id'])->findAll();
|
||||||
|
$this->attributes['scheduled'] = false;
|
||||||
|
$this->attributes['transfer'] = ((count($this->attributes['details']) == 1) && $accounts->isAccount($this->attributes['details'][0]->account_id));
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setInvoice(\CodeIgniter\HTTP\Files\UploadedFile $file){
|
||||||
|
$this->file = $file;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getNew(){
|
||||||
|
$this->attributes['datum'] = date('Y-m-d');
|
||||||
|
$this->attributes['details'][] = new \App\Entities\eBookingLine();
|
||||||
|
log_message('debug','eBooking::getNew: '.json_encode($this->attributes));
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFormData(){
|
||||||
|
$billDet = new \App\Entities\eBookingLine();
|
||||||
|
$data = $this->toArray();
|
||||||
|
$data['template'] = $billDet->toArray();
|
||||||
|
log_message('debug','eBooking::getFormData:template '.json_encode($data['template']));
|
||||||
|
$accounts = model('App\Models\mAccounts'); /* @var \App\Models\mAccounts $accounts */
|
||||||
|
$data['category'] = $accounts->getDropDownLists($this->attributes['transfer']?'Acc':'InOut');
|
||||||
|
$data['sourcelist'] = $accounts->getDropDownList( type:'Acc', defaultKey:$data['source_id'] );
|
||||||
|
// log_message('debug','eBooking::getFormData: '.json_encode($data));
|
||||||
|
//$billDet->createDropDownLists($data);
|
||||||
|
|
||||||
|
if (is_null($this->attributes['amount'])){
|
||||||
|
$data['total_in'] = '';
|
||||||
|
$data['total_out'] = '';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$data['total_in'] = ($this->attributes['amount'] >= 0.0)? abs($this->attributes['amount']):'';
|
||||||
|
$data['total_out'] = ($this->attributes['amount'] < 0.0)? abs($this->attributes['amount']):'';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->attributes['scheduled']??false){
|
||||||
|
// $data['scheduledNum'] = 0;
|
||||||
|
// $data['scheduledType'] = 0;
|
||||||
|
$data['schedule_lists'] = array('NumList' => array('1'=>'1','2'=>'2','3'=>'3','4'=>'4','5'=>'5','6'=>'6'),
|
||||||
|
'TypeList' => array('week'=>'Woche(n)','month'=>'Monat(e)','year'=>'Jahr(e)'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($this->attributes['details'])>0){
|
||||||
|
foreach ($this->attributes['details'] as $i => $line){
|
||||||
|
$line->createFormData($data,$i);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
foreach ($this->attributes['sid'] as $i => $line){
|
||||||
|
$billDet->createDropDownLists($data,$i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log_message('debug','eBooking::getFormData: '.json_encode($data));
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// public function convertFromPost(array $data){
|
||||||
|
// $this->fill($data);
|
||||||
|
// foreach ($data['sid'] as $i => $value){
|
||||||
|
// $sub = array('id' => $value,
|
||||||
|
// 'bill_id' => $data['id'],
|
||||||
|
// 'comment' => $data['comment'][$i],
|
||||||
|
// 'account_id' => $data['account_id'][$i],
|
||||||
|
// 'subamount' => floatval($data['input'][$i])-floatval($data['output'][$i]),
|
||||||
|
// 'deleted_at' => null);
|
||||||
|
// $details[] = new \App\Entities\eBookingLine($sub);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
private function calcAmount(){
|
||||||
|
$amount = floatval($data['total_in'])-floatval($data['total_out']);
|
||||||
|
$subamounts = 0.0;
|
||||||
|
foreach ($this->attributes['input'] as $i => $value){
|
||||||
|
$subamounts = $subamounts + floatval($value) - floatval($this->attributes['output'][$i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function saveScheduled() {
|
||||||
|
$scheduledModel = model(mScheduled::class);
|
||||||
|
$data = $this->toArray();
|
||||||
|
for ($i=(count($data['account_id'])-1); $i>0; $i--){
|
||||||
|
if ($data['account_id'][$i] == "0") {
|
||||||
|
unset($data['account_id'][$i]);
|
||||||
|
unset($data['sid'][$i]);
|
||||||
|
unset($data['input'][$i]);
|
||||||
|
unset($data['output'][$i]);
|
||||||
|
unset($data['comment'][$i]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $scheduledModel->saveIt($data);
|
||||||
|
|
||||||
|
}
|
||||||
|
//switch scheduled or bill
|
||||||
|
|
||||||
|
public function saveIt() {
|
||||||
|
if ($this->attributes['scheduled'] != 0) return $this->saveScheduled();
|
||||||
|
|
||||||
|
$billModel = model(mBills::class);
|
||||||
|
|
||||||
|
if ($this->attributes['id'] == 0) {
|
||||||
|
|
||||||
|
$billId = $billModel->insert($this, true);
|
||||||
|
log_message('debug','SaveIt with insert result: '.json_encode($billId));
|
||||||
|
if ($billId === false)
|
||||||
|
return $billModel->errors();
|
||||||
|
else{
|
||||||
|
$this->attributes['id'] = $billId;
|
||||||
|
}
|
||||||
|
//$billId = $$billModel->getInsertID();
|
||||||
|
} else {
|
||||||
|
if ($this->attributes['removeBillFile']??false){
|
||||||
|
$this->attributes['rechnung'] = null;
|
||||||
|
unlink(WRITEPATH . 'uploads/'.auth()->user()->preFixDB.'/'.$this->attributes['removeBillFile']);
|
||||||
|
}
|
||||||
|
if ($billModel->update($this->attributes['id'],$this) === false)
|
||||||
|
return $billModel->errors();
|
||||||
|
}
|
||||||
|
|
||||||
|
$billDetailsModel = model(mBillDetails::class);
|
||||||
|
$details = new \App\Entities\eBookingLine;
|
||||||
|
foreach ($this->attributes['sid'] as $i => $value){
|
||||||
|
if ($this->attributes['account_id'][$i] == 0) { // leere Zeile ignorieren bzw wenn id (also bereits in DB) dann löschen
|
||||||
|
if ($value == 0) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
$billDetailsModel->delete($value);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$sub = array('sid' => ($value == 0)? NULL: $value,
|
||||||
|
'bill_id' => $this->attributes['id'],
|
||||||
|
'comment' => $this->attributes['comment'][$i],
|
||||||
|
'account_id' => $this->attributes['account_id'][$i],
|
||||||
|
'subamount' => floatval($this->attributes['input'][$i])-floatval($this->attributes['output'][$i]),
|
||||||
|
'deleted_at' => null);
|
||||||
|
$details->fill($sub);
|
||||||
|
$billDetailsModel->save($details);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->file) {
|
||||||
|
if (! $this->file->isValid() && ($this->file->getError() != UPLOAD_ERR_NO_FILE)) {
|
||||||
|
throw new \RuntimeException($this->file->getErrorString() . '(' . $this->file->getError() . ')');
|
||||||
|
} else if ($this->file->isValid()) {
|
||||||
|
helper('url');
|
||||||
|
$date = Time::parse($this->attributes['datum']);
|
||||||
|
$name = url_title($date->toLocalizedString('yyyyMMdd')." ".$this->attributes['receiver']." ".$this->attributes['id']);
|
||||||
|
$this->file->move(WRITEPATH . 'uploads/'.auth()->user()->preFixDB,$name.".".$this->file->guessExtension());
|
||||||
|
log_message('debug', $this->file->getName());
|
||||||
|
$this->attributes['rechnung'] = $this->file->getName();
|
||||||
|
if ($billModel->update($this->attributes['id'],$this) === false)
|
||||||
|
return $billModel->errors();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// $details = model('App\Models\mBillDetails');
|
||||||
|
// return $details->getDetails([$this->id]);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
69
app/Entities/eBookingLine.php
Normal file
69
app/Entities/eBookingLine.php
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Entities;
|
||||||
|
|
||||||
|
use CodeIgniter\Entity\Entity;
|
||||||
|
use App\Models\mAccounts;
|
||||||
|
|
||||||
|
class eBookingLine extends Entity{
|
||||||
|
protected $attributes =[
|
||||||
|
'id' => 0,
|
||||||
|
'bill_id' => 0,
|
||||||
|
'comment' => '',
|
||||||
|
'account_id' => 0,
|
||||||
|
'subamount' => null,
|
||||||
|
'deleted_at' => null,
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $datamap = [
|
||||||
|
// property_name => db_column_name
|
||||||
|
'sid' => 'id',
|
||||||
|
];
|
||||||
|
private function checkCreateParentDefault(array &$list, int $parentId) : void {
|
||||||
|
if ($parentId == 0) return;
|
||||||
|
if (!array_key_exists($parentId, $list)){
|
||||||
|
log_message('debug',"Parent not exists: $parentId in List: ".json_encode(array_keys($list)));
|
||||||
|
$list[$parentId] = $this->accounts->getDropDownEntry($parentId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function checkCreateSubDefault(array &$list, int $accountId) : void {
|
||||||
|
if (!array_key_exists($accountId, $list)){
|
||||||
|
if ($accountId > 0)
|
||||||
|
$list[$accountId] = $this->accounts->getDropDownEntry($accountId);
|
||||||
|
else
|
||||||
|
$list[0] = '-----';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createFormData(array &$data, int $i){
|
||||||
|
if (!array_key_exists('sid', $data)) $data['sid'] = [];
|
||||||
|
if (!array_key_exists('comment', $data)) $data['comment'] = [];
|
||||||
|
if (!array_key_exists('account_id', $data)) $data['account_id'] = [];
|
||||||
|
if (!array_key_exists('deleted_at', $data)) $data['deleted_at'] = [];
|
||||||
|
if (!array_key_exists('input', $data)) $data['input'] = [];
|
||||||
|
if (!array_key_exists('output', $data)) $data['output'] = [];
|
||||||
|
|
||||||
|
$data['sid'][$i] = $this->attributes['id'];
|
||||||
|
$data['comment'][$i] = $this->attributes['comment'];
|
||||||
|
$data['account_id'][$i] = $this->attributes['account_id'];
|
||||||
|
$data['deleted_at'][$i] = $this->attributes['deleted_at'];
|
||||||
|
$data['input'][$i] = (!is_null($this->attributes['subamount']) && $this->attributes['subamount'] > 0.0) ? $this->attributes['subamount'] :'';
|
||||||
|
$data['output'][$i] = (!is_null($this->attributes['subamount']) && $this->attributes['subamount'] <= 0.0) ? abs($this->attributes['subamount']) :'';
|
||||||
|
$this->createDropDownLists($data,$i);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createDropDownLists(array &$data, int $i){
|
||||||
|
$accounts = model('App\Models\mAccounts'); /* @var \App\Models\mAccounts $accounts */
|
||||||
|
$lists = $data['category'] ?? [];
|
||||||
|
if (!array_key_exists('parent_id', $data)) $data['parent_id'] = [];
|
||||||
|
if (!array_key_exists('cat_parent', $data)) $data['cat_parent'] = [];
|
||||||
|
if (!array_key_exists('cat_sub', $data)) $data['cat_sub'] = [];
|
||||||
|
|
||||||
|
$data['parent_id'][$i] = $accounts->getParent($data['account_id'][$i]);
|
||||||
|
$data['cat_parent'][$i] = $lists['parent'];
|
||||||
|
$this->checkCreateParentDefault($data['cat_parent'][$i],$data['parent_id'][$i]);
|
||||||
|
$data['cat_sub'][$i] = $lists['subs']->{$data['parent_id'][$i]} ?? [];
|
||||||
|
$this->checkCreateSubDefault($data['cat_sub'][$i],$data['account_id'][$i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
78
app/Language/de/Validation.php
Normal file
78
app/Language/de/Validation.php
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file is part of CodeIgniter 4 framework.
|
||||||
|
*
|
||||||
|
* (c) CodeIgniter Foundation <admin@codeigniter.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Validation language settings
|
||||||
|
return [
|
||||||
|
// Core Messages
|
||||||
|
'noRuleSets' => 'No rule sets specified in Validation configuration.',
|
||||||
|
'ruleNotFound' => '"{0}" is not a valid rule.',
|
||||||
|
'groupNotFound' => '"{0}" is not a validation rules group.',
|
||||||
|
'groupNotArray' => '"{0}" rule group must be an array.',
|
||||||
|
'invalidTemplate' => '"{0}" is not a valid Validation template.',
|
||||||
|
|
||||||
|
// Rule Messages
|
||||||
|
'alpha' => 'The {field} field may only contain alphabetical characters.',
|
||||||
|
'alpha_dash' => 'The {field} field may only contain alphanumeric, underscore, and dash characters.',
|
||||||
|
'alpha_numeric' => 'The {field} field may only contain alphanumeric characters.',
|
||||||
|
'alpha_numeric_punct' => 'The {field} field may contain only alphanumeric characters, spaces, and ~ ! # $ % & * - _ + = | : . characters.',
|
||||||
|
'alpha_numeric_space' => 'The {field} field may only contain alphanumeric and space characters.',
|
||||||
|
'alpha_space' => 'The {field} field may only contain alphabetical characters and spaces.',
|
||||||
|
'decimal' => 'The {field} field must contain a decimal number.',
|
||||||
|
'differs' => 'The {field} field must differ from the {param} field.',
|
||||||
|
'equals' => 'Das Feld {field} muss exakt sein: {param}.',
|
||||||
|
'exact_length' => 'The {field} field must be exactly {param} characters in length.',
|
||||||
|
'field_exists' => 'The {field} field must exist.',
|
||||||
|
'greater_than' => 'The {field} field must contain a number greater than {param}.',
|
||||||
|
'greater_than_equal_to' => 'The {field} field must contain a number greater than or equal to {param}.',
|
||||||
|
'hex' => 'The {field} field may only contain hexadecimal characters.',
|
||||||
|
'in_list' => 'The {field} field must be one of: {param}.',
|
||||||
|
'integer' => 'The {field} field must contain an integer.',
|
||||||
|
'is_natural' => 'The {field} field must only contain digits.',
|
||||||
|
'is_natural_no_zero' => 'The {field} field must only contain digits and must be greater than zero.',
|
||||||
|
'is_not_unique' => 'The {field} field must contain a previously existing value in the database.',
|
||||||
|
'is_unique' => 'The {field} field must contain a unique value.',
|
||||||
|
'less_than' => 'The {field} field must contain a number less than {param}.',
|
||||||
|
'less_than_equal_to' => 'The {field} field must contain a number less than or equal to {param}.',
|
||||||
|
'matches' => 'The {field} field does not match the {param} field.',
|
||||||
|
'max_length' => '{field} darf nicht länger als {param} Zeichen sein.',
|
||||||
|
'min_length' => 'The {field} field must be at least {param} characters in length.',
|
||||||
|
'not_equals' => 'The {field} field cannot be: {param}.',
|
||||||
|
'not_in_list' => 'The {field} field must not be one of: {param}.',
|
||||||
|
'numeric' => 'Das Feld {field} darf nur Zahlen enthalten.',
|
||||||
|
'regex_match' => 'The {field} field is not in the correct format.',
|
||||||
|
'required' => 'Das Feld {field} ist erforderlich.',
|
||||||
|
'required_with' => 'The {field} field is required when {param} is present.',
|
||||||
|
'required_without' => 'Das Feld {field} muss ausgefüllt werden, wenn {param} nicht vorhanden ist.',
|
||||||
|
'string' => 'The {field} field must be a valid string.',
|
||||||
|
'timezone' => 'The {field} field must be a valid timezone.',
|
||||||
|
'valid_base64' => 'The {field} field must be a valid base64 string.',
|
||||||
|
'valid_email' => 'The {field} field must contain a valid email address.',
|
||||||
|
'valid_emails' => 'The {field} field must contain all valid email addresses.',
|
||||||
|
'valid_ip' => 'The {field} field must contain a valid IP.',
|
||||||
|
'valid_url' => 'The {field} field must contain a valid URL.',
|
||||||
|
'valid_url_strict' => 'The {field} field must contain a valid URL.',
|
||||||
|
'valid_date' => 'The {field} field must contain a valid date.',
|
||||||
|
'valid_json' => 'The {field} field must contain a valid json.',
|
||||||
|
|
||||||
|
// Credit Cards
|
||||||
|
'valid_cc_number' => '{field} does not appear to be a valid credit card number.',
|
||||||
|
|
||||||
|
// Files
|
||||||
|
'uploaded' => '{field} is not a valid uploaded file.',
|
||||||
|
'max_size' => '{field} is too large of a file.',
|
||||||
|
'is_image' => '{field} is not a valid, uploaded image file.',
|
||||||
|
'mime_in' => '{field} does not have a valid mime type.',
|
||||||
|
'ext_in' => '{field} does not have a valid file extension.',
|
||||||
|
'max_dims' => '{field} is either not an image, or it is too wide or tall.',
|
||||||
|
'min_dims' => '{field} is either not an image, or it is not wide or tall enough.',
|
||||||
|
];
|
||||||
49
app/Models/Cast/CastMyDate.php
Normal file
49
app/Models/Cast/CastMyDate.php
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Models\Cast;
|
||||||
|
//namespace CodeIgniter\DataCaster\Cast;
|
||||||
|
use CodeIgniter\Database\BaseConnection;
|
||||||
|
use CodeIgniter\Exceptions\InvalidArgumentException;
|
||||||
|
use CodeIgniter\DataCaster\Cast\BaseCast;
|
||||||
|
use CodeIgniter\I18n\Time;
|
||||||
|
|
||||||
|
// The class must inherit the CodeIgniter\DataCaster\Cast\BaseCast class
|
||||||
|
class CastMyDate extends BaseCast
|
||||||
|
{
|
||||||
|
public static function get( mixed $value, array $params = [], ?object $helper = null,): string {
|
||||||
|
if (! is_string($value)) {
|
||||||
|
self::invalidTypeValueError($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! $helper instanceof BaseConnection) {
|
||||||
|
$message = 'The parameter $helper must be BaseConnection.';
|
||||||
|
|
||||||
|
throw new InvalidArgumentException($message);
|
||||||
|
}
|
||||||
|
|
||||||
|
$format = $helper->dateFormat['date'];
|
||||||
|
|
||||||
|
return Time::createFromFormat($format, $value)->toLocalizedString($params[0] ?? 'yyyy-MM-dd');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function set( mixed $value, array $params = [], ?object $helper = null,): string {
|
||||||
|
if ( is_string($value)) {
|
||||||
|
$value = Time::createFromFormat("Y-m-d", $value);
|
||||||
|
}
|
||||||
|
if (! $value instanceof Time) {
|
||||||
|
self::invalidTypeValueError($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! $helper instanceof BaseConnection) {
|
||||||
|
$message = 'The parameter $helper must be BaseConnection.';
|
||||||
|
|
||||||
|
throw new InvalidArgumentException($message);
|
||||||
|
}
|
||||||
|
|
||||||
|
$format = $helper->dateFormat['date'];
|
||||||
|
|
||||||
|
return $value->format($format);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,41 +3,65 @@
|
|||||||
use CodeIgniter\Model;
|
use CodeIgniter\Model;
|
||||||
|
|
||||||
class mAccounts extends Model {
|
class mAccounts extends Model {
|
||||||
protected $table = 'budget_accounts';
|
private $defaultTableName='_budget_accounts';
|
||||||
protected $primaryKey = 'id';
|
protected $primaryKey = 'id';
|
||||||
|
|
||||||
protected $useAutoIncrement = true;
|
protected $useAutoIncrement = true;
|
||||||
|
|
||||||
protected $returnType = 'object';
|
protected $returnType = 'object';
|
||||||
protected $useSoftDeletes = false;
|
protected $useSoftDeletes = true;
|
||||||
|
protected $deletedField ="deleted_at";
|
||||||
|
|
||||||
protected $allowedFields = ['parent_id','type','bookable','description','lkz'];
|
protected $allowedFields = ['parent_id','bookable','description','account','monitor','deleted_at'];
|
||||||
|
|
||||||
protected $useTimestamps = false;
|
protected $useTimestamps = false;
|
||||||
private $mAccountList = array();
|
private ?array $mAccountList = null;
|
||||||
|
|
||||||
protected function initialize()
|
protected array $casts = [
|
||||||
{
|
'bookable' => 'boolean',
|
||||||
$result = $this->findAll();
|
'monitor' => 'boolean',
|
||||||
foreach ($result as $value) {
|
'account' => 'boolean',
|
||||||
$this->mAccountList[$value->id] = $value;
|
];
|
||||||
|
|
||||||
|
protected function initialize() {
|
||||||
|
log_message('debug','mAccounts initialize');
|
||||||
|
$this->table = auth()->user()->preFixDB.$this->defaultTableName;
|
||||||
|
$this->checkOrCreateTable();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sicherstellen dass mAccountList gefüllt ist
|
||||||
|
*/
|
||||||
|
private function populateAccountList(): void {
|
||||||
|
if ($this->mAccountList === null) {
|
||||||
|
log_message('debug','mAccounts populateAccountList New');
|
||||||
|
$result = $this->withDeleted()->findAll();
|
||||||
|
// log_message('debug','mAccounts DB-Result '.json_encode($result));
|
||||||
|
$this->mAccountList = [];
|
||||||
|
foreach ($result as $value) {
|
||||||
|
$this->mAccountList[$value->id] = $value;
|
||||||
|
}
|
||||||
|
//log_message('debug','mAccounts intern List '.json_encode($this->mAccountList));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Erstellt DropDownListe aus gegeben array
|
* Erstellt DropDownListe aus gegeben array
|
||||||
* @param array liste der daten
|
* @param array $data liste der daten
|
||||||
* @param bool wenn true wird auch ein 0-Eintrag erstellt
|
* @param bool $withnull wenn true wird auch ein 0-Eintrag erstellt
|
||||||
|
* @param int $key index für null eintrag
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
private function createDropDownList($data,$withnull = true,$key=0)
|
private function createDropDownList(array $data, bool $withnull = true, int $key=0) {
|
||||||
{
|
|
||||||
$liste = array();
|
$liste = array();
|
||||||
if ($withnull)
|
if ($withnull){
|
||||||
$liste[$key] = '-----';
|
if ($key > 0)
|
||||||
foreach ( $data as $row )
|
$liste[$key] = '-----';
|
||||||
{
|
// else
|
||||||
|
// $liste[""] = '-----';
|
||||||
|
}
|
||||||
|
foreach ( $data as $row ) {
|
||||||
$liste[$row->id] = $row->description;
|
$liste[$row->id] = $row->description;
|
||||||
}
|
}
|
||||||
asort( $liste );
|
asort( $liste );
|
||||||
@@ -46,114 +70,114 @@ class mAccounts extends Model {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* holt Text vom gegebenen Element
|
* holt Text vom gegebenen Element
|
||||||
* @param int id des gewünschten Elements
|
* @param int $id ID des gewünschten Elements
|
||||||
* @return string Full Name of Entry
|
* @return string Full Name of Entry
|
||||||
*/
|
*/
|
||||||
public function getDropDownEntry($id){
|
public function getDropDownEntry(int $id) {
|
||||||
|
$this->populateAccountList();
|
||||||
$element = $this->mAccountList[$id];
|
$element = $this->mAccountList[$id];
|
||||||
$description = $element->description;
|
$description = $element->description;
|
||||||
$id = $element->parent_id;
|
$id = $element->parent_id;
|
||||||
while ( $id > 0 )
|
while ( $id > 0 ) {
|
||||||
{
|
|
||||||
$description = $this->mAccountList[$id]->description .'-'.$description;
|
$description = $this->mAccountList[$id]->description .'-'.$description;
|
||||||
$id = $this->mAccountList[$id]->parent_id;
|
$id = $this->mAccountList[$id]->parent_id;
|
||||||
}
|
}
|
||||||
return $description;;
|
return $description;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function filterIt(string $type = 'all', bool $bookableOnly = true, bool $withDeleted = false, ?int $defaultKey = null){
|
||||||
|
return unserialize(serialize(array_filter($this->mAccountList, function($var) use($type, $bookableOnly, $withDeleted, $defaultKey) {
|
||||||
|
if ($defaultKey !== null && $var->id == $defaultKey)
|
||||||
|
return true;
|
||||||
|
if (!($withDeleted) && $var->deleted_at)
|
||||||
|
return false;
|
||||||
|
if ($bookableOnly && !$var->bookable)
|
||||||
|
return false;
|
||||||
|
if ($type == 'Acc' && !$var->account)
|
||||||
|
return false;
|
||||||
|
elseif ($type == 'InOut' && $var->account)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
})));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* liefert DropDown Liste mit gegeben Suchparametern
|
* liefert DropDown Liste mit gegeben Suchparametern
|
||||||
* @param string Kontotyp "InOut,In,Out,Acc"
|
* @param string $type Kontotyp "InOut,Acc,all"
|
||||||
* @param bool ob bookable gesetzt sein muss
|
* @param bool $bookableOnly ob bookable gesetzt sein muss
|
||||||
* @return bool ob lkz Flag gesetzt sein darf
|
* @param bool $withDeleted ob gelöschte auch
|
||||||
|
* @return array fertige DropDownListe
|
||||||
*/
|
*/
|
||||||
public function getDropDownList($type, $bookable = true, $lkz = false )
|
public function getDropDownList(string $type, bool $bookableOnly = true, bool $withDeleted = false, ?int $defaultKey = null) : array {
|
||||||
{
|
$this->populateAccountList();
|
||||||
if ($bookable == true)
|
$result = $this->filterIt($type,$bookableOnly,$withDeleted,$defaultKey);
|
||||||
$this->where('bookable',true);
|
foreach ( $result as &$element ) {
|
||||||
if ($lkz == false) $this->where('lkz',NULL);
|
|
||||||
if ( $type == 'InOut' ) $this->where('type !=','account');
|
|
||||||
elseif ( $type == 'Acc' ) $this->where('type','account');
|
|
||||||
elseif ( $type == 'In' ) $this->where('type','input');
|
|
||||||
elseif ( $type == 'Out' ) $this->where('type','output');
|
|
||||||
$this->orderBy('description');
|
|
||||||
$result = $this->findAll();
|
|
||||||
$parent = array();
|
|
||||||
foreach ( $result as &$element )
|
|
||||||
{
|
|
||||||
$id = $element->parent_id;
|
$id = $element->parent_id;
|
||||||
while ( $id > 0 )
|
while ( $id > 0 ) {
|
||||||
{
|
|
||||||
$element->description = $this->mAccountList[$id]->description .'-'.$element->description;
|
$element->description = $this->mAccountList[$id]->description .'-'.$element->description;
|
||||||
if ($this->mAccountList[$id]->parent_id == 0){
|
|
||||||
$parent[] = (object)['id' => $element->id,'description' => $element->description ];
|
|
||||||
}
|
|
||||||
$id = $this->mAccountList[$id]->parent_id;
|
$id = $this->mAccountList[$id]->parent_id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $this->createDropDownList($result);
|
return $this->createDropDownList($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getCurDDLists(string $type, bool $bookableOnly = true, bool $withDeleted = false, ?int $defaultKey = null ) : array {
|
||||||
|
$this->populateAccountList();
|
||||||
|
$list = $this->filterIt($type,$bookableOnly,$withDeleted, $defaultKey);
|
||||||
|
$parent = $this->getParent($defaultKey);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
* liefert 2 DropDown Listen mit gegeben Suchparametern
|
* liefert 2 DropDown Listen mit gegeben Suchparametern
|
||||||
* parent für Vorselektion, subs für Untereinträge
|
* parent für Vorselektion, subs für Untereinträge
|
||||||
* @param string Kontotyp "InOut,In,Out,Acc"
|
* @param string $type Kontotyp "InOut,In,Out,Acc"
|
||||||
* @param bool ob bookable gesetzt sein muss
|
* @param bool $bookableOnly ob bookable gesetzt sein muss
|
||||||
* @return bool ob lkz Flag gesetzt sein darf
|
* @param bool $withDeleted ob lkz Flag gesetzt sein darf
|
||||||
|
* @return array fertige DropDownListen mit parent und subs
|
||||||
*/
|
*/
|
||||||
public function getDropDownLists($type, $bookable = true, $lkz = false )
|
public function getDropDownLists(string $type, bool $bookableOnly = true, bool $withDeleted = false, ?int $defaultKey = null ) : array {
|
||||||
{
|
$this->populateAccountList();
|
||||||
if ($bookable == true) $this->where('bookable',true);
|
$list = $this->filterIt($type,$bookableOnly,$withDeleted, $defaultKey);
|
||||||
if ($lkz == false) $this->where('lkz',null);
|
|
||||||
if ( $type == 'InOut' ) $this->where('type !=','account');
|
|
||||||
elseif ( $type == 'Acc' ) $this->where('type','account');
|
|
||||||
elseif ( $type == 'In' ) $this->where('type','output');
|
|
||||||
elseif ( $type == 'Out' ) $this->where('type','input');
|
|
||||||
$this->orderBy('description');
|
|
||||||
$result = $this->findAll();
|
|
||||||
|
|
||||||
$parent = array();
|
$parent = array();
|
||||||
$listen = array();
|
$listen = array();
|
||||||
foreach ( $result as &$element )
|
foreach ( $list as &$element ) {
|
||||||
{
|
|
||||||
$id = $element->parent_id;
|
$id = $element->parent_id;
|
||||||
while ( $id > 0 )
|
while ( $id > 0 ) {
|
||||||
{
|
if ($this->mAccountList[$id]->deleted_at) continue 2;
|
||||||
if ($this->mAccountList[$id]->lkz == 1) continue 2;
|
|
||||||
if ($this->mAccountList[$id]->parent_id == 0){
|
if ($this->mAccountList[$id]->parent_id == 0){
|
||||||
if (!array_key_exists($id, $parent))
|
if (!array_key_exists($id, $parent))
|
||||||
$parent[$id] = (object)['id' => $id,'description' => $this->mAccountList[$id]->description ];
|
$parent[$id] = (object)['id' => $id,'description' => $this->mAccountList[$id]->description ];
|
||||||
$listen[$id][$element->id] = (object)['id' => $element->id,'description' => $element->description ];
|
$listen[$id][$element->id] = (object)['id' => $element->id,'description' => $element->description ];
|
||||||
}
|
} else{
|
||||||
else{
|
|
||||||
$element->description = $this->mAccountList[$id]->description .'-'.$element->description;
|
$element->description = $this->mAccountList[$id]->description .'-'.$element->description;
|
||||||
}
|
}
|
||||||
$id = $this->mAccountList[$id]->parent_id;
|
$id = $this->mAccountList[$id]->parent_id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$subs = array();
|
$subs = array();
|
||||||
$subs[0] = $this->createDropDownList(array());
|
$subs[0] = ["0"=>"----"];
|
||||||
foreach ( $listen as $key => $element ){
|
foreach ( $listen as $key => $element ){
|
||||||
$subs[$key] = $this->createDropDownList($element,($this->mAccountList[$key]->bookable=="t"), $key);
|
$subs[$key] = $this->createDropDownList($element,($this->mAccountList[$key]->bookable), $key);
|
||||||
}
|
}
|
||||||
return array('parent'=> $this->createDropDownList($parent),'subs'=>(object)$subs);
|
return array('parent'=> $this->createDropDownList($parent),'subs'=>(object)$subs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* liefert parent id für category
|
* liefert parent id für category
|
||||||
* @param int account id
|
* @param int $sid account id
|
||||||
* @return int parent id
|
* @return int parent id
|
||||||
*/
|
*/
|
||||||
public function getParent($sid){
|
public function getParent(int $sid): int{
|
||||||
if ($sid == 0) return 0;
|
if ($sid == 0) return 0;
|
||||||
$result = $sid;
|
$this->populateAccountList();
|
||||||
$id = $this->mAccountList[$sid]->parent_id;
|
while ( $this->mAccountList[$sid]->parent_id > 0 ) {
|
||||||
while ( $id > 0 )
|
$sid = $this->mAccountList[$sid]->parent_id;
|
||||||
{
|
|
||||||
$result = $id;
|
|
||||||
$id = $this->mAccountList[$id]->parent_id;
|
|
||||||
}
|
}
|
||||||
return $result;
|
return $sid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -163,45 +187,71 @@ class mAccounts extends Model {
|
|||||||
*/
|
*/
|
||||||
public function getTreeData(){
|
public function getTreeData(){
|
||||||
helper('array');
|
helper('array');
|
||||||
$parents = array();
|
$this->populateAccountList();
|
||||||
$subs = array();
|
$parents = array_filter($this->mAccountList, function($var) {
|
||||||
foreach ( $this->mAccountList as $element )
|
return ($var->parent_id == 0);
|
||||||
{
|
});
|
||||||
if ($element->parent_id == 0)
|
foreach ( $this->mAccountList as $element ) {
|
||||||
$parents[$element->id] = $element;
|
|
||||||
}
|
|
||||||
foreach ( $this->mAccountList as $element )
|
|
||||||
{
|
|
||||||
// if ($element->parent_id > 0)
|
|
||||||
// echo "".$parents[$element->parent_id]->id;
|
|
||||||
if (($element->parent_id > 0) && array_key_exists($element->parent_id , $parents))
|
if (($element->parent_id > 0) && array_key_exists($element->parent_id , $parents))
|
||||||
$parents[$element->parent_id]->subs[$element->id] = $element;
|
$parents[$element->parent_id]->subs[$element->id] = $element;
|
||||||
}
|
}
|
||||||
array_sort_by_multiple_keys($parents, ['description' => SORT_ASC]);
|
array_sort_by_multiple_keys($parents, ['description' => SORT_ASC]);
|
||||||
return ['parents'=>$parents,'subs'=>$subs, 'all'=>$this->mAccountList];
|
return ['parents'=>$parents, 'all'=>$this->mAccountList];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* erstellt oder updatet den gegeben Account
|
* erstellt oder updatet den gegeben Account
|
||||||
* @var array formulardaten
|
* @var array formulardaten
|
||||||
*/
|
*/
|
||||||
public function saveAccount($data){
|
public function saveAccount(array $data) : bool{
|
||||||
$this->set('parent_id',$data['parent']);
|
$this->set('parent_id',$data['parent']);
|
||||||
$this->set('type', $data['type']);
|
$this->set('bookable', array_key_exists('bookable', $data));
|
||||||
$this->set('bookable', array_key_exists('bookable', $data) ? true : false);
|
$this->set('monitor', array_key_exists('monitor', $data));
|
||||||
|
$this->set('account', array_key_exists('account', $data));
|
||||||
$this->set('description', $data['description']);
|
$this->set('description', $data['description']);
|
||||||
$this->set('lkz', (array_key_exists('lkz', $data) ? 1 : null));
|
$this->set('deleted_at', (array_key_exists('deleted_at', $data) ? 'LOCALTIMESTAMP' : null),(array_key_exists('deleted_at', $data)? false: true));
|
||||||
if ($data['id'] == 0)
|
if ($data['id'] == 0)
|
||||||
$this->insert();
|
$result = $this->insert();
|
||||||
else
|
else
|
||||||
$this->update($data['id']);
|
$result = $this->update($data['id']);
|
||||||
$this->initialize();
|
log_message('debug',$this->db->getLastQuery());
|
||||||
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function checkType($id, $type){
|
/**
|
||||||
return ($this->mAccountList[$id]->type == $type);
|
* prüft ob gegebene Kategorie ein Konot ist
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isAccount(int $id){
|
||||||
|
$this->populateAccountList();
|
||||||
|
return ($this->mAccountList[$id]->account);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function checkOrCreateTable(){
|
||||||
|
log_message('debug',"Check or Create Account Table");
|
||||||
|
if ($this->db->tableExists($this->table)) return;
|
||||||
|
$forge = \Config\Database::forge();
|
||||||
|
$fields = array(
|
||||||
|
'id' => array( 'type' => 'serial'),
|
||||||
|
'parent_id' => array( 'type' => 'integer','default'=>'0'),
|
||||||
|
'bookable' => array( 'type' => 'boolean' ),
|
||||||
|
'description' => array( 'type' => 'character varying','constraint' => '80'),
|
||||||
|
'monitor' => array( 'type' => 'boolean','default'=>'false' ),
|
||||||
|
'account' => array( 'type' => 'boolean','default'=>'false' ),
|
||||||
|
'deleted_at'=> array( 'type' => 'timestamp without time zone','null'=>true),
|
||||||
|
);
|
||||||
|
$forge->addField( $fields );
|
||||||
|
$forge->addPrimaryKey('id');
|
||||||
|
|
||||||
|
// $this->db->query("CREATE TABLE $this->table (LIKE $this->defaultTableName INCLUDING DEFAULTS INCLUDING CONSTRAINTS) PARTITION BY RANGE (datum);");
|
||||||
|
$forge->createTable($this->table,true);
|
||||||
|
// CREATE TABLE temperatures_y2025q1 PARTITION OF temperatures
|
||||||
|
// FOR VALUES FROM ('2025-01-01') TO ('2025-04-01');
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
?>
|
?>
|
||||||
@@ -3,31 +3,60 @@
|
|||||||
use CodeIgniter\Model;
|
use CodeIgniter\Model;
|
||||||
|
|
||||||
class mBillDetails extends Model {
|
class mBillDetails extends Model {
|
||||||
protected $table = 'budget_billdetails';
|
private $defaultTableName='_budget_billdetails';
|
||||||
protected $primaryKey = 'id';
|
protected $primaryKey = 'id';
|
||||||
|
|
||||||
protected $useAutoIncrement = true;
|
protected $useAutoIncrement = true;
|
||||||
|
|
||||||
protected $returnType = 'object';
|
protected $returnType = \App\Entities\eBookingLine::class;
|
||||||
protected $useSoftDeletes = false;
|
protected $useSoftDeletes = true;
|
||||||
|
protected $deletedField ="deleted_at";
|
||||||
|
|
||||||
protected $allowedFields = ['bill_id','comment','account_id','subamount','lkz'];
|
protected $allowedFields = ['bill_id','comment','account_id','subamount','deleted_at'];
|
||||||
|
|
||||||
protected $useTimestamps = false;
|
protected $useTimestamps = false;
|
||||||
|
|
||||||
// public function getEntries($id){
|
protected array $casts = [
|
||||||
// $this->select('mw_budget_bookingdetails.*,mw_budget_categories.description');
|
'subamount' => 'float',
|
||||||
// $this->join('mw_budget_categories', 'mw_budget_categories.id = mw_budget_bookingdetails.account_id', 'left');
|
'account_id' => 'int',
|
||||||
// $result = $this->orderBy('id','asc')->where('bill_id',$id)->findAll();
|
'bill_id' => 'int',
|
||||||
// foreach ($result as $key => $value) {
|
];
|
||||||
|
|
||||||
// // $value->datum = date( "d.m.Y", strtotime( $value->datum ));
|
|
||||||
// // $value->amount = number_format( $value->amount , 2, ',', '.' );
|
|
||||||
// }
|
|
||||||
// return $result;
|
|
||||||
// }
|
|
||||||
|
|
||||||
public function getDetails($ids){
|
protected $validationRules = [
|
||||||
|
'bill_id' => 'required|numeric',
|
||||||
|
'account_id' => 'required|numeric',
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $validationMessages = [
|
||||||
|
'bill_id' => [
|
||||||
|
'required' => 'Die Buchungsnummer muss angegeben sein.',
|
||||||
|
'numeric' => 'Die Buchungsnummer muss eine Zahl sein.',
|
||||||
|
],
|
||||||
|
'account_id' => [
|
||||||
|
'required' => 'Die Kategorie muss angegeben sein.',
|
||||||
|
'numeric' => 'Die Kategorie muss eine Zahl sein.',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
protected function initialize() {
|
||||||
|
log_message('debug','mBillDetails initialize');
|
||||||
|
$this->table = auth()->user()->preFixDB.$this->defaultTableName;
|
||||||
|
$this->checkOrCreateTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getEntries(int $id){
|
||||||
|
$accounts = model('App\Models\mAccounts'); /* @var \App\Models\mAccounts $accounts */
|
||||||
|
$this->select($this->table.'.*,'.$accounts->getTable().'.description');
|
||||||
|
$this->join($accounts->getTable(), $accounts->getTable().'.id = '.$this->table.'.account_id', 'left');
|
||||||
|
$result = $this->orderBy('id','asc')->where('bill_id',$id)->findAll();
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* liefert für gegebene Buchung Details
|
||||||
|
* @param array<int> $ids id der Buchung
|
||||||
|
*/
|
||||||
|
public function getDetails(array $ids): array {
|
||||||
$quelle = model('App\Models\mAccounts');
|
$quelle = model('App\Models\mAccounts');
|
||||||
$rows = $this->whereIn('bill_id', $ids)->findAll();
|
$rows = $this->whereIn('bill_id', $ids)->findAll();
|
||||||
$result = array();
|
$result = array();
|
||||||
@@ -37,9 +66,18 @@ class mBillDetails extends Model {
|
|||||||
}
|
}
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
public function getEntriesForForm($billId, &$result, $accounts){
|
|
||||||
$this->select('budget_billdetails.*,budget_accounts.description');
|
/**
|
||||||
$this->join('budget_accounts', 'budget_accounts.id = budget_billdetails.account_id', 'left');
|
* liefert für gegebene Buchung Details im Formularformat
|
||||||
|
* @param int $billId id der Buchung
|
||||||
|
* @param mixed $result Datenstruktur für Formular mit defaults
|
||||||
|
* @param \App\Models\mAccounts $accounts modelClass für Konten
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function getEntriesForForm(int $billId, &$result){
|
||||||
|
$accounts = model('App\Models\mAccounts');
|
||||||
|
$this->select($this->table.'.*,'.$accounts->getTable().'.description');
|
||||||
|
$this->join($accounts->getTable(), $accounts->getTable().'.id = '.$this->table.'.account_id', 'left');
|
||||||
$data = $this->orderBy('id','asc')->where('bill_id',$billId)->findAll();
|
$data = $this->orderBy('id','asc')->where('bill_id',$billId)->findAll();
|
||||||
$amount = 0.0;
|
$amount = 0.0;
|
||||||
foreach ($data as $key => $row){
|
foreach ($data as $key => $row){
|
||||||
@@ -58,12 +96,12 @@ class mBillDetails extends Model {
|
|||||||
$result['total_in']= ($amount >= 0.0)?number_format( abs( $amount ), 2, ',', '' ):'';
|
$result['total_in']= ($amount >= 0.0)?number_format( abs( $amount ), 2, ',', '' ):'';
|
||||||
$result['total_out']= ($amount < 0.0)?number_format( abs( $amount ), 2, ',', '' ):'';
|
$result['total_out']= ($amount < 0.0)?number_format( abs( $amount ), 2, ',', '' ):'';
|
||||||
}
|
}
|
||||||
else if ($accounts->checkType($result['category'][0],'account'))
|
else if ($accounts->isAccount($result['category'][0]))
|
||||||
$result['transfer'] = true;
|
$result['transfer'] = true;
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function saveEntries($data, $billId){
|
public function saveEntries(array $data, int $billId){
|
||||||
for ($i=0;$i<10;$i++){
|
for ($i=0;$i<10;$i++){
|
||||||
if ($data['category'][$i] > 0){
|
if ($data['category'][$i] > 0){
|
||||||
$this->set('subamount', floatval($data['input'][$i])-floatval($data['output'][$i])); //floatval($data['total_in'])-floatval($data['total_out']));
|
$this->set('subamount', floatval($data['input'][$i])-floatval($data['output'][$i])); //floatval($data['total_in'])-floatval($data['total_out']));
|
||||||
@@ -82,5 +120,28 @@ class mBillDetails extends Model {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function checkOrCreateTable(){
|
||||||
|
log_message('debug',"Check or Create BillDetails Table");
|
||||||
|
if ($this->db->tableExists($this->table)) return;
|
||||||
|
log_message('debug',"Create BillDetails Table ".$this->table);
|
||||||
|
$accounts = model('App\Models\mAccounts'); /* @var \App\Models\mAccounts $accounts */
|
||||||
|
$bills = model('App\Models\mBills'); /* @var \App\Models\mBills $bills */
|
||||||
|
$forge = \Config\Database::forge();
|
||||||
|
$fields = array(
|
||||||
|
'id' => array( 'type' => 'serial'),
|
||||||
|
'bill_id' => array( 'type' => 'integer'),
|
||||||
|
'account_id' => array( 'type' => 'integer' ),
|
||||||
|
'subamount' => array( 'type' => 'numeric','constraint' => '9,2' ),
|
||||||
|
'comment' => array( 'type' => 'character varying','constraint' => '150'),
|
||||||
|
'deleted_at'=> array( 'type' => 'timestamp without time zone','null'=>true),
|
||||||
|
);
|
||||||
|
$forge->addField( $fields );
|
||||||
|
$forge->addPrimaryKey('id');
|
||||||
|
$forge->addForeignKey('bill_id', $bills->getTable(), 'id','NO ACTION','NO ACTION','bill_id_fk');
|
||||||
|
$forge->addForeignKey('account_id', $accounts->getTable(), 'id','NO ACTION','NO ACTION','account_id_fk');
|
||||||
|
$forge->createTable($this->table,true);
|
||||||
|
log_message('debug','Create BillDetails Table '.$this->db->lastQuery);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
?>
|
?>
|
||||||
@@ -1,33 +1,58 @@
|
|||||||
<?php namespace App\Models;
|
<?php namespace App\Models;
|
||||||
|
|
||||||
|
use App\Models\Cast\CastMyDate;
|
||||||
use CodeIgniter\Model;
|
use CodeIgniter\Model;
|
||||||
use App\Models\Mbookingdetails;
|
|
||||||
use App\Models\Mcategories;
|
|
||||||
|
|
||||||
class mBills extends Model {
|
class mBills extends Model {
|
||||||
protected $table = 'budget_bills';
|
private $defaultTableName='_budget_bills';
|
||||||
|
|
||||||
protected $primaryKey = 'id';
|
protected $primaryKey = 'id';
|
||||||
protected $useAutoIncrement = true;
|
protected $useAutoIncrement = true;
|
||||||
|
|
||||||
protected $returnType = 'object';
|
protected $returnType = \App\Entities\eBooking::class;
|
||||||
|
|
||||||
|
protected $useSoftDeletes = true;
|
||||||
|
protected $deletedField ="deleted_at";
|
||||||
|
|
||||||
protected $useSoftDeletes = false;
|
|
||||||
//TODO timestamps aktivieren
|
//TODO timestamps aktivieren
|
||||||
// protected $createdField = 'created_at';
|
// protected $createdField = 'created_at';
|
||||||
// protected $updatedField = 'updated_at';
|
// protected $updatedField = 'updated_at';
|
||||||
// protected $deletedField = 'deleted_at';
|
// protected $deletedField = 'deleted_at';
|
||||||
|
|
||||||
protected $allowedFields = ['renummer','datum','receiver','source_id','amount','type','comment','validate','lkz','rechnung'];
|
protected $allowedFields = ['datum','receiver','source_id','amount','validate','deleted_at','rechnung'];
|
||||||
|
|
||||||
protected $useTimestamps = false;
|
protected $useTimestamps = false;
|
||||||
|
|
||||||
|
// Bind the type to the handler
|
||||||
|
protected array $castHandlers = [
|
||||||
|
'myDate' => CastMyDate::class,
|
||||||
|
];
|
||||||
|
//protected $afterFind = ['checkTransfer'];
|
||||||
|
protected array $casts = [
|
||||||
|
'id' => 'int',
|
||||||
|
'amount' => 'float',
|
||||||
|
'datum' => 'myDate[dd.MM.yyyy]',
|
||||||
|
'validate' => 'boolean',
|
||||||
|
'source_id' => 'int',
|
||||||
|
];
|
||||||
|
|
||||||
|
protected function initialize() {
|
||||||
|
log_message('debug','mBills initialize');
|
||||||
|
$this->table = auth()->user()->preFixDB.$this->defaultTableName;
|
||||||
|
$this->checkOrCreateTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTable() : string {
|
||||||
|
return $this->table;
|
||||||
|
}
|
||||||
|
// protected function checkTransfer(array $data){
|
||||||
|
// $data['data']['transfer'] = ((count($this->attributes['details']) == 1) && $accounts->isAccount($this->attributes['details'][0]->account_id));
|
||||||
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* liefert Buchungen für Aktivitätenliste
|
* liefert Buchungen für Aktivitätenliste für alte datentabelle
|
||||||
* @return mixed Datensätze für Tabelle
|
* @return mixed Datensätze für Tabelle
|
||||||
*/
|
*/
|
||||||
public function getEntriesDet($start, $ende, $source){
|
public function getEntriesDet(string $start, string $ende, int $source){
|
||||||
$details = model('App\Models\mBillDetails');
|
$details = model('App\Models\mBillDetails');
|
||||||
$quelle = model('App\Models\mAccounts');
|
$quelle = model('App\Models\mAccounts');
|
||||||
$this->where('datum >=', date( 'Y-m-d', strtotime($start)));
|
$this->where('datum >=', date( 'Y-m-d', strtotime($start)));
|
||||||
@@ -51,7 +76,7 @@ class mBills extends Model {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = $this->orderBy('datum','desc')->where('lkz',null)->findAll();
|
$result = $this->orderBy('datum','desc')->findAll(); //->where('lkz',null)
|
||||||
if (0 == sizeof($result)){
|
if (0 == sizeof($result)){
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
@@ -64,7 +89,6 @@ class mBills extends Model {
|
|||||||
|
|
||||||
foreach ($result as $value) {
|
foreach ($result as $value) {
|
||||||
$value->details = $ergebnis[$value->id]??null;
|
$value->details = $ergebnis[$value->id]??null;
|
||||||
$value->datum = date( "d.m.Y", strtotime( $value->datum ));
|
|
||||||
$value->source = $quelle->getDropDownEntry($value->source_id);
|
$value->source = $quelle->getDropDownEntry($value->source_id);
|
||||||
// $value->amount = number_format( $value->amount , 2, ',', '.' );
|
// $value->amount = number_format( $value->amount , 2, ',', '.' );
|
||||||
}
|
}
|
||||||
@@ -72,72 +96,44 @@ class mBills extends Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* liefert Buchungen für Aktivitätenliste
|
||||||
|
* @return mixed Datensätze für Tabelle
|
||||||
|
*/
|
||||||
|
public function getActivities(string $start, string $ende, int $source){
|
||||||
|
$quelle = model('App\Models\mAccounts');
|
||||||
|
$this->where('datum >=', date( 'Y-m-d', strtotime($start)));
|
||||||
|
$this->where('datum <=', date( 'Y-m-d', strtotime($ende)));
|
||||||
|
if ($source > 0) {
|
||||||
|
$this->where('source_id', $source );
|
||||||
|
}
|
||||||
|
$result = $this->orderBy('datum','desc')->findAll();
|
||||||
|
if (0 == sizeof($result)) return $result;
|
||||||
|
foreach ($result as $value) {
|
||||||
|
$value->source = $quelle->getDropDownEntry($value->source_id);
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
|
||||||
|
}
|
||||||
|
/**
|
||||||
* liefert Buchungen für Übersichtstabelle
|
* liefert Buchungen für Übersichtstabelle
|
||||||
* @return mixed Datensätze für Tabelle
|
* @return mixed Datensätze für Tabelle
|
||||||
*/
|
*/
|
||||||
function getEntries(){
|
public function getEntries(int $zeilen = 10){
|
||||||
$details = model('App\Models\mBillDetails');
|
$result = $this->orderBy('datum','desc')->where('validate',false)->findAll($zeilen); //->where('lkz',null)
|
||||||
$quelle = model('App\Models\mAccounts');
|
if (0 == sizeof($result)) return $result;
|
||||||
$result = $this->orderBy('datum','desc')->where('validate',false)->where('lkz',null)->findAll(10);
|
|
||||||
$keys=array();
|
|
||||||
foreach ($result as $value) {
|
|
||||||
$keys[] = intval($value->id);
|
|
||||||
}
|
|
||||||
//$ergebnis = $details->whereIn('bill_id', $keys)->asArray()->findAll();
|
|
||||||
$ergebnis = $details->getDetails($keys);
|
|
||||||
// print_r($ergebnis);
|
|
||||||
|
|
||||||
foreach ($result as $value) {
|
|
||||||
$value->details = $ergebnis[$value->id]??null;//$details->getEntries($value->id);
|
|
||||||
$value->datum = date( "d.m.Y", strtotime( $value->datum ));
|
|
||||||
$value->quelle = $quelle->getDropDownEntry($value->source_id);
|
|
||||||
// $value->amount = number_format( $value->amount , 2, ',', '.' );
|
|
||||||
}
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getToDos(){
|
||||||
* liefert gegebene Buchung inkl. Details im Formularformat
|
$result = $this->orderBy('datum','desc')->where('validate',true)->findAll();
|
||||||
* @param int id der Buchung
|
|
||||||
* @return mixed Datenstruktur für Formular
|
|
||||||
*/
|
|
||||||
function getEntry($id, &$result, $accounts){
|
|
||||||
$details = model('App\Models\mBillDetails');
|
|
||||||
$quelle = model('App\Models\mAccounts');
|
|
||||||
$data = $this->orderBy('datum','desc')->find($id);
|
|
||||||
$result['datum'] = $data->datum;//date( "d.m.Y", strtotime($data->datum));
|
|
||||||
$result['receiver'] = $data->receiver;
|
|
||||||
$result['billfile'] = $data->rechnung;
|
|
||||||
$result['source'] = $data->source_id;
|
|
||||||
$result['validate'] = $data->validate;
|
|
||||||
$result['id'] = $id;
|
|
||||||
$result = array_merge($result, $details->getEntriesForForm($id, $result, $accounts));
|
|
||||||
$result['transfer'] = $result['transfer'] || ($data->type == 'transfer');
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getToDos(){
|
public function getAccountsBalance(){
|
||||||
$details = model('App\Models\mBillDetails');
|
$sums = $this->db->query("SELECT * FROM finanzen.getbalances('".auth()->user()->preFixDB."'::text,ARRAY[]::integer[])"); // mit datensyntax ARRAY[210,216]
|
||||||
$quelle = model('App\Models\mAccounts');
|
// log_message('debug', $this->db->getLastQuery());
|
||||||
$result = $this->orderBy('datum','desc')->where('validate',true)->where('lkz',null)->findAll();
|
// log_message('debug', print_r($sums->getResultArray(), true));
|
||||||
$keys=array();
|
return $sums->getResultArray();
|
||||||
foreach ($result as $value) {
|
|
||||||
$keys[] = intval($value->id);
|
|
||||||
}
|
|
||||||
$ergebnis = $details->getDetails($keys);
|
|
||||||
|
|
||||||
foreach ($result as $value) {
|
|
||||||
$value->details = $ergebnis[$value->id]??null;
|
|
||||||
//$value->details = $details->getEntries($value->id);
|
|
||||||
$value->datum = date( "d.m.Y", strtotime( $value->datum ));
|
|
||||||
$value->quelle = $quelle->getDropDownEntry($value->source_id);;
|
|
||||||
// $value->amount = number_format( $value->amount , 2, ',', '.' );
|
|
||||||
}
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
function getAccountsBalance(){
|
|
||||||
$sums = $this->db->query("SELECT * FROM get_account_balance4()");
|
|
||||||
return $sums->getResult();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function storeBillFile(int $billId, string $filename){
|
public function storeBillFile(int $billId, string $filename){
|
||||||
@@ -148,52 +144,49 @@ class mBills extends Model {
|
|||||||
$this->update($billId);
|
$this->update($billId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function saveBill($data) : int {
|
|
||||||
$details = model('App\Models\mBillDetails');
|
|
||||||
$accounts = model('App\Models\mAccounts');
|
|
||||||
$this->set('datum', date( "Y-m-d", strtotime($data['datum'] ) ));
|
|
||||||
|
|
||||||
$this->set('source_id', $data['source']);
|
|
||||||
$total = floatval($data['total_in'])-floatval($data['total_out']);
|
|
||||||
if ( !isset($data['multi']) )
|
|
||||||
$total = floatval($data['input'][0])-floatval($data['output'][0]);
|
|
||||||
if ( isset($data['rechnung']) )
|
|
||||||
$this->set('rechnung', $data['rechnung']);
|
|
||||||
$this->set('amount', $total);
|
|
||||||
$this->set('validate', $data['validate']??false);
|
|
||||||
if ($data['transfer']==1){
|
|
||||||
$this->set('receiver', $accounts->getDropDownEntry($data['category'][0]));
|
|
||||||
$this->set('type', 'transfer');
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
$this->set('receiver', $data['receiver']);
|
|
||||||
$this->set('type', 'multiple');
|
|
||||||
}
|
|
||||||
//$tabdata['type']
|
|
||||||
if ( 0 == $data['id'] ){
|
|
||||||
$this->insert();
|
|
||||||
$billId = $this->getInsertID();
|
|
||||||
//insert
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
$billId = $data['id'];
|
|
||||||
$this->update($data['id']);
|
|
||||||
}
|
|
||||||
$details->saveEntries($data, $billId);
|
|
||||||
return $billId;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* löscht gegebene Buchung inkl. Details
|
* löscht gegebene Buchung inkl. Details
|
||||||
* @param int id der Buchung
|
* @param int id der Buchung
|
||||||
* @return mixed Datenstruktur für Formular
|
* @return mixed Datenstruktur für Formular
|
||||||
*/
|
*/
|
||||||
function deleteEntry($id){
|
public function deleteEntry(int $id) : bool {
|
||||||
|
$result = true;
|
||||||
$details = model('App\Models\mBillDetails');
|
$details = model('App\Models\mBillDetails');
|
||||||
if ($id > 0){
|
if ($id > 0){
|
||||||
$details->where('bill_id',$id)->delete();
|
$result = $details->where('bill_id',$id)->delete();
|
||||||
$this->delete($id);
|
if ($result === true)
|
||||||
|
$result = $this->delete($id);
|
||||||
}
|
}
|
||||||
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function checkOrCreateTable(){
|
||||||
|
log_message('debug',"Check or Create Bill Table");
|
||||||
|
if ($this->db->tableExists('finanzen.'.$this->table)) return;
|
||||||
|
log_message('debug','Create Bills Table '.$this->db->lastQuery);
|
||||||
|
log_message('debug',"Create Bills Table ".$this->table);
|
||||||
|
$accounts = model('App\Models\mAccounts'); /* @var \App\Models\mAccounts $accounts */
|
||||||
|
$forge = \Config\Database::forge();
|
||||||
|
$fields = array(
|
||||||
|
'id' => array( 'type' => 'serial'),
|
||||||
|
'datum' => array( 'type' => 'date'),
|
||||||
|
'receiver' => array( 'type' => 'character varying','constraint' => '120'),
|
||||||
|
'source_id' => array( 'type' => 'integer' ),
|
||||||
|
'amount' => array( 'type' => 'numeric','constraint' => '9,2' ),
|
||||||
|
'validate' => array( 'type' => 'boolean' ),
|
||||||
|
'rechnung' => array( 'type' => 'character varying','constraint' => '50','null'=>true),
|
||||||
|
'deleted_at'=> array( 'type' => 'timestamp without time zone','null'=>true),
|
||||||
|
);
|
||||||
|
$forge->addField( $fields );
|
||||||
|
$forge->addPrimaryKey('id');
|
||||||
|
$forge->addForeignKey('source_id', $accounts->getTable(), 'id','NO ACTION','NO ACTION','source_id_fk');
|
||||||
|
// $this->db->query("CREATE TABLE $this->table (LIKE $this->defaultTableName INCLUDING DEFAULTS INCLUDING CONSTRAINTS) PARTITION BY RANGE (datum);");
|
||||||
|
$forge->createTable($this->table,true,['PARTITION BY RANGE'=>'(datum)']);
|
||||||
|
log_message('debug','Create Bills Table '.$this->db->lastQuery);
|
||||||
|
// CREATE TABLE temperatures_y2025q1 PARTITION OF temperatures
|
||||||
|
// FOR VALUES FROM ('2025-01-01') TO ('2025-04-01');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
?>
|
?>
|
||||||
@@ -3,17 +3,26 @@
|
|||||||
use CodeIgniter\Model;
|
use CodeIgniter\Model;
|
||||||
|
|
||||||
class mScheduled extends Model {
|
class mScheduled extends Model {
|
||||||
protected $table = 'budget_scheduled';
|
private $defaultTableName='_budget_scheduled';
|
||||||
protected $primaryKey = 'id';
|
|
||||||
|
|
||||||
|
protected $primaryKey = 'id';
|
||||||
protected $useAutoIncrement = true;
|
protected $useAutoIncrement = true;
|
||||||
protected $returnType = 'array';
|
protected $returnType = 'array';
|
||||||
protected $useSoftDeletes = false;
|
protected $useSoftDeletes = true;
|
||||||
|
protected $deletedField ="deleted_at";
|
||||||
|
|
||||||
protected $allowedFields = ['creat_date','next_date','data'];
|
protected $allowedFields = ['creat_date','next_date','data'];
|
||||||
protected $useTimestamps = false;
|
protected $useTimestamps = false;
|
||||||
protected $skipValidation = false;
|
protected $skipValidation = false;
|
||||||
|
|
||||||
public function calcNextDate($date, $num, $type)
|
|
||||||
|
protected function initialize() {
|
||||||
|
$this->table = auth()->user()->preFixDB.$this->defaultTableName;
|
||||||
|
$this->checkOrCreateTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function calcNextDate(string $date, string $num, string $type)
|
||||||
{
|
{
|
||||||
$start = strtotime( $date );
|
$start = strtotime( $date );
|
||||||
$period = $num .' '. $type;
|
$period = $num .' '. $type;
|
||||||
@@ -24,68 +33,78 @@ class mScheduled extends Model {
|
|||||||
return date( "Y-m-d", $future );
|
return date( "Y-m-d", $future );
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getEntry($id){
|
public function getEntry(int $id){
|
||||||
$accounts = model('App\Models\mAccounts');
|
|
||||||
$data = $this->asObject()->find($id);
|
$data = $this->asObject()->find($id);
|
||||||
$result = (array)json_decode($data->data);
|
$result = (array)json_decode($data->data);
|
||||||
$result['id'] = $id;
|
$result['id'] = $id;
|
||||||
$result['datum'] = $data->next_date; //date( "d.m.Y", strtotime($data->next_date));
|
$result['datum'] = $data->next_date; //date( "d.m.Y", strtotime($data->next_date));
|
||||||
for ($i=0;$i<10;$i++){
|
|
||||||
$result['category_parent'][$i]= $accounts->getParent($result['category'][$i]);
|
|
||||||
}
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getEntries(){
|
public function getEntries(){
|
||||||
$quelle = model('App\Models\mAccounts');
|
$quelle = model('App\Models\mAccounts');
|
||||||
$result = $this->asObject()->findAll();
|
$result = $this->asObject()->findAll();
|
||||||
|
log_message('error', 'Get Entries Schedules: {msg}', ['msg'=>(string)$this->db->getLastQuery()]);
|
||||||
foreach ($result as $value) {
|
foreach ($result as $value) {
|
||||||
$details = json_decode($value->data);
|
$details = json_decode($value->data);
|
||||||
for ($i=0;$i<10;$i++){
|
foreach ($details->input as $key => $line){
|
||||||
if ((floatval($details->input[$i]) == 0.0) && (floatval($details->output[$i]) == 0.0))
|
if ((floatval($line) == 0.0) && (floatval($details->output[$key]) == 0.0))
|
||||||
continue;
|
continue;
|
||||||
$value->details[] = ['comment'=>$details->comment[$i], 'description'=>$quelle->getDropDownEntry($details->category[$i]), 'subamount'=>(floatval($details->input[$i])-floatval($details->output[$i]))];
|
// $account_id = (!isset($details->account_id))?$details->category:$details->account_id;
|
||||||
|
$value->details[] = ['comment'=>$details->comment[$key], 'description'=>$quelle->getDropDownEntry($details->account_id[$key]), 'subamount'=>(floatval($details->input[$key])-floatval($details->output[$key]))];
|
||||||
}
|
}
|
||||||
//$value->details = null;
|
//$value->details = null;
|
||||||
$value->datum = date( "d.m.Y", strtotime( $value->next_date ));
|
$value->datum = date( "d.m.Y", strtotime( $value->next_date ));
|
||||||
$value->source = $quelle->getDropDownEntry($details->source);
|
$source_id = (!isset($details->source_id))?$details->source:$details->source_id;
|
||||||
|
$value->source = $quelle->getDropDownEntry($source_id);
|
||||||
$value->receiver = $details->receiver;
|
$value->receiver = $details->receiver;
|
||||||
$value->amount = floatval($details->total_in)-floatval($details->total_out);
|
// if (!isset($details->amount)){
|
||||||
// $value->amount = number_format( $value->amount , 2, ',', '.' );
|
// $value->amount = floatval($details->total_in)-floatval($details->total_out);
|
||||||
|
// $value->amount = number_format( floatval($value->amount) , 2, ',', '.' );
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
$value->amount = $details->amount; //number_format( floatval($details->amount) , 2, ',', '.' );
|
||||||
}
|
}
|
||||||
return $result;
|
return $result;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function saveBill($data){
|
public function saveIt(array $data){
|
||||||
$accounts = model('App\Models\mAccounts');
|
$accounts = model('App\Models\mAccounts');
|
||||||
$data['validate'] = true;
|
$data['validate'] = true;
|
||||||
$data['scheduled'] = true;
|
$data['scheduled'] = true;
|
||||||
$data['renummer'] = isset($data['renummer']);
|
|
||||||
|
|
||||||
if ($data['transfer']==1){
|
|
||||||
$data['receiver'] = $accounts->getDropDownEntry($data['category'][0]);
|
|
||||||
$data['transfer'] = true;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
$data['multi'] = isset($data['multiple']);
|
|
||||||
$data['transfer'] = false;
|
|
||||||
}
|
|
||||||
unset($data['openamount']);
|
unset($data['openamount']);
|
||||||
unset($data['category_parent']);
|
unset($data['category_parent']);
|
||||||
$data['datum'] = date( "Y-m-d", strtotime($data['datum'] ) );
|
unset($data['total_in']);
|
||||||
|
unset($data['total_out']);
|
||||||
|
|
||||||
|
// $data['datum'] = date( "Y-m-d", strtotime($data['datum'] ) );
|
||||||
$this->set('next_date', $data['datum']);
|
$this->set('next_date', $data['datum']);
|
||||||
|
|
||||||
$data['total_in'] = 0;
|
|
||||||
$data['total_out'] = 0;
|
|
||||||
for ($i=0;$i<10;$i++){
|
|
||||||
if ($data['category'][$i] > 0){
|
|
||||||
$data['total_in'] += floatval($data['input'][$i]);
|
|
||||||
$data['total_out'] += floatval($data['output'][$i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$this->set('data',json_encode($data));
|
$this->set('data',json_encode($data));
|
||||||
|
|
||||||
|
log_message("debug","save Scheduled".json_encode($data));
|
||||||
if ( 0 == $data['id']) $this->insert();
|
if ( 0 == $data['id']) $this->insert();
|
||||||
else $this->update($data['id']);
|
else $this->update($data['id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function checkOrCreateTable(){
|
||||||
|
log_message('debug',"Check or Create Scheduled Table");
|
||||||
|
if ($this->db->tableExists($this->table)) return;
|
||||||
|
log_message('debug','Create Scheduled Table '.$this->db->lastQuery);
|
||||||
|
log_message('debug',"Create Scheduled Table ".$this->table);
|
||||||
|
$forge = \Config\Database::forge();
|
||||||
|
$fields = array(
|
||||||
|
'id' => array( 'type' => 'serial'),
|
||||||
|
'creat_date' => array( 'type' => 'date','default'=>new \CodeIgniter\Database\RawSql('CURRENT_TIMESTAMP')),
|
||||||
|
'next_date' => array( 'type' => 'date'),
|
||||||
|
'data' => array( 'type' => 'text'),
|
||||||
|
'deleted_at'=> array( 'type' => 'timestamp without time zone','null'=>true),
|
||||||
|
);
|
||||||
|
$forge->addField( $fields );
|
||||||
|
$forge->addPrimaryKey('id');
|
||||||
|
$forge->createTable($this->table,true);
|
||||||
|
log_message('debug','Create Scheduled Table '.$this->db->lastQuery);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,13 +2,13 @@
|
|||||||
<div class="card text-bg-dark">
|
<div class="card text-bg-dark">
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<form class="form form-vertical" id="editaccount" method="post" action="<?= base_url() ?>/editAccount">
|
<form class="form form-vertical" id="editaccount" method="post" action="<?= base_url() ?>/viewAccounts">
|
||||||
<input type="hidden" value="<?= $id??0 ?>" name="id" id="id">
|
<input type="hidden" value="<?= $id??0 ?>" name="id" id="id">
|
||||||
<?php if (! empty($validation)) : ?>
|
<?php if (! empty($errors)) : ?>
|
||||||
<div class='alert alert-danger mt-2'>
|
<div class='alert alert-danger mt-2'>
|
||||||
<div class="errors" role="alert">
|
<div class="errors" role="alert">
|
||||||
<ul>
|
<ul>
|
||||||
<?php foreach ($validation as $error) : ?>
|
<?php foreach ($errors as $error) : ?>
|
||||||
<li><?= esc($error) ?></li>
|
<li><?= esc($error) ?></li>
|
||||||
<?php endforeach ?>
|
<?php endforeach ?>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -26,33 +26,36 @@
|
|||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="parent">Überkonto:</label>
|
<label for="parent">Überkonto:</label>
|
||||||
<?= form_dropdown('parent', $ddlist, $parent??0,'id="parent" class="form-select"'); ?>
|
<select name="parent" class="form-select" required id="parent" >
|
||||||
|
<option value="0">----</option>
|
||||||
|
<?php foreach ($ddlist as $key => $value): ?>
|
||||||
|
<option value="<?= $key ?>" <?= ($key == ($parent??0))?'selected':'' ?>><?= $value ?></option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<div class="form-check form-check-inline">
|
<div class="form-check form-switch">
|
||||||
<input class="form-check-input" type="checkbox" id="typeAccount" value="account" name="type" <?= set_radio('type', 'account') ?>>
|
<label class="form-check-label" for="account">Typ Konto</label>
|
||||||
<label class="form-check-label" for="inlineCheckbox1">Konto</label>
|
<input class="form-check-input" type="checkbox" id="account" name="account" <?= set_checkbox('account', 'on', $account??false) ?> >
|
||||||
</div>
|
|
||||||
<div class="form-check form-check-inline">
|
|
||||||
<input class="form-check-input" type="checkbox" id="typeInput" value="input" name="type" <?= set_radio('type', 'input') ?> >
|
|
||||||
<label class="form-check-label" for="inlineCheckbox2">Einnahmen</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check form-check-inline">
|
|
||||||
<input class="form-check-input" type="checkbox" id="typeOutput" value="output" name="type" <?= set_radio('type', 'output', true) ?> >
|
|
||||||
<label class="form-check-label" for="inlineCheckbox3">Ausgaben</label>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<div class="form-check form-switch">
|
<div class="form-check form-switch">
|
||||||
<label class="form-check-label" for="bookable">Buchbarkeit</label>
|
<label class="form-check-label" for="bookable">Buchbarkeit</label>
|
||||||
<input class="form-check-input" type="checkbox" id="bookable" value="bookable" name="bookable" <?= set_checkbox('bookable', 'on', (($bookable??"f")=="t")?true:false) ?> >
|
<input class="form-check-input" type="checkbox" id="bookable" value="bookable" name="bookable" <?= set_checkbox('bookable', 'on', $bookable??false) ?> >
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<div class="form-check form-switch">
|
<div class="form-check form-switch">
|
||||||
<label class="form-check-label" for="lkz">lkz</label>
|
<label class="form-check-label" for="monitor">Monitor</label>
|
||||||
<input class="form-check-input" type="checkbox" id="lkz" value="1" name="lkz" <?= set_checkbox('lkz', '1', $lkz??false) ?>>
|
<input class="form-check-input" type="checkbox" id="monitor" name="monitor" <?= set_checkbox('monitor', 'on', $monitor??false) ?> >
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="form-check form-switch">
|
||||||
|
<label class="form-check-label" for="deleted_at">Gelöscht</label>
|
||||||
|
<input class="form-check-input" type="checkbox" id="deleted_at" value="1" name="deleted_at" <?= set_checkbox('deleted_at', '1', $deleted_at??false) ?>>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
|
|||||||
@@ -3,31 +3,49 @@
|
|||||||
|
|
||||||
<?= $this->section('css'); ?>
|
<?= $this->section('css'); ?>
|
||||||
<link rel="stylesheet" href="/css/mawim.css">
|
<link rel="stylesheet" href="/css/mawim.css">
|
||||||
<link rel="stylesheet" href="/assets/jquery-ui-1.13.2.custom/jquery-ui.css">
|
|
||||||
<?= $this->endSection(); ?>
|
<?= $this->endSection(); ?>
|
||||||
<?= $this->section('menu'); ?>
|
<?= $this->section('menu'); ?>
|
||||||
<?= $this->include('sidebar') ?>
|
<?= $this->include('sidebar') ?>
|
||||||
<?= $this->endSection(); ?>
|
<?= $this->endSection(); ?>
|
||||||
<?= $this->section('content'); ?>
|
<?= $this->section('content'); ?>
|
||||||
|
<?php if (!function_exists('printBool')) {
|
||||||
|
function printBool(bool $var){
|
||||||
|
return ($var)?"true":"false";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
<?php function printsub($id, $all){
|
<?php if (!function_exists('printsub')) { function printsub(int $id, $all){
|
||||||
$liste = '';
|
$liste = '';
|
||||||
$ret='';
|
$ret='';
|
||||||
foreach($all as $ele){
|
foreach($all as $ele){
|
||||||
$class ="";
|
$class ="";
|
||||||
|
$vis ="d-none";
|
||||||
if ($ele->parent_id == $id){
|
if ($ele->parent_id == $id){
|
||||||
if ($ele->lkz) $class = "text-bg-danger";
|
if ($ele->deleted_at) {
|
||||||
else if ($ele->bookable == "f") $class = "text-bg-warning";
|
$class = "text-bg-danger";
|
||||||
$toolt ="bookable: $ele->bookable; lkz: $ele->lkz; Id: $ele->id; PID:$ele->parent_id";
|
$vis="d-none";
|
||||||
$liste .= "<li><span data-bs-toggle='tooltip' data-bs-html=true title='$toolt'";
|
}
|
||||||
|
else {
|
||||||
|
$vis="";
|
||||||
|
if (!$ele->bookable)
|
||||||
|
$class = "text-bg-warning";
|
||||||
|
}
|
||||||
|
$toolt = ($ele->bookable)?"":"not ";
|
||||||
|
$toolt .= "bookable; ";
|
||||||
|
$toolt .= ($ele->deleted_at)?"gelöscht; ":"";
|
||||||
|
$toolt .="Id: $ele->id; PID:$ele->parent_id";
|
||||||
|
$liste .= "<li class=\"$vis\"><i class=\"fa-solid\"></i> <span data-bs-toggle='tooltip' data-bs-html=true title='$toolt'";
|
||||||
$liste .= "data-id=\"$ele->id\"";
|
$liste .= "data-id=\"$ele->id\"";
|
||||||
$liste .= "data-pid=\"$ele->parent_id\"";
|
$liste .= "data-pid=\"$ele->parent_id\"";
|
||||||
$liste .= "data-bookable=\"$ele->bookable\"";
|
$liste .= "data-bookable=\"".printBool($ele->bookable)."\"";
|
||||||
$liste .= "data-lkz=\"$ele->lkz\"";
|
$liste .= "data-account=\"".printBool($ele->account)."\"";
|
||||||
$liste .= "data-type=\"$ele->type\"";
|
$liste .= "data-monitor=\"".printBool($ele->monitor)."\"";
|
||||||
|
$liste .= "data-deleted=\"$ele->deleted_at\"";
|
||||||
$liste .= "data-description=\"$ele->description\"";
|
$liste .= "data-description=\"$ele->description\"";
|
||||||
$liste .= "class='$class'>$ele->description</span></li>";
|
$liste .= "class='$class'>$ele->description</span>";
|
||||||
$liste .= printsub($ele->id, $all);
|
$liste .= printsub($ele->id, $all);
|
||||||
|
$liste .= "</li>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($liste !=''){
|
if ($liste !=''){
|
||||||
@@ -36,33 +54,53 @@
|
|||||||
$ret .= "</ul>";
|
$ret .= "</ul>";
|
||||||
}
|
}
|
||||||
return $ret;
|
return $ret;
|
||||||
} ?>
|
}} ?>
|
||||||
<div class="page-heading">
|
<div class="page-heading">
|
||||||
<h3> Kategorien bearbeiten</h3>
|
<h3> Kategorien bearbeiten</h3>
|
||||||
|
<?php if ($saveDB??false) : ?>
|
||||||
|
<div class='alert <?= $saveDB["mode"] ?> mt-2'>
|
||||||
|
<?= $saveDB["message"] ?>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-3 col-12" id="tree">
|
<div class="col-md-3 col-12" id="tree">
|
||||||
<div class="card text-bg-dark">
|
<div class="card text-bg-dark">
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div><a class="btn btn-info multi" onclick="newCat();" role="button">Neue Kategorie</a></div>
|
<div class="d-flex justify-content-between">
|
||||||
|
<div class="col-sm-12 col-md-6">
|
||||||
|
<a class="btn btn-info multi" onclick="newCat();" role="button"> + Neue Kategorie</a>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-6 form-check form-check-reverse form-switch justify-content-end">
|
||||||
|
<input class="form-check-input" type="checkbox" id="viewdeleted" value="1" name="viewdeleted">
|
||||||
|
<label class="form-check-label" for="viewdeleted">Gelöschte</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="tree">
|
<div class="tree">
|
||||||
<ul>
|
<ul>
|
||||||
<?php foreach($parents as $parent): ?>
|
<?php foreach($parents as $parent): ?>
|
||||||
<?php $class='';
|
<?php $class=''; $vis ="d-none";
|
||||||
if ($parent->lkz) $class = "text-bg-danger";
|
if ($parent->deleted_at) {
|
||||||
else if ($parent->bookable == "f") $class = "text-bg-warning"; ?>
|
$class = "text-bg-danger";
|
||||||
<li> <span data-bs-toggle='tooltip'
|
$vis = "d-none";
|
||||||
|
} else {
|
||||||
|
$vis = "";
|
||||||
|
if (!$parent->bookable) $class = "text-bg-warning";
|
||||||
|
}?>
|
||||||
|
<li class="<?=$vis?>"><i class="fa-solid"></i> <span data-bs-toggle='tooltip'
|
||||||
data-bs-html=true
|
data-bs-html=true
|
||||||
data-id="<?=$parent->id?>"
|
data-id="<?=$parent->id?>"
|
||||||
data-pid="0"
|
data-pid="0"
|
||||||
data-bookable="<?=$parent->bookable?>"
|
data-bookable=<?=printBool($parent->bookable)?>
|
||||||
data-lkz=" <?= $parent->lkz?>"
|
data-monitor=<?=printBool($parent->monitor)?>
|
||||||
data-type="<?= $parent->type?>"
|
data-account=<?=printBool($parent->account)?>
|
||||||
|
data-deleted="<?= $parent->deleted_at?>"
|
||||||
data-description="<?= $parent->description?>";
|
data-description="<?= $parent->description?>";
|
||||||
title="bookable: <?=$parent->bookable?>; lkz: <?= $parent->lkz?>; Id: <?=$parent->id?>;" class="<?=$class?>"><?=$parent->description?></span>
|
title="<?=($parent->bookable)?"":"not "?>bookable; <?= ($parent->deleted_at)?"gelöscht; ":""?>Id: <?=$parent->id?>;"
|
||||||
|
class="<?=$class?>"><?=$parent->description?></span>
|
||||||
<?= printsub($parent->id, $all); ?>
|
<?= printsub($parent->id, $all); ?>
|
||||||
|
<li>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@@ -70,13 +108,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3 col-12 d-none" id="editor">
|
<div class="col-md-3 col-12 <?= (empty($errors))?"d-none" :"" ?>" id="editor">
|
||||||
<?= $this->include('accountsform') ?>
|
<?= $this->include('accountsform') ?>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<?= $this->endSection(); ?>
|
<?= $this->endSection(); ?>
|
||||||
<?= $this->section('scripts'); ?>
|
<?= $this->section('scripts'); ?>
|
||||||
<script src="/assets/jquery-ui-1.13.2.custom/jquery-ui.js"></script>
|
|
||||||
<script></script>
|
|
||||||
<script src="/js/accounts.js"></script>
|
<script src="/js/accounts.js"></script>
|
||||||
<?= $this->endSection(); ?>
|
<?= $this->endSection(); ?>
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
<?= $this->extend('layout'); ?>
|
<?= $this->extend('layout'); ?>
|
||||||
|
|
||||||
<?= $this->section('css'); ?>
|
<?= $this->section('css'); ?>
|
||||||
<link rel="stylesheet" href="/assets/jquery-ui-1.13.2.custom/jquery-ui.css">
|
|
||||||
<link rel="stylesheet" href="/css/mawim.css">
|
<link rel="stylesheet" href="/css/mawim.css">
|
||||||
<?= $this->endSection(); ?>
|
<?= $this->endSection(); ?>
|
||||||
<?= $this->section('menu'); ?>
|
<?= $this->section('menu'); ?>
|
||||||
@@ -13,71 +12,40 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xxl-8 col-12">
|
<div class="col-xxl-8 col-12">
|
||||||
<div class="text-white-50"><h2>Verlauf</h2></div>
|
<div class="text-white-50"><h2>Verlauf</h2></div>
|
||||||
<form class="form row row-cols align-items-bottom" id="getData" method="post" action="<?= base_url() ?>/Ajax/getTabelData">
|
<form class="form row row-cols align-items-bottom" id="getData" method="post" action="/getActivitiesData">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-3 col-12">
|
<div class="col-lg-3 col-12">
|
||||||
<input type="text" class="form-control" id="datepickers" data-date-format="mm.dd.yyyy" name="datum_start" placeholder="Datum Start" value="<?= $datum_start??$start ?>"/>
|
<input type="date" class="form-control" name="datum_start" placeholder="Datum Start" value="<?= $datum_start??$start ?>"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-3 col-12">
|
<div class="col-lg-3 col-12">
|
||||||
<input type="text" class="form-control" id="datepickere" data-date-format="mm.dd.yyyy" name="datum_ende" placeholder="Datum Ende" value="<?= $datum_ende??$ende ?>"/>
|
<input type="date" class="form-control" name="datum_ende" placeholder="Datum Ende" value="<?= $datum_ende??$ende ?>"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-3 col-12">
|
<div class="col-lg-3 col-12">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<?= form_dropdown('source', $sourcelist, $source,'id="source" class="form-select"'); ?>
|
<select name="source" class="form-select">
|
||||||
|
<option value="0">----</option>
|
||||||
|
<?php foreach ($sourcelist as $key => $value): ?>
|
||||||
|
<option value="<?= $key ?>" <?= ($key == $source)?'selected':'' ?>><?= $value ?></option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-3 col-12">
|
<div class="col-lg-3 col-12">
|
||||||
<a class="btn btn-primary" onclick="datatable.ajax.reload();" role="button">Aktualisieren</a>
|
<a class="btn btn-primary" onclick="loadActivityData();" role="button">Aktualisieren</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<table class="table table-sm table-striped" id="bookings" cellspacing="0"></table>
|
<table id="activities" cellspacing="0"></table>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xxl-4 col-12 d-none d-xxl-block">
|
<div class="col-xxl-4 col-12 d-none d-xxl-block">
|
||||||
<div class="text-white-50"><h2>Aktuelle Kontostände</h2></div>
|
<div class="text-white-50"><h2>Aktuelle Kontostände</h2></div>
|
||||||
<table class="table table-striped table-sm" id="accounts" cellspacing="0"></table>
|
<table id="accounts" cellspacing="0"></table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<?= $this->endSection(); ?>
|
<?= $this->endSection(); ?>
|
||||||
<?= $this->section('scripts'); ?>
|
<?= $this->section('scripts'); ?>
|
||||||
<script src="/assets/jquery-ui-1.13.2.custom/jquery-ui.js"></script>
|
|
||||||
<script>
|
|
||||||
$.datepicker.regional['de'] = {clearText: 'löschen', clearStatus: 'aktuelles Datum löschen',
|
|
||||||
closeText: 'schließen', closeStatus: 'ohne Änderungen schließen',
|
|
||||||
prevText: '<zurück', prevStatus: 'letzten Monat zeigen',
|
|
||||||
nextText: 'Vor>', nextStatus: 'nächsten Monat zeigen',
|
|
||||||
currentText: 'heute', currentStatus: '',
|
|
||||||
monthNames: ['Januar','Februar','März','April','Mai','Juni',
|
|
||||||
'Juli','August','September','Oktober','November','Dezember'],
|
|
||||||
monthNamesShort: ['Jan','Feb','Mär','Apr','Mai','Jun',
|
|
||||||
'Jul','Aug','Sep','Okt','Nov','Dez'],
|
|
||||||
monthStatus: 'anderen Monat anzeigen', yearStatus: 'anderes Jahr anzeigen',
|
|
||||||
weekHeader: 'Wo', weekStatus: 'Woche des Monats',
|
|
||||||
dayNames: ['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'],
|
|
||||||
dayNamesShort: ['So','Mo','Di','Mi','Do','Fr','Sa'],
|
|
||||||
dayNamesMin: ['So','Mo','Di','Mi','Do','Fr','Sa'],
|
|
||||||
dayStatus: 'Setze DD als ersten Wochentag', dateStatus: 'Wähle D, M d',
|
|
||||||
dateFormat: 'dd.mm.yy', firstDay: 1,
|
|
||||||
initStatus: 'Wähle ein Datum', isRTL: false};
|
|
||||||
$.datepicker.setDefaults($.datepicker.regional['de']);
|
|
||||||
$('#datepickers').datepicker(
|
|
||||||
{
|
|
||||||
format: "dd.mm.yyyy",
|
|
||||||
language: 'de-DE',
|
|
||||||
weekStart: 1,
|
|
||||||
autoclose: true,
|
|
||||||
todayHighlight: false});
|
|
||||||
$('#datepickere').datepicker(
|
|
||||||
{
|
|
||||||
format: "dd.mm.yyyy",
|
|
||||||
language: 'de-DE',
|
|
||||||
weekStart: 1,
|
|
||||||
autoclose: true,
|
|
||||||
todayHighlight: false});
|
|
||||||
</script>
|
|
||||||
<script src="/js/tables.js"></script>
|
<script src="/js/tables.js"></script>
|
||||||
<script src="/js/tab_accounts.js"></script>
|
<script src="/js/tab_accounts.js"></script>
|
||||||
<script src="/js/activities.js"></script>
|
<script src="/js/tab_activities.js"></script>
|
||||||
|
|
||||||
<?= $this->endSection(); ?>
|
<?= $this->endSection(); ?>
|
||||||
56
app/Views/bill_bookingline.php
Normal file
56
app/Views/bill_bookingline.php
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
<?php
|
||||||
|
if (!$template) {
|
||||||
|
$parentList = $booking['cat_parent'][$i];
|
||||||
|
$subList = $booking['cat_sub'][$i];
|
||||||
|
$account_id = $booking['account_id'][$i];
|
||||||
|
$parent_id = $booking['parent_id'][$i];
|
||||||
|
$comment = $booking['comment'][$i];
|
||||||
|
$input = $booking['input'][$i];
|
||||||
|
$output = $booking['output'][$i];
|
||||||
|
$sid = $booking['sid'][$i];
|
||||||
|
} else {
|
||||||
|
$i = 0;
|
||||||
|
$account_id = 0;
|
||||||
|
$parent_id = 0;
|
||||||
|
$parentList = $booking['category']['parent'];
|
||||||
|
$subList = $booking['category']['subs']->{$parent_id};
|
||||||
|
$comment = '';
|
||||||
|
$input = '';
|
||||||
|
$output = '';
|
||||||
|
$sid = 0;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div <?=(($template)?'id="template"':'')?> class="row <?=(($template)?'d-none':'')?>">
|
||||||
|
<input type="hidden" value="<?= $sid ?>" name="sid[]">
|
||||||
|
|
||||||
|
<div class="col-lg-3 col-6 col-md-6 <?=(($i>0)?'multi':'')?> order-sm-2 px-0">
|
||||||
|
<select name="parent_id[]" class="form-select parent" <?=(($i==0 && !$template)?'required':'')?>>
|
||||||
|
<option value="">----</option>
|
||||||
|
<?php foreach ($parentList as $key => $value): ?>
|
||||||
|
<option value="<?= $key ?>" <?= ($key == $parent_id)?'selected':'' ?>><?= $value ?></option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-lg-3 col-6 col-md-6 <?=(($i>0)?'multi':'')?> order-sm-2 px-0" <?=(($i==0 && !$template)?'required':'')?>>
|
||||||
|
<select name="account_id[]" class="form-select sub">
|
||||||
|
<?php foreach ($subList as $key => $value): ?>
|
||||||
|
<option value="<?= $key ?>" <?= ($key == $account_id && $account_id>0)?'selected':'' ?>><?= $value ?></option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="w-100 d-md-none"></div>
|
||||||
|
<div class="col-lg-2 col-6 <?=(($i>0)?'multi':'')?> <?= ($booking['transfer']?' d-none':'') ?> px-0 order-sm-2">
|
||||||
|
<input type="text" name="input[]" class="form-control dt-subamount input" placeholder="Einnahme" value="<?= $input ?>"
|
||||||
|
pattern="[0-9\*\(\)\-\+\/,.]*"
|
||||||
|
oninput="if (!this.checkValidity()) this.value = this.value.slice(0, -1)">
|
||||||
|
</div>
|
||||||
|
<div class="<?= ($booking['transfer']?'col-lg-4 col-12':'col-lg-2 col-6') ?> <?=(($i>0)?'multi':'')?> px-0 order-sm-2">
|
||||||
|
<input type="text" name="output[]" placeholder="Ausgabe" value="<?= $output ?>"
|
||||||
|
pattern="[0-9\*\(\)\-\+\/,.]*"
|
||||||
|
oninput="if (!this.checkValidity()) this.value = this.value.slice(0, -1)" class="form-control dt-subamount output text-danger" >
|
||||||
|
</div>
|
||||||
|
<div class="col-lg-2 col-12 col-md-12 <?=(($i>0)?'multi':'')?> order-sm-1 px-0 mb-3 mb-md-0">
|
||||||
|
<input type="text" name="comment[]" class="form-control" placeholder="Kommentar" value="<?= $comment ?>">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
19
app/Views/bill_scheduled.php
Normal file
19
app/Views/bill_scheduled.php
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<div class="col-12 scheduled <?=($booking['scheduled']?'':'d-none')?>">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="scheduledNum">Scheduled:</label>
|
||||||
|
<div class="input-group">
|
||||||
|
<select name="scheduledNum" id="scheduledNum" class="form-select" required>
|
||||||
|
<option value="">----</option>
|
||||||
|
<?php foreach ($booking['schedule_lists']['NumList'] as $key => $value): ?>
|
||||||
|
<option value="<?= $key ?>" <?= ($key == $booking['scheduledNum'])?'selected':'' ?>><?= $value ?></option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
<select name="scheduledType" id="scheduledType" class="form-select" required>
|
||||||
|
<option value="">----</option>
|
||||||
|
<?php foreach ($booking['schedule_lists']['TypeList'] as $key => $value): ?>
|
||||||
|
<option value="<?= $key ?>" <?= ($key == $booking['scheduledType'])?'selected':'' ?>><?= $value ?></option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -8,18 +8,14 @@
|
|||||||
<meta name="description" content="Adminpage for Finanzen" />
|
<meta name="description" content="Adminpage for Finanzen" />
|
||||||
<meta name="author" content="Wimpissinger Markus" />
|
<meta name="author" content="Wimpissinger Markus" />
|
||||||
<?= $this->renderSection('css_first') ?>
|
<?= $this->renderSection('css_first') ?>
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com">
|
<link href="/assets/bootstrap/css/bootstrap.css" rel="stylesheet" />
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@300;400;600;700;800&display=swap" rel="stylesheet">
|
<link href="/assets/font-awesome/css/fontawesome.css" rel="stylesheet">
|
||||||
<link href="/assets/bootstrap-5.3.0-alpha1-dist/css/bootstrap.min.css" rel="stylesheet" />
|
<link href="/assets/font-awesome/css/solid.css" rel="stylesheet">
|
||||||
<link href="/assets/fontawesome6.4.0/css/fontawesome.css" rel="stylesheet">
|
<link href="/assets/font-awesome/css/brands.css" rel="stylesheet">
|
||||||
<link href="/assets/fontawesome6.4.0/css/solid.css" rel="stylesheet">
|
<link href="/assets/font-awesome/css/regular.css" rel="stylesheet">
|
||||||
<link href="/assets/fontawesome6.4.0/css/brands.css" rel="stylesheet">
|
|
||||||
<link href="/assets/fontawesome6.4.0/css/regular.css" rel="stylesheet">
|
|
||||||
<!-- <link rel="stylesheet" href="/assets/vendors/perfect-scrollbar/perfect-scrollbar.css"> -->
|
|
||||||
<link rel="stylesheet" href="/assets/css/app.css">
|
<link rel="stylesheet" href="/assets/css/app.css">
|
||||||
<link href="/assets/DataTables/datatables.min.css" rel="stylesheet"/>
|
<!-- <script src="https://cdn.jsdelivr.net/npm/simple-datatables@latest" type="text/javascript"></script> -->
|
||||||
<?= $this->renderSection('css') ?>
|
<?= $this->renderSection('css') ?>
|
||||||
<!-- <link rel="shortcut icon" href="/assets/images/favicon.svg" type="image/x-icon"> -->
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
@@ -34,20 +30,41 @@
|
|||||||
</a>
|
</a>
|
||||||
</header>
|
</header>
|
||||||
<?= $this->renderSection('content') ?>
|
<?= $this->renderSection('content') ?>
|
||||||
<div class="modal" id="mymodal" tabindex="-1">
|
<div class="modal fade" id="mymodal" tabindex="-1">
|
||||||
<div class="modal-dialog modal-dialog-centered">
|
<div class="modal-dialog modal-dialog-centered">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
|
<div class="modal-header d-none">
|
||||||
|
<h1 class="modal-title fs-5" id="modalTitle">Modal Title</h1>
|
||||||
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<h5 class="modal-title"></h5>
|
<p>Modal body</p>
|
||||||
<p>Wirklich löschen?</p>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Abbruch</button>
|
<div class ="mx-auto">
|
||||||
<button type="button" id="modal_ok" class="btn btn-primary">Löschen</button>
|
<button type="button" id="modal_ok" data-bs-dismiss="modal" class="btn btn-primary">Ok</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="modal" id="mymodalDelete" tabindex="-1">
|
||||||
|
<div class="modal-dialog modal-dialog-centered">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title fs-5" id="modalDelTitle">Wirklich löschen?</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body d-none">
|
||||||
|
<p class="modal-text">Wirklich löschen?</p>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<div class ="mx-auto">
|
||||||
|
<button type="button" id="modal_delete" class="btn btn-primary" data-bs-target="#mymodal" data-bs-toggle="modal">Löschen</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="modal fade" id="mySnycModal" tabindex="-1" aria-labelledby="Snc Result Window" aria-hidden="true">
|
<div class="modal fade" id="mySnycModal" tabindex="-1" aria-labelledby="Snc Result Window" aria-hidden="true">
|
||||||
<div class="modal-dialog">
|
<div class="modal-dialog">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
@@ -82,16 +99,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- <script src="/assets/vendors/perfect-scrollbar/perfect-scrollbar.min.js"></script>
|
<!-- <script src="/assets/vendors/perfect-scrollbar/perfect-scrollbar.min.js"></script> -->
|
||||||
<script src="/assets/js/bootstrap.bundle.min.js"></script> -->
|
<script src="/assets/bootstrap/js/bootstrap.bundle.js" type="text/javascript"></script>
|
||||||
<script src="/assets/jquery-3.6.4.min.js" type="text/javascript"></script>
|
<script src="/assets/fiduswriter/simple-datatables.js" type="text/javascript"></script>
|
||||||
<script src="/assets/bootstrap-5.3.0-alpha1-dist/js/bootstrap.bundle.js" type="text/javascript"></script>
|
<!-- <script defer src="/assets/fontawesome/js/solid.js"></script>
|
||||||
<script defer src="/assets/fontawesome6.4.0/js/solid.js"></script>
|
<script defer src="/assets/fontawesome/js/brands.js"></script>
|
||||||
<script defer src="/assets/fontawesome6.4.0/js/brands.js"></script>
|
<script defer src="/assets/fontawesome/js/regular.js"></script> -->
|
||||||
<script defer src="/assets/fontawesome6.4.0/js/regular.js"></script>
|
|
||||||
<script src="/assets/DataTables/datatables.min.js"></script>
|
|
||||||
<script src="/js/menue.js"></script>
|
<script src="/js/menue.js"></script>
|
||||||
<script src="/assets/js/main.js"></script>
|
<script src="/assets/js/main.js"></script>
|
||||||
<?= $this->renderSection('scripts') ?>
|
<?= $this->renderSection('scripts') ?>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
|||||||
@@ -14,10 +14,10 @@
|
|||||||
<div class="col-md-8 col-12">
|
<div class="col-md-8 col-12">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header pb-0">
|
<div class="card-header pb-0">
|
||||||
<?php if ($id) : ?>
|
<?php if ($booking['id']) : ?>
|
||||||
<h4 class="card-title"><?= ($transfer?'Transfer bearbeiten':($isScheduled?'Terminbuchung bearbeiten':'Rechnung bearbeiten'))?></h4>
|
<h4 class="card-title"><?= ($booking['transfer']?'Transfer '.$booking['id'].' bearbeiten':($booking['scheduled']?'Terminbuchung '.$booking['id'].' bearbeiten':'Rechnung '.$booking['id'].' bearbeiten'))?></h4>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<h4 class="card-title"><?= ($transfer?'Neuer Transfer':($isScheduled?'Neue Terminbuchung':'Neue Rechnung'))?></h4>
|
<h4 class="card-title"><?= ($booking['transfer']?'Neuer Transfer':($booking['scheduled']?'Neue Terminbuchung':'Neue Rechnung'))?></h4>
|
||||||
|
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<?php if (! empty($validation)) : ?>
|
<?php if (! empty($validation)) : ?>
|
||||||
@@ -34,27 +34,25 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<?= form_open_multipart('newBill','class="form form-vertical" onsubmit="logData(event)" id="newbill"') ?>
|
<?= view("bill_bookingline",['booking'=>$booking, 'template'=>true]); ?>
|
||||||
|
<form id="newbill" action="/edit" class="form form-vertical needs-validation" method="post" enctype="multipart/form-data" onsubmit="checkForm(event,this)" novalidate>
|
||||||
<!-- <form class="form form-vertical" id="newbill" method="post" enctype="multipart/form-data" onsubmit="logData(event)" action="<?= base_url() ?>newBill"> -->
|
<!-- <form class="form form-vertical" id="newbill" method="post" enctype="multipart/form-data" onsubmit="logData(event)" action="<?= base_url() ?>newBill"> -->
|
||||||
<input type="hidden" value="<?= $id ?>" name="id">
|
<input type="hidden" value="<?= $booking['id'] ?>" name="id">
|
||||||
<input type="hidden" value="<?= $transfer?'1':'0' ?>" name="transfer">
|
<input type="hidden" value="<?= $booking['amount']??0.0 ?>" name="amount">
|
||||||
|
<input type="hidden" value="<?= $booking['transfer']?'1':'0' ?>" name="transfer">
|
||||||
|
<input type="hidden" value="<?= ($booking['scheduled']??false)?'1':'0' ?>" name="scheduled">
|
||||||
|
|
||||||
<div class="form-body">
|
<div class="form-body">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12 <?= ($transfer?' d-none':'') ?>">
|
<div class="col-12 <?= ($booking['transfer']?' d-none':(($booking['scheduled']??false)?' d-none':'')) ?>">
|
||||||
<div class="form-check form-switch">
|
|
||||||
<label class="form-check-label" for="multi">Multi Rechnung</label>
|
|
||||||
<input class="form-check-input" type="checkbox" id="multi" value="on" name="multi" <?= set_checkbox('multi', 'on', $multi??false) ?>>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 <?= ($transfer?' d-none':($isScheduled?' d-none':'')) ?>">
|
|
||||||
<label for="billfile">Rechnung:</label>
|
<label for="billfile">Rechnung:</label>
|
||||||
<input type="file" id="billfile" name="billfile" class="form-control <?= (!isset($billfile))?'':'d-none' ?>" capture="environment" accept="image/*, application/pdf">
|
<input type="file" id="billfile" name="billfile" class="form-control <?= (!isset($booking['rechnung']))?'':'d-none' ?>" capture="environment" accept="image/*, application/pdf">
|
||||||
<?php if (isset($billfile)): ?>
|
<?php if (isset($booking['rechnung'])): ?>
|
||||||
<a href="/viewBill/<?= $billfile ?>" id="billfileRef"><?= $billfile ?></a>
|
<a href="/viewInvoice/<?= $booking['rechnung'] ?>" id="billfileRef" target="_blank"> <?= $booking['rechnung'] ?></a>
|
||||||
<a class="" onclick="removeBillFile(this);"><i class="fa fa-trash"></i></a>
|
<a class="" onclick="removeBillFile(this);"><i class="fa fa-trash"></i></a>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 <?= ($transfer?' d-none':'d-none') ?>">
|
<div class="col-12 <?= ($booking['transfer']?' d-none':'d-none') ?>">
|
||||||
<div class='form-check'>
|
<div class='form-check'>
|
||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
<label for="renummer">Re-Nr.</label>
|
<label for="renummer">Re-Nr.</label>
|
||||||
@@ -64,76 +62,64 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<label for="datum">Datum</label>
|
<label for="datum">Datum</label>
|
||||||
<input type="date" class="form-control" id="datum" name="datum" value="<?= $datum ?>" onclick="openBox(this);"/>
|
<input type="date" class="form-control" id="datum" name="datum" value="<?= $booking['datum'] ?>" onclick="openBox(this);"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 <?= ($transfer?' d-none':'') ?>">
|
<div class="col-12 <?= ($booking['transfer']?' d-none':'') ?>">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="receiver">Empfänger</label>
|
<label for="receiver">Empfänger</label>
|
||||||
<input type="text" class="form-control" id="receiver" name="receiver" value="<?= $receiver ?>">
|
<input type="text" class="form-control" id="receiver" name="receiver" <?=(($booking['transfer'])?'':'required')?> value="<?= $booking['receiver'] ?>">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="source">Konto:</label>
|
<label for="sourceID">Konto:</label>
|
||||||
<?= form_dropdown('source', $sourcelist, $source,'id="source" class="form-select"'); ?>
|
<select name="source_id" class="form-select" required id="sourceID" >
|
||||||
|
<option value="">----</option>
|
||||||
|
<?php foreach ($booking['sourcelist'] as $key => $value): ?>
|
||||||
|
<option value="<?= $key ?>" <?= ($key == $booking['source_id'])?'selected':'' ?>><?= $value ?></option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 multi">
|
<div class="col-12 multi">
|
||||||
<div class="input-group">
|
<div class="input-group has-validation">
|
||||||
<input type="text" class="form-control dt-amount" id="total_in" name="total_in" placeholder="Einnahme" maxlength=120 value="<?= $total_in ?>">
|
<input type="text" id="total_in" name="total_in" value="<?= $booking['total_in'] ?>"
|
||||||
<input type="text" class="form-control dt-amount text-danger" id="total_out" name="total_out" placeholder="Ausgabe" maxlength=120 value="<?= $total_out ?>">
|
class="form-control dt-amount input"
|
||||||
</div>
|
pattern="[0-9\*\(\)\-\+\/,.]*"
|
||||||
</div>
|
oninput="if (!this.checkValidity()) this.value = this.value.slice(0, -1)"
|
||||||
<div class="col-12 scheduled <?=($isScheduled?'':'d-none')?>">
|
placeholder="Einnahme" maxlength=120 ">
|
||||||
<div class="form-group">
|
<input type="text" id="total_out" name="total_out" value="<?= $booking['total_out'] ?>"
|
||||||
<label for="scheduledNum">Scheduled:</label>
|
class="form-control dt-amount output text-danger"
|
||||||
<div class="input-group">
|
pattern="[0-9\*\(\)\-\+\/,.]*"
|
||||||
<input type="hidden" value="<?= $isScheduled?'1':'0' ?>" name="scheduled">
|
oninput="if (!this.checkValidity()) this.value = this.value.slice(0, -1)"
|
||||||
<?= form_dropdown("scheduledNum", $scheduled['NumList'], $scheduledNum,$scheduled['style']); ?>
|
placeholder="Ausgabe" maxlength=120>
|
||||||
<?= form_dropdown("scheduledType",$scheduled['TypeList'], $scheduledType,$scheduled['style']); ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<?php if ($booking['scheduled']??false)
|
||||||
|
echo view("bill_scheduled",['booking'=>$booking]);
|
||||||
|
?>
|
||||||
<div class="col-12 d-none multi">
|
<div class="col-12 d-none multi">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="openamount">Offener Betrag:</label>
|
<label for="openamount">Offener Betrag:</label>
|
||||||
<input type="text" class="form-control dt-amount" readonly="readonly" id="openamount" name="openamount">
|
<input type="text" class="form-control dt-amount" readonly="readonly" id="openamount" name="openamount">
|
||||||
|
<div class="invalid-feedback"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12" id="linecont">
|
<div class="col-12" id="linecont">
|
||||||
<?php for ($i=0;$i<10;$i++): ?>
|
<?php $i = 0; foreach ($booking['sid'] as $_sid) :
|
||||||
<div class="row <?= (($i<3 || $input[$i]>0 || $output[$i]>0)?'':' d-none')?>">
|
echo view("bill_bookingline",['booking'=>$booking, 'i'=>$i,'template'=>false]);
|
||||||
<input type="hidden" value="<?= $sid[$i] ?>" name="sid[<?=$i?>]">
|
?>
|
||||||
|
<?php $i++; endforeach; ?>
|
||||||
<div class="col-lg-3 col-6 col-md-6 <?=(($i>0)?'multi':'')?> order-sm-2 px-0">
|
|
||||||
<?= form_dropdown("category_parent[$i]", $subsparent[$i], $category_parent[$i], 'class="form-select parent"'); ?>
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-3 col-6 col-md-6 <?=(($i>0)?'multi':'')?> order-sm-2 px-0 sub">
|
|
||||||
<?= form_dropdown("category[$i]", $subscategory[$i], $category[$i], 'class="form-select"'); ?>
|
|
||||||
</div>
|
|
||||||
<div class="w-100 d-md-none"></div>
|
|
||||||
<div class="col-lg-2 col-6 <?=(($i>0)?'multi':'')?> <?= ($transfer?' d-none':'') ?> px-0 order-sm-2">
|
|
||||||
<input type="text" name="input[<?=$i?>]" class="form-control dt-subamount" placeholder="Einnahme" value="<?= $input[$i] ?>">
|
|
||||||
</div>
|
|
||||||
<div class="<?= ($transfer?'col-lg-4 col-12':'col-lg-2 col-6') ?> <?=(($i>0)?'multi':'')?> px-0 order-sm-2">
|
|
||||||
<input type="text" name="output[<?=$i?>]" class="form-control dt-subamount text-danger" placeholder="Ausgabe" value="<?= $output[$i] ?>">
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-2 col-12 col-md-12 <?=(($i>0)?'multi':'')?> order-sm-1 px-0 mb-3 mb-md-0">
|
|
||||||
<input type="text" name="comment[<?=$i?>]" class="form-control" placeholder="Kommentar" value="<?= $comment[$i] ?>">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<?php endfor; ?>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 d-flex" role="group">
|
<div class="col-12 d-flex" role="group">
|
||||||
<a class="btn btn-info multi" onclick="addLine();" role="button">+ Zeile</a>
|
<a id="multiadd" class="btn btn-info <?= ($booking['transfer']?' d-none':'') ?>" onclick="addLine();" role="button">+ Zeile</a>
|
||||||
<input type="checkbox" id="validate" name="validate" value="1" class='btn-check' autocomplete="off" <?= set_checkbox('validate', '1', (($validate??"f")=="t")?true:false) ?>>
|
<input type="checkbox" id="validate" name="validate" value="1" class='btn-check' autocomplete="off" <?= set_checkbox('validate', '1', ($booking['validate'])?true:false) ?>>
|
||||||
<label class="btn btn-outline-danger" for="validate">Entwurf</label>
|
<label class="btn btn-outline-danger" for="validate">Entwurf</label>
|
||||||
<?php if ($id) : ?>
|
<?php if ($booking['id']) : ?>
|
||||||
<a class="btn btn-danger" data-bs-toggle="modal" data-bs-id="<?= $id ?>" data-bs-target="#mymodal"><i class="fa fa-trash"></i></a>
|
<a class="btn btn-danger" data-bs-toggle="modal" data-bs-table="<?= ($booking['scheduled']??false)?'scheduled':'bill'?>" data-bs-id="<?= $booking['id'] ?>" data-bs-target="#mymodalDelete"><i class="fa fa-trash"></i></a>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<button type="submit" class="btn btn-primary">Submit</button>
|
<button type="submit" class="btn btn-primary">Submit</button>
|
||||||
<a class="btn btn-secondary" onclick="history.back();" role="button"><i class="fa-solid fa-rotate-left"></i></a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -149,7 +135,7 @@
|
|||||||
function openBox(e) {
|
function openBox(e) {
|
||||||
e.showPicker();
|
e.showPicker();
|
||||||
}
|
}
|
||||||
subsdata = <?= $subsdata; ?>;
|
subsdata = <?= json_encode($booking['category']['subs']) ?>;
|
||||||
</script>
|
</script>
|
||||||
<script src="/js/billing.js"></script>
|
<script src="/js/billing.js"></script>
|
||||||
<?= $this->endSection(); ?>
|
<?= $this->endSection(); ?>
|
||||||
@@ -1,31 +1,29 @@
|
|||||||
<?= $this->extend('layout'); ?>
|
<?= $this->extend('layout'); ?>
|
||||||
|
|
||||||
<?= $this->section('css'); ?>
|
<?= $this->section('css'); ?>
|
||||||
<link rel="stylesheet" href="/assets/jquery-ui-1.13.2.custom/jquery-ui.css">
|
|
||||||
<link rel="stylesheet" href="/css/mawim.css">
|
<link rel="stylesheet" href="/css/mawim.css">
|
||||||
<?= $this->endSection(); ?>
|
<?= $this->endSection(); ?>
|
||||||
<?= $this->section('menu'); ?>
|
<?= $this->section('menu'); ?>
|
||||||
<?= $this->include('sidebar') ?>
|
<?= $this->include('sidebar') ?>
|
||||||
<?= $this->endSection(); ?>
|
<?= $this->endSection(); ?>
|
||||||
<?= $this->section('content'); ?>
|
<?= $this->section('content'); ?>
|
||||||
<?php session()->set('redirect_url',base_url('show-passwords')); ?>
|
<?php session()->set('redirect_url',base_url('viewScheduled')); ?>
|
||||||
<div class="page-content">
|
<div class="page-content">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xxl-8 col-12">
|
<div class="col-xxl-8 col-12">
|
||||||
<div class="text-white-50"><h2>Terminbuchungen</h2></div>
|
<div class="text-white-50"><h2>Terminbuchungen</h2></div>
|
||||||
<table class="table table-striped table-sm" id="scheduled" cellspacing="0"></table>
|
<table id="scheduled" cellspacing="0"></table>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xxl-4 col-12 d-none d-xxl-block">
|
<div class="col-xxl-4 col-12 d-none d-xxl-block">
|
||||||
<div class="text-white-50"><h2>Aktuelle Kontostände</h2></div>
|
<div class="text-white-50"><h2>Aktuelle Kontostände</h2></div>
|
||||||
<table class="table table-striped table-sm" id="accounts" cellspacing="0"></table>
|
<table id="accounts" cellspacing="0"></table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<?= $this->endSection(); ?>
|
<?= $this->endSection(); ?>
|
||||||
<?= $this->section('scripts'); ?>
|
<?= $this->section('scripts'); ?>
|
||||||
<script src="/assets/jquery-ui-1.13.2.custom/jquery-ui.js"></script>
|
|
||||||
<script src="/js/tables.js"></script>
|
<script src="/js/tables.js"></script>
|
||||||
<script src="/js/tab_accounts.js"></script>
|
<script src="/js/tab_accounts.js"></script>
|
||||||
<script src="/js/scheduled.js"></script>
|
<script src="/js/tab_scheduled.js"></script>
|
||||||
|
|
||||||
<?= $this->endSection(); ?>
|
<?= $this->endSection(); ?>
|
||||||
@@ -30,10 +30,10 @@
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="sidebar-item active">
|
<li class="sidebar-item active">
|
||||||
<a href="javascript:syncScheduled()" class='sidebar-link'>
|
<a class="sidebar-link" data-bs-toggle="modal" role="button" data-bs-target="#mySnycModal" onclick="syncScheduled(this)">
|
||||||
<i class="fa-solid fa-pen-to-square"></i>
|
<i class="fa-solid fa-pen-to-square"></i>
|
||||||
<span>Sync Automatische</span>
|
<span>Sync Automatische</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="sidebar-item active">
|
<li class="sidebar-item active">
|
||||||
<a href="/viewAccounts" class='sidebar-link'>
|
<a href="/viewAccounts" class='sidebar-link'>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?= $this->extend('layout'); ?>
|
<?= $this->extend('layout'); ?>
|
||||||
|
|
||||||
<?= $this->section('css'); ?>
|
<?= $this->section('css'); ?>
|
||||||
<link rel="stylesheet" href="/css/mawim.css">
|
<link rel="stylesheet" href="/css/mawim.css">
|
||||||
@@ -15,21 +15,21 @@
|
|||||||
<div class="col-xl-4 col-md-8 col-sm-12">
|
<div class="col-xl-4 col-md-8 col-sm-12">
|
||||||
<div class="text-white-50"><h2>Aktuelle Buchungen</h2></div>
|
<div class="text-white-50"><h2>Aktuelle Buchungen</h2></div>
|
||||||
<div class="">
|
<div class="">
|
||||||
<table class="table table-striped table-sm" id="bookings" cellspacing="0">
|
<table id="bookings" cellspacing="0">
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xl-4 col-md-8 col-sm-12">
|
<div class="col-xl-4 col-md-8 col-sm-12">
|
||||||
<div class="text-white-50"><h2>Aktuelle Kontostände</h2></div>
|
<div class="text-white-50"><h2>Aktuelle Kontostände</h2></div>
|
||||||
<div class="">
|
<div class="">
|
||||||
<table class="table table-striped table-sm" id="accounts" cellspacing="0">
|
<table id="accounts" cellspacing="0">
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xl-4 col-md-8 col-sm-12">
|
<div class="col-xl-4 col-md-8 col-sm-12">
|
||||||
<div class="text-white-50"><h2>Überfällige</h2></div>
|
<div class="text-white-50"><h2>Überfällige</h2></div>
|
||||||
<div class="">
|
<div class="">
|
||||||
<table class="table table-striped table-sm" id="todos" cellspacing="0">
|
<table id="todos" cellspacing="0">
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -40,6 +40,7 @@
|
|||||||
<?= $this->section('scripts'); ?>
|
<?= $this->section('scripts'); ?>
|
||||||
<script src="/js/tables.js"></script>
|
<script src="/js/tables.js"></script>
|
||||||
<script src="/js/tab_accounts.js"></script>
|
<script src="/js/tab_accounts.js"></script>
|
||||||
<script src="/js/tabs_overview.js"></script>
|
<script src="/js/tab_todos.js"></script>
|
||||||
|
<script src="/js/tab_overview.js"></script>
|
||||||
|
|
||||||
<?= $this->endSection(); ?>
|
<?= $this->endSection(); ?>
|
||||||
@@ -918,7 +918,9 @@
|
|||||||
z-index: 10;
|
z-index: 10;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
|
background-color: var(--bs-body-bg);
|
||||||
transition: left .5s ease-out
|
transition: left .5s ease-out
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-wrapper .sidebar-header {
|
.sidebar-wrapper .sidebar-header {
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
.dt-amount, .dt-subamount{
|
.dt-amount, .dt-subamount{
|
||||||
text-align:right;
|
text-align:right;
|
||||||
}
|
}
|
||||||
|
.invalid-feedback{
|
||||||
|
text-align:right;
|
||||||
|
}
|
||||||
|
|
||||||
.dataTables_info{
|
.dataTables_info{
|
||||||
float:left;
|
float:left;
|
||||||
padding-top:0px !important;
|
padding-top:0px !important;
|
||||||
@@ -10,6 +14,19 @@
|
|||||||
float:left;
|
float:left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.datatable-sorter {
|
||||||
|
color: inherit;
|
||||||
|
background-color: inherit;
|
||||||
|
border-color: inherit;
|
||||||
|
border: 0;
|
||||||
|
padding: 0;
|
||||||
|
font-weight:700;
|
||||||
|
}
|
||||||
|
.datatable-icon {
|
||||||
|
padding-left:0 !important;
|
||||||
|
padding-right:0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
.toolbar, .syncbutton{
|
.toolbar, .syncbutton{
|
||||||
float:left;
|
float:left;
|
||||||
padding-left:10px;
|
padding-left:10px;
|
||||||
|
|||||||
@@ -1,67 +1,71 @@
|
|||||||
function newCat(){
|
function moveEditor(){
|
||||||
$('#editor').removeClass('d-none');
|
treepos = 90 - document.getElementById("tree").getBoundingClientRect().top;
|
||||||
$("#id").val(0);
|
editor.style.position = 'relative';
|
||||||
tree = document.getElementById('tree');
|
editor.style.top = treepos+'px';
|
||||||
editor = document.getElementById("editor");
|
}
|
||||||
var elementTop = $('#editor').offset().top;
|
function scrollToEditor(){
|
||||||
var elementBottom = elementTop + $(this).outerHeight();
|
let editor = document.getElementById("editor");
|
||||||
|
editor.scrollIntoView( {behavior: "smooth" });
|
||||||
var viewportTop = $(window).scrollTop();
|
|
||||||
var viewportBottom = viewportTop + $(window).height();
|
|
||||||
|
|
||||||
|
|
||||||
if (!(elementBottom > viewportTop && elementTop < viewportBottom))
|
|
||||||
editor.scrollIntoView( {behavior: "smooth" });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$(function () {
|
function newCat(){
|
||||||
$('.tree li:has(ul)').addClass('parent_li').find(' > span');
|
document.getElementById("editor").classList.remove("d-none");
|
||||||
$('.tree li.parent_li > span').on('click', function (e) {
|
document.getElementById("id").value = 0;
|
||||||
var children = $(this).parent('li.parent_li').find(' > ul > li');
|
document.getElementById("bookable").checked = true;
|
||||||
if (children.is(":visible")) {
|
document.getElementById("account").checked = false;
|
||||||
children.hide('fast');
|
document.getElementById("monitor").checked = false;
|
||||||
// $(this).find(' > i').addClass('icon-plus-sign').removeClass('icon-minus-sign');
|
document.getElementById("deleted_at").checked = false;
|
||||||
} else {
|
document.getElementById("parent").value = 0;
|
||||||
children.show('fast');
|
document.getElementById("description").value = "";
|
||||||
// $(this).find(' > i').addClass('icon-minus-sign').removeClass('icon-plus-sign');
|
// scrollEditor();
|
||||||
}
|
}
|
||||||
e.stopPropagation();
|
|
||||||
});
|
|
||||||
$("span").on('click', function(e){
|
|
||||||
$('#editor').removeClass('d-none');
|
|
||||||
bookable = ($(this).attr('data-bookable') == "f")?false:true;
|
|
||||||
lkz = ($(this).attr('data-lkz') == 0)?false:true;
|
|
||||||
type = $(this).attr('data-type');
|
|
||||||
pid = $(this).attr('data-pid');
|
|
||||||
id = $(this).attr('data-id');
|
|
||||||
description = $(this).attr('data-description');
|
|
||||||
typeAccount = (type === "account") ? true : false;
|
|
||||||
typeInput = (type === "input") ? true : false;
|
|
||||||
typeOutput = (type === "output") ? true : false;
|
|
||||||
$('#bookable').prop('checked', bookable);
|
|
||||||
$('#typeInput').prop('checked', typeInput);
|
|
||||||
$('#typeOutput').prop('checked', typeOutput);
|
|
||||||
$('#typeAccount').prop('checked', typeAccount);
|
|
||||||
$('#lkz').prop('checked', lkz);
|
|
||||||
$("#parent").val(pid).change();
|
|
||||||
$("#id").val(id);
|
|
||||||
$("#description").val(description).change();
|
|
||||||
tree = document.getElementById('tree');
|
|
||||||
editor = document.getElementById("editor");
|
|
||||||
var elementTop = $('#editor').offset().top;
|
|
||||||
var elementBottom = elementTop + $(this).outerHeight();
|
|
||||||
|
|
||||||
var viewportTop = $(window).scrollTop();
|
|
||||||
var viewportBottom = viewportTop + $(window).height();
|
|
||||||
|
|
||||||
|
|
||||||
if (!(elementBottom > viewportTop && elementTop < viewportBottom))
|
|
||||||
editor.scrollIntoView( {behavior: "smooth" });
|
|
||||||
//$('#parent').prop('selected', pid);
|
|
||||||
|
|
||||||
// title: "Edit Account",
|
document.addEventListener("DOMContentLoaded", function(event) {
|
||||||
// placement: 'bottom',
|
editor = document.getElementById("editor");
|
||||||
// html: true,
|
document.querySelectorAll('.tree li:has(ul)').forEach((single) => {
|
||||||
// content: $('[data-name="popover-content"]')
|
single.classList.add("parent_li");
|
||||||
|
single.getElementsByTagName("i")[0].classList.add("fa-square-minus");
|
||||||
|
});
|
||||||
|
document.querySelectorAll(".tree span").forEach((spa) => {
|
||||||
|
spa.addEventListener("dblclick", (event) => {
|
||||||
|
const viewportWidth = document.documentElement.clientWidth;
|
||||||
|
if (viewportWidth < 768)
|
||||||
|
scrollToEditor();
|
||||||
|
else
|
||||||
|
moveEditor();
|
||||||
|
|
||||||
|
editor.classList.remove("d-none");
|
||||||
|
|
||||||
|
document.getElementById("bookable").checked = event.target.getAttribute("data-bookable")=="true";
|
||||||
|
document.getElementById("account").checked = event.target.getAttribute("data-account")=="true";
|
||||||
|
document.getElementById("monitor").checked = event.target.getAttribute("data-monitor")=="true";
|
||||||
|
document.getElementById("deleted_at").checked = event.target.getAttribute("data-deleted")!== "";
|
||||||
|
document.getElementById("id").value = event.target.getAttribute("data-id");
|
||||||
|
document.getElementById("parent").value = event.target.getAttribute("data-pid");
|
||||||
|
document.getElementById("description").value = event.target.getAttribute("data-description");
|
||||||
|
// scrollEditor();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
document.querySelectorAll('.tree li.parent_li > span, .tree li.parent_li > i').forEach((parent) => {
|
||||||
|
parent.addEventListener("click",(event) => {
|
||||||
|
let single = event.target.parentElement.querySelector('ul,li');
|
||||||
|
let visible = single.classList.toggle("d-none");
|
||||||
|
if (visible) {
|
||||||
|
event.target.parentElement.querySelector("i").classList.add("fa-square-plus");
|
||||||
|
event.target.parentElement.querySelector("i").classList.remove("fa-square-minus");
|
||||||
|
} else {
|
||||||
|
event.target.parentElement.querySelector("i").classList.add("fa-square-minus");
|
||||||
|
event.target.parentElement.querySelector("i").classList.remove("fa-square-plus");
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
document.getElementById("viewdeleted").addEventListener("click",(event) => {
|
||||||
|
document.querySelectorAll(".tree span").forEach((spa) => {
|
||||||
|
if (event.currentTarget.checked && spa.getAttribute("data-deleted")!== "")
|
||||||
|
spa.parentElement.classList.remove("d-none");
|
||||||
|
else if ((!event.currentTarget.checked) && spa.getAttribute("data-deleted")!== "")
|
||||||
|
spa.parentElement.classList.add("d-none");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
var datatable;
|
|
||||||
var colomnspez = columns;
|
|
||||||
function createSearchData(data, type, row){
|
|
||||||
let details = "";
|
|
||||||
data.forEach(function(item){
|
|
||||||
details += item.comment+' '+item.description+' ';
|
|
||||||
details += new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(item.subamount);
|
|
||||||
});
|
|
||||||
return details;
|
|
||||||
}
|
|
||||||
|
|
||||||
colomnspez.splice(3, 0, { title: "Quelle",orderable:false, data: "source",className:"dt-source" });
|
|
||||||
colomnspez.splice(6, 0, { title: "Details",orderable:false, visible:false, searchable:true, data: "details",className:"",render: createSearchData});
|
|
||||||
$(document).ready(function(){
|
|
||||||
datatable = $('#bookings').DataTable({
|
|
||||||
paging: false,
|
|
||||||
searching:true,
|
|
||||||
scrollX:false,
|
|
||||||
info:false,
|
|
||||||
order: [[ 1, 'desc' ],[ 0, 'desc' ]],
|
|
||||||
"processing": true,
|
|
||||||
ajax: {
|
|
||||||
type : 'POST',
|
|
||||||
url : '/Ajax/getTabelData',
|
|
||||||
data : function(d){
|
|
||||||
d.datum_start = $('#datepickers').val();
|
|
||||||
d.datum_ende = $('#datepickere').val();
|
|
||||||
d.source = $('#source').val();
|
|
||||||
},
|
|
||||||
dataSrc:''},
|
|
||||||
layout: {
|
|
||||||
topStart: {
|
|
||||||
buttons: [
|
|
||||||
{text:'Neue Rechnung',className:'btn-sm',action: function ( e, dt, node, config ) {
|
|
||||||
location.href = '/newBill/';
|
|
||||||
}},
|
|
||||||
{text:'Neuer Transfer',className:'btn-sm mx-2',action: function ( e, dt, node, config ) {
|
|
||||||
location.href = '/newTransfer/';
|
|
||||||
}},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
topEnd: 'search'
|
|
||||||
},
|
|
||||||
// dom: '<"toolbar">frt',
|
|
||||||
"createdRow": function ( row, data, index ) {
|
|
||||||
if(data.validate == "t"){
|
|
||||||
$(row).addClass('text-bg-warning');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
columns: colomnspez,
|
|
||||||
});
|
|
||||||
|
|
||||||
// $("div.toolbar").html('<a class="btn-sm btn-secondary mx-2" href="/newBill" role="button">Neue Rechnung</a><a class="btn-sm btn-secondary" href="/newTransfer" role="button">Neuer Transfer</a>');
|
|
||||||
$('#bookings tbody').on('click', 'td.dt-receiver', function () {collapseDetails($(this), datatable);} );
|
|
||||||
$('#bookings tbody').on('click', 'td.dt-datum', function () {location.href = '/editBill/'+getId($(this),datatable);});
|
|
||||||
$('#bookings tbody').on('click', 'table.tabdet', function () {location.href = '/editBill/'+$(this).attr('data-bs-id');});
|
|
||||||
});
|
|
||||||
@@ -1,35 +1,146 @@
|
|||||||
$(function () {
|
document.addEventListener("DOMContentLoaded", function(event) {
|
||||||
$('.parent').change(function () {
|
document.myModal = document.getElementById('mymodal');
|
||||||
var $subs = $(this).parent().parent().children(".sub").children();
|
document.myModalDelete = document.getElementById('mymodalDelete');
|
||||||
$subs.children().remove().end();
|
document.myModalDelete.addEventListener('show.bs.modal', function (event) {
|
||||||
var $output = '';
|
var button = event.relatedTarget;
|
||||||
$liste = subsdata[$(this).val()];
|
var id = button.getAttribute('data-bs-id');
|
||||||
$sort = Object.entries($liste).sort((a, b) => (a[1] > b[1]) ? 1 : (b[1] > a[1]) ? -1 : 0);
|
var tab = button.getAttribute('data-bs-table');
|
||||||
$.each($sort, function (key, value) {
|
document.myModalDelete.setAttribute('data-bs-id',id);
|
||||||
$output += '<option value="' + value[0] + '">' + value[1] + '</option>';
|
document.myModalDelete.setAttribute('data-bs-table',tab);
|
||||||
});
|
});
|
||||||
$subs.append($output);
|
document.myModal.addEventListener('show.bs.modal', function (event) {
|
||||||
|
var button = event.relatedTarget;
|
||||||
|
var id = button.getAttribute('data-bs-id');
|
||||||
|
var tab = button.getAttribute('data-bs-table');
|
||||||
|
document.myModal.setAttribute('data-bs-id',id);
|
||||||
|
document.myModal.setAttribute('data-bs-table',tab);
|
||||||
});
|
});
|
||||||
$('#multi').change(function () {
|
|
||||||
if ($(this).is(":checked")) {
|
|
||||||
$('.single').addClass('d-none');
|
|
||||||
$('.multi').removeClass('d-none');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$('.single').removeClass('d-none');
|
|
||||||
$('.multi').addClass('d-none');
|
|
||||||
//'unchecked' event code
|
|
||||||
}).change();
|
|
||||||
$('.dt-amount, .dt-subamount').change(function () {
|
|
||||||
var temp = convertInput($(this).val());
|
|
||||||
$(this).val(convertOutput(temp));
|
|
||||||
if ($('#multi').is(":checked")) {
|
|
||||||
recalcOpenAmount();
|
|
||||||
}
|
|
||||||
}).change();
|
|
||||||
|
|
||||||
|
document.getElementById('modal_delete').addEventListener('click', deleteEntry );
|
||||||
|
|
||||||
|
|
||||||
|
var event = new Event('change');
|
||||||
|
|
||||||
|
switchMulti();
|
||||||
|
// dropdown elemente anpassen wenn parent sich ändert
|
||||||
|
document.querySelectorAll(".parent").forEach((papa) => {
|
||||||
|
papa.addEventListener("change", hdlDropDownChange);
|
||||||
|
});
|
||||||
|
|
||||||
|
document.querySelectorAll(".dt-amount.input,.dt-amount.output , .dt-subamount").forEach((amount) => {
|
||||||
|
amount.addEventListener("change", hdlAmountChange);
|
||||||
|
amount.dispatchEvent(event);
|
||||||
|
});
|
||||||
|
|
||||||
|
document.querySelectorAll(".dt-amount.input,.dt-amount.output,.dt-subamount, .parent").forEach((amount) => {
|
||||||
|
amount.addEventListener("focus", hdlValidityStateLine);
|
||||||
|
});
|
||||||
|
|
||||||
|
const form = document.getElementById('newbill');
|
||||||
|
form.addEventListener('formdata', function(event) {
|
||||||
|
const formData = event.formData;
|
||||||
|
formData.set('validate', formData.has('validate') ? '1' : '0');
|
||||||
|
// console.log(formData);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function loadPage(ev){
|
||||||
|
let url = ev.relatedTarget.getAttribute('url');
|
||||||
|
window.location.href="url";
|
||||||
|
}
|
||||||
|
|
||||||
|
function switchMulti(){
|
||||||
|
//const multi = document.getElementById("multi");
|
||||||
|
if (document.getElementById("linecont").childElementCount>1) {
|
||||||
|
document.getElementById("multiadd").text = "+Zeile";
|
||||||
|
const singles = document.querySelectorAll(".single").forEach((single) => {
|
||||||
|
single.classList.add("d-none");
|
||||||
|
});
|
||||||
|
const multis = document.querySelectorAll(".multi").forEach((multi) => {
|
||||||
|
multi.classList.remove("d-none");
|
||||||
|
});
|
||||||
|
// addLine();
|
||||||
|
} else {
|
||||||
|
document.getElementById("multiadd").text = "Multi";
|
||||||
|
const singles = document.querySelectorAll(".single").forEach((single) => {
|
||||||
|
single.classList.remove("d-none");
|
||||||
|
});
|
||||||
|
const multis = document.querySelectorAll(".multi").forEach((ele) => {
|
||||||
|
ele.classList.add("d-none");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function recalcRow(einnahme, ausgabe){
|
||||||
|
let value = einnahme.value - ausgabe.value;
|
||||||
|
|
||||||
|
if (value < 0) {
|
||||||
|
ausgabe.value = convertOutput(value *(-1));
|
||||||
|
einnahme.value = '';
|
||||||
|
} else {
|
||||||
|
einnahme.value = convertOutput(value);
|
||||||
|
ausgabe.value = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function hdlAmountChange(event) {
|
||||||
|
var temp = convertInput(event.target.value);
|
||||||
|
event.target.value = convertOutput(temp);
|
||||||
|
|
||||||
|
let zeile = event.target.parentElement.parentElement;
|
||||||
|
var einnahme = zeile.querySelector(".input");
|
||||||
|
var ausgabe = zeile.querySelector(".output");
|
||||||
|
|
||||||
|
if (event.target.classList.contains("input")) {
|
||||||
|
if ( ausgabe.value !== '')
|
||||||
|
recalcRow(einnahme,ausgabe);
|
||||||
|
}else {
|
||||||
|
if ( einnahme.value !== '')
|
||||||
|
recalcRow(einnahme, ausgabe);
|
||||||
|
}
|
||||||
|
|
||||||
|
calcAmount();
|
||||||
|
if (document.getElementById("linecont").childElementCount>1) {
|
||||||
|
recalcOpenAmount();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function hdlDropDownChange(event) {
|
||||||
|
var $sub = event.target.parentElement.parentElement.querySelector(".sub");
|
||||||
|
while ($sub.options.length) {
|
||||||
|
$sub.remove(0);
|
||||||
|
}
|
||||||
|
var output = '';
|
||||||
|
var liste = subsdata[(event.target.value=="")?0:event.target.value];
|
||||||
|
var sort = Object.entries(liste).sort((a, b) => (a[1] > b[1]) ? 1 : (b[1] > a[1]) ? -1 : 0);
|
||||||
|
sort.forEach((value) => {
|
||||||
|
output += '<option value="' + value[0] + '">' + value[1] + '</option>';
|
||||||
|
});
|
||||||
|
$sub.innerHTML = output;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hdlValidityState(ev){
|
||||||
|
form = document.getElementById("newbill");
|
||||||
|
this.classList.remove("is-invalid");
|
||||||
|
this.setCustomValidity("");
|
||||||
|
form.classList.remove('was-validated');
|
||||||
|
}
|
||||||
|
|
||||||
|
function hdlValidityStateLine(ev){
|
||||||
|
let form = document.getElementById("newbill");
|
||||||
|
if (form.classList.contains('was-validated')) {
|
||||||
|
//ev.target.parentNode.parentNode
|
||||||
|
//document.getElementById("linecont").
|
||||||
|
form.querySelectorAll(".dt-amount, .dt-subamount, .parent, .sub").forEach((amount) => {
|
||||||
|
amount.setCustomValidity("");
|
||||||
|
amount.classList.remove("is-invalid");
|
||||||
|
amount.classList.remove("is-valid");
|
||||||
|
});
|
||||||
|
form.classList.remove('was-validated');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function logData(event) {
|
function logData(event) {
|
||||||
var data = document.getElementById("billfile");
|
var data = document.getElementById("billfile");
|
||||||
console.log(data.value);
|
console.log(data.value);
|
||||||
@@ -37,12 +148,21 @@ function logData(event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function addLine() {
|
function addLine() {
|
||||||
$('#linecont > div').each(function () {
|
//let ele =document.querySelector("#linecont > div:last-child");
|
||||||
if ($(this).hasClass("d-none")) {
|
var clonedDiv = document.getElementById("template").cloneNode(true);
|
||||||
$(this).removeClass("d-none");
|
clonedDiv.removeAttribute("id");
|
||||||
return false;
|
clonedDiv.classList.remove("d-none");
|
||||||
}
|
clonedDiv.querySelector(".parent").addEventListener("change", hdlDropDownChange);
|
||||||
|
clonedDiv.querySelectorAll(".dt-subamount").forEach((amount) => {
|
||||||
|
amount.addEventListener("change", hdlAmountChange);
|
||||||
});
|
});
|
||||||
|
clonedDiv.querySelectorAll(".dt-subamount, .parent").forEach((amount) => {
|
||||||
|
amount.addEventListener("focus", hdlValidityStateLine);
|
||||||
|
});
|
||||||
|
document.getElementById("linecont").appendChild(clonedDiv);
|
||||||
|
if (document.getElementById("linecont").childElementCount==2){
|
||||||
|
switchMulti();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeBillFile(e) {
|
function removeBillFile(e) {
|
||||||
@@ -79,23 +199,97 @@ function convertOutput(number) {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
function recalcOpenAmount() {
|
function calcAmount() {
|
||||||
var summe = 0.0;
|
//let amount = convertInput(document.getElementsByName("amount")[0].value);
|
||||||
$('.dt-subamount').each(function () {
|
let amount = 0.0;
|
||||||
b = $(this).val();
|
document.querySelectorAll(".dt-subamount").forEach((subamount) => {
|
||||||
b = convertInput(b);
|
var b = convertInput(subamount.value);
|
||||||
if (typeof b !== 'undefined') {
|
if (typeof b !== 'undefined') {
|
||||||
b = $(this).hasClass("text-danger") ? b * (-1) : b;
|
b = subamount.classList.contains("output") ? b * (-1) : b;
|
||||||
summe = summe + b;
|
amount = amount + b;
|
||||||
}
|
}
|
||||||
// summe = summe + convertInput($(this).val());
|
|
||||||
});
|
});
|
||||||
|
document.getElementsByName("amount")[0].value = convertOutput(amount);
|
||||||
|
|
||||||
$('#openamount').val(Math.round(($('#total_in').val() - $('#total_out').val() - summe) * 100) / 100);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// $('form').submit(function () {
|
function recalcOpenAmount() {
|
||||||
// alert("disable elements");
|
form = document.getElementById('newbill');
|
||||||
// $( ".d-none" ).prop( "disabled", true );
|
let summe = convertInput(document.getElementsByName("amount")[0].value);
|
||||||
// return true;
|
console.log("Re calculating open amount");
|
||||||
// });
|
var total_in = convertInput(document.getElementById("total_in").value || "0.0");
|
||||||
|
var total_out = convertInput(document.getElementById("total_out").value || "0.0");
|
||||||
|
|
||||||
|
let val = convertOutput(Math.round((total_in - total_out - summe) * 100) / 100);
|
||||||
|
if (parseFloat(val) !== 0.0){
|
||||||
|
setValState(form.openamount,"Muss 0 sein");
|
||||||
|
} else {
|
||||||
|
setValState(form.openamount,"Muss 0 sein",true);
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById("openamount").value = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setValState(ele, message,valid=false){
|
||||||
|
if (valid){
|
||||||
|
ele.classList.add("is-valid");
|
||||||
|
ele.classList.remove("is-invalid");
|
||||||
|
ele.setCustomValidity("");
|
||||||
|
} else {
|
||||||
|
ele.classList.add("is-invalid");
|
||||||
|
ele.classList.remove("is-valid");
|
||||||
|
ele.setCustomValidity(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkForm(e,form) {
|
||||||
|
const subinputs = form.elements;
|
||||||
|
|
||||||
|
//for new transfer
|
||||||
|
if (form.receiver.value =='' && form.transfer.value)
|
||||||
|
form.receiver.value = subinputs['parent_id[]'].selectedOptions[0].text+"-"+subinputs['account_id[]'].selectedOptions[0].text;
|
||||||
|
if (!form.total_in.parentElement.parentElement.classList.contains("d-none")) {
|
||||||
|
//Gesamtbetrag fehlt
|
||||||
|
if ((form.total_in.value == "" ) && (form.total_out.value == "")) {
|
||||||
|
if (parseFloat(form.amount.value) > 0.0){
|
||||||
|
setValState(form.total_in, "Notwendig");
|
||||||
|
} else {
|
||||||
|
setValState(form.total_out, "Notwendig");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Restbetrag
|
||||||
|
if (parseFloat(form.openamount.value) !== 0.0){
|
||||||
|
setValState(form.openamount, "Offener Betrag!");
|
||||||
|
form.openamount.readOnly = false;
|
||||||
|
}else{
|
||||||
|
setValState(form.openamount, "Offener Betrag!",true);
|
||||||
|
}
|
||||||
|
subinputs['account_id[]'].forEach((line,index) => {
|
||||||
|
//wenn Kategorie gewählt muss Betrag da sein
|
||||||
|
if (line.value > 0){
|
||||||
|
if (!((parseFloat(subinputs['output[]'][index].value) > 0.0) || (parseFloat(subinputs['input[]'][index].value) > 0.0))){
|
||||||
|
setValState(subinputs['output[]'][index],"Notwendig");
|
||||||
|
setValState(subinputs['input[]'][index],"Notwendig");
|
||||||
|
} else {
|
||||||
|
setValState(subinputs['output[]'][index],"Notwendig",true);
|
||||||
|
setValState(subinputs['input[]'][index],"Notwendig",true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((subinputs['output[]'][index].value !=="") || (subinputs['input[]'][index].value !=="")){
|
||||||
|
setValState(line,"Notwendig");
|
||||||
|
setValState(subinputs['parent_id[]'][index],"Notwendig");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
setValState(line,"Notwendig",true);
|
||||||
|
setValState(subinputs['parent_id[]'][index],"Notwendig",true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (!form.checkValidity()) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
form.openamount.readOnly = true;
|
||||||
|
}
|
||||||
|
form.classList.add('was-validated');
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,26 +1,66 @@
|
|||||||
function syncScheduled(){
|
function syncScheduled(ele){
|
||||||
$('#mySnycModal').modal('show');
|
var myModal = document.getElementById('mySnycModal');
|
||||||
$('#mySnycModal').find('.modal-title').html("Synchronisierte Einträge!");
|
var modalTitle = myModal.querySelector('.modal-title');
|
||||||
$.ajax({
|
let modalBody = myModal.querySelector('.modal-body');
|
||||||
type: "GET",
|
modalTitle.textContent = 'Synchronisierte Einträge!';
|
||||||
url: "/syncScheduled/",
|
modalBody.textContent = 'Please Wait!';
|
||||||
data: {}, // serializes the form's elements.
|
fetch("/syncScheduled", { method: "GET",headers: {"X-Requested-With": "XMLHttpRequest"},})
|
||||||
success: function(data){
|
.then(response => response.text())
|
||||||
const myModale = document.querySelector('#mySnycModal');
|
.then(data => {
|
||||||
var modalText = myModale.querySelector('.modal-body');
|
const myModale = document.querySelector('#mySnycModal');
|
||||||
var modalFenster = myModale.querySelector('.modal-dialog');
|
var modalBody = myModale.querySelector('.modal-body');
|
||||||
modalText.innerHTML = data;
|
if (data === "") {
|
||||||
$('#todos').DataTable().ajax.reload();
|
modalBody.innerHTML = "Nix Neues Synchronisiert!";
|
||||||
},
|
|
||||||
error: function(data){
|
|
||||||
const myModale = document.querySelector('#mySnycModal');
|
|
||||||
var modalText = myModale.querySelector('.modal-body');
|
|
||||||
var modalFenster = myModale.querySelector('.modal-dialog');
|
|
||||||
modalFenster.classList.add("alert");
|
|
||||||
modalFenster.classList.add("alert-danger");
|
|
||||||
modalText.textContent = 'Fehler bei der Ausführung!';
|
|
||||||
$('#todos').DataTable().ajax.reload();
|
|
||||||
}
|
}
|
||||||
});
|
else
|
||||||
// location.href = '/syncScheduled/';
|
modalBody.innerHTML = data;
|
||||||
|
if (typeof loadToDosData === "function")
|
||||||
|
loadToDosData();
|
||||||
|
})
|
||||||
|
.catch(
|
||||||
|
error => {
|
||||||
|
const myModale = document.querySelector('#mySnycModal');
|
||||||
|
var modalBody = myModale.querySelector('.modal-body');
|
||||||
|
modalBody.innerHTML = "Fehler bei der Ausführung! " + error;
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function deleteEntry(event) {
|
||||||
|
let myModalDelete = document.getElementById('mymodalDelete');
|
||||||
|
let id = myModalDelete.getAttribute('data-bs-id');
|
||||||
|
let table = myModalDelete.getAttribute('data-bs-table');
|
||||||
|
let formData = new FormData();
|
||||||
|
formData.set('id',id);
|
||||||
|
|
||||||
|
if (table == "scheduled")
|
||||||
|
cmnd = "/deleteScheduled";
|
||||||
|
else
|
||||||
|
cmnd = "/deleteBill";
|
||||||
|
fetch(cmnd, { method: "POST",headers: {"X-Requested-With": "XMLHttpRequest"}, body: formData})
|
||||||
|
.then(response => {
|
||||||
|
let myModal = document.getElementById('mymodal');
|
||||||
|
let body = myModal.querySelector('.modal-body');
|
||||||
|
if (!response.ok){
|
||||||
|
body.innerHTML = response.statusText;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
myModal.addEventListener('hidden.bs.modal', event => {
|
||||||
|
let url = event.target.getAttribute('data-bs-url');
|
||||||
|
window.location.href= url;
|
||||||
|
})
|
||||||
|
//document.getElementById('modal_ok').addEventListener('click', loadPage );
|
||||||
|
response.json().then(json => {
|
||||||
|
console.log(json);
|
||||||
|
myModal.setAttribute('data-bs-url',json.url);
|
||||||
|
body.innerHTML = "Erfolgreich gelöscht " + json.ID;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(
|
||||||
|
error => {
|
||||||
|
let body = myModal.querySelector('.modal-body');
|
||||||
|
body.innerHTML = "Fehler bei der Ausführung! " + error;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
var datatable;
|
|
||||||
var columnspez = columns;
|
|
||||||
columnspez.splice(3, 0, { title: "Quelle",orderable:false, data: "source",className:"dt-source" });
|
|
||||||
|
|
||||||
$(document).ready(function(){
|
|
||||||
datatable = $('#scheduled').DataTable({
|
|
||||||
paging: false,
|
|
||||||
searching:true,
|
|
||||||
scrollX:false,
|
|
||||||
info:false,
|
|
||||||
order: [[ 1, 'asc' ]],
|
|
||||||
ajax: {url: '/Ajax/getScheduledData',dataSrc:''},
|
|
||||||
layout: {
|
|
||||||
topStart: {
|
|
||||||
buttons: [
|
|
||||||
{text:'Neue Rechnung',className:'btn-sm',action: function ( e, dt, node, config ) {
|
|
||||||
location.href = '/newScheduled';
|
|
||||||
}},
|
|
||||||
{text:'Neuer Transfer',className:'btn-sm mx-2',action: function ( e, dt, node, config ) {
|
|
||||||
location.href = '/newScheduledTransfer';
|
|
||||||
}},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
topEnd: 'search'
|
|
||||||
},
|
|
||||||
columns: columnspez
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#scheduled tbody').on('click', 'td.dt-receiver', function () {collapseDetails($(this), datatable);} );
|
|
||||||
$('#scheduled tbody').on('click', 'td.dt-datum', function () {location.href = '/editScheduled/'+getId($(this),datatable);});
|
|
||||||
$('#scheduled tbody').on('click', 'table.tabdet', function () {location.href = '/editScheduled/'+$(this).attr('data-bs-id');});
|
|
||||||
});
|
|
||||||
@@ -1,16 +1,59 @@
|
|||||||
var accounts;
|
var accountsdata;
|
||||||
$(document).ready(function(){
|
|
||||||
accounts = $('#accounts').DataTable({
|
function loadAccountsData(){
|
||||||
|
document.accounts.setMessage("Loading Data");
|
||||||
|
let status;
|
||||||
|
fetch("/getAccountsBalance", { method: "GET",headers: {"X-Requested-With": "XMLHttpRequest"},})
|
||||||
|
.then(response => {
|
||||||
|
status = response.statusText;
|
||||||
|
if (!response.ok) {
|
||||||
|
throw "HTTP error: " + response.status + "; " + status;
|
||||||
|
} else
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
if (document.accounts.hasRows){
|
||||||
|
document.accounts.data.data.splice(0,document.accounts.data.data.length);
|
||||||
|
document.accounts.hasRows = false;
|
||||||
|
}
|
||||||
|
document.accounts.insert({data:data.map(item => [item.description,item.amount])});
|
||||||
|
document.accounts.update(true);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
document.accounts.setMessage(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function createDtAccounts(){
|
||||||
|
document.accounts = new simpleDatatables.DataTable("#accounts", {
|
||||||
|
searchable: false,
|
||||||
paging: false,
|
paging: false,
|
||||||
searching:true,
|
data: {
|
||||||
scrollX:false,
|
headings: ["Konto","Betrag"],
|
||||||
info:false,
|
data: accountsdata,
|
||||||
ajax: { url: '/Ajax/getAccountsBalance', dataSrc:''},
|
},
|
||||||
layout: { topEnd: 'search' },
|
classes: {
|
||||||
// dom: '<"toolbar">frtip',
|
active: "active",
|
||||||
|
disabled: "disabled",
|
||||||
|
table: "table table-striped table-sm",
|
||||||
|
},
|
||||||
columns: [
|
columns: [
|
||||||
{ title: "Konto",orderable:false, data: "description",className:"dt-receiver" },
|
{
|
||||||
colBetrag
|
select:0,
|
||||||
]
|
type: 'string',
|
||||||
|
cellClass:"dt-receiver",
|
||||||
|
},{
|
||||||
|
select:1,
|
||||||
|
type: 'number',
|
||||||
|
headerClass: "dt-amount",
|
||||||
|
cellClass:"dt-amount",
|
||||||
|
render: renderAmount
|
||||||
|
}
|
||||||
|
]
|
||||||
});
|
});
|
||||||
});
|
loadAccountsData();
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener("DOMContentLoaded", function(event) {
|
||||||
|
createDtAccounts();
|
||||||
|
});
|
||||||
111
public/js/tab_activities.js
Normal file
111
public/js/tab_activities.js
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
var activitydata;
|
||||||
|
var colomnspez = columns;
|
||||||
|
|
||||||
|
function loadActivityData(){
|
||||||
|
document.activities.setMessage("Loading Data");
|
||||||
|
const form = document.querySelector("#getData");
|
||||||
|
let formData = new FormData(form);
|
||||||
|
// formData.append('start', document.getElementById("datum_start").value);
|
||||||
|
// formData.append('end', document.getElementById("datum_ende").value);
|
||||||
|
// formData.append('source', document.getElementById("source").value);
|
||||||
|
fetch("/getActivitiesData", { method: "POST",headers: {"X-Requested-With": "XMLHttpRequest"}, body: formData })
|
||||||
|
.then(response => {
|
||||||
|
let status = response.statusText;
|
||||||
|
if (!response.ok) {
|
||||||
|
throw "HTTP error: " + response.status + "; " + status;
|
||||||
|
} else
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
if (document.activities.hasRows){
|
||||||
|
document.activities.data.data.splice(0,document.activities.data.data.length);
|
||||||
|
document.activities.hasRows = false;
|
||||||
|
}
|
||||||
|
//document.activities.insert({data:data});
|
||||||
|
document.activities.insert({data:data.map(item => [item.id,item.datum,item.receiver,item.source,item.amount,item.validate])});
|
||||||
|
document.activities.update(true);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
document.activities.setMessage(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function createDtActivities(){
|
||||||
|
document.activities = new simpleDatatables.DataTable("#activities", {
|
||||||
|
searchable: true,
|
||||||
|
paging: false,
|
||||||
|
classes: {
|
||||||
|
active: "active",
|
||||||
|
disabled: "disabled",
|
||||||
|
table: "table table-striped table-sm",
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
headings: ["","Datum","Empfänger",,"Quelle","Betrag","draft"],
|
||||||
|
data: activitydata,
|
||||||
|
},
|
||||||
|
rowRender: (row, tr, _index) => {
|
||||||
|
//tr.childNodes[1].childNodes[0].attributes.href = `editBill/${row.cells[0].data}`;
|
||||||
|
tr.childNodes[1].attributes.onclick = `location.href='editBill/${row.cells[0].data}'`;
|
||||||
|
if(row.cells[5].data == true){
|
||||||
|
tr.attributes.class = 'text-bg-warning';
|
||||||
|
}
|
||||||
|
// $(row).addClass('text-bg-warning');
|
||||||
|
// tr.childNodes[2].attributes.onclick = `collapseDetails(this, ${_index})`;
|
||||||
|
},
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
select:0,
|
||||||
|
render: (data, _cell, _dataIndex, _cellIndex) => { return `<a data-bs-toggle="modal" role="button" data-bs-id="${data}" data-bs-target="#mymodalDelete" ><i class="fa-solid fa-trash"></a>` },
|
||||||
|
cellClass: "datatable-icon",
|
||||||
|
type: "number",
|
||||||
|
},{
|
||||||
|
select:1,
|
||||||
|
type: 'date',
|
||||||
|
format: 'dd.mm.yyyy',
|
||||||
|
cellClass:"dt-datum",
|
||||||
|
sortable: true,
|
||||||
|
sort: "desc",
|
||||||
|
},{
|
||||||
|
select:2,
|
||||||
|
type: 'string',
|
||||||
|
cellClass:"dt-receiver",
|
||||||
|
// render: (data, _cell, _dataIndex, _cellIndex) => { return `<a onclick="collapseDetails(this,document.bookings)">${data}</a>` },
|
||||||
|
|
||||||
|
},{
|
||||||
|
select:3,
|
||||||
|
type: 'string',
|
||||||
|
cellClass:"dt-source",
|
||||||
|
// render: (data, _cell, _dataIndex, _cellIndex) => { return `<a onclick="collapseDetails(this,document.bookings)">${data}</a>` },
|
||||||
|
|
||||||
|
},{
|
||||||
|
select:4,
|
||||||
|
type: 'number',
|
||||||
|
headerClass: "dt-amount",
|
||||||
|
cellClass:"dt-amount",
|
||||||
|
render: renderAmount
|
||||||
|
},{
|
||||||
|
select:5,
|
||||||
|
type: 'boolean',
|
||||||
|
hidden:true,
|
||||||
|
}
|
||||||
|
|
||||||
|
],
|
||||||
|
template: (options, dom) => `<div class='${options.classes.top}'>
|
||||||
|
<div class='float-start'>
|
||||||
|
<a class="btn btn-sm btn-secondary" href="newBill">Neue Rechnung</a>
|
||||||
|
<a class="btn btn-sm btn-secondary" href="newTransfer">Neuer Transfer</a>
|
||||||
|
</div>
|
||||||
|
<div class='${options.classes.search} float-end'>
|
||||||
|
<input class='${options.classes.input}' placeholder='Search' type='search' title='${options.labels.searchTitle}'${dom.id ? ` aria-controls="${dom.id}"` : ""}>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class='${options.classes.container}'${options.scrollY.length ? ` style='height: ${options.scrollY}; overflow-Y: auto;'` : ""}></div>
|
||||||
|
<div class='${options.classes.bottom}'>
|
||||||
|
</div>`
|
||||||
|
});
|
||||||
|
loadActivityData();
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener("DOMContentLoaded", function(event) {
|
||||||
|
createDtActivities();
|
||||||
|
});
|
||||||
88
public/js/tab_overview.js
Normal file
88
public/js/tab_overview.js
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
var bookingdata;
|
||||||
|
|
||||||
|
function createDtOverviewBookings(){
|
||||||
|
document.bookings = new simpleDatatables.DataTable("#bookings", {
|
||||||
|
searchable: false,
|
||||||
|
paging: false,
|
||||||
|
data: {
|
||||||
|
headings: ["","Datum","Empfänger","Betrag"],
|
||||||
|
data: bookingdata,
|
||||||
|
},
|
||||||
|
rowRender: (row, tr, _index) => {
|
||||||
|
//tr.childNodes[1].childNodes[0].attributes.href = `editBill/${row.cells[0].data}`;
|
||||||
|
tr.childNodes[1].attributes.onclick = `location.href='editBill/${row.cells[0].data}'`;
|
||||||
|
// tr.childNodes[2].attributes.onclick = `collapseDetails(this, ${_index})`;
|
||||||
|
},
|
||||||
|
classes: {
|
||||||
|
active: "active",
|
||||||
|
disabled: "disabled",
|
||||||
|
table: "table table-striped table-sm",
|
||||||
|
},
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
select:0,
|
||||||
|
// render: (data, _cell, _dataIndex, _cellIndex) => { return `<a data-bs-toggle="modal" role="button" data-bs-id="'${data}'" data-bs-target="#mymodal" ><i class="fa-solid fa-trash"></a>` },
|
||||||
|
cellClass: "datatable-icon",
|
||||||
|
type: "number",
|
||||||
|
hidden:true,
|
||||||
|
},{
|
||||||
|
select:1,
|
||||||
|
type: 'date',
|
||||||
|
format: 'dd.mm.yyyy',
|
||||||
|
cellClass:"dt-datum",
|
||||||
|
sortable: true,
|
||||||
|
sort: "desc",
|
||||||
|
},{
|
||||||
|
select:2,
|
||||||
|
type: 'string',
|
||||||
|
cellClass:"dt-receiver",
|
||||||
|
// render: (data, _cell, _dataIndex, _cellIndex) => { return `<a onclick="collapseDetails(this,document.bookings)">${data}</a>` },
|
||||||
|
|
||||||
|
},{
|
||||||
|
select:3,
|
||||||
|
type: 'number',
|
||||||
|
headerClass: "dt-amount",
|
||||||
|
cellClass:"dt-amount",
|
||||||
|
render: renderAmount
|
||||||
|
}
|
||||||
|
],
|
||||||
|
template: (options, dom) => `<div class='${options.classes.top}'>
|
||||||
|
<div class='float-start'>
|
||||||
|
<a class="btn btn-sm btn-secondary" href="newBill">Neue Rechnung</a>
|
||||||
|
<a class="btn btn-sm btn-secondary" href="newTransfer">Neuer Transfer</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class='${options.classes.container}'${options.scrollY.length ? ` style='height: ${options.scrollY}; overflow-Y: auto;'` : ""}></div>
|
||||||
|
<div class='${options.classes.bottom}'>
|
||||||
|
</div>`
|
||||||
|
});
|
||||||
|
loadOverviewData();
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadOverviewData(){
|
||||||
|
document.bookings.setMessage("Loading Data");
|
||||||
|
fetch("/getOverviewData", { method: "GET",headers: {"X-Requested-With": "XMLHttpRequest"},})
|
||||||
|
.then(response => {
|
||||||
|
let status = response.statusText;
|
||||||
|
if (!response.ok) {
|
||||||
|
throw "HTTP error: " + response.status + "; " + status;
|
||||||
|
} else
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
if (document.bookings.hasRows){
|
||||||
|
document.bookings.data.data.splice(0,document.bookings.data.data.length);
|
||||||
|
document.bookings.hasRows = false;
|
||||||
|
}
|
||||||
|
//document.bookings.insert({data:data});
|
||||||
|
document.bookings.insert({data:data.map(item => [item.id,item.datum,item.receiver,item.amount])});
|
||||||
|
document.bookings.update(true);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
document.bookings.setMessage(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener("DOMContentLoaded", function(event) {
|
||||||
|
createDtOverviewBookings();
|
||||||
|
});
|
||||||
91
public/js/tab_scheduled.js
Normal file
91
public/js/tab_scheduled.js
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
var scheduleddata;
|
||||||
|
var columnspez = columns;
|
||||||
|
columnspez.splice(3, 0, { title: "Quelle",orderable:false, data: "source",className:"dt-source" });
|
||||||
|
|
||||||
|
function loadScheduledData(){
|
||||||
|
document.scheduled.setMessage("Loading Data");
|
||||||
|
fetch("/getScheduledData", { method: "GET",headers: {"X-Requested-With": "XMLHttpRequest"},})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
if (document.scheduled.hasRows){
|
||||||
|
document.scheduled.data.data.splice(0,document.scheduled.data.data.length);
|
||||||
|
document.scheduled.hasRows = false;
|
||||||
|
}
|
||||||
|
//document.scheduled.insert({data:data});
|
||||||
|
document.scheduled.insert({data:data.map(item => [item.id,item.datum,item.receiver,item.source,item.amount])});
|
||||||
|
document.scheduled.update(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function createDtScheduledBookings(){
|
||||||
|
document.scheduled = new simpleDatatables.DataTable("#scheduled", {
|
||||||
|
searchable: true,
|
||||||
|
paging: false,
|
||||||
|
classes: {
|
||||||
|
active: "active",
|
||||||
|
disabled: "disabled",
|
||||||
|
table: "table table-striped table-sm",
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
headings: ["","Datum","Empfänger","Quelle","Betrag"],
|
||||||
|
data: scheduleddata,
|
||||||
|
},
|
||||||
|
rowRender: (row, tr, _index) => {
|
||||||
|
//tr.childNodes[1].childNodes[0].attributes.href = `editBill/${row.cells[0].data}`;
|
||||||
|
tr.childNodes[1].attributes.onclick = `location.href='editScheduled/${row.cells[0].data}'`;
|
||||||
|
|
||||||
|
// $(row).addClass('text-bg-warning');
|
||||||
|
// tr.childNodes[2].attributes.onclick = `collapseDetails(this, ${_index})`;
|
||||||
|
},
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
select:0,
|
||||||
|
render: (data, _cell, _dataIndex, _cellIndex) => { return `<a data-bs-toggle="modal" role="button" data-bs-id="${data}" data-bs-target="#mymodalDelete" ><i class="fa-solid fa-trash"></a>` },
|
||||||
|
cellClass: "datatable-icon",
|
||||||
|
type: "number",
|
||||||
|
sort: "desc",
|
||||||
|
},{
|
||||||
|
select:1,
|
||||||
|
type: 'date',
|
||||||
|
format: 'dd.mm.yyyy',
|
||||||
|
cellClass:"dt-datum",
|
||||||
|
sortable: true,
|
||||||
|
},{
|
||||||
|
select:2,
|
||||||
|
type: 'string',
|
||||||
|
cellClass:"dt-receiver",
|
||||||
|
// render: (data, _cell, _dataIndex, _cellIndex) => { return `<a onclick="collapseDetails(this,document.bookings)">${data}</a>` },
|
||||||
|
|
||||||
|
},{
|
||||||
|
select:3,
|
||||||
|
type: 'string',
|
||||||
|
cellClass:"dt-source",
|
||||||
|
// render: (data, _cell, _dataIndex, _cellIndex) => { return `<a onclick="collapseDetails(this,document.bookings)">${data}</a>` },
|
||||||
|
|
||||||
|
},{
|
||||||
|
select:4,
|
||||||
|
type: 'number',
|
||||||
|
headerClass: "dt-amount",
|
||||||
|
cellClass:"dt-amount",
|
||||||
|
render: renderAmount
|
||||||
|
}
|
||||||
|
],
|
||||||
|
template: (options, dom) => `<div class='${options.classes.top}'>
|
||||||
|
<div class='float-start'>
|
||||||
|
<a class="btn btn-sm btn-secondary" href="newScheduled">Neue Auto Rechnung</a>
|
||||||
|
<a class="btn btn-sm btn-secondary" href="newScheduledTransfer">Neuer Auto Transfer</a>
|
||||||
|
</div>
|
||||||
|
<div class='${options.classes.search} float-end'>
|
||||||
|
<input class='${options.classes.input}' placeholder='Search' type='search' title='${options.labels.searchTitle}'${dom.id ? ` aria-controls="${dom.id}"` : ""}>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class='${options.classes.container}'${options.scrollY.length ? ` style='height: ${options.scrollY}; overflow-Y: auto;'` : ""}></div>
|
||||||
|
<div class='${options.classes.bottom}'>
|
||||||
|
</div>`
|
||||||
|
});
|
||||||
|
loadScheduledData();
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener("DOMContentLoaded", function(event) {
|
||||||
|
createDtScheduledBookings();
|
||||||
|
})
|
||||||
99
public/js/tab_todos.js
Normal file
99
public/js/tab_todos.js
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
var todosdata;
|
||||||
|
|
||||||
|
function loadToDosData(){
|
||||||
|
document.todos.setMessage("Loading Data");
|
||||||
|
fetch("/getToDosData", { method: "GET",headers: {"X-Requested-With": "XMLHttpRequest"},})
|
||||||
|
.then(response => {
|
||||||
|
let status = response.statusText;
|
||||||
|
if (!response.ok) {
|
||||||
|
throw "HTTP error: " + response.status + "; " + status;
|
||||||
|
} else
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
if (document.todos.hasRows){
|
||||||
|
document.todos.data.data.splice(0,document.todos.data.data.length);
|
||||||
|
document.todos.hasRows = false;
|
||||||
|
}
|
||||||
|
document.todos.insert({data:data.map(item => [item.id, item.datum, item.receiver,item.amount])});
|
||||||
|
document.todos.update(true);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
document.todos.setMessage(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function createDtToDos(){
|
||||||
|
document.todos = new simpleDatatables.DataTable("#todos", {
|
||||||
|
searchable: true,
|
||||||
|
paging: true,
|
||||||
|
classes: {
|
||||||
|
active: "active",
|
||||||
|
disabled: "disabled",
|
||||||
|
selector: "form-select",
|
||||||
|
paginationList: "pagination",
|
||||||
|
paginationListItem: "page-item",
|
||||||
|
paginationListItemLink: "page-link",
|
||||||
|
table: "table table-striped table-sm",
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
headings: ["","Datum","Empfänger","Betrag"],
|
||||||
|
data: todosdata,
|
||||||
|
},
|
||||||
|
rowRender: (row, tr, _index) => {
|
||||||
|
tr.childNodes[1].attributes.onclick = `location.href='editBill/${row.cells[0].data}'`;
|
||||||
|
},
|
||||||
|
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
select:0,
|
||||||
|
// render: (data, _cell, _dataIndex, _cellIndex) => { return `<a data-bs-toggle="modal" role="button" data-bs-id="'${data}'" data-bs-target="#mymodal" ><i class="fa-solid fa-trash"></a>` },
|
||||||
|
cellClass: "datatable-icon",
|
||||||
|
type: "number",
|
||||||
|
hidden:true,
|
||||||
|
},{
|
||||||
|
select:1,
|
||||||
|
type: 'date',
|
||||||
|
format: 'dd.mm.yyyy',
|
||||||
|
cellClass:"dt-datum",
|
||||||
|
sortable: true,
|
||||||
|
sort: "desc",
|
||||||
|
},{
|
||||||
|
select:2,
|
||||||
|
type: 'string',
|
||||||
|
cellClass:"dt-receiver",
|
||||||
|
},{
|
||||||
|
select:3,
|
||||||
|
type: 'number',
|
||||||
|
headerClass: "dt-amount",
|
||||||
|
cellClass:"dt-amount",
|
||||||
|
render: renderAmount
|
||||||
|
}
|
||||||
|
],
|
||||||
|
template: (options, dom) => `<div class='${options.classes.top}'>
|
||||||
|
<div class='float-start'>
|
||||||
|
<a class="btn btn-sm btn-secondary" data-bs-toggle="modal" role="button" data-bs-target="#mySnycModal" onclick="syncScheduled(this)">Synch</a>
|
||||||
|
</div>
|
||||||
|
<div class='${options.classes.search} float-end'>
|
||||||
|
<input class='${options.classes.input}' placeholder='Search' type='search' title='${options.labels.searchTitle}'${dom.id ? ` aria-controls="${dom.id}"` : ""}>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class='${options.classes.container}'${options.scrollY.length ? ` style='height: ${options.scrollY}; overflow-Y: auto;'` : ""}></div>
|
||||||
|
<div class='${options.classes.bottom}'>
|
||||||
|
<div class='float-start'>
|
||||||
|
<div class='datatable-dropdown'>
|
||||||
|
<label>
|
||||||
|
<select class='${options.classes.selector}'></select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class='float-end'>
|
||||||
|
<nav class='${options.classes.pagination}'></nav>
|
||||||
|
</div>
|
||||||
|
</div>`
|
||||||
|
});
|
||||||
|
loadToDosData();
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener("DOMContentLoaded", function(event) {
|
||||||
|
createDtToDos();
|
||||||
|
});
|
||||||
@@ -1,3 +1,11 @@
|
|||||||
|
const renderAmount = function(data, _cell, _dataIndex, _cellIndex) {
|
||||||
|
var ret = (Number(data)<0)?'<span style="color:red;">':'<span>';
|
||||||
|
ret += new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(data);
|
||||||
|
ret += '</span>';
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
var colBetrag = {
|
var colBetrag = {
|
||||||
title: "Betrag",
|
title: "Betrag",
|
||||||
orderable:false,
|
orderable:false,
|
||||||
@@ -47,29 +55,6 @@ function alert(alertPlaceholder, message, type) {
|
|||||||
alertPlaceholder.append(wrapper);
|
alertPlaceholder.append(wrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteId(id, table) {
|
|
||||||
if (table == "scheduled")
|
|
||||||
cmnd = "deleteScheduled";
|
|
||||||
else
|
|
||||||
cmnd = "deleteBill";
|
|
||||||
$.ajax({
|
|
||||||
type: "POST",
|
|
||||||
url: "/Ajax/"+cmnd,
|
|
||||||
data: {"id" : id}, // serializes the form's elements.
|
|
||||||
success: function(data){
|
|
||||||
var ph = document.getElementById('alertbox');
|
|
||||||
alert(ph,"erfolgreich gelöscht",'success');
|
|
||||||
$('#'+table).DataTable().ajax.reload();
|
|
||||||
},
|
|
||||||
error: function(data){
|
|
||||||
var ph = document.getElementById('alertbox');
|
|
||||||
alert(ph,"Fehler beim löschen",'danger');
|
|
||||||
$('#'+table).DataTable().ajax.reload();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatDetails ( d ) {
|
function formatDetails ( d ) {
|
||||||
details = '';
|
details = '';
|
||||||
str='';
|
str='';
|
||||||
@@ -104,20 +89,22 @@ function formatDetails ( d ) {
|
|||||||
// null
|
// null
|
||||||
// ] )
|
// ] )
|
||||||
// } );
|
// } );
|
||||||
function collapseDetails(element, table){
|
function collapseDetails(e,index){
|
||||||
var tr = element.closest('tr');
|
console.log(e,index);
|
||||||
var row = table.row( tr );
|
|
||||||
|
|
||||||
if ( row.child.isShown() ) {
|
var tr = e.closest('tr');
|
||||||
// This row is already open - close it
|
// var row = table.row( tr );
|
||||||
row.child.hide();
|
|
||||||
tr.removeClass('shown');
|
// if ( row.child.isShown() ) {
|
||||||
}
|
// // This row is already open - close it
|
||||||
else {
|
// row.child.hide();
|
||||||
// Open this row
|
// tr.removeClass('shown');
|
||||||
row.child( formatDetails(row.data()) ).show();
|
// }
|
||||||
tr.addClass('shown');
|
// else {
|
||||||
}
|
// // Open this row
|
||||||
|
// row.child( formatDetails(row.data()) ).show();
|
||||||
|
// tr.addClass('shown');
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
function getId(ele, table) {
|
function getId(ele, table) {
|
||||||
@@ -126,21 +113,28 @@ function getId(ele, table) {
|
|||||||
return row.data().id;
|
return row.data().id;
|
||||||
}
|
}
|
||||||
|
|
||||||
$(document).ready(function(){
|
document.addEventListener("DOMContentLoaded", function(event) {
|
||||||
var myModal = document.getElementById('mymodal');
|
var myModal = document.getElementById('mymodal');
|
||||||
const modal = new bootstrap.Modal(myModal);
|
var myModalDelete = document.getElementById('mymodalDelete');
|
||||||
$("#modal_ok").click(function (e) {
|
|
||||||
modal.hide();
|
myModalDelete.addEventListener('show.bs.modal', function (event) {
|
||||||
deleteId(myModal.getAttribute('data-bs-id'), myModal.getAttribute('data-bs-table'));
|
var button = event.relatedTarget;
|
||||||
|
var id = button.getAttribute('data-bs-id');
|
||||||
|
let tab = button.closest('table').id; // table row ID
|
||||||
|
myModalDelete.setAttribute('data-bs-id',id);
|
||||||
|
myModalDelete.setAttribute('data-bs-table',tab);
|
||||||
|
var modalTitle = myModalDelete.querySelector('.modal-title');
|
||||||
|
modalTitle.textContent = 'Lösche Eintrag Nr. ' + id;
|
||||||
});
|
});
|
||||||
|
|
||||||
myModal.addEventListener('show.bs.modal', function (event) {
|
myModal.addEventListener('show.bs.modal', function (event) {
|
||||||
var button = event.relatedTarget;
|
var button = event.relatedTarget;
|
||||||
table = button.closest('table').id; // table row ID
|
|
||||||
var id = button.getAttribute('data-bs-id');
|
var id = button.getAttribute('data-bs-id');
|
||||||
|
let table = button.getAttribute('data-bs-table');
|
||||||
myModal.setAttribute('data-bs-id',id);
|
myModal.setAttribute('data-bs-id',id);
|
||||||
myModal.setAttribute('data-bs-table',table);
|
myModal.setAttribute('data-bs-table',table);
|
||||||
var modalTitle = myModal.querySelector('.modal-title');
|
var modalTitle = myModal.querySelector('.modal-title');
|
||||||
modalTitle.textContent = 'Lösche Eintrag Nr. ' + id;
|
modalTitle.textContent = 'Lösche Eintrag Nr. ' + id;
|
||||||
});
|
});
|
||||||
|
document.getElementById('modal_delete').addEventListener('click', deleteEntry );
|
||||||
});
|
});
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
var datatable;
|
|
||||||
var todos;
|
|
||||||
|
|
||||||
$(document).ready(function(){
|
|
||||||
datatable = $('#bookings').DataTable({
|
|
||||||
paging: false,
|
|
||||||
searching:true,
|
|
||||||
scrollX:false,
|
|
||||||
info:false,
|
|
||||||
order: [[ 1, 'desc' ]],
|
|
||||||
ajax: { url: '/Ajax/getOverviewData', dataSrc:''},
|
|
||||||
layout: {
|
|
||||||
topStart: {
|
|
||||||
buttons: [
|
|
||||||
{text:'Neue Rechnung',className:'btn-sm',action: function ( e, dt, node, config ) {
|
|
||||||
location.href = '/newBill/';
|
|
||||||
}},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
topEnd: 'search'
|
|
||||||
},
|
|
||||||
// dom: '<"toolbar">frt',
|
|
||||||
columns: columns,
|
|
||||||
});
|
|
||||||
// $("div.toolbar").html('<a class="btn-sm btn-secondary" href="/newBill" role="button">Neuer Eintrag</a>');
|
|
||||||
// Add event listener for opening and closing details
|
|
||||||
$('#bookings tbody').on('click', 'td.dt-receiver', function () {collapseDetails($(this), datatable);} );
|
|
||||||
$('#bookings tbody').on('click', 'td.dt-datum', function () {location.href = '/editBill/'+getId($(this),datatable);});
|
|
||||||
$('#bookings tbody').on('click', 'table.tabdet', function () {location.href = '/editBill/'+$(this).attr('data-bs-id');});
|
|
||||||
|
|
||||||
todos = $('#todos').DataTable({
|
|
||||||
paging: true,
|
|
||||||
searching:true,
|
|
||||||
scrollX:false,
|
|
||||||
info:true,
|
|
||||||
order: [[ 1, 'desc' ]],
|
|
||||||
ajax: { url: '/Ajax/getToDosData', dataSrc:''},
|
|
||||||
layout: {
|
|
||||||
topStart: {
|
|
||||||
buttons: [
|
|
||||||
{text:'Sync',className:'btn-sm',action: syncScheduled},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
topEnd: 'search'
|
|
||||||
},
|
|
||||||
// dom: '<"top"i<"syncbutton">>frt<"bottom"lp><"clear">',
|
|
||||||
columns: columns,
|
|
||||||
});
|
|
||||||
// $("div.syncbutton").html('<a class="btn-sm btn-secondary" href="/syncScheduled" role="button">Sync</a>');
|
|
||||||
// Add event listener for opening and closing details
|
|
||||||
$('#todos tbody').on('click', 'td.dt-receiver', function () {collapseDetails($(this), todos);} );
|
|
||||||
$('#todos tbody').on('click', 'td.dt-datum', function () {location.href = '/editBill/'+getId($(this),todos);});
|
|
||||||
$('#todos tbody').on('click', 'table.tabdet', function () {location.href = '/editBill/'+$(this).attr('data-bs-id');});
|
|
||||||
});
|
|
||||||
Reference in New Issue
Block a user