first commit wtf lol

This commit is contained in:
Brandon Shipley 2025-08-09 14:07:39 -07:00
commit 74f95a2f91
Signed by: bmfs
GPG Key ID: 14E38571D8BB0DE4
149 changed files with 15057 additions and 0 deletions

10
.gitignore vendored Normal file
View File

@ -0,0 +1,10 @@
/composer.lock
/composer.phar
/phpunit.xml
/.phpunit.result.cache
/.phpunit.cache
/phpunit.phar
/config/Migrations/schema-dump-default.lock
/vendor/
/.idea/
config/app_local.php

8
.idea/CakeAccounting.iml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

8
.idea/modules.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/CakeAccounting.iml" filepath="$PROJECT_DIR$/.idea/CakeAccounting.iml" />
</modules>
</component>
</project>

11
README.md Normal file
View File

@ -0,0 +1,11 @@
# CakeAccounting plugin for CakePHP
## Installation
You can install this plugin into your CakePHP application using [composer](https://getcomposer.org).
The recommended way to install composer packages is:
```
composer require your-name-here/cake-accounting
```

35
composer.json Normal file
View File

@ -0,0 +1,35 @@
{
"name": "hi-powered-dev/cake-accounting",
"description": "CakeAccounting plugin for CakePHP",
"type": "cakephp-plugin",
"license": "AGPL-3.0-or-later",
"keywords": [
"cakephp"
],
"authors": [
{
"name": "HiPoweredDev",
"homepage": "https://hipowered.dev",
"role": "Author"
}
],
"require": {
"php": ">=8.1",
"cakephp/cakephp": "^5.0.1",
"ext-bcmath" : "*"
},
"require-dev": {
"phpunit/phpunit": "^10.1"
},
"autoload": {
"psr-4": {
"CakeAccounting\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"CakeAccounting\\Test\\": "tests/",
"Cake\\Test\\": "vendor/cakephp/cakephp/tests/"
}
}
}

2613
composer.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,102 @@
<?php
declare(strict_types=1);
use Migrations\AbstractMigration;
class CreateInitialLookupTables extends AbstractMigration
{
/**
* Change Method.
*
* More information on this method is available here:
* https://book.cakephp.org/phinx/0/en/migrations.html#the-change-method
* @return void
*/
public function change(): void
{
// double entry types
$table = $this->table('de_base_types', ['id' => false, 'primary_key' => ['de_code']]);
$table->addColumn('de_code', 'string', [
'default' => null,
'limit' => 2,
'null' => false,
]);
$table->addColumn('name', 'string', [
'default' => null,
'limit' => 45,
'null' => false,
]);
$table->create();
// entity types
$table = $this->table('de_entity_types', ['id' => false, 'primary_key' => ['entity_type_code']]);
$table->addColumn('entity_type_code', 'string', [
'default' => null,
'limit' => 2,
'null' => false,
]);
$table->addColumn('name', 'string', [
'default' => null,
'limit' => 45,
'null' => false,
]);
$table->create();
// transaction types
$table = $this->table('de_transaction_types', ['id' => false, 'primary_key' => ['transaction_type_code']]);
$table->addColumn('transaction_type_code', 'string', [
'default' => null,
'limit' => 2,
'null' => false,
]);
$table->addColumn('name', 'string', [
'default' => null,
'limit' => 45,
'null' => false,
]);
$table->create();
// bank account types
$table = $this->table('de_bank_account_types', ['id' => false, 'primary_key' => ['bank_account_type_code']]);
$table->addColumn('bank_account_type_code', 'string', [
'default' => null,
'limit' => 2,
'null' => false,
]);
$table->addColumn('de_code', 'string', [
'default' => null,
'limit' => 2,
'null' => false,
]);
$table->addColumn('name', 'string', [
'default' => null,
'limit' => 45,
'null' => false,
]);
// $table->addForeignKey(
// 'de_code',
// 'de_base_types',
// 'de_code',
// [
// 'update' => 'RESTRICT',
// 'delete' => 'RESTRICT',
// 'constraint' => 'bank_accounts_base_de_code_fk'
// ]
// );
$table->create();
// internal account types
$table = $this->table('de_account_types', ['id' => false, 'primary_key' => ['account_type_code']]);
$table->addColumn('account_type_code', 'string', [
'default' => null,
'limit' => 2,
'null' => false,
]);
$table->addColumn('name', 'string', [
'default' => null,
'limit' => 45,
'null' => false,
]);
$table->create();
}
}

View File

@ -0,0 +1,118 @@
<?php
declare(strict_types=1);
use Migrations\AbstractMigration;
class CreateAccountTables extends AbstractMigration
{
/**
* Change Method.
*
* More information on this method is available here:
* https://book.cakephp.org/phinx/0/en/migrations.html#the-change-method
* @return void
*/
public function change(): void
{
$table = $this->table('de_accounts');
$table->addColumn('account_number', 'integer', [
'default' => null,
'limit' => 11,
'null' => false,
]);
$table->addColumn('parent_id', 'integer', [
'default' => null,
'limit' => 11,
'null' => true,
]);
$table->addColumn('lft', 'integer', [
'default' => null,
'limit' => 11,
'null' => false,
]);
$table->addColumn('rght', 'integer', [
'default' => null,
'limit' => 11,
'null' => false,
]);
$table->addColumn('account_type_code', 'string', [
'default' => null,
'limit' => 2,
'null' => false,
]);
$table->addColumn('name', 'string', [
'default' => null,
'limit' => 255,
'null' => false,
]);
$table->addColumn('account_limit', 'integer', [
'default' => null,
'limit' => 11,
'null' => true,
]);
$table->addColumn('can_credit', 'boolean', [
'default' => true,
'null' => false,
]);
$table->addColumn('can_debit', 'boolean', [
'default' => true,
'null' => false,
]);
$table->addIndex('account_number', ['unique' => true]);
$table->addIndex('parent_id', ['unique' => false]);
$table->addIndex('lft', ['unique' => false]);
// $table->addForeignKey(
// 'account_type_code',
// 'de_internal_account_types',
// 'account_type_code',
// [
// 'update' => 'RESTRICT',
// 'delete' => 'RESTRICT',
// 'constraint' => 'de_ledgers_de_account_type_code_fk',
// ]
// );
// $table->addForeignKey(
// 'ledger_type_code',
// 'de_ledger_types',
// 'ledger_type_code',
// [
// 'update' => 'RESTRICT',
// 'delete' => 'RESTRICT',
// 'constraint' => 'de_ledgers_de_ledger_type_code_fk',
// ]
// );
$table->create();
$table = $this->table('de_account_statements', ['id' => false, 'primary_key' => ['account_statement_id']]);
$table->addColumn('account_statement_id', 'uuid', [
'default' => null,
'null' => false,
]);
$table->addColumn('account_number', 'integer', [
'default' => null,
'limit' => 11,
'null' => false,
]);
$table->addColumn('statement_date', 'date', [
'default' => null,
'null' => false,
]);
$table->addColumn('closing_balance', 'decimal', [
'default' => null,
'precision' => 15,
'scale' => 6,
'null' => false,
]);
// $table->addForeignKey(
// 'account_number',
// 'de_ledgers',
// 'account_number',
// [
// 'update' => 'RESTRICT',
// 'delete' => 'RESTRICT',
// 'constraint' => 'ledger_statements_account_number_fk',
// ]
// );
$table->create();
}
}

View File

@ -0,0 +1,277 @@
<?php
declare(strict_types=1);
use Migrations\AbstractMigration;
class CreateTransactionTables extends AbstractMigration
{
/**
* Change Method.
*
* More information on this method is available here:
* https://book.cakephp.org/phinx/0/en/migrations.html#the-change-method
* @return void
*/
public function change(): void
{
// de_accounts
$table = $this->table('de_external_accounts', ['id' => false, 'primary_key' => ['external_account_number']]);
$table->addColumn('external_account_number', 'uuid', [
'default' => null,
'limit' => 11,
'null' => false,
]);
$table->addColumn('entity_type_code', 'string', [
'default' => null,
'limit' => 2,
'null' => false,
]);
$table->addColumn('created', 'datetime', [
'default' => null,
'null' => false,
]);
$table->addColumn('related_model', 'string', [
'default' => null,
'limit' => 255,
'null' => true,
]);
$table->addColumn('related_model_fk', 'integer', [
'default' => null,
'limit' => 11,
'null' => true,
]);
// $table->addForeignKey(
// 'entity_type_code',
// 'de_entity_types',
// 'entity_type_code',
// [
// 'update' => 'RESTRICT',
// 'delete' => 'RESTRICT',
// 'constraint' => 'de_accounts_entity_type_fk'
// ]
// );
$table->create();
// de_account_statements
$table = $this->table('de_external_account_statements', ['id' => false, 'primary_key' => 'external_account_statement_id']);
$table->addColumn('external_account_statement_id', 'uuid', [
'default' => null,
'null' => false,
]);
$table->addColumn('external_account_number', 'uuid', [
'default' => null,
'null' => false,
]);
$table->addColumn('statement_date', 'date', [
'default' => null,
'null' => false,
]);
$table->addColumn('closing_balance', 'decimal', [
'default' => null,
'precision' => 15,
'scale' => 6,
'null' => false,
]);
$table->addColumn('total_credit', 'decimal', [
'default' => null,
'precision' => 15,
'scale' => 6,
'null' => false,
]);
$table->addColumn('total_debit', 'decimal', [
'default' => null,
'precision' => 15,
'scale' => 6,
'null' => false,
]);
// $table->addForeignKey(
// 'external_account_number',
// 'de_external_accounts',
// 'external_account_number',
// [
// 'update' => 'RESTRICT',
// 'delete' => 'RESTRICT',
// 'constraint' => 'de_ext_acct_statements_ext_account_number_fk',
// ]
// );
$table->create();
// de_journal_types
$table = $this->table('de_journal_types', ['id' => false, 'primary_key' => 'de_journal_type_code']);
$table->addColumn('de_journal_type_code', 'string', [
'default' => null,
'limit' => 5,
'null' => false,
]);
$table->create();
// de_journals
$table = $this->table('de_journals');
$table->addColumn('name', 'string', [
'default' => null,
'limit' => 45,
'null' => false,
]);
$table->addColumn('short_code', 'string', [
'default' => null,
'limit' => 5,
'null' => false,
]);
$table->addColumn('default_account_number_credit', 'integer', [
'default' => null,
'limit' => 11,
'null' => true,
]);
$table->addColumn('default_account_number_debit', 'integer', [
'default' => null,
'limit' => 11,
'null' => true,
]);
$table->addColumn('de_journal_type_code', 'string', [
'default' => null,
'limit' => 5,
'null' => false,
]);
// $table->addForeignKey(
// 'default_account_number_credit',
// 'de_ledgers',
// 'account_number',
// [
// 'update' => 'RESTRICT',
// 'delete' => 'RESTRICT',
// 'constraint' => 'de_journals_default_credit_account_number_fk',
// ]
// );
// $table->addForeignKey(
// 'default_account_number_debit',
// 'de_ledgers',
// 'account_number',
// [
// 'update' => 'RESTRICT',
// 'delete' => 'RESTRICT',
// 'constraint' => 'de_journals_default_debit_account_number_fk',
// ]
// );
// $table->addForeignKey(
// 'de_journal_type_code',
// 'de_journal_types',
// 'de_journal_type_code',
// [
// 'update' => 'RESTRICT',
// 'delete' => 'RESTRICT',
// 'constraint' => 'de_journal_types_for_journals_fk',
// ]
// );
$table->create();
// de_journal_entries
$table = $this->table('de_journal_entries');
$table->addColumn('de_journal_id', 'integer', [
'default' => null,
'limit' => 11,
'null' => false,
]);
$table->addColumn('user_id', 'integer', [
'default' => null,
'limit' => 11,
'null' => true,
]);
$table->addColumn('created', 'datetime', [
'default' => null,
'null' => false,
]);
$table->addColumn('notes', 'text', [
'default' => null,
'null' => true,
]);
$table->create();
// de_journal_items
$table = $this->table('de_journal_items');
$table->addColumn('account_number_credit', 'integer', [
'default' => null,
'limit' => 11,
'null' => false,
]);
$table->addColumn('account_number_debit', 'integer', [
'default' => null,
'limit' => 11,
'null' => false,
]);
$table->addColumn('external_account_number_credit', 'uuid', [
'default' => null,
'null' => true,
]);
$table->addColumn('external_account_number_debit', 'uuid', [
'default' => null,
'null' => true,
]);
$table->addColumn('de_journal_entry_id', 'integer', [
'default' => null,
'limit' => 11,
'null' => false,
]);
$table->addColumn('amount', 'decimal', [
'default' => null,
'precision' => 15,
'scale' => 6,
'null' => false,
]);
$table->addColumn('created', 'datetime', [
'default' => null,
'null' => false,
]);
// $table->addForeignKey(
// 'de_journal_entry_id',
// 'de_journal_entries',
// 'id',
// [
// 'update' => 'RESTRICT',
// 'delete' => 'RESTRICT',
// 'constraint' => 'de_journal_items_journal_entry_id_fk',
// ]
// );
// $table->addForeignKey(
// 'account_number_credit',
// 'de_ledgers',
// 'account_number',
// [
// 'update' => 'RESTRICT',
// 'delete' => 'RESTRICT',
// 'constraint' => 'de_journal_items_account_number_credit_fk',
// ]
// );
// $table->addForeignKey(
// 'account_number_debit',
// 'de_ledgers',
// 'account_number',
// [
// 'update' => 'RESTRICT',
// 'delete' => 'RESTRICT',
// 'constraint' => 'de_journal_items_account_number_debit_fk',
// ]
// );
// $table->addForeignKey(
// 'external_account_number_credit',
// 'de_external_accounts',
// 'external_account_number',
// [
// 'update' => 'RESTRICT',
// 'delete' => 'RESTRICT',
// 'constraint' => 'de_journal_items_external_account_number_credit_fk',
// ]
// );
// $table->addForeignKey(
// 'external_account_number_debit',
// 'de_external_accounts',
// 'external_account_number',
// [
// 'update' => 'RESTRICT',
// 'delete' => 'RESTRICT',
// 'constraint' => 'de_journal_items_external_account_number_debit_fk',
// ]
// );
$table->create();
}
}

View File

@ -0,0 +1,102 @@
<?php
declare(strict_types=1);
use Migrations\AbstractMigration;
class CreateExampleAccounts extends AbstractMigration
{
/**
* Change Method.
*
* More information on this method is available here:
* https://book.cakephp.org/phinx/0/en/migrations.html#the-change-method
* @return void
*/
public function change(): void
{
$table = $this->table('de_account_templates');
$table->addColumn('name', 'string', [
'default' => null,
'limit' => 45,
'null' => false,
]);
$table->addColumn('deleted', 'datetime', [
'default' => null,
'null' => true,
]);
$table->create();
$table = $this->table('de_templated_accounts');
$table->addColumn('account_number', 'integer', [
'default' => null,
'limit' => 11,
'null' => false,
]);
$table->addColumn('account_template_id', 'integer', [
'default' => null,
'limit' => 11,
'null' => false,
]);
$table->addColumn('parent_id', 'integer', [
'default' => null,
'limit' => 11,
'null' => true,
]);
$table->addColumn('lft', 'integer', [
'default' => null,
'limit' => 11,
'null' => false,
]);
$table->addColumn('rght', 'integer', [
'default' => null,
'limit' => 11,
'null' => false,
]);
$table->addColumn('account_type_code', 'string', [
'default' => null,
'limit' => 2,
'null' => false,
]);
$table->addColumn('account_limit', 'integer', [
'default' => null,
'limit' => 11,
'null' => true,
]);
$table->addColumn('can_credit', 'boolean', [
'default' => true,
'null' => false,
]);
$table->addColumn('can_debit', 'boolean', [
'default' => true,
'null' => false,
]);
$table->addColumn('name', 'string', [
'default' => null,
'limit' => 255,
'null' => false,
]);
// $table->addForeignKey(
// 'ledger_type_code',
// 'de_ledger_types',
// 'ledger_type_code',
// [
// 'update' => 'RESTRICT',
// 'delete' => 'RESTRICT',
// 'constraint' => 'de_templated_ledgers_de_ledger_type_fk',
// ]
// );
// $table->addForeignKey(
// 'account_type_code',
// 'de_internal_account_types',
// 'account_type_code',
// [
// 'update' => 'RESTRICT',
// 'delete' => 'RESTRICT',
// 'constraint' => 'de_templated_ledgers_de_account_type_code_fk',
// ]
// );
$table->addIndex('parent_id', ['unique' => false]);
$table->addIndex('lft', ['unique' => false]);
$table->create();
}
}

Binary file not shown.

View File

@ -0,0 +1,283 @@
<?php
declare(strict_types=1);
use Cake\Log\Log;
use Cake\ORM\TableRegistry;
use Migrations\AbstractSeed;
/**
* BareBonesAccountTemplate seed.
*/
class BareBonesAccountTemplateSeed extends AbstractSeed
{
/**
* @return string[]
*/
public function getDependencies(): array
{
return [
'SeedLookupTablesSeed',
];
}
/**
* Run Method.
*
* Write your database seeder using this method.
*
* More information on writing seeds is available here:
* https://book.cakephp.org/phinx/0/en/seeding.html
*
* @return void
*/
public function run(): void
{
// base types
$stmt = $this->query('SELECT * FROM de_account_templates'); // returns PDOStatement
$existing = $stmt->fetchAll(); // returns the result as an array
if (!$existing) {
$data = [
[
'id' => 1,
'name' => 'Basic',
]
];
$table = $this->table('de_account_templates');
$table->insert($data)->save();
$templatedAccountsTable = TableRegistry::getTableLocator()->get('CakeAccounting.DeTemplatedAccounts');
$roots = [
[
'account_number' => 10000,
'account_template_id' => 1,
'parent_id' => null,
'account_type_code' => DE_ACCOUNT_TYPE_ASSET,
'name' => 'Assets',
],
[
'account_number' => 20000,
'account_template_id' => 1,
'parent_id' => null,
'account_type_code' => DE_ACCOUNT_TYPE_LIABILITY,
'name' => 'Liabilities',
],
[
'account_number' => 30000,
'account_template_id' => 1,
'parent_id' => null,
'account_type_code' => DE_ACCOUNT_TYPE_EQUITY,
'name' => 'Equity',
],
[
'account_number' => 40000,
'account_template_id' => 1,
'parent_id' => null,
'account_type_code' => DE_ACCOUNT_TYPE_REVENUE,
'name' => 'Revenue',
],
[
'account_number' => 50000,
'account_template_id' => 1,
'parent_id' => null,
'account_type_code' => DE_ACCOUNT_TYPE_EXPENSES,
'name' => 'Expenses',
],
];
$added = [];
foreach ($roots as $root) {
$rootEntity = $templatedAccountsTable->newEntity($root);
$saveResultRootEntity = $templatedAccountsTable->save($rootEntity);
if (!$saveResultRootEntity) {
Log::debug(print_r('$rootEntity->getErrors()', true));
Log::debug(print_r($rootEntity->getErrors(), true));
continue;
}
$added[$saveResultRootEntity->account_number] = $saveResultRootEntity->id;
}
$children = [
[
'account_number' => 11000,
'account_template_id' => 1,
'parent_id' => 10000,
'account_type_code' => DE_ACCOUNT_TYPE_ASSET,
'name' => 'Cash',
],
[
'account_number' => 12000,
'account_template_id' => 1,
'parent_id' => 10000,
'account_type_code' => DE_ACCOUNT_TYPE_ASSET,
'name' => 'Investments',
],
[
'account_number' => 13000,
'account_template_id' => 1,
'parent_id' => 10000,
'account_type_code' => DE_ACCOUNT_TYPE_ASSET,
'name' => 'Accounts Receivable',
],
[
'account_number' => 14000,
'account_template_id' => 1,
'parent_id' => 10000,
'account_type_code' => DE_ACCOUNT_TYPE_ASSET,
'name' => 'Inventory',
],
[
'account_number' => 15000,
'account_template_id' => 1,
'parent_id' => 10000,
'account_type_code' => DE_ACCOUNT_TYPE_ASSET,
'name' => 'Prepaid Expenses',
],
[
'account_number' => 16000,
'account_template_id' => 1,
'parent_id' => 10000,
'account_type_code' => DE_ACCOUNT_TYPE_ASSET,
'name' => 'Property & Equipment',
],
// liabilities
[
'account_number' => 21000,
'account_template_id' => 1,
'parent_id' => 20000,
'account_type_code' => DE_ACCOUNT_TYPE_LIABILITY,
'name' => 'Accounts Payable',
],
[
'account_number' => 22000,
'account_template_id' => 1,
'parent_id' => 20000,
'account_type_code' => DE_ACCOUNT_TYPE_LIABILITY,
'name' => 'Accrued Payroll Expenses',
],
[
'account_number' => 23000,
'account_template_id' => 1,
'parent_id' => 20000,
'account_type_code' => DE_ACCOUNT_TYPE_LIABILITY,
'name' => 'Accrued Expenses',
],
[
'account_number' => 24000,
'account_template_id' => 1,
'parent_id' => 20000,
'account_type_code' => DE_ACCOUNT_TYPE_LIABILITY,
'name' => 'Taxes',
],
[
'account_number' => 25000,
'account_template_id' => 1,
'parent_id' => 20000,
'account_type_code' => DE_ACCOUNT_TYPE_LIABILITY,
'name' => 'Long Term Debt',
],
// equity
[
'account_number' => 31000,
'account_template_id' => 1,
'parent_id' => 30000,
'account_type_code' => DE_ACCOUNT_TYPE_EQUITY,
'name' => 'Owner\'s Equity',
],
[
'account_number' => 32000,
'account_template_id' => 1,
'parent_id' => 30000,
'account_type_code' => DE_ACCOUNT_TYPE_EQUITY,
'name' => 'Retained Earnings',
],
// revenue
[
'account_number' => 41000,
'account_template_id' => 1,
'parent_id' => 40000,
'account_type_code' => DE_ACCOUNT_TYPE_REVENUE,
'name' => 'Sales',
],
[
'account_number' => 41100,
'account_template_id' => 1,
'parent_id' => 41000,
'account_type_code' => DE_ACCOUNT_TYPE_REVENUE,
'name' => 'Product Sales',
],
[
'account_number' => 41200,
'account_template_id' => 1,
'parent_id' => 41000,
'account_type_code' => DE_ACCOUNT_TYPE_REVENUE,
'name' => 'Service Sales',
],
// expenses
[
'account_number' => 51000,
'account_template_id' => 1,
'parent_id' => 50000,
'account_type_code' => DE_ACCOUNT_TYPE_EXPENSES,
'name' => 'Payroll Expenses',
],
[
'account_number' => 52000,
'account_template_id' => 1,
'parent_id' => 50000,
'account_type_code' => DE_ACCOUNT_TYPE_EXPENSES,
'name' => 'Rent & Utilities',
],
[
'account_number' => 53000,
'account_template_id' => 1,
'parent_id' => 50000,
'account_type_code' => DE_ACCOUNT_TYPE_EXPENSES,
'name' => 'Marketing',
],
[
'account_number' => 54000,
'account_template_id' => 1,
'parent_id' => 50000,
'account_type_code' => DE_ACCOUNT_TYPE_EXPENSES,
'name' => 'Insurance',
],
[
'account_number' => 55000,
'account_template_id' => 1,
'parent_id' => 50000,
'account_type_code' => DE_ACCOUNT_TYPE_EXPENSES,
'name' => 'Cost of Goods Sold',
],
[
'account_number' => 56000,
'account_template_id' => 1,
'parent_id' => 50000,
'account_type_code' => DE_ACCOUNT_TYPE_EXPENSES,
'name' => 'Other Expenses',
],
];
foreach ($children as $child) {
$child['parent_id'] = $added[$child['parent_id']];
$childEntity = $templatedAccountsTable->newEntity($child);
$saveResultChildEntity = $templatedAccountsTable->save($childEntity);
if (!$saveResultChildEntity) {
Log::debug(print_r('$childEntity->getErrors()', true));
Log::debug(print_r($childEntity->getErrors(), true));
continue;
}
$added[$saveResultChildEntity->account_number] = $saveResultChildEntity->id;
}
}
}
}

View File

@ -0,0 +1,86 @@
<?php
declare(strict_types=1);
use Migrations\AbstractSeed;
/**
* SeedLookupTables seed.
*/
class JournalsTablesSeed extends AbstractSeed
{
/**
* Run Method.
*
* Write your database seeder using this method.
*
* More information on writing seeds is available here:
* https://book.cakephp.org/phinx/0/en/seeding.html
*
* @return void
*/
public function run(): void
{
// base types
$stmt = $this->query('SELECT * FROM de_journal_types'); // returns PDOStatement
$existing = $stmt->fetchAll(); // returns the result as an array
if (!$existing) {
$journalTypes = [
[
'de_journal_type_code' => DE_JOURNAL_TYPE_SALES,
],
[
'de_journal_type_code' => DE_JOURNAL_TYPE_PURCHASING,
],
[
'de_journal_type_code' => DE_JOURNAL_TYPE_BANK,
],
[
'de_journal_type_code' => DE_JOURNAL_TYPE_MISC,
],
[
'de_journal_type_code' => DE_JOURNAL_TYPE_CASH,
],
];
$table = $this->table('de_journal_types');
$table->insert($journalTypes)->save();
}
// entity types
$stmt = $this->query('SELECT * FROM de_journals'); // returns PDOStatement
$existing = $stmt->fetchAll(); // returns the result as an array
if (!$existing) {
$entityTypes = [
[
'name' => 'Customer Invoices',
'de_journal_type_code' => DE_JOURNAL_TYPE_SALES,
'short_code' => 'SALES',
],
[
'name' => 'Vendor Bills',
'de_journal_type_code' => DE_JOURNAL_TYPE_PURCHASING,
'short_code' => 'BILLS',
],
[
'name' => 'Bank',
'de_journal_type_code' => DE_JOURNAL_TYPE_BANK,
'short_code' => 'BANK',
],
[
'name' => 'Misc.',
'de_journal_type_code' => DE_JOURNAL_TYPE_MISC,
'short_code' => 'MISC',
],
[
'name' => 'Cash',
'de_journal_type_code' => DE_JOURNAL_TYPE_CASH,
'short_code' => 'CASH',
],
];
$table = $this->table('de_journals');
$table->insert($entityTypes)->save();
}
}
}

View File

@ -0,0 +1,175 @@
<?php
declare(strict_types=1);
use Migrations\AbstractSeed;
/**
* SeedLookupTables seed.
*/
class SeedLookupTablesSeed extends AbstractSeed
{
/**
* Run Method.
*
* Write your database seeder using this method.
*
* More information on writing seeds is available here:
* https://book.cakephp.org/phinx/0/en/seeding.html
*
* @return void
*/
public function run(): void
{
// base types
$stmt = $this->query('SELECT * FROM de_base_types'); // returns PDOStatement
$existing = $stmt->fetchAll(); // returns the result as an array
if (!$existing) {
$baseTypes = [
[
'de_code' => DE_TYPE_CREDIT,
'name' => 'Credit',
],
[
'de_code' => DE_TYPE_DEBIT,
'name' => 'Debit',
],
];
$table = $this->table('de_base_types');
$table->insert($baseTypes)->save();
}
// entity types
$stmt = $this->query('SELECT * FROM de_entity_types'); // returns PDOStatement
$existing = $stmt->fetchAll(); // returns the result as an array
if (!$existing) {
$entityTypes = [
[
'entity_type_code' => DE_ENTITY_TYPE_PERSON,
'name' => 'Person',
],
[
'entity_type_code' => DE_ENTITY_TYPE_ORGANIZATION,
'name' => 'Organization',
],
[
'entity_type_code' => DE_ENTITY_TYPE_PROPERTY,
'name' => 'Property',
],
[
'entity_type_code' => DE_ENTITY_TYPE_BANK_ACCOUNT,
'name' => 'Bank Account',
],
];
$table = $this->table('de_entity_types');
$table->insert($entityTypes)->save();
}
// transaction types
$stmt = $this->query('SELECT * FROM de_transaction_types'); // returns PDOStatement
$existing = $stmt->fetchAll(); // returns the result as an array
if (!$existing) {
$transactionTypes = [
[
'transaction_type_code' => DE_TRANSACTION_TYPE_ADJUST_CREDIT,
'name' => 'Adjust Credit',
],
[
'transaction_type_code' => DE_TRANSACTION_TYPE_ADJUST_DEBIT,
'name' => 'Adjust Debit',
],
[
'transaction_type_code' => DE_TRANSACTION_TYPE_DEPOSIT,
'name' => 'Deposit',
],
[
'transaction_type_code' => DE_TRANSACTION_TYPE_WITHDRAW,
'name' => 'Withdrawal',
],
[
'transaction_type_code' => DE_TRANSACTION_TYPE_ESTIMATE_CREDIT,
'name' => 'Estimate Credit',
],
[
'transaction_type_code' => DE_TRANSACTION_TYPE_ESTIMATE_DEBIT,
'name' => 'Estimate Debit',
]
];
$table = $this->table('de_transaction_types');
$table->insert($transactionTypes)->save();
}
// bank account types
$stmt = $this->query('SELECT * FROM de_bank_account_types'); // returns PDOStatement
$existing = $stmt->fetchAll(); // returns the result as an array
if (!$existing) {
$bankAccountTypes = [
[
'bank_account_type_code' => DE_BANK_ACCOUNT_TYPE_CHECKING,
'de_code' => DE_TYPE_CREDIT,
'name' => 'Checking',
],
[
'bank_account_type_code' => DE_BANK_ACCOUNT_TYPE_SAVINGS,
'de_code' => DE_TYPE_CREDIT,
'name' => 'Savings',
],
[
'bank_account_type_code' => DE_BANK_ACCOUNT_TYPE_LINE_OF_CREDIT,
'de_code' => DE_TYPE_DEBIT,
'name' => 'Line of Credit',
],
[
'bank_account_type_code' => DE_BANK_ACCOUNT_TYPE_MORTGAGE,
'de_code' => DE_TYPE_DEBIT,
'name' => 'Mortgage',
],
];
$table = $this->table('de_bank_account_types');
$table->insert($bankAccountTypes)->save();
}
// account types
$stmt = $this->query('SELECT * FROM de_account_types'); // returns PDOStatement
$existing = $stmt->fetchAll(); // returns the result as an array
if (!$existing) {
$internalAccountTypes = [
[
'account_type_code' => DE_ACCOUNT_TYPE_ASSET,
'name' => 'Asset',
],
[
'account_type_code' => DE_ACCOUNT_TYPE_LIABILITY,
'name' => 'Liability',
],
[
'account_type_code' => DE_ACCOUNT_TYPE_REVENUE,
'name' => 'Revenue',
],
[
'account_type_code' => DE_ACCOUNT_TYPE_EXPENSES,
'name' => 'Expenses',
],
[
'account_type_code' => DE_ACCOUNT_TYPE_EQUITY,
'name' => 'Equity',
],
[
'account_type_code' => DE_ACCOUNT_TYPE_GAIN,
'name' => 'Gain',
],
[
'account_type_code' => DE_ACCOUNT_TYPE_LOSS,
'name' => 'Loss',
],
];
$table = $this->table('de_account_types');
$table->insert($internalAccountTypes)->save();
}
}
}

7
config/bootstrap.php Normal file
View File

@ -0,0 +1,7 @@
<?php
declare(strict_types=1);
/*
* Configure paths required to find CakePHP + general filepath constants
*/
require __DIR__ . DIRECTORY_SEPARATOR . 'constants.php';

56
config/constants.php Normal file
View File

@ -0,0 +1,56 @@
<?php
// double entry types
/*---------------------------------------------*/
const DE_TYPE_CREDIT = 'Cr';
const DE_TYPE_DEBIT = 'Dr';
// entity types
/*---------------------------------------------*/
const DE_ENTITY_TYPE_PERSON = 'H';
const DE_ENTITY_TYPE_ORGANIZATION = 'O';
const DE_ENTITY_TYPE_PROPERTY = 'P';
const DE_ENTITY_TYPE_BANK_ACCOUNT = 'B';
// transaction types
/*---------------------------------------------*/
const DE_TRANSACTION_TYPE_ADJUST_CREDIT = 'AC';
const DE_TRANSACTION_TYPE_ADJUST_DEBIT = 'AD';
const DE_TRANSACTION_TYPE_ESTIMATE_CREDIT = 'EC';
const DE_TRANSACTION_TYPE_ESTIMATE_DEBIT = 'ED';
const DE_TRANSACTION_TYPE_DEPOSIT = 'Dp';
const DE_TRANSACTION_TYPE_WITHDRAW = 'Wd';
// bank account types
/*---------------------------------------------*/
const DE_BANK_ACCOUNT_TYPE_CHECKING = 'Ck';
const DE_BANK_ACCOUNT_TYPE_SAVINGS = 'Sv';
const DE_BANK_ACCOUNT_TYPE_LINE_OF_CREDIT = 'LC';
const DE_BANK_ACCOUNT_TYPE_MORTGAGE = 'M';
// internal account types
/*---------------------------------------------*/
const DE_ACCOUNT_TYPE_ASSET = 'AA';
const DE_ACCOUNT_TYPE_LIABILITY = 'AL';
const DE_ACCOUNT_TYPE_REVENUE = 'RR';
const DE_ACCOUNT_TYPE_EXPENSES = 'RE';
const DE_ACCOUNT_TYPE_EQUITY = 'EQ';
const DE_ACCOUNT_TYPE_GAIN = 'GG';
const DE_ACCOUNT_TYPE_LOSS = 'GL';
const DE_ACCOUNT_TYPE_ROOT = 'R';
// ledger types
/*---------------------------------------------*/
const DE_LEDGER_TYPE_ACCOUNT = 'A'; // account/leaf - can record against
const DE_LEDGER_TYPE_INTERMEDIATE = 'I'; // for summarizing accounts below it
// journal types
const DE_JOURNAL_TYPE_SALES = 'SALES';
const DE_JOURNAL_TYPE_PURCHASING = 'PURCH';
const DE_JOURNAL_TYPE_BANK = 'BANK';
const DE_JOURNAL_TYPE_CASH = 'CASH';
const DE_JOURNAL_TYPE_MISC = 'MISC';

30
phpunit.xml.dist Normal file
View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
colors="true"
processIsolation="false"
stopOnFailure="false"
bootstrap="tests/bootstrap.php"
>
<php>
<ini name="memory_limit" value="-1"/>
<ini name="apc.enable_cli" value="1"/>
</php>
<!-- Add any additional test suites you want to run here -->
<testsuites>
<testsuite name="CakeAccounting">
<directory>tests/TestCase/</directory>
</testsuite>
</testsuites>
<!-- Setup fixture extension -->
<extensions>
<bootstrap class="Cake\TestSuite\Fixture\Extension\PHPUnitExtension"/>
</extensions>
<source>
<include>
<directory suffix=".php">src/</directory>
</include>
</source>
</phpunit>

View File

@ -0,0 +1,99 @@
<?php
declare(strict_types=1);
namespace CakeAccounting;
use App\View\AppView;
use Cake\Console\CommandCollection;
use Cake\Core\BasePlugin;
use Cake\Core\ContainerInterface;
use Cake\Core\PluginApplicationInterface;
use Cake\Http\MiddlewareQueue;
use Cake\Routing\RouteBuilder;
use CakeAccounting\Service\AccountingService;
use CakeAccounting\View\Helper\AccountingHelper;
require __DIR__ . DIRECTORY_SEPARATOR . '..' . DS . 'config' . DS . 'constants.php';
/**
* Plugin for CakeAccounting
*/
class CakeAccountingPlugin extends BasePlugin
{
/**
* Load all the plugin configuration and bootstrap logic.
*
* The host application is provided as an argument. This allows you to load
* additional plugin dependencies, or attach events.
*
* @param \Cake\Core\PluginApplicationInterface $app The host application
* @return void
*/
public function bootstrap(PluginApplicationInterface $app): void
{
}
/**
* Add routes for the plugin.
*
* If your plugin has many routes and you would like to isolate them into a separate file,
* you can create `$plugin/config/routes.php` and delete this method.
*
* @param \Cake\Routing\RouteBuilder $routes The route builder to update.
* @return void
*/
public function routes(RouteBuilder $routes): void
{
$routes->plugin(
'CakeAccounting',
['path' => '/cake-accounting'],
function (RouteBuilder $builder) {
// Add custom routes here
$builder->fallbacks();
}
);
parent::routes($routes);
}
/**
* Add middleware for the plugin.
*
* @param \Cake\Http\MiddlewareQueue $middlewareQueue The middleware queue to update.
* @return \Cake\Http\MiddlewareQueue
*/
public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue
{
// Add your middlewares here
return $middlewareQueue;
}
/**
* Add commands for the plugin.
*
* @param \Cake\Console\CommandCollection $commands The command collection to update.
* @return \Cake\Console\CommandCollection
*/
public function console(CommandCollection $commands): CommandCollection
{
// Add your commands here
$commands = parent::console($commands);
return $commands;
}
/**
* Register application container services.
*
* @param \Cake\Core\ContainerInterface $container The Container to update.
* @return void
* @link https://book.cakephp.org/4/en/development/dependency-injection.html#dependency-injection
*/
public function services(ContainerInterface $container): void
{
// Add your services here
$container->add(AccountingService::class);
}
}

View File

@ -0,0 +1,10 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Controller;
use App\Controller\AppController as BaseController;
class AppController extends BaseController
{
}

View File

@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Controller\Component;
use Cake\Controller\Component;
use Cake\Controller\ComponentRegistry;
/**
* Accounting component
*/
class AccountingComponent extends Component
{
/**
* Default configuration.
*
* @var array<string, mixed>
*/
protected array $_defaultConfig = [];
}

View File

@ -0,0 +1,105 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Controller;
use CakeAccounting\Controller\AppController;
/**
* DeAccountStatements Controller
*
* @property \CakeAccounting\Model\Table\DeAccountStatementsTable $DeAccountStatements
*/
class DeAccountStatementsController extends AppController
{
/**
* Index method
*
* @return \Cake\Http\Response|null|void Renders view
*/
public function index()
{
$query = $this->DeAccountStatements->find()
->contain(['DeAccounts']);
$deAccountStatements = $this->paginate($query);
$this->set(compact('deAccountStatements'));
}
/**
* View method
*
* @param string|null $id De Account Statement id.
* @return \Cake\Http\Response|null|void Renders view
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
*/
public function view($id = null)
{
$deAccountStatement = $this->DeAccountStatements->get($id, contain: ['DeAccounts']);
$this->set(compact('deAccountStatement'));
}
/**
* Add method
*
* @return \Cake\Http\Response|null|void Redirects on successful add, renders view otherwise.
*/
public function add()
{
$deAccountStatement = $this->DeAccountStatements->newEmptyEntity();
if ($this->request->is('post')) {
$deAccountStatement = $this->DeAccountStatements->patchEntity($deAccountStatement, $this->request->getData());
if ($this->DeAccountStatements->save($deAccountStatement)) {
$this->Flash->success(__('The de account statement has been saved.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('The de account statement could not be saved. Please, try again.'));
}
$deAccounts = $this->DeAccountStatements->DeAccounts->find('list', limit: 200)->all();
$this->set(compact('deAccountStatement', 'deAccounts'));
}
/**
* Edit method
*
* @param string|null $id De Account Statement id.
* @return \Cake\Http\Response|null|void Redirects on successful edit, renders view otherwise.
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
*/
public function edit($id = null)
{
$deAccountStatement = $this->DeAccountStatements->get($id, contain: []);
if ($this->request->is(['patch', 'post', 'put'])) {
$deAccountStatement = $this->DeAccountStatements->patchEntity($deAccountStatement, $this->request->getData());
if ($this->DeAccountStatements->save($deAccountStatement)) {
$this->Flash->success(__('The de account statement has been saved.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('The de account statement could not be saved. Please, try again.'));
}
$deAccounts = $this->DeAccountStatements->DeAccounts->find('list', limit: 200)->all();
$this->set(compact('deAccountStatement', 'deAccounts'));
}
/**
* Delete method
*
* @param string|null $id De Account Statement id.
* @return \Cake\Http\Response|null Redirects to index.
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
*/
public function delete($id = null)
{
$this->request->allowMethod(['post', 'delete']);
$deAccountStatement = $this->DeAccountStatements->get($id);
if ($this->DeAccountStatements->delete($deAccountStatement)) {
$this->Flash->success(__('The de account statement has been deleted.'));
} else {
$this->Flash->error(__('The de account statement could not be deleted. Please, try again.'));
}
return $this->redirect(['action' => 'index']);
}
}

View File

@ -0,0 +1,142 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Controller;
use Cake\Log\Log;
use CakeAccounting\Controller\AppController;
/**
* DeAccountTemplates Controller
*
* @property \CakeAccounting\Model\Table\DeAccountTemplatesTable $DeAccountTemplates
*/
class DeAccountTemplatesController extends AppController
{
/**
* Index method
*
* @return \Cake\Http\Response|null|void Renders view
*/
public function index()
{
$query = $this->DeAccountTemplates->find();
$deAccountTemplates = $this->paginate($query);
$this->set(compact('deAccountTemplates'));
}
/**
* select method
*
* @param string|null $id De Account Template id.
* @return \Cake\Http\Response|null Redirects to index.
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
*/
public function select($id = null)
{
$mainDeAccountsTable = $this->getTableLocator()->get('CakeAccounting.DeAccounts');
$this->request->allowMethod(['post']);
$deAccountTemplate = $this->DeAccountTemplates->get($id);
$accounts = $this->DeAccountTemplates->DeTemplatedAccounts->find('threaded')
->where(['account_template_id' => $id])
// ->where(['parent_id IS' => null])
->toArray();
$newAccountData = [];
$added = [];
foreach ($accounts as $account) {
$mainDeAccountsTable->importAccountFromTemplatedAccount($account);
}
$newAccounts = $mainDeAccountsTable->find()->count();
if ($newAccounts >= count($accounts)) {
$this->Flash->success(__('Imported Accounts from Accounts Template: ' . $deAccountTemplate->name));
} else {
$this->Flash->error(__('Failed to import Accounts from Accounts Template: ' . $deAccountTemplate->name));
}
return $this->redirect([
'controller' => 'DeAccounts',
'action' => 'index'
]);
}
/**
* View method
*
* @param string|null $id De Account Template id.
* @return \Cake\Http\Response|null|void Renders view
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
*/
public function view($id = null)
{
$deAccountTemplate = $this->DeAccountTemplates->get($id, contain: ['DeTemplatedAccounts']);
$this->set(compact('deAccountTemplate'));
}
/**
* Add method
*
* @return \Cake\Http\Response|null|void Redirects on successful add, renders view otherwise.
*/
public function add()
{
$deAccountTemplate = $this->DeAccountTemplates->newEmptyEntity();
if ($this->request->is('post')) {
$postData = $this->request->getData();
$deAccountTemplate = $this->DeAccountTemplates->patchEntity($deAccountTemplate, $postData);
if ($this->DeAccountTemplates->save($deAccountTemplate)) {
$this->Flash->success(__('The de account template has been saved.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('The de account template could not be saved. Please, try again.'));
}
$this->set(compact('deAccountTemplate'));
}
/**
* Edit method
*
* @param string|null $id De Account Template id.
* @return \Cake\Http\Response|null|void Redirects on successful edit, renders view otherwise.
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
*/
public function edit($id = null)
{
$deAccountTemplate = $this->DeAccountTemplates->get($id, contain: []);
if ($this->request->is(['patch', 'post', 'put'])) {
$deAccountTemplate = $this->DeAccountTemplates->patchEntity($deAccountTemplate, $this->request->getData());
if ($this->DeAccountTemplates->save($deAccountTemplate)) {
$this->Flash->success(__('The de account template has been saved.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('The de account template could not be saved. Please, try again.'));
}
$this->set(compact('deAccountTemplate'));
}
/**
* Delete method
*
* @param string|null $id De Account Template id.
* @return \Cake\Http\Response|null Redirects to index.
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
*/
public function delete($id = null)
{
$this->request->allowMethod(['post', 'delete']);
$deAccountTemplate = $this->DeAccountTemplates->get($id);
if ($this->DeAccountTemplates->delete($deAccountTemplate)) {
$this->Flash->success(__('The de account template has been deleted.'));
} else {
$this->Flash->error(__('The de account template could not be deleted. Please, try again.'));
}
return $this->redirect(['action' => 'index']);
}
}

View File

@ -0,0 +1,177 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Controller;
use Cake\Event\EventInterface;
use Cake\Log\Log;
use CakeAccounting\Controller\AppController;
use CakeAccounting\Service\AccountingService;
/**
* DeAccounts Controller
*
* @property \CakeAccounting\Model\Table\DeAccountsTable $DeAccounts
*/
class DeAccountsController extends AppController
{
/**
* @param EventInterface $event
*
* @return void
*/
public function beforeRender(EventInterface $event)
{
parent::beforeRender($event);
$this->viewBuilder()->addHelper('CakeAccounting.Accounting');
}
/**
* Index method
*
* @return \Cake\Http\Response|null|void Renders view
*/
public function index(AccountingService $accounting)
{
$deAccounts = $this->DeAccounts->find('threaded')->contain(['DeAccountTypes'])->toArray();
$totals = [];
foreach ($deAccounts as $deAccount) {
// Log::debug('account in de accounts controller index for loop');
// Log::debug('$deAccount->account_number');
// Log::debug("$deAccount->account_number");
$totals[$deAccount->account_number] = $accounting->getAccountBalance($deAccount);
}
$this->set(compact('deAccounts', 'totals'));
}
/**
* View method
*
* @param string|null $accountNumber De Account account number.
* @return \Cake\Http\Response|null|void Renders view
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
*/
public function view(AccountingService $accounting, $accountNumber = null, )
{
$deAccount = $this->DeAccounts->find()
->contain(['DeAccountTypes', 'DeAccountStatements'])
->where(['DeAccounts.account_number' => $accountNumber])
->firstOrFail();
$deAccount->children = $this->DeAccounts->find('children', for: $deAccount->id)->find('threaded')->toArray();
$totals[$deAccount->account_number] = $accounting->getAccountBalance($deAccount);
$this->set(compact('deAccount', 'totals'));
}
/**
* Add method
*
* @return \Cake\Http\Response|null|void Redirects on successful add, renders view otherwise.
*/
public function add()
{
$deAccount = $this->DeAccounts->newEmptyEntity();
if ($this->request->is('post')) {
$postData = $this->request->getData();
if ($this->request->getData('parent_id')) {
$parent = $this->DeAccounts->find()->where(['DeAccounts.account_number' => $this->request->getData('parent_id')])->first();
if (isset($parent)) {
$postData['parent_id'] = $parent->id;
$postData['account_type_code'] = $parent->account_type_code;
}
}
$deAccount = $this->DeAccounts->patchEntity($deAccount, $postData);
if ($this->DeAccounts->save($deAccount)) {
$this->Flash->success(__('The de account has been saved.'));
return $this->redirect(['action' => 'index']);
}
Log::debug(print_r('$deAccount->getErrors() adding', true));
Log::debug(print_r($deAccount->getErrors(), true));
$this->Flash->error(__('The de account could not be saved. Please, try again.'));
}
$deAccountTypes = $this->DeAccounts->DeAccountTypes->find('list', limit: 200)->all();
$accounts = $this->DeAccounts->find('accountTreeList')->toArray();
$this->set(compact('deAccount', 'deAccountTypes', 'accounts'));
}
/**
* Edit method
*
* @param string|null $accountNumber De Account account number.
* @return \Cake\Http\Response|null|void Redirects on successful edit, renders view otherwise.
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
*/
public function edit($accountNumber = null)
{
$deAccount = $this->DeAccounts->find()
->where(['DeAccounts.account_number' => $accountNumber])
->firstOrFail();
$children = $this->DeAccounts->find()->where(['parent_id' => $deAccount->id])->count();
$journalItems = $this->DeAccounts->CreditDeJournalItems->find()
->where([
'OR' => [
'account_number_credit' => $accountNumber,
'account_number_debit' => $accountNumber,
],
])
->count();
if ($children) {
$this->Flash->error('Account cannot be edited as there are are sub-accounts underneath this account.');
}
if ($journalItems) {
$this->Flash->error('Account cannot be edited as journal entries already exist on this account.');
}
if ($children || $journalItems) {
return $this->redirect(['action' => 'view', $accountNumber]);
}
if ($this->request->is(['patch', 'post', 'put'])) {
$postData = $this->request->getData();
if ($this->request->getData('parent_id')) {
$parent = $this->DeAccounts->find()->where(['DeAccounts.account_number' => $this->request->getData('parent_id')])->first();
if (isset($parent)) {
$postData['parent_id'] = $parent->id;
$postData['account_type_code'] = $parent->account_type_code;
}
}
$deAccount = $this->DeAccounts->patchEntity($deAccount, $postData);
if ($this->DeAccounts->save($deAccount)) {
$this->Flash->success(__('The de account has been saved.'));
return $this->redirect(['action' => 'index']);
}
Log::debug(print_r('$deAccount->getErrors() editing', true));
Log::debug(print_r($deAccount->getErrors(), true));
$this->Flash->error(__('The de account could not be saved. Please, try again.'));
}
$deAccountTypes = $this->DeAccounts->DeAccountTypes->find('list', limit: 200)->all();
$parentDeAccounts = $this->DeAccounts->ParentDeAccounts->find('list', limit: 200)->all();
$this->set(compact('deAccount', 'deAccountTypes', 'parentDeAccounts'));
}
/**
* Delete method
*
* @param string|null $accountNumber De Account id.
* @return \Cake\Http\Response|null Redirects to index.
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
*/
public function delete($accountNumber = null)
{
$this->request->allowMethod(['post', 'delete']);
$deAccount = $this->DeAccounts->find()
->where(['DeAccounts.account_number' => $accountNumber])
->firstOrFail();
if ($this->DeAccounts->delete($deAccount)) {
$this->Flash->success(__('The de account has been deleted.'));
} else {
$this->Flash->error(__('The de account could not be deleted. Please, try again.'));
}
return $this->redirect(['action' => 'index']);
}
}

View File

@ -0,0 +1,43 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Controller;
use Cake\Datasource\Exception\RecordNotFoundException;
use Cake\Http\Response;
use CakeAccounting\Controller\AppController;
use CakeAccounting\Model\Table\DeExternalAccountStatementsTable;
/**
* DeExternalAccountStatements Controller
*
* @property DeExternalAccountStatementsTable $DeExternalAccountStatements
*/
class DeExternalAccountStatementsController extends AppController
{
/**
* Index method
*
* @return Response|null|void Renders view
*/
public function index()
{
$query = $this->DeExternalAccountStatements->find();
$deExternalAccountStatements = $this->paginate($query);
$this->set(compact('deExternalAccountStatements'));
}
/**
* View method
*
* @param string|null $id De External Account Statement id.
* @return Response|null|void Renders view
* @throws RecordNotFoundException When record not found.
*/
public function view($id = null)
{
$deExternalAccountStatement = $this->DeExternalAccountStatements->get($id, contain: []);
$this->set(compact('deExternalAccountStatement'));
}
}

View File

@ -0,0 +1,102 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Controller;
use CakeAccounting\Controller\AppController;
/**
* DeExternalAccounts Controller
*
* @property \CakeAccounting\Model\Table\DeExternalAccountsTable $DeExternalAccounts
*/
class DeExternalAccountsController extends AppController
{
/**
* Index method
*
* @return \Cake\Http\Response|null|void Renders view
*/
public function index()
{
$query = $this->DeExternalAccounts->find();
$deExternalAccounts = $this->paginate($query);
$this->set(compact('deExternalAccounts'));
}
/**
* View method
*
* @param string|null $id De External Account id.
* @return \Cake\Http\Response|null|void Renders view
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
*/
public function view($id = null)
{
$deExternalAccount = $this->DeExternalAccounts->get($id, contain: []);
$this->set(compact('deExternalAccount'));
}
/**
* Add method
*
* @return \Cake\Http\Response|null|void Redirects on successful add, renders view otherwise.
*/
public function add()
{
$deExternalAccount = $this->DeExternalAccounts->newEmptyEntity();
if ($this->request->is('post')) {
$deExternalAccount = $this->DeExternalAccounts->patchEntity($deExternalAccount, $this->request->getData());
if ($this->DeExternalAccounts->save($deExternalAccount)) {
$this->Flash->success(__('The de external account has been saved.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('The de external account could not be saved. Please, try again.'));
}
$this->set(compact('deExternalAccount'));
}
/**
* Edit method
*
* @param string|null $id De External Account id.
* @return \Cake\Http\Response|null|void Redirects on successful edit, renders view otherwise.
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
*/
public function edit($id = null)
{
$deExternalAccount = $this->DeExternalAccounts->get($id, contain: []);
if ($this->request->is(['patch', 'post', 'put'])) {
$deExternalAccount = $this->DeExternalAccounts->patchEntity($deExternalAccount, $this->request->getData());
if ($this->DeExternalAccounts->save($deExternalAccount)) {
$this->Flash->success(__('The de external account has been saved.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('The de external account could not be saved. Please, try again.'));
}
$this->set(compact('deExternalAccount'));
}
/**
* Delete method
*
* @param string|null $id De External Account id.
* @return \Cake\Http\Response|null Redirects to index.
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
*/
public function delete($id = null)
{
$this->request->allowMethod(['post', 'delete']);
$deExternalAccount = $this->DeExternalAccounts->get($id);
if ($this->DeExternalAccounts->delete($deExternalAccount)) {
$this->Flash->success(__('The de external account has been deleted.'));
} else {
$this->Flash->error(__('The de external account could not be deleted. Please, try again.'));
}
return $this->redirect(['action' => 'index']);
}
}

View File

@ -0,0 +1,79 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Controller;
use Cake\Log\Log;
use Cake\ORM\TableRegistry;
use CakeAccounting\Controller\AppController;
/**
* DeJournalEntries Controller
*
* @property \CakeAccounting\Model\Table\DeJournalEntriesTable $DeJournalEntries
*/
class DeJournalEntriesController extends AppController
{
/**
* Index method
*
* @return \Cake\Http\Response|null|void Renders view
*/
public function index()
{
$query = $this->DeJournalEntries->find()
->contain(['DeJournals']);
$deJournalEntries = $this->paginate($query);
$this->set(compact('deJournalEntries'));
}
/**
* View method
*
* @param string|null $id De Journal Entry id.
* @return \Cake\Http\Response|null|void Renders view
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
*/
public function view($id = null)
{
$deJournalEntry = $this->DeJournalEntries->get($id,
contain: ['DeJournals', 'DeJournalItems']
);
$this->set(compact('deJournalEntry'));
}
/**
* Add method
*
* @return \Cake\Http\Response|null|void Redirects on successful add, renders view otherwise.
*/
public function add()
{
$deJournalEntry = $this->DeJournalEntries->newEmptyEntity();
if ($this->request->is('post')) {
$postData = $this->request->getData();
$saveOptions = [
'associated' => [
'DeJournalItems',
],
];
if ($this->request->getSession()->read('Auth.User.id')) {
$postData['user_id'] = $this->request->getSession()->read('Auth.User.id');
}
$deJournalEntry = $this->DeJournalEntries->patchEntity($deJournalEntry, $postData, $saveOptions);
if ($this->DeJournalEntries->save($deJournalEntry, $saveOptions)) {
$this->Flash->success(__('The de journal entry has been saved.'));
return $this->redirect(['action' => 'index']);
}
Log::debug(print_r('$deJournalEntry->getErrors()', true));
Log::debug(print_r($deJournalEntry->getErrors(), true));
$this->Flash->error(__('The de journal entry could not be saved. Please, try again.'));
}
$deJournals = $this->DeJournalEntries->DeJournals->find('list', limit: 200)->all();
$accounts = $this->DeJournalEntries->DeJournalItems->CreditDeAccounts->find('accountTreeList')->toArray();
$this->set(compact('deJournalEntry', 'deJournals', 'accounts'));
}
}

View File

@ -0,0 +1,45 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Controller;
use CakeAccounting\Controller\AppController;
/**
* DeJournalItems Controller
*
* @property \CakeAccounting\Model\Table\DeJournalItemsTable $DeJournalItems
*/
class DeJournalItemsController extends AppController
{
/**
* Index method
*
* @return \Cake\Http\Response|null|void Renders view
*/
public function index()
{
$query = $this->DeJournalItems->find()->contain([
'DeJournalEntries',
'DeJournalEntries.DeJournals',
'DebitDeAccounts',
'CreditDeAccounts',
]);
$deJournalItems = $this->paginate($query);
$this->set(compact('deJournalItems'));
}
/**
* View method
*
* @param string|null $id De Journal Item id.
* @return \Cake\Http\Response|null|void Renders view
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
*/
public function view($id = null)
{
$deJournalItem = $this->DeJournalItems->get($id, contain: ['DeJournalEntries']);
$this->set(compact('deJournalItem'));
}
}

View File

@ -0,0 +1,105 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Controller;
use Cake\Datasource\Exception\RecordNotFoundException;
use Cake\Http\Response;
use CakeAccounting\Controller\AppController;
use CakeAccounting\Model\Table\DeJournalsTable;
/**
* DeJournals Controller
*
* @property DeJournalsTable $DeJournals
*/
class DeJournalsController extends AppController
{
/**
* Index method
*
* @return Response|null|void Renders view
*/
public function index()
{
$query = $this->DeJournals->find();
$deJournals = $this->paginate($query);
$this->set(compact('deJournals'));
}
/**
* View method
*
* @param string|null $id De Journal id.
* @return Response|null|void Renders view
* @throws RecordNotFoundException When record not found.
*/
public function view($id = null)
{
$deJournal = $this->DeJournals->get($id, contain: ['DeJournalEntries']);
$this->set(compact('deJournal'));
}
/**
* Add method
*
* @return Response|null|void Redirects on successful add, renders view otherwise.
*/
public function add()
{
$deJournal = $this->DeJournals->newEmptyEntity();
if ($this->request->is('post')) {
$deJournal = $this->DeJournals->patchEntity($deJournal, $this->request->getData());
if ($this->DeJournals->save($deJournal)) {
$this->Flash->success(__('The de journal has been saved.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('The de journal could not be saved. Please, try again.'));
}
$this->set(compact('deJournal'));
}
/**
* Edit method
*
* @param string|null $id De Journal id.
* @return Response|null|void Redirects on successful edit, renders view otherwise.
* @throws RecordNotFoundException When record not found.
*/
public function edit($id = null)
{
$deJournal = $this->DeJournals->get($id, contain: []);
if ($this->request->is(['patch', 'post', 'put'])) {
$deJournal = $this->DeJournals->patchEntity($deJournal, $this->request->getData());
if ($this->DeJournals->save($deJournal)) {
$this->Flash->success(__('The de journal has been saved.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('The de journal could not be saved. Please, try again.'));
}
$this->set(compact('deJournal'));
}
/**
* Delete method
*
* @param string|null $id De Journal id.
* @return Response|null Redirects to index.
* @throws RecordNotFoundException When record not found.
*/
public function delete($id = null)
{
$this->request->allowMethod(['post', 'delete']);
$deJournal = $this->DeJournals->get($id);
if ($this->DeJournals->delete($deJournal)) {
$this->Flash->success(__('The de journal has been deleted.'));
} else {
$this->Flash->error(__('The de journal could not be deleted. Please, try again.'));
}
return $this->redirect(['action' => 'index']);
}
}

View File

@ -0,0 +1,100 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Controller;
use Cake\Log\Log;
use CakeAccounting\Controller\AppController;
/**
* DeAccountTemplates Controller
*
* @property \CakeAccounting\Model\Table\DeAccountTemplatesTable $DeAccountTemplates
*/
class DeAccountTemplatesController extends AppController
{
/**
* select method
*
* @return \Cake\Http\Response|null|void Renders view
*/
public function index()
{
$query = $this->DeAccountTemplates->find();
$deAccountTemplates = $this->paginate($query);
$this->set(compact('deAccountTemplates'));
}
/**
* View method
*
* @param string|null $id De Account Template id.
* @return \Cake\Http\Response|null|void Renders view
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
*/
public function view($id = null)
{
$deAccountTemplate = $this->DeAccountTemplates->get($id, contain: []);
$this->set(compact('deAccountTemplate'));
}
/**
* select method
*
* @param string|null $id De Account Template id.
* @return \Cake\Http\Response|null Redirects to index.
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
*/
public function select($id = null)
{
$mainDeAccountsTable = $this->getTableLocator()->get('CakeAccounting.DeAccounts');
$this->request->allowMethod(['post']);
$deAccountTemplate = $this->DeAccountTemplates->get($id);
$ledgers = $this->DeAccountTemplates->DeTemplatedAccounts->find('threaded')
->where(['account_template_id' => $id])
// ->where(['parent_id IS' => null])
->toArray();
// Log::debug(print_r('$rootAccounts', true));
// Log::debug(print_r($rootAccounts, true));
$newAccountData = [];
$added = [];
foreach ($ledgers as $ledger) {
$importResult = $mainDeAccountsTable->importAccountFromTemplatedAccount($ledger);
Log::debug(print_r('$importResult', true));
Log::debug(print_r($importResult, true));
}
$newAccounts = $mainDeAccountsTable->find()->count();
if ($newAccounts >= count($ledgers)) {
$this->Flash->success(__('Imported Accounts from Accounts Template: ' . $deAccountTemplate->name));
} else {
$this->Flash->error(__('Failed to import Accounts from Accounts Template: ' . $deAccountTemplate->name));
}
return $this->redirect(['action' => 'index']);
}
/**
* Delete method
*
* @param string|null $id De Account Template id.
* @return \Cake\Http\Response|null Redirects to index.
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
*/
public function delete($id = null)
{
$this->request->allowMethod(['post', 'delete']);
$deAccountTemplate = $this->DeAccountTemplates->get($id);
if ($this->DeAccountTemplates->delete($deAccountTemplate)) {
$this->Flash->success(__('The de ledger template has been deleted.'));
} else {
$this->Flash->error(__('The de ledger template could not be deleted. Please, try again.'));
}
return $this->redirect(['action' => 'index']);
}
}

View File

@ -0,0 +1,57 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Model\Entity;
use Cake\ORM\Entity;
/**
* DeAccount Entity
*
* @property int $id
* @property int $account_number
* @property int|null $parent_id
* @property int $lft
* @property int $rght
* @property string $account_type_code
* @property string $name
* @property int|null $account_limit
* @property bool $can_credit
* @property bool $can_debit
*
* @property \CakeAccounting\Model\Entity\ParentDeAccount $parent_de_account
* @property \CakeAccounting\Model\Entity\ChildDeAccount[] $child_de_accounts
*/
class DeAccount extends Entity
{
/**
* Fields that can be mass assigned using newEntity() or patchEntity().
*
* Note that when '*' is set to true, this allows all unspecified fields to
* be mass assigned. For security purposes, it is advised to set '*' to false
* (or remove it), and explicitly make individual fields accessible as needed.
*
* @var array<string, bool>
*/
protected array $_accessible = [
'account_number' => true,
'parent_id' => true,
'lft' => true,
'rght' => true,
'account_type_code' => true,
'name' => true,
'account_limit' => true,
'can_credit' => true,
'can_debit' => true,
'parent_de_account' => true,
'child_de_accounts' => true,
];
/**
* @return string
*/
protected function _getAccountNumberAndName()
{
return $this->account_number . ' : ' . $this->name;
}
}

View File

@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Model\Entity;
use Cake\ORM\Entity;
/**
* DeAccountStatement Entity
*
* @property int $account_number
* @property \Cake\I18n\Date $statement_date
* @property string $closing_balance
*/
class DeAccountStatement extends Entity
{
/**
* Fields that can be mass assigned using newEntity() or patchEntity().
*
* Note that when '*' is set to true, this allows all unspecified fields to
* be mass assigned. For security purposes, it is advised to set '*' to false
* (or remove it), and explicitly make individual fields accessible as needed.
*
* @var array<string, bool>
*/
protected array $_accessible = [
'account_number' => true,
'statement_date' => true,
'closing_balance' => true,
];
}

View File

@ -0,0 +1,30 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Model\Entity;
use Cake\ORM\Entity;
/**
* DeAccountTemplate Entity
*
* @property int $id
* @property string $name
* @property \Cake\I18n\DateTime|null $deleted
*/
class DeAccountTemplate extends Entity
{
/**
* Fields that can be mass assigned using newEntity() or patchEntity().
*
* Note that when '*' is set to true, this allows all unspecified fields to
* be mass assigned. For security purposes, it is advised to set '*' to false
* (or remove it), and explicitly make individual fields accessible as needed.
*
* @var array<string, bool>
*/
protected array $_accessible = [
'name' => true,
'deleted' => true,
];
}

View File

@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Model\Entity;
use Cake\ORM\Entity;
/**
* DeAccountType Entity
*
* @property string $account_type_code
* @property string $name
*/
class DeAccountType extends Entity
{
/**
* Fields that can be mass assigned using newEntity() or patchEntity().
*
* Note that when '*' is set to true, this allows all unspecified fields to
* be mass assigned. For security purposes, it is advised to set '*' to false
* (or remove it), and explicitly make individual fields accessible as needed.
*
* @var array<string, bool>
*/
protected array $_accessible = [
'name' => true,
];
}

View File

@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Model\Entity;
use Cake\ORM\Entity;
/**
* DeBankAccountType Entity
*
* @property string $bank_account_type_code
* @property string $de_code
* @property string $name
*
* @property \CakeAccounting\Model\Entity\DeBaseType $de_base_type
*/
class DeBankAccountType extends Entity
{
/**
* Fields that can be mass assigned using newEntity() or patchEntity().
*
* Note that when '*' is set to true, this allows all unspecified fields to
* be mass assigned. For security purposes, it is advised to set '*' to false
* (or remove it), and explicitly make individual fields accessible as needed.
*
* @var array<string, bool>
*/
protected array $_accessible = [
'de_code' => true,
'name' => true,
'de_base_type' => true,
];
}

View File

@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Model\Entity;
use Cake\ORM\Entity;
/**
* DeBaseType Entity
*
* @property string $de_code
* @property string $name
*/
class DeBaseType extends Entity
{
/**
* Fields that can be mass assigned using newEntity() or patchEntity().
*
* Note that when '*' is set to true, this allows all unspecified fields to
* be mass assigned. For security purposes, it is advised to set '*' to false
* (or remove it), and explicitly make individual fields accessible as needed.
*
* @var array<string, bool>
*/
protected array $_accessible = [
'name' => true,
];
}

View File

@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Model\Entity;
use Cake\ORM\Entity;
/**
* DeEntityType Entity
*
* @property string $entity_type_code
* @property string $name
*/
class DeEntityType extends Entity
{
/**
* Fields that can be mass assigned using newEntity() or patchEntity().
*
* Note that when '*' is set to true, this allows all unspecified fields to
* be mass assigned. For security purposes, it is advised to set '*' to false
* (or remove it), and explicitly make individual fields accessible as needed.
*
* @var array<string, bool>
*/
protected array $_accessible = [
'name' => true,
];
}

View File

@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Model\Entity;
use Cake\ORM\Entity;
/**
* DeExternalAccount Entity
*
* @property string $external_account_number
* @property string $entity_type_code
* @property \Cake\I18n\DateTime $created
* @property string|null $related_model
* @property int|null $related_model_fk
*/
class DeExternalAccount extends Entity
{
/**
* Fields that can be mass assigned using newEntity() or patchEntity().
*
* Note that when '*' is set to true, this allows all unspecified fields to
* be mass assigned. For security purposes, it is advised to set '*' to false
* (or remove it), and explicitly make individual fields accessible as needed.
*
* @var array<string, bool>
*/
protected array $_accessible = [
'entity_type_code' => true,
'created' => true,
'related_model' => true,
'related_model_fk' => true,
];
}

View File

@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Model\Entity;
use Cake\ORM\Entity;
/**
* DeExternalAccountStatement Entity
*
* @property string $external_account_number
* @property \Cake\I18n\Date $statement_date
* @property string $closing_balance
* @property string $total_credit
* @property string $total_debit
*/
class DeExternalAccountStatement extends Entity
{
/**
* Fields that can be mass assigned using newEntity() or patchEntity().
*
* Note that when '*' is set to true, this allows all unspecified fields to
* be mass assigned. For security purposes, it is advised to set '*' to false
* (or remove it), and explicitly make individual fields accessible as needed.
*
* @var array<string, bool>
*/
protected array $_accessible = [
'closing_balance' => true,
'total_credit' => true,
'total_debit' => true,
];
}

View File

@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Model\Entity;
use Cake\ORM\Entity;
/**
* DeJournal Entity
*
* @property int $id
* @property string $name
* @property string $short_code
* @property int|null $default_account_number_credit
* @property int|null $default_account_number_debit
* @property string $de_journal_type_code
*
* @property \CakeAccounting\Model\Entity\DeJournalEntry[] $de_journal_entries
*/
class DeJournal extends Entity
{
/**
* Fields that can be mass assigned using newEntity() or patchEntity().
*
* Note that when '*' is set to true, this allows all unspecified fields to
* be mass assigned. For security purposes, it is advised to set '*' to false
* (or remove it), and explicitly make individual fields accessible as needed.
*
* @var array<string, bool>
*/
protected array $_accessible = [
'name' => true,
'short_code' => true,
'default_account_number_credit' => true,
'default_account_number_debit' => true,
'de_journal_type_code' => true,
'de_journal_entries' => true,
];
}

View File

@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Model\Entity;
use Cake\ORM\Entity;
/**
* DeJournalEntry Entity
*
* @property int $id
* @property int $de_journal_id
* @property int|null $user_id
* @property \Cake\I18n\DateTime $created
* @property string|null $notes
*
* @property \CakeAccounting\Model\Entity\DeJournal $de_journal
* @property \CakeAccounting\Model\Entity\User $user
* @property \CakeAccounting\Model\Entity\DeJournalItem[] $de_journal_items
*/
class DeJournalEntry extends Entity
{
/**
* Fields that can be mass assigned using newEntity() or patchEntity().
*
* Note that when '*' is set to true, this allows all unspecified fields to
* be mass assigned. For security purposes, it is advised to set '*' to false
* (or remove it), and explicitly make individual fields accessible as needed.
*
* @var array<string, bool>
*/
protected array $_accessible = [
'de_journal_id' => true,
'user_id' => true,
'created' => true,
'notes' => true,
'de_journal' => true,
'user' => true,
'de_journal_items' => true,
];
}

View File

@ -0,0 +1,43 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Model\Entity;
use Cake\ORM\Entity;
/**
* DeJournalItem Entity
*
* @property int $id
* @property int $account_number_credit
* @property int $account_number_debit
* @property int|null $external_account_number_credit
* @property int|null $external_account_number_debit
* @property int $de_journal_entry_id
* @property string $amount
* @property \Cake\I18n\DateTime $created
*
* @property \CakeAccounting\Model\Entity\DeJournalEntry $de_journal_entry
*/
class DeJournalItem extends Entity
{
/**
* Fields that can be mass assigned using newEntity() or patchEntity().
*
* Note that when '*' is set to true, this allows all unspecified fields to
* be mass assigned. For security purposes, it is advised to set '*' to false
* (or remove it), and explicitly make individual fields accessible as needed.
*
* @var array<string, bool>
*/
protected array $_accessible = [
'account_number_credit' => true,
'account_number_debit' => true,
'external_account_number_credit' => true,
'external_account_number_debit' => true,
'de_journal_entry_id' => true,
'amount' => true,
'created' => true,
'de_journal_entry' => true,
];
}

View File

@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Model\Entity;
use Cake\ORM\Entity;
/**
* DeJournalType Entity
*
* @property string $de_journal_type_code
*/
class DeJournalType extends Entity
{
/**
* Fields that can be mass assigned using newEntity() or patchEntity().
*
* Note that when '*' is set to true, this allows all unspecified fields to
* be mass assigned. For security purposes, it is advised to set '*' to false
* (or remove it), and explicitly make individual fields accessible as needed.
*
* @var array<string, bool>
*/
protected array $_accessible = [
'*' => true,
'de_journal_type_code' => false,
];
}

View File

@ -0,0 +1,51 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Model\Entity;
use Cake\ORM\Entity;
/**
* DeTemplatedAccount Entity
*
* @property int $id
* @property int $account_number
* @property int $account_template_id
* @property int|null $parent_id
* @property int $lft
* @property int $rght
* @property string $account_type_code
* @property int|null $account_limit
* @property bool $can_credit
* @property bool $can_debit
* @property string $name
*
* @property \CakeAccounting\Model\Entity\ParentDeTemplatedAccount $parent_de_templated_account
* @property \CakeAccounting\Model\Entity\ChildDeTemplatedAccount[] $child_de_templated_accounts
*/
class DeTemplatedAccount extends Entity
{
/**
* Fields that can be mass assigned using newEntity() or patchEntity().
*
* Note that when '*' is set to true, this allows all unspecified fields to
* be mass assigned. For security purposes, it is advised to set '*' to false
* (or remove it), and explicitly make individual fields accessible as needed.
*
* @var array<string, bool>
*/
protected array $_accessible = [
'account_number' => true,
'account_template_id' => true,
'parent_id' => true,
'lft' => true,
'rght' => true,
'account_type_code' => true,
'account_limit' => true,
'can_credit' => true,
'can_debit' => true,
'name' => true,
'parent_de_templated_account' => true,
'child_de_templated_accounts' => true,
];
}

View File

@ -0,0 +1,49 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Model\Entity;
use Cake\ORM\Entity;
/**
* DeTemplatedAccount Entity
*
* @property int $id
* @property int $account_number
* @property int $account_template_id
* @property int|null $parent_id
* @property int $lft
* @property int $rght
* @property string $account_type_code
* @property int|null $limit
* @property bool $can_credit
* @property bool $can_debit
* @property string $name
*
* @property \CakeAccounting\Model\Entity\DeTemplatedAccount $parent_de_templated_ledger
*/
class DeTemplatedAccount extends Entity
{
/**
* Fields that can be mass assigned using newEntity() or patchEntity().
*
* Note that when '*' is set to true, this allows all unspecified fields to
* be mass assigned. For security purposes, it is advised to set '*' to false
* (or remove it), and explicitly make individual fields accessible as needed.
*
* @var array<string, bool>
*/
protected array $_accessible = [
'account_number' => true,
'account_template_id' => true,
'parent_id' => true,
'lft' => true,
'rght' => true,
'account_type_code' => true,
'limit' => true,
'can_credit' => true,
'can_debit' => true,
'name' => true,
'parent_de_templated_ledger' => true,
];
}

View File

@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Model\Entity;
use Cake\ORM\Entity;
/**
* DeTransactionType Entity
*
* @property string $transaction_type_code
* @property string $name
*/
class DeTransactionType extends Entity
{
/**
* Fields that can be mass assigned using newEntity() or patchEntity().
*
* Note that when '*' is set to true, this allows all unspecified fields to
* be mass assigned. For security purposes, it is advised to set '*' to false
* (or remove it), and explicitly make individual fields accessible as needed.
*
* @var array<string, bool>
*/
protected array $_accessible = [
'name' => true,
];
}

View File

@ -0,0 +1,116 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Model\Table;
use Cake\Datasource\EntityInterface;
use Cake\Datasource\ResultSetInterface;
use Cake\Log\Log;
use Cake\ORM\Query\SelectQuery;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
use CakeAccounting\Model\Entity\DeAccount;
use CakeAccounting\Model\Entity\DeAccountStatement;
use Closure;
use Psr\SimpleCache\CacheInterface;
/**
* DeAccountStatements Model
*
* @method DeAccountStatement newEmptyEntity()
* @method DeAccountStatement newEntity(array $data, array $options = [])
* @method array<DeAccountStatement> newEntities(array $data, array $options = [])
* @method DeAccountStatement get(mixed $primaryKey, array|string $finder = 'all', CacheInterface|string|null $cache = null, Closure|string|null $cacheKey = null, mixed ...$args)
* @method DeAccountStatement findOrCreate($search, ?callable $callback = null, array $options = [])
* @method DeAccountStatement patchEntity(EntityInterface $entity, array $data, array $options = [])
* @method array<DeAccountStatement> patchEntities(iterable $entities, array $data, array $options = [])
* @method DeAccountStatement|false save(EntityInterface $entity, array $options = [])
* @method DeAccountStatement saveOrFail(EntityInterface $entity, array $options = [])
* @method iterable<DeAccountStatement>|ResultSetInterface<DeAccountStatement>|false saveMany(iterable $entities, array $options = [])
* @method iterable<DeAccountStatement>|ResultSetInterface<DeAccountStatement> saveManyOrFail(iterable $entities, array $options = [])
* @method iterable<DeAccountStatement>|ResultSetInterface<DeAccountStatement>|false deleteMany(iterable $entities, array $options = [])
* @method iterable<DeAccountStatement>|ResultSetInterface<DeAccountStatement> deleteManyOrFail(iterable $entities, array $options = [])
*/
class DeAccountStatementsTable extends Table
{
/**
* Initialize method
*
* @param array<string, mixed> $config The configuration for the Table.
* @return void
*/
public function initialize(array $config): void
{
parent::initialize($config);
$this->setTable('de_account_statements');
$this->setDisplayField('account_statement_id');
$this->setPrimaryKey('account_statement_id');
$this->belongsTo('DeAccounts', [
'bindingKey' => 'account_number',
'foreignKey' => 'account_number',
'className' => 'CakeAccounting.DeAccounts',
]);
}
/**
* Default validation rules.
*
* @param Validator $validator Validator instance.
* @return Validator
*/
public function validationDefault(Validator $validator): Validator
{
$validator
->uuid('account_statement_id');
$validator
->date('statement_date')
->requirePresence('statement_date', 'create');
$validator
->decimal('closing_balance')
->requirePresence('closing_balance', 'create')
->notEmptyString('closing_balance');
return $validator;
}
/**
* Returns a rules checker object that will be used for validating
* application integrity.
*
* @param RulesChecker $rules The rules object to be modified.
* @return RulesChecker
*/
public function buildRules(RulesChecker $rules): RulesChecker
{
$rules->add($rules->existsIn(['account_number'], 'DeAccounts'), ['errorField' => 'account_number']);
return $rules;
}
/**
* @param DeAccount $deAccount
*
* @return \Cake\Datasource\EntityInterface|false
*/
public function createFirstAccountSatement(DeAccount $deAccount)
{
$statementDate = date('Y') . '-' . date('m') . '-01';
$data = [
'account_number' => $deAccount->account_number,
'statement_date' => $statementDate,
'closing_balance' => 0,
];
$deAccountStatement = $this->newEntity($data);
if ($deAccountStatement->getErrors()) {
Log::debug(print_r('$deAccountStatement->getErrors() creating new/first blank statement', true));
Log::debug(print_r($deAccountStatement->getErrors(), true));
}
return $this->save($deAccountStatement);
}
}

View File

@ -0,0 +1,75 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Model\Table;
use Cake\Datasource\EntityInterface;
use Cake\Datasource\ResultSetInterface;
use Cake\ORM\Query\SelectQuery;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
use CakeAccounting\Model\Entity\DeAccountTemplate;
use Closure;
use Psr\SimpleCache\CacheInterface;
/**
* DeAccountTemplates Model
*
* @method DeAccountTemplate newEmptyEntity()
* @method DeAccountTemplate newEntity(array $data, array $options = [])
* @method array<DeAccountTemplate> newEntities(array $data, array $options = [])
* @method DeAccountTemplate get(mixed $primaryKey, array|string $finder = 'all', CacheInterface|string|null $cache = null, Closure|string|null $cacheKey = null, mixed ...$args)
* @method DeAccountTemplate findOrCreate($search, ?callable $callback = null, array $options = [])
* @method DeAccountTemplate patchEntity(EntityInterface $entity, array $data, array $options = [])
* @method array<DeAccountTemplate> patchEntities(iterable $entities, array $data, array $options = [])
* @method DeAccountTemplate|false save(EntityInterface $entity, array $options = [])
* @method DeAccountTemplate saveOrFail(EntityInterface $entity, array $options = [])
* @method iterable<DeAccountTemplate>|ResultSetInterface<DeAccountTemplate>|false saveMany(iterable $entities, array $options = [])
* @method iterable<DeAccountTemplate>|ResultSetInterface<DeAccountTemplate> saveManyOrFail(iterable $entities, array $options = [])
* @method iterable<DeAccountTemplate>|ResultSetInterface<DeAccountTemplate>|false deleteMany(iterable $entities, array $options = [])
* @method iterable<DeAccountTemplate>|ResultSetInterface<DeAccountTemplate> deleteManyOrFail(iterable $entities, array $options = [])
*/
class DeAccountTemplatesTable extends Table
{
/**
* Initialize method
*
* @param array<string, mixed> $config The configuration for the Table.
* @return void
*/
public function initialize(array $config): void
{
parent::initialize($config);
$this->setTable('de_account_templates');
$this->setDisplayField('name');
$this->setPrimaryKey('id');
$this->hasMany('DeTemplatedAccounts', [
'foreignKey' => 'account_template_id',
'className' => 'CakeAccounting.DeTemplatedAccounts',
]);
}
/**
* Default validation rules.
*
* @param Validator $validator Validator instance.
* @return Validator
*/
public function validationDefault(Validator $validator): Validator
{
$validator
->scalar('name')
->maxLength('name', 45)
->requirePresence('name', 'create')
->notEmptyString('name');
$validator
->dateTime('deleted')
->allowEmptyDateTime('deleted');
return $validator;
}
}

View File

@ -0,0 +1,61 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Model\Table;
use Cake\ORM\Query\SelectQuery;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
/**
* DeAccountTypes Model
*
* @method \CakeAccounting\Model\Entity\DeAccountType newEmptyEntity()
* @method \CakeAccounting\Model\Entity\DeAccountType newEntity(array $data, array $options = [])
* @method array<\CakeAccounting\Model\Entity\DeAccountType> newEntities(array $data, array $options = [])
* @method \CakeAccounting\Model\Entity\DeAccountType get(mixed $primaryKey, array|string $finder = 'all', \Psr\SimpleCache\CacheInterface|string|null $cache = null, \Closure|string|null $cacheKey = null, mixed ...$args)
* @method \CakeAccounting\Model\Entity\DeAccountType findOrCreate($search, ?callable $callback = null, array $options = [])
* @method \CakeAccounting\Model\Entity\DeAccountType patchEntity(\Cake\Datasource\EntityInterface $entity, array $data, array $options = [])
* @method array<\CakeAccounting\Model\Entity\DeAccountType> patchEntities(iterable $entities, array $data, array $options = [])
* @method \CakeAccounting\Model\Entity\DeAccountType|false save(\Cake\Datasource\EntityInterface $entity, array $options = [])
* @method \CakeAccounting\Model\Entity\DeAccountType saveOrFail(\Cake\Datasource\EntityInterface $entity, array $options = [])
* @method iterable<\CakeAccounting\Model\Entity\DeAccountType>|\Cake\Datasource\ResultSetInterface<\CakeAccounting\Model\Entity\DeAccountType>|false saveMany(iterable $entities, array $options = [])
* @method iterable<\CakeAccounting\Model\Entity\DeAccountType>|\Cake\Datasource\ResultSetInterface<\CakeAccounting\Model\Entity\DeAccountType> saveManyOrFail(iterable $entities, array $options = [])
* @method iterable<\CakeAccounting\Model\Entity\DeAccountType>|\Cake\Datasource\ResultSetInterface<\CakeAccounting\Model\Entity\DeAccountType>|false deleteMany(iterable $entities, array $options = [])
* @method iterable<\CakeAccounting\Model\Entity\DeAccountType>|\Cake\Datasource\ResultSetInterface<\CakeAccounting\Model\Entity\DeAccountType> deleteManyOrFail(iterable $entities, array $options = [])
*/
class DeAccountTypesTable extends Table
{
/**
* Initialize method
*
* @param array<string, mixed> $config The configuration for the Table.
* @return void
*/
public function initialize(array $config): void
{
parent::initialize($config);
$this->setTable('de_account_types');
$this->setDisplayField('name');
$this->setPrimaryKey('account_type_code');
}
/**
* Default validation rules.
*
* @param \Cake\Validation\Validator $validator Validator instance.
* @return \Cake\Validation\Validator
*/
public function validationDefault(Validator $validator): Validator
{
$validator
->scalar('name')
->maxLength('name', 45)
->requirePresence('name', 'create')
->notEmptyString('name');
return $validator;
}
}

View File

@ -0,0 +1,253 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Model\Table;
use ArrayObject;
use Cake\Datasource\EntityInterface;
use Cake\Datasource\ResultSetInterface;
use Cake\Core\Exception\CakeException;
use Cake\Event\EventInterface;
use Cake\Log\Log;
use Cake\ORM\Association\BelongsTo;
use Cake\ORM\Association\HasMany;
use Cake\ORM\Behavior\TreeBehavior;
use Cake\ORM\Query;
use Cake\ORM\Query\SelectQuery;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\ORM\TableRegistry;
use Cake\Validation\Validator;
use CakeAccounting\Model\Entity\DeAccount;
use CakeAccounting\Model\Entity\DeTemplatedAccount;
use Closure;
use Psr\SimpleCache\CacheInterface;
/**
* DeAccounts Model
*
* @property DeAccountsTable&BelongsTo $ParentDeAccounts
* @property DeAccountsTable&HasMany $ChildDeAccounts
*
* @method DeAccount newEmptyEntity()
* @method DeAccount newEntity(array $data, array $options = [])
* @method array<DeAccount> newEntities(array $data, array $options = [])
* @method DeAccount get(mixed $primaryKey, array|string $finder = 'all', CacheInterface|string|null $cache = null, Closure|string|null $cacheKey = null, mixed ...$args)
* @method DeAccount findOrCreate($search, ?callable $callback = null, array $options = [])
* @method DeAccount patchEntity(EntityInterface $entity, array $data, array $options = [])
* @method array<DeAccount> patchEntities(iterable $entities, array $data, array $options = [])
* @method DeAccount|false save(EntityInterface $entity, array $options = [])
* @method DeAccount saveOrFail(EntityInterface $entity, array $options = [])
* @method iterable<DeAccount>|ResultSetInterface<DeAccount>|false saveMany(iterable $entities, array $options = [])
* @method iterable<DeAccount>|ResultSetInterface<DeAccount> saveManyOrFail(iterable $entities, array $options = [])
* @method iterable<DeAccount>|ResultSetInterface<DeAccount>|false deleteMany(iterable $entities, array $options = [])
* @method iterable<DeAccount>|ResultSetInterface<DeAccount> deleteManyOrFail(iterable $entities, array $options = [])
*
* @mixin TreeBehavior
*/
class DeAccountsTable extends Table
{
/**
* Initialize method
*
* @param array<string, mixed> $config The configuration for the Table.
* @return void
*/
public function initialize(array $config): void
{
parent::initialize($config);
$this->setTable('de_accounts');
$this->setDisplayField('name');
$this->setPrimaryKey('id');
$this->addBehavior('Tree');
$this->belongsTo('DeAccountTypes', [
'foreignKey' => 'account_type_code',
'bindingKey' => 'account_type_code',
'className' => 'CakeAccounting.DeAccountTypes',
]);
$this->belongsTo('ParentDeAccounts', [
'foreignKey' => 'parent_id',
'className' => 'CakeAccounting.DeAccounts',
]);
$this->hasMany('ChildDeAccounts', [
'foreignKey' => 'parent_id',
'className' => 'CakeAccounting.DeAccounts',
]);
$this->hasMany('DeAccountStatements', [
'foreignKey' => 'account_number',
'className' => 'CakeAccounting.DeAccountStatements',
]);
$this->hasMany('DebitDeJournalItems', [
'bindingKey' => 'account_number',
'foreignKey' => 'debit_account_number',
'className' => 'CakeAccounting.DeJournalItems',
]);
$this->hasMany('CreditDeJournalItems', [
'bindingKey' => 'account_number',
'foreignKey' => 'credit_account_number',
'className' => 'CakeAccounting.DeJournalItems',
]);
}
/**
* Default validation rules.
*
* @param Validator $validator Validator instance.
* @return Validator
*/
public function validationDefault(Validator $validator): Validator
{
$validator
->integer('account_number')
->requirePresence('account_number', 'create')
->notEmptyString('account_number')
->add('account_number', 'unique', ['rule' => 'validateUnique', 'provider' => 'table']);
$validator
->integer('parent_id')
->allowEmptyString('parent_id');
$validator
->scalar('account_type_code')
->maxLength('account_type_code', 2)
->requirePresence('account_type_code', 'create')
->notEmptyString('account_type_code');
$validator
->scalar('name')
->maxLength('name', 255)
->requirePresence('name', 'create')
->notEmptyString('name');
$validator
->integer('account_limit')
->allowEmptyString('account_limit');
$validator
->boolean('can_credit')
->notEmptyString('can_credit');
$validator
->boolean('can_debit')
->notEmptyString('can_debit');
return $validator;
}
/**
* Returns a rules checker object that will be used for validating
* application integrity.
*
* @param RulesChecker $rules The rules object to be modified.
*
* @return RulesChecker
*/
public function buildRules(RulesChecker $rules): RulesChecker
{
$rules->add($rules->isUnique(['account_number']), ['errorField' => 'account_number']);
$rules->add($rules->existsIn(['parent_id'], 'ParentDeAccounts'), ['errorField' => 'parent_id']);
$rules->add($rules->existsIn(['account_type_code'], 'DeAccountTypes'), ['errorField' => 'account_type_code']);
return $rules;
}
/**
* @param EventInterface $event event object
* @param DeAccount|EntityInterface $entity entity just saved
* @param ArrayObject $options save options
*
* @return void
*/
public function afterSave(EventInterface $event, DeAccount|EntityInterface $entity, ArrayObject $options): void
{
if ($entity->isNew()) {
$firstBlankStatement = $this->DeAccountStatements->find()->where(['account_number' => $entity->account_number])->first();
if (!isset($firstBlankStatement)) {
$firstBlankStatement = $this->DeAccountStatements->createFirstAccountSatement($entity);
}
}
}
/**
* @param Query $query The query object to be modified.
* @param array $options finder options - not used in this custom finder
*
* @return Query
*/
public function findAccountTreeList(Query $query, array $options): Query
{
return $query->find('treeList', keyPath: 'account_number', valuePath: 'account_number_and_name');
}
/**
* @param Query $query The query object to be modified.
* @param array $options finder options - not used in this custom finder
*
* @return Query
*/
public function findByAccountNumber(Query $query, array $options): Query
{
if (!array_key_exists('account_number', $options) || !$options['account_number']) {
throw new CakeException('Account not found. Account Number not provided.', 404);
}
return $query->where(['DeAccounts.account_number' => $options['account_number']]);
}
/**
* @param DeTemplatedAccount $deTemplatedAccount
*
* @return DeAccount|false|void
*/
public function importAccountFromTemplatedAccount(DeTemplatedAccount $deTemplatedAccount): DeAccount|bool
{
$templatedAccountsTable = TableRegistry::getTableLocator()->get('CakeAccounting.DeTemplatedAccounts');
$tmpData = $deTemplatedAccount->toArray();
if ($deTemplatedAccount->parent_id) {
Log::debug('parent id set');
$tmpOldParent = $templatedAccountsTable->get($deTemplatedAccount->parent_id);
$tmpNewParent = $this->find()->where(['account_number' => $tmpOldParent->account_number])->first();
if (!isset($tmpNewParent)) {
Log::debug('new parent not set - try to import the old parent now');
$parentImportResult = $this->importAccountFromTemplatedAccount($tmpOldParent);
Log::debug(print_r('$parentImportResult', true));
Log::debug(print_r($parentImportResult, true));
}
$tmpNewParent = $this->find()->where(['account_number' => $tmpOldParent->account_number])->first();
if (!isset($tmpNewParent)) {
Log::debug('failed to get new parent for a second time');
return false;
}
$tmpData['parent_id'] = $tmpNewParent->id;
}
$entity = $this->newEntity($tmpData);
$saveResult = $this->save($entity);
if (!$saveResult) {
Log::debug(print_r('$entity->getErrors()', true));
Log::debug(print_r($entity->getErrors(), true));
}
if (!isset($deTemplatedAccount->children)) {
$deTemplatedAccount->children = $templatedAccountsTable
->find('children', for: $deTemplatedAccount->id)
->find('threaded')
->toArray();
}
if (!isset($deTemplatedAccount->children) || !$deTemplatedAccount->children) {
return $saveResult;
}
$allResult = true;
foreach ($deTemplatedAccount->children as $child) {
if (!$this->importAccountFromTemplatedAccount($child)) {
$allResult = false;
}
}
return $allResult;
}
}

View File

@ -0,0 +1,67 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Model\Table;
use Cake\ORM\Query\SelectQuery;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
/**
* DeBankAccountTypes Model
*
* @method \CakeAccounting\Model\Entity\DeBankAccountType newEmptyEntity()
* @method \CakeAccounting\Model\Entity\DeBankAccountType newEntity(array $data, array $options = [])
* @method array<\CakeAccounting\Model\Entity\DeBankAccountType> newEntities(array $data, array $options = [])
* @method \CakeAccounting\Model\Entity\DeBankAccountType get(mixed $primaryKey, array|string $finder = 'all', \Psr\SimpleCache\CacheInterface|string|null $cache = null, \Closure|string|null $cacheKey = null, mixed ...$args)
* @method \CakeAccounting\Model\Entity\DeBankAccountType findOrCreate($search, ?callable $callback = null, array $options = [])
* @method \CakeAccounting\Model\Entity\DeBankAccountType patchEntity(\Cake\Datasource\EntityInterface $entity, array $data, array $options = [])
* @method array<\CakeAccounting\Model\Entity\DeBankAccountType> patchEntities(iterable $entities, array $data, array $options = [])
* @method \CakeAccounting\Model\Entity\DeBankAccountType|false save(\Cake\Datasource\EntityInterface $entity, array $options = [])
* @method \CakeAccounting\Model\Entity\DeBankAccountType saveOrFail(\Cake\Datasource\EntityInterface $entity, array $options = [])
* @method iterable<\CakeAccounting\Model\Entity\DeBankAccountType>|\Cake\Datasource\ResultSetInterface<\CakeAccounting\Model\Entity\DeBankAccountType>|false saveMany(iterable $entities, array $options = [])
* @method iterable<\CakeAccounting\Model\Entity\DeBankAccountType>|\Cake\Datasource\ResultSetInterface<\CakeAccounting\Model\Entity\DeBankAccountType> saveManyOrFail(iterable $entities, array $options = [])
* @method iterable<\CakeAccounting\Model\Entity\DeBankAccountType>|\Cake\Datasource\ResultSetInterface<\CakeAccounting\Model\Entity\DeBankAccountType>|false deleteMany(iterable $entities, array $options = [])
* @method iterable<\CakeAccounting\Model\Entity\DeBankAccountType>|\Cake\Datasource\ResultSetInterface<\CakeAccounting\Model\Entity\DeBankAccountType> deleteManyOrFail(iterable $entities, array $options = [])
*/
class DeBankAccountTypesTable extends Table
{
/**
* Initialize method
*
* @param array<string, mixed> $config The configuration for the Table.
* @return void
*/
public function initialize(array $config): void
{
parent::initialize($config);
$this->setTable('de_bank_account_types');
$this->setDisplayField('name');
$this->setPrimaryKey('bank_account_type_code');
}
/**
* Default validation rules.
*
* @param \Cake\Validation\Validator $validator Validator instance.
* @return \Cake\Validation\Validator
*/
public function validationDefault(Validator $validator): Validator
{
$validator
->scalar('de_code')
->maxLength('de_code', 2)
->requirePresence('de_code', 'create')
->notEmptyString('de_code');
$validator
->scalar('name')
->maxLength('name', 45)
->requirePresence('name', 'create')
->notEmptyString('name');
return $validator;
}
}

View File

@ -0,0 +1,61 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Model\Table;
use Cake\ORM\Query\SelectQuery;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
/**
* DeBaseTypes Model
*
* @method \CakeAccounting\Model\Entity\DeBaseType newEmptyEntity()
* @method \CakeAccounting\Model\Entity\DeBaseType newEntity(array $data, array $options = [])
* @method array<\CakeAccounting\Model\Entity\DeBaseType> newEntities(array $data, array $options = [])
* @method \CakeAccounting\Model\Entity\DeBaseType get(mixed $primaryKey, array|string $finder = 'all', \Psr\SimpleCache\CacheInterface|string|null $cache = null, \Closure|string|null $cacheKey = null, mixed ...$args)
* @method \CakeAccounting\Model\Entity\DeBaseType findOrCreate($search, ?callable $callback = null, array $options = [])
* @method \CakeAccounting\Model\Entity\DeBaseType patchEntity(\Cake\Datasource\EntityInterface $entity, array $data, array $options = [])
* @method array<\CakeAccounting\Model\Entity\DeBaseType> patchEntities(iterable $entities, array $data, array $options = [])
* @method \CakeAccounting\Model\Entity\DeBaseType|false save(\Cake\Datasource\EntityInterface $entity, array $options = [])
* @method \CakeAccounting\Model\Entity\DeBaseType saveOrFail(\Cake\Datasource\EntityInterface $entity, array $options = [])
* @method iterable<\CakeAccounting\Model\Entity\DeBaseType>|\Cake\Datasource\ResultSetInterface<\CakeAccounting\Model\Entity\DeBaseType>|false saveMany(iterable $entities, array $options = [])
* @method iterable<\CakeAccounting\Model\Entity\DeBaseType>|\Cake\Datasource\ResultSetInterface<\CakeAccounting\Model\Entity\DeBaseType> saveManyOrFail(iterable $entities, array $options = [])
* @method iterable<\CakeAccounting\Model\Entity\DeBaseType>|\Cake\Datasource\ResultSetInterface<\CakeAccounting\Model\Entity\DeBaseType>|false deleteMany(iterable $entities, array $options = [])
* @method iterable<\CakeAccounting\Model\Entity\DeBaseType>|\Cake\Datasource\ResultSetInterface<\CakeAccounting\Model\Entity\DeBaseType> deleteManyOrFail(iterable $entities, array $options = [])
*/
class DeBaseTypesTable extends Table
{
/**
* Initialize method
*
* @param array<string, mixed> $config The configuration for the Table.
* @return void
*/
public function initialize(array $config): void
{
parent::initialize($config);
$this->setTable('de_base_types');
$this->setDisplayField('name');
$this->setPrimaryKey('de_code');
}
/**
* Default validation rules.
*
* @param \Cake\Validation\Validator $validator Validator instance.
* @return \Cake\Validation\Validator
*/
public function validationDefault(Validator $validator): Validator
{
$validator
->scalar('name')
->maxLength('name', 45)
->requirePresence('name', 'create')
->notEmptyString('name');
return $validator;
}
}

View File

@ -0,0 +1,61 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Model\Table;
use Cake\ORM\Query\SelectQuery;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
/**
* DeEntityTypes Model
*
* @method \CakeAccounting\Model\Entity\DeEntityType newEmptyEntity()
* @method \CakeAccounting\Model\Entity\DeEntityType newEntity(array $data, array $options = [])
* @method array<\CakeAccounting\Model\Entity\DeEntityType> newEntities(array $data, array $options = [])
* @method \CakeAccounting\Model\Entity\DeEntityType get(mixed $primaryKey, array|string $finder = 'all', \Psr\SimpleCache\CacheInterface|string|null $cache = null, \Closure|string|null $cacheKey = null, mixed ...$args)
* @method \CakeAccounting\Model\Entity\DeEntityType findOrCreate($search, ?callable $callback = null, array $options = [])
* @method \CakeAccounting\Model\Entity\DeEntityType patchEntity(\Cake\Datasource\EntityInterface $entity, array $data, array $options = [])
* @method array<\CakeAccounting\Model\Entity\DeEntityType> patchEntities(iterable $entities, array $data, array $options = [])
* @method \CakeAccounting\Model\Entity\DeEntityType|false save(\Cake\Datasource\EntityInterface $entity, array $options = [])
* @method \CakeAccounting\Model\Entity\DeEntityType saveOrFail(\Cake\Datasource\EntityInterface $entity, array $options = [])
* @method iterable<\CakeAccounting\Model\Entity\DeEntityType>|\Cake\Datasource\ResultSetInterface<\CakeAccounting\Model\Entity\DeEntityType>|false saveMany(iterable $entities, array $options = [])
* @method iterable<\CakeAccounting\Model\Entity\DeEntityType>|\Cake\Datasource\ResultSetInterface<\CakeAccounting\Model\Entity\DeEntityType> saveManyOrFail(iterable $entities, array $options = [])
* @method iterable<\CakeAccounting\Model\Entity\DeEntityType>|\Cake\Datasource\ResultSetInterface<\CakeAccounting\Model\Entity\DeEntityType>|false deleteMany(iterable $entities, array $options = [])
* @method iterable<\CakeAccounting\Model\Entity\DeEntityType>|\Cake\Datasource\ResultSetInterface<\CakeAccounting\Model\Entity\DeEntityType> deleteManyOrFail(iterable $entities, array $options = [])
*/
class DeEntityTypesTable extends Table
{
/**
* Initialize method
*
* @param array<string, mixed> $config The configuration for the Table.
* @return void
*/
public function initialize(array $config): void
{
parent::initialize($config);
$this->setTable('de_entity_types');
$this->setDisplayField('name');
$this->setPrimaryKey('entity_type_code');
}
/**
* Default validation rules.
*
* @param \Cake\Validation\Validator $validator Validator instance.
* @return \Cake\Validation\Validator
*/
public function validationDefault(Validator $validator): Validator
{
$validator
->scalar('name')
->maxLength('name', 45)
->requirePresence('name', 'create')
->notEmptyString('name');
return $validator;
}
}

View File

@ -0,0 +1,84 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Model\Table;
use Cake\Datasource\EntityInterface;
use Cake\Datasource\ResultSetInterface;
use Cake\ORM\Query\SelectQuery;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
use CakeAccounting\Model\Entity\DeExternalAccountStatement;
use Closure;
use Psr\SimpleCache\CacheInterface;
/**
* DeExternalAccountStatements Model
*
* @method DeExternalAccountStatement newEmptyEntity()
* @method DeExternalAccountStatement newEntity(array $data, array $options = [])
* @method array<DeExternalAccountStatement> newEntities(array $data, array $options = [])
* @method DeExternalAccountStatement get(mixed $primaryKey, array|string $finder = 'all', CacheInterface|string|null $cache = null, Closure|string|null $cacheKey = null, mixed ...$args)
* @method DeExternalAccountStatement findOrCreate($search, ?callable $callback = null, array $options = [])
* @method DeExternalAccountStatement patchEntity(EntityInterface $entity, array $data, array $options = [])
* @method array<DeExternalAccountStatement> patchEntities(iterable $entities, array $data, array $options = [])
* @method DeExternalAccountStatement|false save(EntityInterface $entity, array $options = [])
* @method DeExternalAccountStatement saveOrFail(EntityInterface $entity, array $options = [])
* @method iterable<DeExternalAccountStatement>|ResultSetInterface<DeExternalAccountStatement>|false saveMany(iterable $entities, array $options = [])
* @method iterable<DeExternalAccountStatement>|ResultSetInterface<DeExternalAccountStatement> saveManyOrFail(iterable $entities, array $options = [])
* @method iterable<DeExternalAccountStatement>|ResultSetInterface<DeExternalAccountStatement>|false deleteMany(iterable $entities, array $options = [])
* @method iterable<DeExternalAccountStatement>|ResultSetInterface<DeExternalAccountStatement> deleteManyOrFail(iterable $entities, array $options = [])
*/
class DeExternalAccountStatementsTable extends Table
{
/**
* Initialize method
*
* @param array<string, mixed> $config The configuration for the Table.
* @return void
*/
public function initialize(array $config): void
{
parent::initialize($config);
$this->setTable('de_external_account_statements');
$this->setDisplayField('external_account_statement_id');
$this->setPrimaryKey('external_account_statement_id');
$this->belongsTo('DeExternalAccounts', [
'className' => 'CakeAccounting.DeExternalAccounts',
'foreignKey' => 'external_account_number',
'bindingKey' => 'external_account_number',
]);
}
/**
* Default validation rules.
*
* @param Validator $validator Validator instance.
* @return Validator
*/
public function validationDefault(Validator $validator): Validator
{
$validator
->uuid('external_account_statement_id');
$validator
->decimal('closing_balance')
->requirePresence('closing_balance', 'create')
->notEmptyString('closing_balance');
$validator
->decimal('total_credit')
->requirePresence('total_credit', 'create')
->notEmptyString('total_credit');
$validator
->decimal('total_debit')
->requirePresence('total_debit', 'create')
->notEmptyString('total_debit');
return $validator;
}
}

View File

@ -0,0 +1,91 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Model\Table;
use Cake\Datasource\EntityInterface;
use Cake\Datasource\ResultSetInterface;
use Cake\ORM\Behavior\TimestampBehavior;
use Cake\ORM\Query\SelectQuery;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
use CakeAccounting\Model\Entity\DeExternalAccount;
use Closure;
use Psr\SimpleCache\CacheInterface;
/**
* DeExternalAccounts Model
*
* @method DeExternalAccount newEmptyEntity()
* @method DeExternalAccount newEntity(array $data, array $options = [])
* @method array<DeExternalAccount> newEntities(array $data, array $options = [])
* @method DeExternalAccount get(mixed $primaryKey, array|string $finder = 'all', CacheInterface|string|null $cache = null, Closure|string|null $cacheKey = null, mixed ...$args)
* @method DeExternalAccount findOrCreate($search, ?callable $callback = null, array $options = [])
* @method DeExternalAccount patchEntity(EntityInterface $entity, array $data, array $options = [])
* @method array<DeExternalAccount> patchEntities(iterable $entities, array $data, array $options = [])
* @method DeExternalAccount|false save(EntityInterface $entity, array $options = [])
* @method DeExternalAccount saveOrFail(EntityInterface $entity, array $options = [])
* @method iterable<DeExternalAccount>|ResultSetInterface<DeExternalAccount>|false saveMany(iterable $entities, array $options = [])
* @method iterable<DeExternalAccount>|ResultSetInterface<DeExternalAccount> saveManyOrFail(iterable $entities, array $options = [])
* @method iterable<DeExternalAccount>|ResultSetInterface<DeExternalAccount>|false deleteMany(iterable $entities, array $options = [])
* @method iterable<DeExternalAccount>|ResultSetInterface<DeExternalAccount> deleteManyOrFail(iterable $entities, array $options = [])
*
* @mixin TimestampBehavior
*/
class DeExternalAccountsTable extends Table
{
/**
* Initialize method
*
* @param array<string, mixed> $config The configuration for the Table.
* @return void
*/
public function initialize(array $config): void
{
parent::initialize($config);
$this->setTable('de_external_accounts');
$this->setDisplayField('entity_type_code');
$this->setPrimaryKey('external_account_number');
$this->addBehavior('Timestamp');
$this->belongsTo('DeEntityTypes', [
'className' => 'CakeAccounting.DeEntityTypes',
'foreignKey' => 'entity_type_code',
'bindingKey' => 'entity_type_code',
]);
$this->hasMany('DeExternalAccountStatements', [
'className' => 'CakeAccounting.DeExternalAccountStatements',
'foreignKey' => 'external_account_number',
'bindingKey' => 'external_account_number',
]);
}
/**
* Default validation rules.
*
* @param Validator $validator Validator instance.
* @return Validator
*/
public function validationDefault(Validator $validator): Validator
{
$validator
->scalar('entity_type_code')
->maxLength('entity_type_code', 2)
->requirePresence('entity_type_code', 'create')
->notEmptyString('entity_type_code');
$validator
->scalar('related_model')
->maxLength('related_model', 255)
->allowEmptyString('related_model');
$validator
->integer('related_model_fk')
->allowEmptyString('related_model_fk');
return $validator;
}
}

View File

@ -0,0 +1,66 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Model\Table;
use Cake\Datasource\EntityInterface;
use Cake\Datasource\ResultSetInterface;
use Cake\ORM\Query\SelectQuery;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
use CakeAccounting\Model\Entity\DeInternalAccountType;
use Closure;
use Psr\SimpleCache\CacheInterface;
/**
* DeInternalAccountTypes Model
*
* @method DeInternalAccountType newEmptyEntity()
* @method DeInternalAccountType newEntity(array $data, array $options = [])
* @method array<DeInternalAccountType> newEntities(array $data, array $options = [])
* @method DeInternalAccountType get(mixed $primaryKey, array|string $finder = 'all', CacheInterface|string|null $cache = null, Closure|string|null $cacheKey = null, mixed ...$args)
* @method DeInternalAccountType findOrCreate($search, ?callable $callback = null, array $options = [])
* @method DeInternalAccountType patchEntity(EntityInterface $entity, array $data, array $options = [])
* @method array<DeInternalAccountType> patchEntities(iterable $entities, array $data, array $options = [])
* @method DeInternalAccountType|false save(EntityInterface $entity, array $options = [])
* @method DeInternalAccountType saveOrFail(EntityInterface $entity, array $options = [])
* @method iterable<DeInternalAccountType>|ResultSetInterface<DeInternalAccountType>|false saveMany(iterable $entities, array $options = [])
* @method iterable<DeInternalAccountType>|ResultSetInterface<DeInternalAccountType> saveManyOrFail(iterable $entities, array $options = [])
* @method iterable<DeInternalAccountType>|ResultSetInterface<DeInternalAccountType>|false deleteMany(iterable $entities, array $options = [])
* @method iterable<DeInternalAccountType>|ResultSetInterface<DeInternalAccountType> deleteManyOrFail(iterable $entities, array $options = [])
*/
class DeInternalAccountTypesTable extends Table
{
/**
* Initialize method
*
* @param array<string, mixed> $config The configuration for the Table.
* @return void
*/
public function initialize(array $config): void
{
parent::initialize($config);
$this->setTable('de_internal_account_types');
$this->setDisplayField('name');
$this->setPrimaryKey('account_type_code');
}
/**
* Default validation rules.
*
* @param Validator $validator Validator instance.
* @return Validator
*/
public function validationDefault(Validator $validator): Validator
{
$validator
->scalar('name')
->maxLength('name', 45)
->requirePresence('name', 'create')
->notEmptyString('name');
return $validator;
}
}

View File

@ -0,0 +1,113 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Model\Table;
use Cake\Datasource\EntityInterface;
use Cake\Datasource\ResultSetInterface;
use Cake\ORM\Association\BelongsTo;
use Cake\ORM\Association\HasMany;
use Cake\ORM\Behavior\TimestampBehavior;
use Cake\ORM\Query\SelectQuery;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
use CakeAccounting\Model\Entity\DeJournalEntry;
use Closure;
use Psr\SimpleCache\CacheInterface;
/**
* DeJournalEntries Model
*
* @property DeJournalsTable&BelongsTo $DeJournals
* @property UsersTable&BelongsTo $Users
* @property DeJournalItemsTable&HasMany $DeJournalItems
*
* @method DeJournalEntry newEmptyEntity()
* @method DeJournalEntry newEntity(array $data, array $options = [])
* @method array<DeJournalEntry> newEntities(array $data, array $options = [])
* @method DeJournalEntry get(mixed $primaryKey, array|string $finder = 'all', CacheInterface|string|null $cache = null, Closure|string|null $cacheKey = null, mixed ...$args)
* @method DeJournalEntry findOrCreate($search, ?callable $callback = null, array $options = [])
* @method DeJournalEntry patchEntity(EntityInterface $entity, array $data, array $options = [])
* @method array<DeJournalEntry> patchEntities(iterable $entities, array $data, array $options = [])
* @method DeJournalEntry|false save(EntityInterface $entity, array $options = [])
* @method DeJournalEntry saveOrFail(EntityInterface $entity, array $options = [])
* @method iterable<DeJournalEntry>|ResultSetInterface<DeJournalEntry>|false saveMany(iterable $entities, array $options = [])
* @method iterable<DeJournalEntry>|ResultSetInterface<DeJournalEntry> saveManyOrFail(iterable $entities, array $options = [])
* @method iterable<DeJournalEntry>|ResultSetInterface<DeJournalEntry>|false deleteMany(iterable $entities, array $options = [])
* @method iterable<DeJournalEntry>|ResultSetInterface<DeJournalEntry> deleteManyOrFail(iterable $entities, array $options = [])
*
* @mixin TimestampBehavior
*/
class DeJournalEntriesTable extends Table
{
/**
* Initialize method
*
* @param array<string, mixed> $config The configuration for the Table.
* @return void
*/
public function initialize(array $config): void
{
parent::initialize($config);
$this->setTable('de_journal_entries');
$this->setDisplayField('id');
$this->setPrimaryKey('id');
$this->addBehavior('Timestamp');
$this->belongsTo('DeJournals', [
'foreignKey' => 'de_journal_id',
'joinType' => 'INNER',
'className' => 'CakeAccounting.DeJournals',
]);
// $this->belongsTo('Users', [
// 'foreignKey' => 'user_id',
// 'className' => 'CakeAccounting.Users',
// ]);
$this->hasMany('DeJournalItems', [
'foreignKey' => 'de_journal_entry_id',
'className' => 'CakeAccounting.DeJournalItems',
]);
}
/**
* Default validation rules.
*
* @param Validator $validator Validator instance.
* @return Validator
*/
public function validationDefault(Validator $validator): Validator
{
$validator
->integer('de_journal_id')
->requirePresence('de_journal_id', 'create')
->notEmptyString('de_journal_id');
$validator
->integer('user_id')
->allowEmptyString('user_id');
$validator
->scalar('notes')
->allowEmptyString('notes');
return $validator;
}
/**
* Returns a rules checker object that will be used for validating
* application integrity.
*
* @param RulesChecker $rules The rules object to be modified.
* @return RulesChecker
*/
public function buildRules(RulesChecker $rules): RulesChecker
{
$rules->add($rules->existsIn(['de_journal_id'], 'DeJournals'), ['errorField' => 'de_journal_id']);
// $rules->add($rules->existsIn(['user_id'], 'Users'), ['errorField' => '1']);
return $rules;
}
}

View File

@ -0,0 +1,151 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Model\Table;
use Cake\Datasource\EntityInterface;
use Cake\Datasource\ResultSetInterface;
use Cake\ORM\Association\BelongsTo;
use Cake\ORM\Behavior\TimestampBehavior;
use Cake\ORM\Query;
use Cake\ORM\Query\SelectQuery;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
use CakeAccounting\Model\Entity\DeJournalItem;
use Closure;
use Psr\SimpleCache\CacheInterface;
/**
* DeJournalItems Model
*
* @property DeJournalEntriesTable&BelongsTo $DeJournalEntries
*
* @method DeJournalItem newEmptyEntity()
* @method DeJournalItem newEntity(array $data, array $options = [])
* @method array<DeJournalItem> newEntities(array $data, array $options = [])
* @method DeJournalItem get(mixed $primaryKey, array|string $finder = 'all', CacheInterface|string|null $cache = null, Closure|string|null $cacheKey = null, mixed ...$args)
* @method DeJournalItem findOrCreate($search, ?callable $callback = null, array $options = [])
* @method DeJournalItem patchEntity(EntityInterface $entity, array $data, array $options = [])
* @method array<DeJournalItem> patchEntities(iterable $entities, array $data, array $options = [])
* @method DeJournalItem|false save(EntityInterface $entity, array $options = [])
* @method DeJournalItem saveOrFail(EntityInterface $entity, array $options = [])
* @method iterable<DeJournalItem>|ResultSetInterface<DeJournalItem>|false saveMany(iterable $entities, array $options = [])
* @method iterable<DeJournalItem>|ResultSetInterface<DeJournalItem> saveManyOrFail(iterable $entities, array $options = [])
* @method iterable<DeJournalItem>|ResultSetInterface<DeJournalItem>|false deleteMany(iterable $entities, array $options = [])
* @method iterable<DeJournalItem>|ResultSetInterface<DeJournalItem> deleteManyOrFail(iterable $entities, array $options = [])
*
* @mixin TimestampBehavior
*/
class DeJournalItemsTable extends Table
{
/**
* Initialize method
*
* @param array<string, mixed> $config The configuration for the Table.
* @return void
*/
public function initialize(array $config): void
{
parent::initialize($config);
$this->setTable('de_journal_items');
$this->setDisplayField('id');
$this->setPrimaryKey('id');
$this->addBehavior('Timestamp');
$this->belongsTo('DeJournalEntries', [
'foreignKey' => 'de_journal_entry_id',
'joinType' => 'INNER',
'className' => 'CakeAccounting.DeJournalEntries',
]);
$this->belongsTo('CreditDeAccounts', [
'foreignKey' => 'account_number_credit',
'bindingKey' => 'account_number',
'joinType' => 'INNER',
'className' => 'CakeAccounting.DeAccounts',
]);
$this->belongsTo('DebitDeAccounts', [
'foreignKey' => 'account_number_debit',
'bindingKey' => 'account_number',
'joinType' => 'INNER',
'className' => 'CakeAccounting.DeAccounts',
]);
$this->belongsTo('CreditDeExternalAccounts', [
'foreignKey' => 'external_account_number_credit',
'bindingKey' => 'external_account_number',
'className' => 'CakeAccounting.DeExternalAccounts',
]);
$this->belongsTo('DebitDeExternalAccounts', [
'foreignKey' => 'external_account_number_debit',
'bindingKey' => 'external_account_number',
'className' => 'CakeAccounting.DeExternalAccounts',
]);
}
/**
* Default validation rules.
*
* @param Validator $validator Validator instance.
* @return Validator
*/
public function validationDefault(Validator $validator): Validator
{
$validator
->integer('account_number_credit')
->requirePresence('account_number_credit', 'create')
->notEmptyString('account_number_credit');
$validator
->integer('account_number_debit')
->requirePresence('account_number_debit', 'create')
->notEmptyString('account_number_debit');
$validator
->uuid('external_account_number_credit')
->allowEmptyString('external_account_number_credit');
$validator
->uuid('external_account_number_debit')
->allowEmptyString('external_account_number_debit');
$validator
->integer('de_journal_entry_id')
->notEmptyString('de_journal_entry_id');
$validator
->decimal('amount')
->requirePresence('amount', 'create')
->notEmptyString('amount');
return $validator;
}
/**
* Returns a rules checker object that will be used for validating
* application integrity.
*
* @param RulesChecker $rules The rules object to be modified.
* @return RulesChecker
*/
public function buildRules(RulesChecker $rules): RulesChecker
{
$rules->add($rules->existsIn(['de_journal_entry_id'], 'DeJournalEntries'), ['errorField' => 'de_journal_entry_id']);
$rules->add($rules->existsIn(['account_number_credit'], 'CreditDeAccounts'), ['errorField' => 'account_number_credit']);
$rules->add($rules->existsIn(['account_number_debit'], 'DebitDeAccounts'), ['errorField' => 'account_number_debit']);
$rules->add($rules->existsIn(['external_account_number_credit'], 'CreditDeExternalAccounts'), ['errorField' => 'external_account_number_credit']);
$rules->add($rules->existsIn(['external_account_number_debit'], 'DebitDeExternalAccounts'), ['errorField' => 'external_account_number_debit']);
return $rules;
}
public function findDebitsForAccountNumber(Query $query, int $accountNumber): Query
{
return $query->where(['account_number_debit' => $accountNumber]);
}
public function findCreditsForAccountNumber(Query $query, int $accountNumber): Query
{
return $query->where(['account_number_credit' => $accountNumber]);
}
}

View File

@ -0,0 +1,49 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Model\Table;
use Cake\Datasource\EntityInterface;
use Cake\Datasource\ResultSetInterface;
use Cake\ORM\Query\SelectQuery;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
use CakeAccounting\Model\Entity\DeJournalType;
use Closure;
use Psr\SimpleCache\CacheInterface;
/**
* DeJournalTypes Model
*
* @method DeJournalType newEmptyEntity()
* @method DeJournalType newEntity(array $data, array $options = [])
* @method array<DeJournalType> newEntities(array $data, array $options = [])
* @method DeJournalType get(mixed $primaryKey, array|string $finder = 'all', CacheInterface|string|null $cache = null, Closure|string|null $cacheKey = null, mixed ...$args)
* @method DeJournalType findOrCreate($search, ?callable $callback = null, array $options = [])
* @method DeJournalType patchEntity(EntityInterface $entity, array $data, array $options = [])
* @method array<DeJournalType> patchEntities(iterable $entities, array $data, array $options = [])
* @method DeJournalType|false save(EntityInterface $entity, array $options = [])
* @method DeJournalType saveOrFail(EntityInterface $entity, array $options = [])
* @method iterable<DeJournalType>|ResultSetInterface<DeJournalType>|false saveMany(iterable $entities, array $options = [])
* @method iterable<DeJournalType>|ResultSetInterface<DeJournalType> saveManyOrFail(iterable $entities, array $options = [])
* @method iterable<DeJournalType>|ResultSetInterface<DeJournalType>|false deleteMany(iterable $entities, array $options = [])
* @method iterable<DeJournalType>|ResultSetInterface<DeJournalType> deleteManyOrFail(iterable $entities, array $options = [])
*/
class DeJournalTypesTable extends Table
{
/**
* Initialize method
*
* @param array<string, mixed> $config The configuration for the Table.
* @return void
*/
public function initialize(array $config): void
{
parent::initialize($config);
$this->setTable('de_journal_types');
$this->setDisplayField('de_journal_type_code');
$this->setPrimaryKey('de_journal_type_code');
}
}

View File

@ -0,0 +1,99 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Model\Table;
use Cake\Datasource\EntityInterface;
use Cake\Datasource\ResultSetInterface;
use Cake\ORM\Association\HasMany;
use Cake\ORM\Query\SelectQuery;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
use CakeAccounting\Model\Entity\DeJournal;
use Closure;
use Psr\SimpleCache\CacheInterface;
/**
* DeJournals Model
*
* @property DeJournalEntriesTable&HasMany $DeJournalEntries
*
* @method DeJournal newEmptyEntity()
* @method DeJournal newEntity(array $data, array $options = [])
* @method array<DeJournal> newEntities(array $data, array $options = [])
* @method DeJournal get(mixed $primaryKey, array|string $finder = 'all', CacheInterface|string|null $cache = null, Closure|string|null $cacheKey = null, mixed ...$args)
* @method DeJournal findOrCreate($search, ?callable $callback = null, array $options = [])
* @method DeJournal patchEntity(EntityInterface $entity, array $data, array $options = [])
* @method array<DeJournal> patchEntities(iterable $entities, array $data, array $options = [])
* @method DeJournal|false save(EntityInterface $entity, array $options = [])
* @method DeJournal saveOrFail(EntityInterface $entity, array $options = [])
* @method iterable<DeJournal>|ResultSetInterface<DeJournal>|false saveMany(iterable $entities, array $options = [])
* @method iterable<DeJournal>|ResultSetInterface<DeJournal> saveManyOrFail(iterable $entities, array $options = [])
* @method iterable<DeJournal>|ResultSetInterface<DeJournal>|false deleteMany(iterable $entities, array $options = [])
* @method iterable<DeJournal>|ResultSetInterface<DeJournal> deleteManyOrFail(iterable $entities, array $options = [])
*/
class DeJournalsTable extends Table
{
/**
* Initialize method
*
* @param array<string, mixed> $config The configuration for the Table.
* @return void
*/
public function initialize(array $config): void
{
parent::initialize($config);
$this->setTable('de_journals');
$this->setDisplayField('name');
$this->setPrimaryKey('id');
$this->hasMany('DeJournalEntries', [
'foreignKey' => 'de_journal_id',
'className' => 'CakeAccounting.DeJournalEntries',
]);
$this->belongsTo('DeJournalTypes', [
'foreignKey' => 'de_journal_type_code',
'bindingKey' => 'de_journal_type_code',
'className' => 'CakeAccounting.DeJournalTypes',
]);
}
/**
* Default validation rules.
*
* @param Validator $validator Validator instance.
* @return Validator
*/
public function validationDefault(Validator $validator): Validator
{
$validator
->scalar('name')
->maxLength('name', 45)
->requirePresence('name', 'create')
->notEmptyString('name');
$validator
->scalar('short_code')
->maxLength('short_code', 5)
->requirePresence('short_code', 'create')
->notEmptyString('short_code');
$validator
->integer('default_account_number_credit')
->allowEmptyString('default_account_number_credit');
$validator
->integer('default_account_number_debit')
->allowEmptyString('default_account_number_debit');
$validator
->scalar('de_journal_type_code')
->maxLength('de_journal_type_code', 5)
->requirePresence('de_journal_type_code', 'create')
->notEmptyString('de_journal_type_code');
return $validator;
}
}

View File

@ -0,0 +1,140 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Model\Table;
use Cake\Datasource\EntityInterface;
use Cake\Datasource\ResultSetInterface;
use Cake\ORM\Association\BelongsTo;
use Cake\ORM\Association\HasMany;
use Cake\ORM\Behavior\TreeBehavior;
use Cake\ORM\Query\SelectQuery;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
use CakeAccounting\Model\Entity\DeTemplatedAccount;
use Closure;
use Psr\SimpleCache\CacheInterface;
/**
* DeTemplatedAccounts Model
*
* @property DeTemplatedAccountsTable&BelongsTo $ParentDeTemplatedAccounts
* @property DeTemplatedAccountsTable&HasMany $ChildDeTemplatedAccounts
*
* @method DeTemplatedAccount newEmptyEntity()
* @method DeTemplatedAccount newEntity(array $data, array $options = [])
* @method array<DeTemplatedAccount> newEntities(array $data, array $options = [])
* @method DeTemplatedAccount get(mixed $primaryKey, array|string $finder = 'all', CacheInterface|string|null $cache = null, Closure|string|null $cacheKey = null, mixed ...$args)
* @method DeTemplatedAccount findOrCreate($search, ?callable $callback = null, array $options = [])
* @method DeTemplatedAccount patchEntity(EntityInterface $entity, array $data, array $options = [])
* @method array<DeTemplatedAccount> patchEntities(iterable $entities, array $data, array $options = [])
* @method DeTemplatedAccount|false save(EntityInterface $entity, array $options = [])
* @method DeTemplatedAccount saveOrFail(EntityInterface $entity, array $options = [])
* @method iterable<DeTemplatedAccount>|ResultSetInterface<DeTemplatedAccount>|false saveMany(iterable $entities, array $options = [])
* @method iterable<DeTemplatedAccount>|ResultSetInterface<DeTemplatedAccount> saveManyOrFail(iterable $entities, array $options = [])
* @method iterable<DeTemplatedAccount>|ResultSetInterface<DeTemplatedAccount>|false deleteMany(iterable $entities, array $options = [])
* @method iterable<DeTemplatedAccount>|ResultSetInterface<DeTemplatedAccount> deleteManyOrFail(iterable $entities, array $options = [])
*
* @mixin TreeBehavior
*/
class DeTemplatedAccountsTable extends Table
{
/**
* Initialize method
*
* @param array<string, mixed> $config The configuration for the Table.
* @return void
*/
public function initialize(array $config): void
{
parent::initialize($config);
$this->setTable('de_templated_accounts');
$this->setDisplayField('name');
$this->setPrimaryKey('id');
$this->addBehavior('Tree');
$this->belongsTo('ParentDeTemplatedAccounts', [
'foreignKey' => 'parent_id',
'className' => 'CakeAccounting.DeTemplatedAccounts',
]);
$this->belongsTo('DeAccountTypes', [
'foreignKey' => 'account_type_code',
'bindingKey' => 'account_type_code',
'className' => 'CakeAccounting.DeAccountTypes',
]);
$this->belongsTo('DeAccountTemplates', [
'foreignKey' => 'account_template_id',
'className' => 'CakeAccounting.DeAccountTemplates',
]);
$this->hasMany('ChildDeTemplatedAccounts', [
'foreignKey' => 'parent_id',
'className' => 'CakeAccounting.DeTemplatedAccounts',
]);
}
/**
* Default validation rules.
*
* @param Validator $validator Validator instance.
* @return Validator
*/
public function validationDefault(Validator $validator): Validator
{
$validator
->integer('account_number')
->requirePresence('account_number', 'create')
->notEmptyString('account_number');
$validator
->integer('account_template_id')
->requirePresence('account_template_id', 'create')
->notEmptyString('account_template_id');
$validator
->integer('parent_id')
->allowEmptyString('parent_id');
$validator
->scalar('account_type_code')
->maxLength('account_type_code', 2)
->requirePresence('account_type_code', 'create')
->notEmptyString('account_type_code');
$validator
->integer('account_limit')
->allowEmptyString('account_limit');
$validator
->boolean('can_credit')
->notEmptyString('can_credit');
$validator
->boolean('can_debit')
->notEmptyString('can_debit');
$validator
->scalar('name')
->maxLength('name', 255)
->requirePresence('name', 'create')
->notEmptyString('name');
return $validator;
}
/**
* Returns a rules checker object that will be used for validating
* application integrity.
*
* @param RulesChecker $rules The rules object to be modified.
* @return RulesChecker
*/
public function buildRules(RulesChecker $rules): RulesChecker
{
$rules->add($rules->existsIn(['parent_id'], 'ParentDeTemplatedAccounts'), ['errorField' => '0']);
return $rules;
}
}

View File

@ -0,0 +1,61 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Model\Table;
use Cake\ORM\Query\SelectQuery;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
/**
* DeTransactionTypes Model
*
* @method \CakeAccounting\Model\Entity\DeTransactionType newEmptyEntity()
* @method \CakeAccounting\Model\Entity\DeTransactionType newEntity(array $data, array $options = [])
* @method array<\CakeAccounting\Model\Entity\DeTransactionType> newEntities(array $data, array $options = [])
* @method \CakeAccounting\Model\Entity\DeTransactionType get(mixed $primaryKey, array|string $finder = 'all', \Psr\SimpleCache\CacheInterface|string|null $cache = null, \Closure|string|null $cacheKey = null, mixed ...$args)
* @method \CakeAccounting\Model\Entity\DeTransactionType findOrCreate($search, ?callable $callback = null, array $options = [])
* @method \CakeAccounting\Model\Entity\DeTransactionType patchEntity(\Cake\Datasource\EntityInterface $entity, array $data, array $options = [])
* @method array<\CakeAccounting\Model\Entity\DeTransactionType> patchEntities(iterable $entities, array $data, array $options = [])
* @method \CakeAccounting\Model\Entity\DeTransactionType|false save(\Cake\Datasource\EntityInterface $entity, array $options = [])
* @method \CakeAccounting\Model\Entity\DeTransactionType saveOrFail(\Cake\Datasource\EntityInterface $entity, array $options = [])
* @method iterable<\CakeAccounting\Model\Entity\DeTransactionType>|\Cake\Datasource\ResultSetInterface<\CakeAccounting\Model\Entity\DeTransactionType>|false saveMany(iterable $entities, array $options = [])
* @method iterable<\CakeAccounting\Model\Entity\DeTransactionType>|\Cake\Datasource\ResultSetInterface<\CakeAccounting\Model\Entity\DeTransactionType> saveManyOrFail(iterable $entities, array $options = [])
* @method iterable<\CakeAccounting\Model\Entity\DeTransactionType>|\Cake\Datasource\ResultSetInterface<\CakeAccounting\Model\Entity\DeTransactionType>|false deleteMany(iterable $entities, array $options = [])
* @method iterable<\CakeAccounting\Model\Entity\DeTransactionType>|\Cake\Datasource\ResultSetInterface<\CakeAccounting\Model\Entity\DeTransactionType> deleteManyOrFail(iterable $entities, array $options = [])
*/
class DeTransactionTypesTable extends Table
{
/**
* Initialize method
*
* @param array<string, mixed> $config The configuration for the Table.
* @return void
*/
public function initialize(array $config): void
{
parent::initialize($config);
$this->setTable('de_transaction_types');
$this->setDisplayField('name');
$this->setPrimaryKey('transaction_type_code');
}
/**
* Default validation rules.
*
* @param \Cake\Validation\Validator $validator Validator instance.
* @return \Cake\Validation\Validator
*/
public function validationDefault(Validator $validator): Validator
{
$validator
->scalar('name')
->maxLength('name', 45)
->requirePresence('name', 'create')
->notEmptyString('name');
return $validator;
}
}

View File

@ -0,0 +1,257 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\Service;
use Cake\Cache\Cache;
use Cake\Core\ServiceConfig;
use Cake\I18n\Date;
use Cake\I18n\DateTime;
use Cake\I18n\FrozenDate;
use Cake\Log\Log;
use Cake\ORM\Table;
use Cake\ORM\TableRegistry;
use CakeAccounting\Model\Entity\DeAccount;
use CakeAccounting\Model\Table\DeAccountsTable;
/**
* @property DeAccountsTable
*/
class AccountingService
{
/**
* @var DeAccountsTable|Table
*/
protected DeAccountsTable|Table $DeAccounts;
public function __construct()
{
$this->DeAccounts = TableRegistry::getTableLocator()->get('CakeAccounting.DeAccounts');
}
public function getLastAccountStatement(DeAccount $deAccount)
{
$statementDate = date('Y') . '-' . date('m') . '-01';
$accountStatement = $this->DeAccounts->DeAccountStatements->find()
->where(['statement_date' => $statementDate, 'account_number' => $deAccount->account_number])
->first();
if ($accountStatement) {
return $accountStatement;
}
$accountStatement = $this->DeAccounts->DeAccountStatements->find()
->where(['account_number' => $deAccount->account_number])
->orderBy(['statement_date' => 'DESC'])
->first();
if (!$accountStatement) {
$newBlankStatement = $this->DeAccounts->DeAccountStatements->createFirstAccountSatement($deAccount);
return $this->getLastAccountStatement($deAccount);
}
}
public function getAccountBalance(DeAccount $deAccount)
{
$now = DateTime::now();
Log::debug(print_r('inside get account balance de account number is next', true));
Log::debug(print_r($deAccount->account_number, true));
$lastAccountStatement = $this->getLastAccountStatement($deAccount);
// Log::debug(print_r('$lastAccountStatement', true));
// Log::debug(print_r("$lastAccountStatement", true));
if (!$deAccount->children) {
Log::debug(print_r('no children &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&', true));
$debitSumsQuery = $this->DeAccounts->DebitDeJournalItems->find();
$debitSumsQuery->select([
'debit_sum' => $debitSumsQuery->func()->sum('amount'),
'account_number_debit',
])
->where([
'account_number_debit' => $deAccount->account_number,
'created >=' => $lastAccountStatement->statement_date,
]);
$debitSums = $debitSumsQuery->first();
$creditSumsQuery = $this->DeAccounts->DebitDeJournalItems->find();
$creditSumsQuery->select([
'credit_sum' => $creditSumsQuery->func()->sum('amount'),
'account_number_credit',
])
->where([
'account_number_credit' => $deAccount->account_number,
'created >=' => $lastAccountStatement->statement_date,
]);
$creditSums = $creditSumsQuery->first();
// Log::debug(print_r('$debitSums', true));
// Log::debug(print_r($debitSums, true));
//
// Log::debug(print_r('$creditSums', true));
// Log::debug(print_r($creditSums, true));
$debitSum = $debitSums->debit_sum ?? 0;
$creditSum = $creditSums->credit_sum ?? 0;
$lastAccountStatementBalance = isset($lastAccountStatement) ? $lastAccountStatement->closing_balance : 0;
return [
'last_statement_balance' => $lastAccountStatementBalance,
'total_credits_since' => $creditSum,
'total_debits_since' => $debitSum,
'balance' => bcadd(bcadd("$lastAccountStatementBalance", "$debitSum", 5), "$creditSum", 5),
'children' => [],
];
}
$children = [];
$sumCredits = '0';
$sumDebits = '0';
$balance = '0';
foreach ($deAccount->children as $child) {
$tmpAccountBalanceChildResult = $this->getAccountBalance($child);
$children[$child->account_number] = $tmpAccountBalanceChildResult;
$childBalance = $this->getSumOfChildrenBalance($child, $tmpAccountBalanceChildResult);
$childDebits = $this->getSumOfChildrenBalance($child, $tmpAccountBalanceChildResult);
$childCredits = $this->getSumOfChildrenBalance($child, $tmpAccountBalanceChildResult);
$balance = bcadd("$balance", "$childBalance", 5);
$sumCredits = bcadd("$balance", "$childCredits", 5);
$sumDebits = bcadd("$balance", "$childDebits", 5);
}
$lastAccountStatementBalance = isset($lastAccountStatement) ? $lastAccountStatement->closing_balance : 0;
return [
'last_statement_balance' => $lastAccountStatementBalance,
'total_credits_since' => $sumCredits,
'total_debits_since' => $sumDebits,
'balance' => bcadd("$lastAccountStatementBalance", "$balance", 5),
'children' => $children,
];
}
public function createAccountStatement(DeAccount $deAccount, Date $statementDate = null)
{
$debitsSumQuery = $this->DeAccounts->DebitDeJournalItems->find();
$debitsSumQuery
->select([
'debits_sum' => $debitsSumQuery->func()->sum('amount'),
])
->find('debitsForAccountNumber', accountNumber: $deAccount->account_number)
->all();
Log::debug(print_r('$debitsSumQuery', true));
Log::debug(print_r($debitsSumQuery, true));
// ->find('beforeDate', before: $statementDate)
// ->find('afterDate', before: $submittedAt)
$data = [
'account_number' => $deAccount->account_number,
'statement_date' => $statementDate,
'closing_balance' => 0,
];
$deAccountStatement = $this->DeAccounts->DeAccountStatements->newEntity($data);
if ($deAccountStatement->getErrors()) {
Log::debug(print_r('$deAccountStatement->getErrors() creating a new statement', true));
Log::debug(print_r($deAccountStatement->getErrors(), true));
}
return $this->DeAccounts->DeAccountStatements->save($deAccountStatement);
}
/**
* @param DeAccount $deAccount
* @param array $totals
*
* @return int|mixed|string
*/
public function getSumOfChildrenBalance(DeAccount $deAccount, array $totals = [])
{
Log::debug(print_r('inside accounting helper getSumOfChildrenBalance account number next', true));
Log::debug(print_r($deAccount->account_number, true));
Log::debug(print_r('$totals', true));
Log::debug(print_r($totals, true));
if (!isset($deAccount->children) || !$deAccount->children) {
Log::debug('no children exists in accounting helper returning next');
return array_key_exists('balance', $totals) ? $totals['balance'] : 0;
}
$balance = 0;
foreach ($deAccount->children as $child) {
Log::debug('inside foreach children loop getSumOfChildrenBalance');
Log::debug('$child->account_number');
Log::debug("$child->account_number");
$childTotals = array_key_exists('children', $totals) && array_key_exists($child->account_number, $totals['children']) ? $totals['children'][$child->account_number] : [];
$childBalance = $this->getSumOfChildrenBalance($child, $childTotals ?? []);
$balance = bcadd("$balance", "$childBalance", 5);
}
return $balance;
}
/**
* @param DeAccount $deAccount
* @param array $totals
*
* @return int|mixed|string
*/
public function getSumOfChildrenDebits(DeAccount $deAccount, array $totals = [])
{
// Log::debug(print_r('inside accounting helper getSumOfChildrenDebits account number next', true));
// Log::debug(print_r($deAccount->account_number, true));
// Log::debug(print_r('$totals', true));
// Log::debug(print_r($totals, true));
if (!isset($deAccount->children) || !$deAccount->children) {
Log::debug('no children exists in accounting helper returning next');
return array_key_exists('total_debits_since', $totals) ? $totals['total_debits_since'] : 0;
}
$debits = 0;
foreach ($deAccount->children as $child) {
// Log::debug('inside foreach children loop getSumOfChildrenDebits');
// Log::debug('$child->account_number');
// Log::debug("$child->account_number");
$childTotals = array_key_exists('children', $totals) && array_key_exists($child->account_number, $totals['children']) ? $totals['children'][$child->account_number] : [];
$childDebits = $this->getSumOfChildrenDebits($child, $childTotals ?? []);
$debits = bcadd("$debits", "$childDebits", 5);
}
return $debits;
}
/**
* @param DeAccount $deAccount
* @param array $totals
*
* @return int|mixed|string
*/
public function getSumOfChildrenCredits(DeAccount $deAccount, array $totals = [])
{
// Log::debug(print_r('inside accounting helper getSumOfChildrenCredits account number next', true));
// Log::debug(print_r($deAccount->account_number, true));
// Log::debug(print_r('$totals', true));
// Log::debug(print_r($totals, true));
if (!isset($deAccount->children) || !$deAccount->children) {
Log::debug('no children exists in accounting helper returning next');
return array_key_exists('total_credits_since', $totals) ? $totals['total_credits_since'] : 0;
}
$credits = 0;
foreach ($deAccount->children as $child) {
// Log::debug('inside foreach children loop getSumOfChildrenCredits');
// Log::debug('$child->account_number');
// Log::debug("$child->account_number");
$childTotals = array_key_exists('children', $totals) && array_key_exists($child->account_number, $totals['children']) ? $totals['children'][$child->account_number] : [];
$childCredits = $this->getSumOfChildrenCredits($child, $childTotals ?? []);
$credits = bcadd("$credits", "$childCredits", 5);
}
return $credits;
}
}

View File

@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
namespace CakeAccounting\View\Helper;
use Cake\Log\Log;
use Cake\View\Helper;
use Cake\View\View;
use CakeAccounting\Model\Entity\DeAccount;
/**
* Accounting helper
*/
class AccountingHelper extends Helper
{
/**
* Default configuration.
*
* @var array<string, mixed>
*/
protected array $_defaultConfig = [];
protected array $helpers = [
'Number',
];
public function currency($number)
{
return $this->Number->currency($number, null, ['precision' => 5, 'places' => 5]);
}
}

View File

@ -0,0 +1,28 @@
<?php
/**
* @var \App\View\AppView $this
* @var \Cake\Datasource\EntityInterface $deAccountStatement
* @var \Cake\Collection\CollectionInterface|string[] $deAccounts
*/
?>
<div class="row">
<aside class="column">
<div class="side-nav">
<h4 class="heading"><?= __('Actions') ?></h4>
<?= $this->Html->link(__('List De Account Statements'), ['action' => 'index'], ['class' => 'side-nav-item']) ?>
</div>
</aside>
<div class="column column-80">
<div class="deAccountStatements form content">
<?= $this->Form->create($deAccountStatement) ?>
<fieldset>
<legend><?= __('Add De Account Statement') ?></legend>
<?php
echo $this->Form->control('closing_balance');
?>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
</div>
</div>
</div>

View File

@ -0,0 +1,33 @@
<?php
/**
* @var \App\View\AppView $this
* @var \Cake\Datasource\EntityInterface $deAccountStatement
* @var string[]|\Cake\Collection\CollectionInterface $deAccounts
*/
?>
<div class="row">
<aside class="column">
<div class="side-nav">
<h4 class="heading"><?= __('Actions') ?></h4>
<?= $this->Form->postLink(
__('Delete'),
['action' => 'delete', $deAccountStatement->account_number],
['confirm' => __('Are you sure you want to delete # {0}?', $deAccountStatement->account_number), 'class' => 'side-nav-item']
) ?>
<?= $this->Html->link(__('List De Account Statements'), ['action' => 'index'], ['class' => 'side-nav-item']) ?>
</div>
</aside>
<div class="column column-80">
<div class="deAccountStatements form content">
<?= $this->Form->create($deAccountStatement) ?>
<fieldset>
<legend><?= __('Edit De Account Statement') ?></legend>
<?php
echo $this->Form->control('closing_balance');
?>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
</div>
</div>
</div>

View File

@ -0,0 +1,46 @@
<?php
/**
* @var \App\View\AppView $this
* @var iterable<\Cake\Datasource\EntityInterface> $deAccountStatements
*/
?>
<div class="deAccountStatements index content">
<?= $this->Html->link(__('New De Account Statement'), ['action' => 'add'], ['class' => 'button float-right']) ?>
<h3><?= __('De Account Statements') ?></h3>
<div class="table-responsive">
<table>
<thead>
<tr>
<th><?= $this->Paginator->sort('account_number') ?></th>
<th><?= $this->Paginator->sort('statement_date') ?></th>
<th><?= $this->Paginator->sort('closing_balance') ?></th>
<th class="actions"><?= __('Actions') ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($deAccountStatements as $deAccountStatement): ?>
<tr>
<td><?= $deAccountStatement->hasValue('de_account') ? $this->Html->link($deAccountStatement->de_account->name, ['controller' => 'DeAccounts', 'action' => 'view', $deAccountStatement->de_account->id]) : '' ?></td>
<td><?= h($deAccountStatement->statement_date) ?></td>
<td><?= $this->Number->format($deAccountStatement->closing_balance) ?></td>
<td class="actions">
<?= $this->Html->link(__('View'), ['action' => 'view', $deAccountStatement->account_number]) ?>
<?= $this->Html->link(__('Edit'), ['action' => 'edit', $deAccountStatement->account_number]) ?>
<?= $this->Form->postLink(__('Delete'), ['action' => 'delete', $deAccountStatement->account_number], ['confirm' => __('Are you sure you want to delete # {0}?', $deAccountStatement->account_number)]) ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<div class="paginator">
<ul class="pagination">
<?= $this->Paginator->first('<< ' . __('first')) ?>
<?= $this->Paginator->prev('< ' . __('previous')) ?>
<?= $this->Paginator->numbers() ?>
<?= $this->Paginator->next(__('next') . ' >') ?>
<?= $this->Paginator->last(__('last') . ' >>') ?>
</ul>
<p><?= $this->Paginator->counter(__('Page {{page}} of {{pages}}, showing {{current}} record(s) out of {{count}} total')) ?></p>
</div>
</div>

View File

@ -0,0 +1,36 @@
<?php
/**
* @var \App\View\AppView $this
* @var \Cake\Datasource\EntityInterface $deAccountStatement
*/
?>
<div class="row">
<aside class="column">
<div class="side-nav">
<h4 class="heading"><?= __('Actions') ?></h4>
<?= $this->Html->link(__('Edit De Account Statement'), ['action' => 'edit', $deAccountStatement->account_number], ['class' => 'side-nav-item']) ?>
<?= $this->Form->postLink(__('Delete De Account Statement'), ['action' => 'delete', $deAccountStatement->account_number], ['confirm' => __('Are you sure you want to delete # {0}?', $deAccountStatement->account_number), 'class' => 'side-nav-item']) ?>
<?= $this->Html->link(__('List De Account Statements'), ['action' => 'index'], ['class' => 'side-nav-item']) ?>
<?= $this->Html->link(__('New De Account Statement'), ['action' => 'add'], ['class' => 'side-nav-item']) ?>
</div>
</aside>
<div class="column column-80">
<div class="deAccountStatements view content">
<h3><?= h($deAccountStatement->Array) ?></h3>
<table>
<tr>
<th><?= __('De Account') ?></th>
<td><?= $deAccountStatement->hasValue('de_account') ? $this->Html->link($deAccountStatement->de_account->name, ['controller' => 'DeAccounts', 'action' => 'view', $deAccountStatement->de_account->id]) : '' ?></td>
</tr>
<tr>
<th><?= __('Closing Balance') ?></th>
<td><?= $this->Number->format($deAccountStatement->closing_balance) ?></td>
</tr>
<tr>
<th><?= __('Statement Date') ?></th>
<td><?= h($deAccountStatement->statement_date) ?></td>
</tr>
</table>
</div>
</div>
</div>

View File

@ -0,0 +1,28 @@
<?php
/**
* @var \App\View\AppView $this
* @var \Cake\Datasource\EntityInterface $deAccountTemplate
*/
?>
<div class="row">
<aside class="column">
<div class="side-nav">
<h4 class="heading"><?= __('Actions') ?></h4>
<?= $this->Html->link(__('List De Account Templates'), ['action' => 'index'], ['class' => 'side-nav-item']) ?>
</div>
</aside>
<div class="column column-80">
<div class="deAccountTemplates form content">
<?= $this->Form->create($deAccountTemplate) ?>
<fieldset>
<legend><?= __('Add De Account Template') ?></legend>
<?php
echo $this->Form->control('name');
echo $this->Form->control('deleted', ['empty' => true]);
?>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
</div>
</div>
</div>

View File

@ -0,0 +1,33 @@
<?php
/**
* @var \App\View\AppView $this
* @var \Cake\Datasource\EntityInterface $deAccountTemplate
*/
?>
<div class="row">
<aside class="column">
<div class="side-nav">
<h4 class="heading"><?= __('Actions') ?></h4>
<?= $this->Form->postLink(
__('Delete'),
['action' => 'delete', $deAccountTemplate->id],
['confirm' => __('Are you sure you want to delete # {0}?', $deAccountTemplate->id), 'class' => 'side-nav-item']
) ?>
<?= $this->Html->link(__('List De Account Templates'), ['action' => 'index'], ['class' => 'side-nav-item']) ?>
</div>
</aside>
<div class="column column-80">
<div class="deAccountTemplates form content">
<?= $this->Form->create($deAccountTemplate) ?>
<fieldset>
<legend><?= __('Edit De Account Template') ?></legend>
<?php
echo $this->Form->control('name');
echo $this->Form->control('deleted', ['empty' => true]);
?>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
</div>
</div>
</div>

View File

@ -0,0 +1,52 @@
<?php
/**
* @var \App\View\AppView $this
* @var iterable<\Cake\Datasource\EntityInterface> $deAccountTemplates
*/
?>
<div class="deAccountTemplates index content">
<?= $this->Html->link(__('New De Account Template'), ['action' => 'add'], ['class' => 'button float-right']) ?>
<h3><?= __('De Account Templates') ?></h3>
<div class="table-responsive">
<table>
<thead>
<tr>
<th><?= $this->Paginator->sort('id') ?></th>
<th><?= $this->Paginator->sort('name') ?></th>
<th><?= $this->Paginator->sort('deleted') ?></th>
<th class="actions"><?= __('Actions') ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($deAccountTemplates as $deAccountTemplate): ?>
<tr>
<td><?= $this->Number->format($deAccountTemplate->id) ?></td>
<td><?= h($deAccountTemplate->name) ?></td>
<td><?= h($deAccountTemplate->deleted) ?></td>
<td class="actions">
<?= $this->Html->link(__('View'), ['action' => 'view', $deAccountTemplate->id]) ?>
<?= $this->Html->link(__('Edit'), ['action' => 'edit', $deAccountTemplate->id]) ?>
<?= $this->Form->postLink(__('Import'), [
'action' => 'select',
$deAccountTemplate->id,
], [
'confirm' => __('Are you sure you want to import Accounts from Accounts Template "{0}"?', $deAccountTemplate->name),
]); ?>
<?= $this->Form->postLink(__('Delete'), ['action' => 'delete', $deAccountTemplate->id], ['confirm' => __('Are you sure you want to delete # {0}?', $deAccountTemplate->id)]) ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<div class="paginator">
<ul class="pagination">
<?= $this->Paginator->first('<< ' . __('first')) ?>
<?= $this->Paginator->prev('< ' . __('previous')) ?>
<?= $this->Paginator->numbers() ?>
<?= $this->Paginator->next(__('next') . ' >') ?>
<?= $this->Paginator->last(__('last') . ' >>') ?>
</ul>
<p><?= $this->Paginator->counter(__('Page {{page}} of {{pages}}, showing {{current}} record(s) out of {{count}} total')) ?></p>
</div>
</div>

View File

@ -0,0 +1,79 @@
<?php
/**
* @var \App\View\AppView $this
* @var \Cake\Datasource\EntityInterface $deAccountTemplate
*/
?>
<div class="row">
<aside class="column">
<div class="side-nav">
<h4 class="heading"><?= __('Actions') ?></h4>
<?= $this->Html->link(__('Edit De Account Template'), ['action' => 'edit', $deAccountTemplate->id], ['class' => 'side-nav-item']) ?>
<?= $this->Form->postLink(__('Delete De Account Template'), ['action' => 'delete', $deAccountTemplate->id], ['confirm' => __('Are you sure you want to delete # {0}?', $deAccountTemplate->id), 'class' => 'side-nav-item']) ?>
<?= $this->Html->link(__('List De Account Templates'), ['action' => 'index'], ['class' => 'side-nav-item']) ?>
<?= $this->Html->link(__('New De Account Template'), ['action' => 'add'], ['class' => 'side-nav-item']) ?>
</div>
</aside>
<div class="column column-80">
<div class="deAccountTemplates view content">
<h3><?= h($deAccountTemplate->name) ?></h3>
<table>
<tr>
<th><?= __('Name') ?></th>
<td><?= h($deAccountTemplate->name) ?></td>
</tr>
<tr>
<th><?= __('Id') ?></th>
<td><?= $this->Number->format($deAccountTemplate->id) ?></td>
</tr>
<tr>
<th><?= __('Deleted') ?></th>
<td><?= h($deAccountTemplate->deleted) ?></td>
</tr>
</table>
<div class="related">
<h4><?= __('Related De Templated Accounts') ?></h4>
<?php if (!empty($deAccountTemplate->de_templated_accounts)) : ?>
<div class="table-responsive">
<table>
<tr>
<th><?= __('Id') ?></th>
<th><?= __('Account Number') ?></th>
<th><?= __('Account Template Id') ?></th>
<th><?= __('Parent Id') ?></th>
<th><?= __('Lft') ?></th>
<th><?= __('Rght') ?></th>
<th><?= __('Account Type Code') ?></th>
<th><?= __('Account Limit') ?></th>
<th><?= __('Can Credit') ?></th>
<th><?= __('Can Debit') ?></th>
<th><?= __('Name') ?></th>
<th class="actions"><?= __('Actions') ?></th>
</tr>
<?php foreach ($deAccountTemplate->de_templated_accounts as $deTemplatedAccounts) : ?>
<tr>
<td><?= h($deTemplatedAccounts->id) ?></td>
<td><?= h($deTemplatedAccounts->account_number) ?></td>
<td><?= h($deTemplatedAccounts->account_template_id) ?></td>
<td><?= h($deTemplatedAccounts->parent_id) ?></td>
<td><?= h($deTemplatedAccounts->lft) ?></td>
<td><?= h($deTemplatedAccounts->rght) ?></td>
<td><?= h($deTemplatedAccounts->account_type_code) ?></td>
<td><?= h($deTemplatedAccounts->account_limit) ?></td>
<td><?= h($deTemplatedAccounts->can_credit) ?></td>
<td><?= h($deTemplatedAccounts->can_debit) ?></td>
<td><?= h($deTemplatedAccounts->name) ?></td>
<td class="actions">
<?= $this->Html->link(__('View'), ['controller' => 'DeTemplatedAccounts', 'action' => 'view', $deTemplatedAccounts->id]) ?>
<?= $this->Html->link(__('Edit'), ['controller' => 'DeTemplatedAccounts', 'action' => 'edit', $deTemplatedAccounts->id]) ?>
<?= $this->Form->postLink(__('Delete'), ['controller' => 'DeTemplatedAccounts', 'action' => 'delete', $deTemplatedAccounts->id], ['confirm' => __('Are you sure you want to delete # {0}?', $deTemplatedAccounts->id)]) ?>
</td>
</tr>
<?php endforeach; ?>
</table>
</div>
<?php endif; ?>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,30 @@
<?php
/**
* @var \App\View\AppView $this
* @var \Cake\Datasource\EntityInterface $deAccountTransaction
* @var \Cake\Collection\CollectionInterface|string[] $deTransactions
*/
?>
<div class="row">
<aside class="column">
<div class="side-nav">
<h4 class="heading"><?= __('Actions') ?></h4>
<?= $this->Html->link(__('List De Account Transactions'), ['action' => 'index'], ['class' => 'side-nav-item']) ?>
</div>
</aside>
<div class="column column-80">
<div class="deAccountTransactions form content">
<?= $this->Form->create($deAccountTransaction) ?>
<fieldset>
<legend><?= __('Add De Account Transaction') ?></legend>
<?php
echo $this->Form->control('transaction_type_code');
echo $this->Form->control('de_code');
echo $this->Form->control('account_number');
?>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
</div>
</div>
</div>

View File

@ -0,0 +1,50 @@
<?php
/**
* @var \App\View\AppView $this
* @var iterable<\Cake\Datasource\EntityInterface> $deAccountTransactions
*/
?>
<div class="deAccountTransactions index content">
<?= $this->Html->link(__('New De Account Transaction'), ['action' => 'add'], ['class' => 'button float-right']) ?>
<h3><?= __('De Account Transactions') ?></h3>
<div class="table-responsive">
<table>
<thead>
<tr>
<th><?= $this->Paginator->sort('ledger_id') ?></th>
<th><?= $this->Paginator->sort('submitted_at') ?></th>
<th><?= $this->Paginator->sort('transaction_type_code') ?></th>
<th><?= $this->Paginator->sort('de_code') ?></th>
<th><?= $this->Paginator->sort('account_number') ?></th>
<th class="actions"><?= __('Actions') ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($deAccountTransactions as $deAccountTransaction): ?>
<tr>
<td><?= $deAccountTransaction->hasValue('de_transaction') ? $this->Html->link($deAccountTransaction->de_transaction->ledger_transaction_type_code, ['controller' => 'DeTransactions', 'action' => 'view', $deAccountTransaction->de_transaction->ledger_id]) : '' ?></td>
<td><?= h($deAccountTransaction->submitted_at) ?></td>
<td><?= h($deAccountTransaction->transaction_type_code) ?></td>
<td><?= h($deAccountTransaction->de_code) ?></td>
<td><?= h($deAccountTransaction->account_number) ?></td>
<td class="actions">
<?= $this->Html->link(__('View'), ['action' => 'view', $deAccountTransaction->ledger_id]) ?>
<?= $this->Html->link(__('Edit'), ['action' => 'edit', $deAccountTransaction->ledger_id]) ?>
<?= $this->Form->postLink(__('Delete'), ['action' => 'delete', $deAccountTransaction->ledger_id], ['confirm' => __('Are you sure you want to delete # {0}?', $deAccountTransaction->ledger_id)]) ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<div class="paginator">
<ul class="pagination">
<?= $this->Paginator->first('<< ' . __('first')) ?>
<?= $this->Paginator->prev('< ' . __('previous')) ?>
<?= $this->Paginator->numbers() ?>
<?= $this->Paginator->next(__('next') . ' >') ?>
<?= $this->Paginator->last(__('last') . ' >>') ?>
</ul>
<p><?= $this->Paginator->counter(__('Page {{page}} of {{pages}}, showing {{current}} record(s) out of {{count}} total')) ?></p>
</div>
</div>

View File

@ -0,0 +1,44 @@
<?php
/**
* @var \App\View\AppView $this
* @var \Cake\Datasource\EntityInterface $deAccountTransaction
*/
?>
<div class="row">
<aside class="column">
<div class="side-nav">
<h4 class="heading"><?= __('Actions') ?></h4>
<?= $this->Html->link(__('Edit De Account Transaction'), ['action' => 'edit', $deAccountTransaction->ledger_id], ['class' => 'side-nav-item']) ?>
<?= $this->Form->postLink(__('Delete De Account Transaction'), ['action' => 'delete', $deAccountTransaction->ledger_id], ['confirm' => __('Are you sure you want to delete # {0}?', $deAccountTransaction->ledger_id), 'class' => 'side-nav-item']) ?>
<?= $this->Html->link(__('List De Account Transactions'), ['action' => 'index'], ['class' => 'side-nav-item']) ?>
<?= $this->Html->link(__('New De Account Transaction'), ['action' => 'add'], ['class' => 'side-nav-item']) ?>
</div>
</aside>
<div class="column column-80">
<div class="deAccountTransactions view content">
<h3><?= h($deAccountTransaction->transaction_type_code) ?></h3>
<table>
<tr>
<th><?= __('De Transaction') ?></th>
<td><?= $deAccountTransaction->hasValue('de_transaction') ? $this->Html->link($deAccountTransaction->de_transaction->ledger_transaction_type_code, ['controller' => 'DeTransactions', 'action' => 'view', $deAccountTransaction->de_transaction->ledger_id]) : '' ?></td>
</tr>
<tr>
<th><?= __('Transaction Type Code') ?></th>
<td><?= h($deAccountTransaction->transaction_type_code) ?></td>
</tr>
<tr>
<th><?= __('De Code') ?></th>
<td><?= h($deAccountTransaction->de_code) ?></td>
</tr>
<tr>
<th><?= __('Account Number') ?></th>
<td><?= h($deAccountTransaction->account_number) ?></td>
</tr>
<tr>
<th><?= __('Submitted At') ?></th>
<td><?= h($deAccountTransaction->submitted_at) ?></td>
</tr>
</table>
</div>
</div>
</div>

View File

@ -0,0 +1,33 @@
<?php
/**
* @var \App\View\AppView $this
* @var \Cake\Datasource\EntityInterface $deAccount
* @var \Cake\Collection\CollectionInterface|string[] $deAccountTypes
* @var \Cake\Collection\CollectionInterface|string[] $parentDeAccounts
*/
?>
<div class="row">
<aside class="column">
<div class="side-nav">
<h4 class="heading"><?= __('Actions') ?></h4>
<?= $this->Html->link(__('List De Accounts'), ['action' => 'index'], ['class' => 'side-nav-item']) ?>
</div>
</aside>
<div class="column column-80">
<div class="deAccounts form content">
<?= $this->Form->create($deAccount) ?>
<fieldset>
<legend><?= __('Add De Account') ?></legend>
<?php
echo $this->Form->control('parent_id', ['options' => $accounts, 'empty' => true]);
echo $this->Form->control('account_type_code', ['options' => $deAccountTypes]);
echo $this->Form->control('account_number');
echo $this->Form->control('name');
echo $this->Form->control('account_limit');
?>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
</div>
</div>
</div>

View File

@ -0,0 +1,40 @@
<?php
/**
* @var \App\View\AppView $this
* @var \Cake\Datasource\EntityInterface $deAccount
* @var string[]|\Cake\Collection\CollectionInterface $deAccountTypes
* @var string[]|\Cake\Collection\CollectionInterface $parentDeAccounts
*/
?>
<div class="row">
<aside class="column">
<div class="side-nav">
<h4 class="heading"><?= __('Actions') ?></h4>
<?= $this->Form->postLink(
__('Delete'),
['action' => 'delete', $deAccount->id],
['confirm' => __('Are you sure you want to delete # {0}?', $deAccount->id), 'class' => 'side-nav-item']
) ?>
<?= $this->Html->link(__('List De Accounts'), ['action' => 'index'], ['class' => 'side-nav-item']) ?>
</div>
</aside>
<div class="column column-80">
<div class="deAccounts form content">
<?= $this->Form->create($deAccount) ?>
<fieldset>
<legend><?= __('Edit De Account') ?></legend>
<?php
echo $this->Form->control('account_number');
echo $this->Form->control('parent_id', ['options' => $parentDeAccounts, 'empty' => true]);
echo $this->Form->control('account_type_code', ['options' => $deAccountTypes]);
echo $this->Form->control('name');
echo $this->Form->control('account_limit');
echo $this->Form->control('can_credit');
echo $this->Form->control('can_debit');
?>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
</div>
</div>
</div>

View File

@ -0,0 +1,36 @@
<?php
/**
* @var \App\View\AppView $this
* @var iterable<\Cake\Datasource\EntityInterface> $deAccounts
*/
?>
<div class="deAccounts index content">
<?= $this->Html->link(__('Use Account Templates'), [
'plugin' => 'CakeAccounting',
'controller' => 'DeAccountTemplates',
'action' => 'index'
], ['class' => 'button float-right']) ?>
<?= $this->Html->link(__('New De Account'), ['action' => 'add'], ['class' => 'button float-right']) ?>
<h3><?= __('De Accounts') ?></h3>
<div class="table-responsive">
<table>
<thead>
<tr>
<th><?= 'Account Type' ?></th>
<th><?= 'Account Number' ?></th>
<th><?= 'Name' ?></th>
<th><?= 'Total' ?></th>
<th class="actions"><?= __('Actions') ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($deAccounts as $deAccount) : ?>
<?= $this->element('DeAccounts/row', [
'account' => $deAccount,
'totals' => array_key_exists($deAccount->account_number, $totals) ? $totals[$deAccount->account_number] : [],
]); ?>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>

View File

@ -0,0 +1,131 @@
<?php
/**
* @var \App\View\AppView $this
* @var \Cake\Datasource\EntityInterface $deAccount
*/
?>
<div class="row">
<aside class="column">
<div class="side-nav">
<h4 class="heading"><?= __('Actions') ?></h4>
<?= $this->Html->link(__('Edit De Account'), ['action' => 'edit', $deAccount->id], ['class' => 'side-nav-item']) ?>
<?= $this->Form->postLink(__('Delete De Account'), ['action' => 'delete', $deAccount->id], ['confirm' => __('Are you sure you want to delete # {0}?', $deAccount->id), 'class' => 'side-nav-item']) ?>
<?= $this->Html->link(__('List De Accounts'), ['action' => 'index'], ['class' => 'side-nav-item']) ?>
<?= $this->Html->link(__('New De Account'), ['action' => 'add'], ['class' => 'side-nav-item']) ?>
</div>
</aside>
<div class="column column-80">
<div class="deAccounts view content">
<h3><?= h($deAccount->name) ?></h3>
<h5><?= 'Current Balance: '; ?><strong>
<?= $totals && array_key_exists($deAccount->account_number, $totals) && array_key_exists('balance', $totals[$deAccount->account_number]) ? $this->Number->format($totals[$deAccount->account_number]['balance']) : 0; ?>
</strong>
</h5>
<table>
<?php if ($deAccount->hasValue('parent_de_account')) : ?>
<tr>
<th><?= __('Parent De Account') ?></th>
<td>
<?= $deAccount->hasValue('parent_de_account') ? $this->Html->link($deAccount->parent_de_account->name, [
'controller' => 'DeAccounts',
'action' => 'view',
$deAccount->parent_de_account->id,
]) : '' ?></td>
</tr>
<?php endif; ?>
<tr>
<th><?= __('De Account Type') ?></th>
<td><?= $deAccount->hasValue('de_account_type') ? $this->Html->link($deAccount->de_account_type->name, ['controller' => 'DeAccountTypes', 'action' => 'view', $deAccount->de_account_type->account_type_code]) : '' ?></td>
</tr>
<tr>
<th><?= __('Name') ?></th>
<td><?= h($deAccount->name) ?></td>
</tr>
<tr>
<th><?= __('Account Number') ?></th>
<td><?= $deAccount->account_number ?></td>
</tr>
<tr>
<th><?= __('Account Limit') ?></th>
<td><?= $deAccount->account_limit === null ? '' : $this->Number->format($deAccount->account_limit) ?></td>
</tr>
<tr>
<th><?= __('Can Credit') ?></th>
<td><?= $deAccount->can_credit ? __('Yes') : __('No'); ?></td>
</tr>
<tr>
<th><?= __('Can Debit') ?></th>
<td><?= $deAccount->can_debit ? __('Yes') : __('No'); ?></td>
</tr>
</table>
<div class="related">
<h4><?= __('Related De Accounts') ?></h4>
<?php if (!empty($deAccount->child_de_accounts)) : ?>
<div class="table-responsive">
<table>
<tr>
<th><?= __('Id') ?></th>
<th><?= __('Account Number') ?></th>
<th><?= __('Parent Id') ?></th>
<th><?= __('Lft') ?></th>
<th><?= __('Rght') ?></th>
<th><?= __('Account Type Code') ?></th>
<th><?= __('Name') ?></th>
<th><?= __('Account Limit') ?></th>
<th><?= __('Can Credit') ?></th>
<th><?= __('Can Debit') ?></th>
<th class="actions"><?= __('Actions') ?></th>
</tr>
<?php foreach ($deAccount->child_de_accounts as $childDeAccounts) : ?>
<tr>
<td><?= h($childDeAccounts->id) ?></td>
<td><?= h($childDeAccounts->account_number) ?></td>
<td><?= h($childDeAccounts->parent_id) ?></td>
<td><?= h($childDeAccounts->lft) ?></td>
<td><?= h($childDeAccounts->rght) ?></td>
<td><?= h($childDeAccounts->account_type_code) ?></td>
<td><?= h($childDeAccounts->name) ?></td>
<td><?= h($childDeAccounts->account_limit) ?></td>
<td><?= h($childDeAccounts->can_credit) ?></td>
<td><?= h($childDeAccounts->can_debit) ?></td>
<td class="actions">
<?= $this->Html->link(__('View'), ['controller' => 'DeAccounts', 'action' => 'view', $childDeAccounts->id]) ?>
<?= $this->Html->link(__('Edit'), ['controller' => 'DeAccounts', 'action' => 'edit', $childDeAccounts->id]) ?>
<?= $this->Form->postLink(__('Delete'), ['controller' => 'DeAccounts', 'action' => 'delete', $childDeAccounts->id], ['confirm' => __('Are you sure you want to delete # {0}?', $childDeAccounts->id)]) ?>
</td>
</tr>
<?php endforeach; ?>
</table>
</div>
<?php endif; ?>
</div>
<div class="related">
<h4><?= __('Related De Account Statements') ?></h4>
<?php if (!empty($deAccount->de_account_statements)) : ?>
<div class="table-responsive">
<table>
<tr>
<th><?= __('Account Number') ?></th>
<th><?= __('Statement Date') ?></th>
<th><?= __('Closing Balance') ?></th>
<th class="actions"><?= __('Actions') ?></th>
</tr>
<?php foreach ($deAccount->de_account_statements as $deAccountStatements) : ?>
<tr>
<td><?= h($deAccountStatements->account_number) ?></td>
<td><?= h($deAccountStatements->statement_date) ?></td>
<td><?= h($deAccountStatements->closing_balance) ?></td>
<td class="actions">
<?= $this->Html->link(__('View'), ['controller' => 'DeAccountStatements', 'action' => 'view', $deAccountStatements->account_number]) ?>
<?= $this->Html->link(__('Edit'), ['controller' => 'DeAccountStatements', 'action' => 'edit', $deAccountStatements->account_number]) ?>
<?= $this->Form->postLink(__('Delete'), ['controller' => 'DeAccountStatements', 'action' => 'delete', $deAccountStatements->account_number], ['confirm' => __('Are you sure you want to delete # {0}?', $deAccountStatements->account_number)]) ?>
</td>
</tr>
<?php endforeach; ?>
</table>
</div>
<?php endif; ?>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,29 @@
<?php
/**
* @var \App\View\AppView $this
* @var \Cake\Datasource\EntityInterface $deExternalAccountStatement
*/
?>
<div class="row">
<aside class="column">
<div class="side-nav">
<h4 class="heading"><?= __('Actions') ?></h4>
<?= $this->Html->link(__('List De External Account Statements'), ['action' => 'index'], ['class' => 'side-nav-item']) ?>
</div>
</aside>
<div class="column column-80">
<div class="deExternalAccountStatements form content">
<?= $this->Form->create($deExternalAccountStatement) ?>
<fieldset>
<legend><?= __('Add De External Account Statement') ?></legend>
<?php
echo $this->Form->control('closing_balance');
echo $this->Form->control('total_credit');
echo $this->Form->control('total_debit');
?>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
</div>
</div>
</div>

View File

@ -0,0 +1,34 @@
<?php
/**
* @var \App\View\AppView $this
* @var \Cake\Datasource\EntityInterface $deExternalAccountStatement
*/
?>
<div class="row">
<aside class="column">
<div class="side-nav">
<h4 class="heading"><?= __('Actions') ?></h4>
<?= $this->Form->postLink(
__('Delete'),
['action' => 'delete', $deExternalAccountStatement->external_account_number],
['confirm' => __('Are you sure you want to delete # {0}?', $deExternalAccountStatement->external_account_number), 'class' => 'side-nav-item']
) ?>
<?= $this->Html->link(__('List De External Account Statements'), ['action' => 'index'], ['class' => 'side-nav-item']) ?>
</div>
</aside>
<div class="column column-80">
<div class="deExternalAccountStatements form content">
<?= $this->Form->create($deExternalAccountStatement) ?>
<fieldset>
<legend><?= __('Edit De External Account Statement') ?></legend>
<?php
echo $this->Form->control('closing_balance');
echo $this->Form->control('total_credit');
echo $this->Form->control('total_debit');
?>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
</div>
</div>
</div>

View File

@ -0,0 +1,50 @@
<?php
/**
* @var \App\View\AppView $this
* @var iterable<\Cake\Datasource\EntityInterface> $deExternalAccountStatements
*/
?>
<div class="deExternalAccountStatements index content">
<?= $this->Html->link(__('New De External Account Statement'), ['action' => 'add'], ['class' => 'button float-right']) ?>
<h3><?= __('De External Account Statements') ?></h3>
<div class="table-responsive">
<table>
<thead>
<tr>
<th><?= $this->Paginator->sort('external_account_number') ?></th>
<th><?= $this->Paginator->sort('statement_date') ?></th>
<th><?= $this->Paginator->sort('closing_balance') ?></th>
<th><?= $this->Paginator->sort('total_credit') ?></th>
<th><?= $this->Paginator->sort('total_debit') ?></th>
<th class="actions"><?= __('Actions') ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($deExternalAccountStatements as $deExternalAccountStatement): ?>
<tr>
<td><?= h($deExternalAccountStatement->external_account_number) ?></td>
<td><?= h($deExternalAccountStatement->statement_date) ?></td>
<td><?= $this->Number->format($deExternalAccountStatement->closing_balance) ?></td>
<td><?= $this->Number->format($deExternalAccountStatement->total_credit) ?></td>
<td><?= $this->Number->format($deExternalAccountStatement->total_debit) ?></td>
<td class="actions">
<?= $this->Html->link(__('View'), ['action' => 'view', $deExternalAccountStatement->external_account_number]) ?>
<?= $this->Html->link(__('Edit'), ['action' => 'edit', $deExternalAccountStatement->external_account_number]) ?>
<?= $this->Form->postLink(__('Delete'), ['action' => 'delete', $deExternalAccountStatement->external_account_number], ['confirm' => __('Are you sure you want to delete # {0}?', $deExternalAccountStatement->external_account_number)]) ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<div class="paginator">
<ul class="pagination">
<?= $this->Paginator->first('<< ' . __('first')) ?>
<?= $this->Paginator->prev('< ' . __('previous')) ?>
<?= $this->Paginator->numbers() ?>
<?= $this->Paginator->next(__('next') . ' >') ?>
<?= $this->Paginator->last(__('last') . ' >>') ?>
</ul>
<p><?= $this->Paginator->counter(__('Page {{page}} of {{pages}}, showing {{current}} record(s) out of {{count}} total')) ?></p>
</div>
</div>

View File

@ -0,0 +1,44 @@
<?php
/**
* @var \App\View\AppView $this
* @var \Cake\Datasource\EntityInterface $deExternalAccountStatement
*/
?>
<div class="row">
<aside class="column">
<div class="side-nav">
<h4 class="heading"><?= __('Actions') ?></h4>
<?= $this->Html->link(__('Edit De External Account Statement'), ['action' => 'edit', $deExternalAccountStatement->external_account_number], ['class' => 'side-nav-item']) ?>
<?= $this->Form->postLink(__('Delete De External Account Statement'), ['action' => 'delete', $deExternalAccountStatement->external_account_number], ['confirm' => __('Are you sure you want to delete # {0}?', $deExternalAccountStatement->external_account_number), 'class' => 'side-nav-item']) ?>
<?= $this->Html->link(__('List De External Account Statements'), ['action' => 'index'], ['class' => 'side-nav-item']) ?>
<?= $this->Html->link(__('New De External Account Statement'), ['action' => 'add'], ['class' => 'side-nav-item']) ?>
</div>
</aside>
<div class="column column-80">
<div class="deExternalAccountStatements view content">
<h3><?= h($deExternalAccountStatement->Array) ?></h3>
<table>
<tr>
<th><?= __('External Account Number') ?></th>
<td><?= h($deExternalAccountStatement->external_account_number) ?></td>
</tr>
<tr>
<th><?= __('Closing Balance') ?></th>
<td><?= $this->Number->format($deExternalAccountStatement->closing_balance) ?></td>
</tr>
<tr>
<th><?= __('Total Credit') ?></th>
<td><?= $this->Number->format($deExternalAccountStatement->total_credit) ?></td>
</tr>
<tr>
<th><?= __('Total Debit') ?></th>
<td><?= $this->Number->format($deExternalAccountStatement->total_debit) ?></td>
</tr>
<tr>
<th><?= __('Statement Date') ?></th>
<td><?= h($deExternalAccountStatement->statement_date) ?></td>
</tr>
</table>
</div>
</div>
</div>

View File

@ -0,0 +1,29 @@
<?php
/**
* @var \App\View\AppView $this
* @var \Cake\Datasource\EntityInterface $deExternalAccount
*/
?>
<div class="row">
<aside class="column">
<div class="side-nav">
<h4 class="heading"><?= __('Actions') ?></h4>
<?= $this->Html->link(__('List De External Accounts'), ['action' => 'index'], ['class' => 'side-nav-item']) ?>
</div>
</aside>
<div class="column column-80">
<div class="deExternalAccounts form content">
<?= $this->Form->create($deExternalAccount) ?>
<fieldset>
<legend><?= __('Add De External Account') ?></legend>
<?php
echo $this->Form->control('entity_type_code');
echo $this->Form->control('related_model');
echo $this->Form->control('related_model_fk');
?>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
</div>
</div>
</div>

View File

@ -0,0 +1,34 @@
<?php
/**
* @var \App\View\AppView $this
* @var \Cake\Datasource\EntityInterface $deExternalAccount
*/
?>
<div class="row">
<aside class="column">
<div class="side-nav">
<h4 class="heading"><?= __('Actions') ?></h4>
<?= $this->Form->postLink(
__('Delete'),
['action' => 'delete', $deExternalAccount->external_account_number],
['confirm' => __('Are you sure you want to delete # {0}?', $deExternalAccount->external_account_number), 'class' => 'side-nav-item']
) ?>
<?= $this->Html->link(__('List De External Accounts'), ['action' => 'index'], ['class' => 'side-nav-item']) ?>
</div>
</aside>
<div class="column column-80">
<div class="deExternalAccounts form content">
<?= $this->Form->create($deExternalAccount) ?>
<fieldset>
<legend><?= __('Edit De External Account') ?></legend>
<?php
echo $this->Form->control('entity_type_code');
echo $this->Form->control('related_model');
echo $this->Form->control('related_model_fk');
?>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
</div>
</div>
</div>

View File

@ -0,0 +1,50 @@
<?php
/**
* @var \App\View\AppView $this
* @var iterable<\Cake\Datasource\EntityInterface> $deExternalAccounts
*/
?>
<div class="deExternalAccounts index content">
<?= $this->Html->link(__('New De External Account'), ['action' => 'add'], ['class' => 'button float-right']) ?>
<h3><?= __('De External Accounts') ?></h3>
<div class="table-responsive">
<table>
<thead>
<tr>
<th><?= $this->Paginator->sort('external_account_number') ?></th>
<th><?= $this->Paginator->sort('entity_type_code') ?></th>
<th><?= $this->Paginator->sort('created') ?></th>
<th><?= $this->Paginator->sort('related_model') ?></th>
<th><?= $this->Paginator->sort('related_model_fk') ?></th>
<th class="actions"><?= __('Actions') ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($deExternalAccounts as $deExternalAccount): ?>
<tr>
<td><?= h($deExternalAccount->external_account_number) ?></td>
<td><?= h($deExternalAccount->entity_type_code) ?></td>
<td><?= h($deExternalAccount->created) ?></td>
<td><?= h($deExternalAccount->related_model) ?></td>
<td><?= $deExternalAccount->related_model_fk === null ? '' : $this->Number->format($deExternalAccount->related_model_fk) ?></td>
<td class="actions">
<?= $this->Html->link(__('View'), ['action' => 'view', $deExternalAccount->external_account_number]) ?>
<?= $this->Html->link(__('Edit'), ['action' => 'edit', $deExternalAccount->external_account_number]) ?>
<?= $this->Form->postLink(__('Delete'), ['action' => 'delete', $deExternalAccount->external_account_number], ['confirm' => __('Are you sure you want to delete # {0}?', $deExternalAccount->external_account_number)]) ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<div class="paginator">
<ul class="pagination">
<?= $this->Paginator->first('<< ' . __('first')) ?>
<?= $this->Paginator->prev('< ' . __('previous')) ?>
<?= $this->Paginator->numbers() ?>
<?= $this->Paginator->next(__('next') . ' >') ?>
<?= $this->Paginator->last(__('last') . ' >>') ?>
</ul>
<p><?= $this->Paginator->counter(__('Page {{page}} of {{pages}}, showing {{current}} record(s) out of {{count}} total')) ?></p>
</div>
</div>

View File

@ -0,0 +1,44 @@
<?php
/**
* @var \App\View\AppView $this
* @var \Cake\Datasource\EntityInterface $deExternalAccount
*/
?>
<div class="row">
<aside class="column">
<div class="side-nav">
<h4 class="heading"><?= __('Actions') ?></h4>
<?= $this->Html->link(__('Edit De External Account'), ['action' => 'edit', $deExternalAccount->external_account_number], ['class' => 'side-nav-item']) ?>
<?= $this->Form->postLink(__('Delete De External Account'), ['action' => 'delete', $deExternalAccount->external_account_number], ['confirm' => __('Are you sure you want to delete # {0}?', $deExternalAccount->external_account_number), 'class' => 'side-nav-item']) ?>
<?= $this->Html->link(__('List De External Accounts'), ['action' => 'index'], ['class' => 'side-nav-item']) ?>
<?= $this->Html->link(__('New De External Account'), ['action' => 'add'], ['class' => 'side-nav-item']) ?>
</div>
</aside>
<div class="column column-80">
<div class="deExternalAccounts view content">
<h3><?= h($deExternalAccount->entity_type_code) ?></h3>
<table>
<tr>
<th><?= __('External Account Number') ?></th>
<td><?= h($deExternalAccount->external_account_number) ?></td>
</tr>
<tr>
<th><?= __('Entity Type Code') ?></th>
<td><?= h($deExternalAccount->entity_type_code) ?></td>
</tr>
<tr>
<th><?= __('Related Model') ?></th>
<td><?= h($deExternalAccount->related_model) ?></td>
</tr>
<tr>
<th><?= __('Related Model Fk') ?></th>
<td><?= $deExternalAccount->related_model_fk === null ? '' : $this->Number->format($deExternalAccount->related_model_fk) ?></td>
</tr>
<tr>
<th><?= __('Created') ?></th>
<td><?= h($deExternalAccount->created) ?></td>
</tr>
</table>
</div>
</div>
</div>

View File

@ -0,0 +1,84 @@
<?php
/**
* @var \App\View\AppView $this
* @var \Cake\Datasource\EntityInterface $deJournalEntry
* @var \Cake\Collection\CollectionInterface|string[] $deJournals
* @var \Cake\Collection\CollectionInterface|string[] $users
*/
?>
<div class="row">
<aside class="column">
<div class="side-nav">
<h4 class="heading"><?= __('Actions') ?></h4>
<?= $this->Html->link(__('List De Journal Entries'), ['action' => 'index'], ['class' => 'side-nav-item']) ?>
</div>
</aside>
<div class="column column-80">
<div class="deJournalEntries form content">
<?= $this->Form->create($deJournalEntry) ?>
<legend><?= __('Add Journal Entry') ?></legend>
<?php
echo $this->Form->control('de_journal_id', ['options' => $deJournals]);
?>
<div class="row">
<div class="column">
<legend><?= __('Debit') ?></legend>
<?php
echo $this->Form->control('de_journal_items.0.account_number_debit', [
'type' => 'select',
'options' => $accounts,
'label' => 'Account',
'empty' => true,
'required' => true,
]);
echo $this->Form->control('de_journal_items.0.external_account_number_debit', [
'type' => 'select',
'options' => $externalAccounts ?? [],
'label' => 'External Account',
'empty' => true,
'required' => false,
]);
?>
</div>
<div class="column">
<legend><?= __('Amount') ?></legend>
<?php
echo $this->Form->control('de_journal_items.0.amount', [
'label' => false,
]);
?>
</div>
<div class="column">
<legend><?= __('Credit') ?></legend>
<?php
echo $this->Form->control('de_journal_items.0.account_number_credit', [
'type' => 'select',
'options' => $accounts,
'label' => 'Account',
'empty' => true,
'required' => true,
]);
echo $this->Form->control('de_journal_items.0.external_account_number_credit', [
'type' => 'select',
'options' => $externalAccounts ?? [],
'label' => 'External Account',
'empty' => true,
'required' => false,
]);
?>
</div>
</div>
<div class="row">
<div class="column">
<?php
echo $this->Form->control('notes', ['type' => 'textarea', 'rows' => 2]);
?>
</div>
</div>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
</div>
</div>
</div>

View File

@ -0,0 +1,35 @@
<?php
/**
* @var \App\View\AppView $this
* @var \Cake\Datasource\EntityInterface $deJournalEntry
* @var string[]|\Cake\Collection\CollectionInterface $deJournals
* @var string[]|\Cake\Collection\CollectionInterface $users
*/
?>
<div class="row">
<aside class="column">
<div class="side-nav">
<h4 class="heading"><?= __('Actions') ?></h4>
<?= $this->Form->postLink(
__('Delete'),
['action' => 'delete', $deJournalEntry->id],
['confirm' => __('Are you sure you want to delete # {0}?', $deJournalEntry->id), 'class' => 'side-nav-item']
) ?>
<?= $this->Html->link(__('List De Journal Entries'), ['action' => 'index'], ['class' => 'side-nav-item']) ?>
</div>
</aside>
<div class="column column-80">
<div class="deJournalEntries form content">
<?= $this->Form->create($deJournalEntry) ?>
<fieldset>
<legend><?= __('Edit De Journal Entry') ?></legend>
<?php
echo $this->Form->control('de_journal_id', ['options' => $deJournals]);
echo $this->Form->control('notes');
?>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
</div>
</div>
</div>

View File

@ -0,0 +1,48 @@
<?php
/**
* @var \App\View\AppView $this
* @var iterable<\Cake\Datasource\EntityInterface> $deJournalEntries
*/
?>
<div class="deJournalEntries index content">
<?= $this->Html->link(__('New De Journal Entry'), ['action' => 'add'], ['class' => 'button float-right']) ?>
<h3><?= __('De Journal Entries') ?></h3>
<div class="table-responsive">
<table>
<thead>
<tr>
<th><?= $this->Paginator->sort('id') ?></th>
<th><?= $this->Paginator->sort('de_journal_id') ?></th>
<th><?= $this->Paginator->sort('user_id') ?></th>
<th><?= $this->Paginator->sort('created') ?></th>
<th class="actions"><?= __('Actions') ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($deJournalEntries as $deJournalEntry): ?>
<tr>
<td><?= $this->Number->format($deJournalEntry->id) ?></td>
<td><?= $deJournalEntry->hasValue('de_journal') ? $this->Html->link($deJournalEntry->de_journal->name, ['controller' => 'DeJournals', 'action' => 'view', $deJournalEntry->de_journal->id]) : '' ?></td>
<td><?= $deJournalEntry->hasValue('user') ? $this->Html->link($deJournalEntry->user->first_name, ['controller' => 'Users', 'action' => 'view', $deJournalEntry->user->id]) : '' ?></td>
<td><?= h($deJournalEntry->created) ?></td>
<td class="actions">
<?= $this->Html->link(__('View'), ['action' => 'view', $deJournalEntry->id]) ?>
<?= $this->Html->link(__('Edit'), ['action' => 'edit', $deJournalEntry->id]) ?>
<?= $this->Form->postLink(__('Delete'), ['action' => 'delete', $deJournalEntry->id], ['confirm' => __('Are you sure you want to delete # {0}?', $deJournalEntry->id)]) ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<div class="paginator">
<ul class="pagination">
<?= $this->Paginator->first('<< ' . __('first')) ?>
<?= $this->Paginator->prev('< ' . __('previous')) ?>
<?= $this->Paginator->numbers() ?>
<?= $this->Paginator->next(__('next') . ' >') ?>
<?= $this->Paginator->last(__('last') . ' >>') ?>
</ul>
<p><?= $this->Paginator->counter(__('Page {{page}} of {{pages}}, showing {{current}} record(s) out of {{count}} total')) ?></p>
</div>
</div>

View File

@ -0,0 +1,83 @@
<?php
/**
* @var \App\View\AppView $this
* @var \Cake\Datasource\EntityInterface $deJournalEntry
*/
?>
<div class="row">
<aside class="column">
<div class="side-nav">
<h4 class="heading"><?= __('Actions') ?></h4>
<?= $this->Html->link(__('Edit De Journal Entry'), ['action' => 'edit', $deJournalEntry->id], ['class' => 'side-nav-item']) ?>
<?= $this->Form->postLink(__('Delete De Journal Entry'), ['action' => 'delete', $deJournalEntry->id], ['confirm' => __('Are you sure you want to delete # {0}?', $deJournalEntry->id), 'class' => 'side-nav-item']) ?>
<?= $this->Html->link(__('List De Journal Entries'), ['action' => 'index'], ['class' => 'side-nav-item']) ?>
<?= $this->Html->link(__('New De Journal Entry'), ['action' => 'add'], ['class' => 'side-nav-item']) ?>
</div>
</aside>
<div class="column column-80">
<div class="deJournalEntries view content">
<h3><?= h($deJournalEntry->id) ?></h3>
<table>
<tr>
<th><?= __('De Journal') ?></th>
<td><?= $deJournalEntry->hasValue('de_journal') ? $this->Html->link($deJournalEntry->de_journal->name, ['controller' => 'DeJournals', 'action' => 'view', $deJournalEntry->de_journal->id]) : '' ?></td>
</tr>
<tr>
<th><?= __('User') ?></th>
<td><?= $deJournalEntry->hasValue('user') ? $this->Html->link($deJournalEntry->user->first_name, ['controller' => 'Users', 'action' => 'view', $deJournalEntry->user->id]) : '' ?></td>
</tr>
<tr>
<th><?= __('Id') ?></th>
<td><?= $this->Number->format($deJournalEntry->id) ?></td>
</tr>
<tr>
<th><?= __('Created') ?></th>
<td><?= h($deJournalEntry->created) ?></td>
</tr>
</table>
<div class="text">
<strong><?= __('Notes') ?></strong>
<blockquote>
<?= $this->Text->autoParagraph(h($deJournalEntry->notes)); ?>
</blockquote>
</div>
<div class="related">
<h4><?= __('Related De Journal Items') ?></h4>
<?php if (!empty($deJournalEntry->de_journal_items)) : ?>
<div class="table-responsive">
<table>
<tr>
<th><?= __('Id') ?></th>
<th><?= __('Account Number Credit') ?></th>
<th><?= __('Account Number Debit') ?></th>
<th><?= __('External Account Number Credit') ?></th>
<th><?= __('External Account Number Debit') ?></th>
<th><?= __('De Journal Entry Id') ?></th>
<th><?= __('Amount') ?></th>
<th><?= __('Created') ?></th>
<th class="actions"><?= __('Actions') ?></th>
</tr>
<?php foreach ($deJournalEntry->de_journal_items as $deJournalItems) : ?>
<tr>
<td><?= h($deJournalItems->id) ?></td>
<td><?= h($deJournalItems->account_number_credit) ?></td>
<td><?= h($deJournalItems->account_number_debit) ?></td>
<td><?= h($deJournalItems->external_account_number_credit) ?></td>
<td><?= h($deJournalItems->external_account_number_debit) ?></td>
<td><?= h($deJournalItems->de_journal_entry_id) ?></td>
<td><?= h($deJournalItems->amount) ?></td>
<td><?= h($deJournalItems->created) ?></td>
<td class="actions">
<?= $this->Html->link(__('View'), ['controller' => 'DeJournalItems', 'action' => 'view', $deJournalItems->id]) ?>
<?= $this->Html->link(__('Edit'), ['controller' => 'DeJournalItems', 'action' => 'edit', $deJournalItems->id]) ?>
<?= $this->Form->postLink(__('Delete'), ['controller' => 'DeJournalItems', 'action' => 'delete', $deJournalItems->id], ['confirm' => __('Are you sure you want to delete # {0}?', $deJournalItems->id)]) ?>
</td>
</tr>
<?php endforeach; ?>
</table>
</div>
<?php endif; ?>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,33 @@
<?php
/**
* @var \App\View\AppView $this
* @var \Cake\Datasource\EntityInterface $deJournalItem
* @var \Cake\Collection\CollectionInterface|string[] $deJournalEntries
*/
?>
<div class="row">
<aside class="column">
<div class="side-nav">
<h4 class="heading"><?= __('Actions') ?></h4>
<?= $this->Html->link(__('List De Journal Items'), ['action' => 'index'], ['class' => 'side-nav-item']) ?>
</div>
</aside>
<div class="column column-80">
<div class="deJournalItems form content">
<?= $this->Form->create($deJournalItem) ?>
<fieldset>
<legend><?= __('Add De Journal Item') ?></legend>
<?php
echo $this->Form->control('account_number_credit');
echo $this->Form->control('account_number_debit');
echo $this->Form->control('external_account_number_credit');
echo $this->Form->control('external_account_number_debit');
echo $this->Form->control('de_journal_entry_id', ['options' => $deJournalEntries]);
echo $this->Form->control('amount');
?>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
</div>
</div>
</div>

View File

@ -0,0 +1,38 @@
<?php
/**
* @var \App\View\AppView $this
* @var \Cake\Datasource\EntityInterface $deJournalItem
* @var string[]|\Cake\Collection\CollectionInterface $deJournalEntries
*/
?>
<div class="row">
<aside class="column">
<div class="side-nav">
<h4 class="heading"><?= __('Actions') ?></h4>
<?= $this->Form->postLink(
__('Delete'),
['action' => 'delete', $deJournalItem->id],
['confirm' => __('Are you sure you want to delete # {0}?', $deJournalItem->id), 'class' => 'side-nav-item']
) ?>
<?= $this->Html->link(__('List De Journal Items'), ['action' => 'index'], ['class' => 'side-nav-item']) ?>
</div>
</aside>
<div class="column column-80">
<div class="deJournalItems form content">
<?= $this->Form->create($deJournalItem) ?>
<fieldset>
<legend><?= __('Edit De Journal Item') ?></legend>
<?php
echo $this->Form->control('account_number_credit');
echo $this->Form->control('account_number_debit');
echo $this->Form->control('external_account_number_credit');
echo $this->Form->control('external_account_number_debit');
echo $this->Form->control('de_journal_entry_id', ['options' => $deJournalEntries]);
echo $this->Form->control('amount');
?>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
</div>
</div>
</div>

View File

@ -0,0 +1,123 @@
<?php
/**
* @var \App\View\AppView $this
* @var iterable<\Cake\Datasource\EntityInterface> $deJournalItems
*/
?>
<div class="deJournalItems index content">
<?= $this->Html->link(__('New De Journal Entry'), ['controller' => 'DeJournalEntries', 'action' => 'add'], ['class' => 'button float-right']) ?>
<h3><?= __('De Journal Items') ?></h3>
<div class="table-responsive">
<table>
<thead>
<tr>
<th><?= $this->Paginator->sort('created') ?></th>
<th><?= $this->Paginator->sort('journal_entry.journal_id', 'Journal') ?></th>
<th><?= $this->Paginator->sort('de_journal_entry_id', 'Journal Entry') ?></th>
<th><?= $this->Paginator->sort('external_account_number_credit', 'DR Ext. Account') ?></th>
<th><?= $this->Paginator->sort('external_account_number_debit', 'CR Ext. Account') ?></th>
<th><?= $this->Paginator->sort('account_number_credit', 'Credit Account') ?></th>
<th><?= $this->Paginator->sort('account_number_debit', 'Debit Account') ?></th>
<th><?= $this->Paginator->sort('account_number_debit', 'Debit') ?></th>
<th><?= $this->Paginator->sort('account_number_credit', 'Credit') ?></th>
<th class="actions"><?= __('Actions') ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($deJournalItems as $deJournalItem): ?>
<tr>
<td><?= h($deJournalItem->created) ?></td>
<td>
<?= $deJournalItem->hasValue('de_journal_entry') && $deJournalItem->de_journal_entry->hasValue('de_journal') ?
$this->Html->link($deJournalItem->de_journal_entry->de_journal->name, ['controller' => 'DeJournals', 'action' => 'view', $deJournalItem->de_journal_entry->journal_id]) :
'' ?>
</td>
<td>
<?= $deJournalItem->hasValue('de_journal_entry') ?
$this->Html->link($deJournalItem->de_journal_entry->id, ['controller' => 'DeJournalEntries', 'action' => 'view', $deJournalItem->de_journal_entry->id]) :
'' ?>
</td>
<td colspan="2" style="text-align: center;">
<?= $deJournalItem->hasValue('debit_de_external_account') ?
$this->Html->link($deJournalItem->debit_de_external_account->account_number, [
'controller' => 'DeExternalAccounts',
'action' => 'view',
$deJournalItem->debit_de_external_account->account_number]) :
'' ?>
</td>
<td colspan="2" style="text-align: right;">
<?= $deJournalItem->hasValue('debit_de_account') ?
$this->Html->link($deJournalItem->debit_de_account->account_number_and_name, [
'controller' => 'DeAccounts',
'action' => 'view',
$deJournalItem->debit_de_account->account_number]) :
'' ?>
</td>
<td><?= $deJournalItem->hasValue('debit_de_account') ? $this->Number->format($deJournalItem->amount) : ''; ?></td>
<td><?= ''; ?></td>
<td class="actions">
<?= $this->Html->link(__('View'), ['action' => 'view', $deJournalItem->id]) ?>
<?= $this->Html->link(__('Edit'), ['action' => 'edit', $deJournalItem->id]) ?>
<?= $this->Form->postLink(__('Delete'), ['action' => 'delete', $deJournalItem->id], ['confirm' => __('Are you sure you want to delete # {0}?', $deJournalItem->id)]) ?>
</td>
</tr>
<tr>
<td><?= h($deJournalItem->created) ?></td>
<td>
<?= $deJournalItem->hasValue('de_journal_entry') && $deJournalItem->de_journal_entry->hasValue('de_journal') ?
$this->Html->link($deJournalItem->de_journal_entry->de_journal->name, ['controller' => 'DeJournals', 'action' => 'view', $deJournalItem->de_journal_entry->journal_id]) :
'' ?>
</td>
<td>
<?= $deJournalItem->hasValue('de_journal_entry') ?
$this->Html->link($deJournalItem->de_journal_entry->id, ['controller' => 'DeJournalEntries', 'action' => 'view', $deJournalItem->de_journal_entry->id]) :
'' ?>
</td>
<td colspan="2" style="text-align: center;">
<?= $deJournalItem->hasValue('credit_de_external_account') ?
$this->Html->link($deJournalItem->credit_de_external_account->account_number, [
'controller' => 'DeExternalAccounts',
'action' => 'view',
$deJournalItem->credit_de_external_account->account_number]) :
'' ?>
</td>
<td colspan="2" style="text-align: right;">
<?= $deJournalItem->hasValue('credit_de_account') ?
$this->Html->link($deJournalItem->credit_de_account->account_number_and_name, [
'controller' => 'DeAccounts',
'action' => 'view',
$deJournalItem->credit_de_account->account_number]) :
'' ?>
</td>
<td><?= ''; ?></td>
<td><?= $deJournalItem->hasValue('credit_de_account') ? $this->Number->format($deJournalItem->amount) : ''; ?></td>
<td class="actions">
<?= $this->Html->link(__('View'), ['action' => 'view', $deJournalItem->id]) ?>
<?= $this->Html->link(__('Edit'), ['action' => 'edit', $deJournalItem->id]) ?>
<?= $this->Form->postLink(__('Delete'), ['action' => 'delete', $deJournalItem->id], ['confirm' => __('Are you sure you want to delete # {0}?', $deJournalItem->id)]) ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<div class="paginator">
<ul class="pagination">
<?= $this->Paginator->first('<< ' . __('first')) ?>
<?= $this->Paginator->prev('< ' . __('previous')) ?>
<?= $this->Paginator->numbers() ?>
<?= $this->Paginator->next(__('next') . ' >') ?>
<?= $this->Paginator->last(__('last') . ' >>') ?>
</ul>
<p><?= $this->Paginator->counter(__('Page {{page}} of {{pages}}, showing {{current}} record(s) out of {{count}} total')) ?></p>
</div>
</div>

View File

@ -0,0 +1,56 @@
<?php
/**
* @var \App\View\AppView $this
* @var \Cake\Datasource\EntityInterface $deJournalItem
*/
?>
<div class="row">
<aside class="column">
<div class="side-nav">
<h4 class="heading"><?= __('Actions') ?></h4>
<?= $this->Html->link(__('Edit De Journal Item'), ['action' => 'edit', $deJournalItem->id], ['class' => 'side-nav-item']) ?>
<?= $this->Form->postLink(__('Delete De Journal Item'), ['action' => 'delete', $deJournalItem->id], ['confirm' => __('Are you sure you want to delete # {0}?', $deJournalItem->id), 'class' => 'side-nav-item']) ?>
<?= $this->Html->link(__('List De Journal Items'), ['action' => 'index'], ['class' => 'side-nav-item']) ?>
<?= $this->Html->link(__('New De Journal Item'), ['action' => 'add'], ['class' => 'side-nav-item']) ?>
</div>
</aside>
<div class="column column-80">
<div class="deJournalItems view content">
<h3><?= h($deJournalItem->id) ?></h3>
<table>
<tr>
<th><?= __('De Journal Entry') ?></th>
<td><?= $deJournalItem->hasValue('de_journal_entry') ? $this->Html->link($deJournalItem->de_journal_entry->id, ['controller' => 'DeJournalEntries', 'action' => 'view', $deJournalItem->de_journal_entry->id]) : '' ?></td>
</tr>
<tr>
<th><?= __('Id') ?></th>
<td><?= $this->Number->format($deJournalItem->id) ?></td>
</tr>
<tr>
<th><?= __('Account Number Credit') ?></th>
<td><?= $this->Number->format($deJournalItem->account_number_credit) ?></td>
</tr>
<tr>
<th><?= __('Account Number Debit') ?></th>
<td><?= $this->Number->format($deJournalItem->account_number_debit) ?></td>
</tr>
<tr>
<th><?= __('External Account Number Credit') ?></th>
<td><?= $deJournalItem->external_account_number_credit === null ? '' : $this->Number->format($deJournalItem->external_account_number_credit) ?></td>
</tr>
<tr>
<th><?= __('External Account Number Debit') ?></th>
<td><?= $deJournalItem->external_account_number_debit === null ? '' : $this->Number->format($deJournalItem->external_account_number_debit) ?></td>
</tr>
<tr>
<th><?= __('Amount') ?></th>
<td><?= $this->Number->format($deJournalItem->amount) ?></td>
</tr>
<tr>
<th><?= __('Created') ?></th>
<td><?= h($deJournalItem->created) ?></td>
</tr>
</table>
</div>
</div>
</div>

View File

@ -0,0 +1,31 @@
<?php
/**
* @var \App\View\AppView $this
* @var \Cake\Datasource\EntityInterface $deJournal
*/
?>
<div class="row">
<aside class="column">
<div class="side-nav">
<h4 class="heading"><?= __('Actions') ?></h4>
<?= $this->Html->link(__('List De Journals'), ['action' => 'index'], ['class' => 'side-nav-item']) ?>
</div>
</aside>
<div class="column column-80">
<div class="deJournals form content">
<?= $this->Form->create($deJournal) ?>
<fieldset>
<legend><?= __('Add De Journal') ?></legend>
<?php
echo $this->Form->control('name');
echo $this->Form->control('short_code');
echo $this->Form->control('default_account_number_credit');
echo $this->Form->control('default_account_number_debit');
echo $this->Form->control('de_journal_type_code');
?>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
</div>
</div>
</div>

View File

@ -0,0 +1,36 @@
<?php
/**
* @var \App\View\AppView $this
* @var \Cake\Datasource\EntityInterface $deJournal
*/
?>
<div class="row">
<aside class="column">
<div class="side-nav">
<h4 class="heading"><?= __('Actions') ?></h4>
<?= $this->Form->postLink(
__('Delete'),
['action' => 'delete', $deJournal->id],
['confirm' => __('Are you sure you want to delete # {0}?', $deJournal->id), 'class' => 'side-nav-item']
) ?>
<?= $this->Html->link(__('List De Journals'), ['action' => 'index'], ['class' => 'side-nav-item']) ?>
</div>
</aside>
<div class="column column-80">
<div class="deJournals form content">
<?= $this->Form->create($deJournal) ?>
<fieldset>
<legend><?= __('Edit De Journal') ?></legend>
<?php
echo $this->Form->control('name');
echo $this->Form->control('short_code');
echo $this->Form->control('default_account_number_credit');
echo $this->Form->control('default_account_number_debit');
echo $this->Form->control('de_journal_type_code');
?>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
</div>
</div>
</div>

View File

@ -0,0 +1,52 @@
<?php
/**
* @var \App\View\AppView $this
* @var iterable<\Cake\Datasource\EntityInterface> $deJournals
*/
?>
<div class="deJournals index content">
<?= $this->Html->link(__('New De Journal'), ['action' => 'add'], ['class' => 'button float-right']) ?>
<h3><?= __('De Journals') ?></h3>
<div class="table-responsive">
<table>
<thead>
<tr>
<th><?= $this->Paginator->sort('id') ?></th>
<th><?= $this->Paginator->sort('name') ?></th>
<th><?= $this->Paginator->sort('short_code') ?></th>
<th><?= $this->Paginator->sort('default_account_number_credit') ?></th>
<th><?= $this->Paginator->sort('default_account_number_debit') ?></th>
<th><?= $this->Paginator->sort('de_journal_type_code') ?></th>
<th class="actions"><?= __('Actions') ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($deJournals as $deJournal): ?>
<tr>
<td><?= $this->Number->format($deJournal->id) ?></td>
<td><?= h($deJournal->name) ?></td>
<td><?= h($deJournal->short_code) ?></td>
<td><?= $deJournal->default_account_number_credit === null ? '' : $this->Number->format($deJournal->default_account_number_credit) ?></td>
<td><?= $deJournal->default_account_number_debit === null ? '' : $this->Number->format($deJournal->default_account_number_debit) ?></td>
<td><?= h($deJournal->de_journal_type_code) ?></td>
<td class="actions">
<?= $this->Html->link(__('View'), ['action' => 'view', $deJournal->id]) ?>
<?= $this->Html->link(__('Edit'), ['action' => 'edit', $deJournal->id]) ?>
<?= $this->Form->postLink(__('Delete'), ['action' => 'delete', $deJournal->id], ['confirm' => __('Are you sure you want to delete # {0}?', $deJournal->id)]) ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<div class="paginator">
<ul class="pagination">
<?= $this->Paginator->first('<< ' . __('first')) ?>
<?= $this->Paginator->prev('< ' . __('previous')) ?>
<?= $this->Paginator->numbers() ?>
<?= $this->Paginator->next(__('next') . ' >') ?>
<?= $this->Paginator->last(__('last') . ' >>') ?>
</ul>
<p><?= $this->Paginator->counter(__('Page {{page}} of {{pages}}, showing {{current}} record(s) out of {{count}} total')) ?></p>
</div>
</div>

View File

@ -0,0 +1,79 @@
<?php
/**
* @var \App\View\AppView $this
* @var \Cake\Datasource\EntityInterface $deJournal
*/
?>
<div class="row">
<aside class="column">
<div class="side-nav">
<h4 class="heading"><?= __('Actions') ?></h4>
<?= $this->Html->link(__('Edit De Journal'), ['action' => 'edit', $deJournal->id], ['class' => 'side-nav-item']) ?>
<?= $this->Form->postLink(__('Delete De Journal'), ['action' => 'delete', $deJournal->id], ['confirm' => __('Are you sure you want to delete # {0}?', $deJournal->id), 'class' => 'side-nav-item']) ?>
<?= $this->Html->link(__('List De Journals'), ['action' => 'index'], ['class' => 'side-nav-item']) ?>
<?= $this->Html->link(__('New De Journal'), ['action' => 'add'], ['class' => 'side-nav-item']) ?>
</div>
</aside>
<div class="column column-80">
<div class="deJournals view content">
<h3><?= h($deJournal->name) ?></h3>
<table>
<tr>
<th><?= __('Name') ?></th>
<td><?= h($deJournal->name) ?></td>
</tr>
<tr>
<th><?= __('Short Code') ?></th>
<td><?= h($deJournal->short_code) ?></td>
</tr>
<tr>
<th><?= __('De Journal Type Code') ?></th>
<td><?= h($deJournal->de_journal_type_code) ?></td>
</tr>
<tr>
<th><?= __('Id') ?></th>
<td><?= $this->Number->format($deJournal->id) ?></td>
</tr>
<tr>
<th><?= __('Default Account Number Credit') ?></th>
<td><?= $deJournal->default_account_number_credit === null ? '' : $this->Number->format($deJournal->default_account_number_credit) ?></td>
</tr>
<tr>
<th><?= __('Default Account Number Debit') ?></th>
<td><?= $deJournal->default_account_number_debit === null ? '' : $this->Number->format($deJournal->default_account_number_debit) ?></td>
</tr>
</table>
<div class="related">
<h4><?= __('Related De Journal Entries') ?></h4>
<?php if (!empty($deJournal->de_journal_entries)) : ?>
<div class="table-responsive">
<table>
<tr>
<th><?= __('Id') ?></th>
<th><?= __('De Journal Id') ?></th>
<th><?= __('User Id') ?></th>
<th><?= __('Created') ?></th>
<th><?= __('Notes') ?></th>
<th class="actions"><?= __('Actions') ?></th>
</tr>
<?php foreach ($deJournal->de_journal_entries as $deJournalEntries) : ?>
<tr>
<td><?= h($deJournalEntries->id) ?></td>
<td><?= h($deJournalEntries->de_journal_id) ?></td>
<td><?= h($deJournalEntries->user_id) ?></td>
<td><?= h($deJournalEntries->created) ?></td>
<td><?= h($deJournalEntries->notes) ?></td>
<td class="actions">
<?= $this->Html->link(__('View'), ['controller' => 'DeJournalEntries', 'action' => 'view', $deJournalEntries->id]) ?>
<?= $this->Html->link(__('Edit'), ['controller' => 'DeJournalEntries', 'action' => 'edit', $deJournalEntries->id]) ?>
<?= $this->Form->postLink(__('Delete'), ['controller' => 'DeJournalEntries', 'action' => 'delete', $deJournalEntries->id], ['confirm' => __('Are you sure you want to delete # {0}?', $deJournalEntries->id)]) ?>
</td>
</tr>
<?php endforeach; ?>
</table>
</div>
<?php endif; ?>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,38 @@
<?php
/**
* @var \App\View\AppView $this
* @var \CakeAccounting\Model\Entity\DeAccount $account
* @var int $nestLevel
* @var array $totals
*/
if (!isset($nestLevel)) {
$nestLevel = 0;
}
$indent = '';
for ( $i = 0; $i < $nestLevel; $i++) {
$indent .= ' -- ';
}
$nestLevel++;
$hasChildren = isset($account->children) && $account->children;
?>
<tr>
<td><?= $account->account_type_code ?></td>
<td><?= $indent . $account->account_number ?></td>
<td><?= $indent . h($account->name) ?></td>
<td>
<?= $totals && array_key_exists('balance', $totals) ? $this->Number->format($totals['balance']) : 0; ?>
</td>
<td class="actions">
<?= $this->Html->link(__('View'), ['action' => 'view', $account->account_number]) ?>
</td>
</tr>
<?php if ($hasChildren) : ?>
<?php foreach ($account->children as $child) : ?>
<?= $this->element('DeAccounts/row', [
'account' => $child,
'nestLevel' => $nestLevel,
'totals' => array_key_exists($child->account_number, $totals['children']) ? $totals['children'][$child->account_number] : [],
]); ?>
<?php endforeach; ?>
<?php endif; ?>

View File

@ -0,0 +1,44 @@
<?= $this->ActiveLink->link('Accounts', [
'plugin' => 'CakeAccounting',
'controller' => 'DeAccounts',
'action' => 'index',
],[
'class' => 'submenu-link',
'target' => [
'plugin' => 'CakeAccounting',
'controller' => 'DeAccounts',
],
]); ?>
<?= $this->ActiveLink->link('External Accounts', [
'plugin' => 'CakeAccounting',
'controller' => 'DeExternalAccounts',
'action' => 'index',
], [
'class' => 'submenu-link',
'target' => [
'plugin' => 'CakeAccounting',
'controller' => 'DeExternalAccounts',
],
]); ?>
<?= $this->ActiveLink->link('Journal Entries', [
'plugin' => 'CakeAccounting',
'controller' => 'DeJournalEntries',
'action' => 'index',
], [
'class' => 'submenu-link',
'target' => [
'plugin' => 'CakeAccounting',
'controller' => 'DeJournalEntries',
],
]); ?>
<?= $this->ActiveLink->link('JournalItems', [
'plugin' => 'CakeAccounting',
'controller' => 'DeJournalItems',
'action' => 'index',
], [
'class' => 'submenu-link',
'target' => [
'plugin' => 'CakeAccounting',
'controller' => 'DeJournalItems',
],
]); ?>

Some files were not shown because too many files have changed in this diff Show More