diff --git a/.github/dev_bug_report.md b/.github/dev_bug_report.md deleted file mode 100755 index ef93e56..0000000 --- a/.github/dev_bug_report.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -name: Dev Bug Report -about: Create a report to help us improve -title: '' -labels: stat_backlog, type_bug -assignees: '' - ---- - -# Bug Description -A clear and concise description of what the bug is. - -# How to Reproduce - -Steps to reproduce the behavior: - -1. Go to '...' -2. Click on '....' -3. Scroll down to '....' -4. See error - -## Minimal Code Example - -``` -// your code ... -``` - -# Expected Behavior -A clear and concise description of what you expected to happen. - -# Screenshots -If applicable, add screenshots to help explain your problem. - -# Additional Information -Add any other context about the problem here. diff --git a/.github/dev_feature_request.md b/.github/dev_feature_request.md deleted file mode 100755 index 9573c35..0000000 --- a/.github/dev_feature_request.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -name: Dev Feature Request -about: Suggest an idea for this project -title: '' -labels: stat_backlog, type_feature -assignees: '' - ---- - -# What is the feature you request -* A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -* A clear and concise description of what you want to happen. - -# Alternatives -A clear and concise description of any alternative solutions or features you've considered. - -# Additional Information -Add any other context or screenshots about the feature request here. diff --git a/Admin/Install/Navigation.install.json b/Admin/Install/Navigation.install.json index 98b91de..487de78 100755 --- a/Admin/Install/Navigation.install.json +++ b/Admin/Install/Navigation.install.json @@ -19,7 +19,7 @@ "type": 2, "subtype": 1, "name": "CostCenters", - "uri": "{/base}/accounting/costcenter/list", + "uri": "{/base}/accounting/costcenter/list?{?}", "target": "self", "icon": null, "order": 5, @@ -33,7 +33,7 @@ "type": 3, "subtype": 1, "name": "List", - "uri": "{/base}/accounting/costcenter/list", + "uri": "{/base}/accounting/costcenter/list?{?}", "target": "self", "icon": null, "order": 1, @@ -65,7 +65,7 @@ "type": 2, "subtype": 1, "name": "CostObjects", - "uri": "{/base}/accounting/costobject/list", + "uri": "{/base}/accounting/costobject/list?{?}", "target": "self", "icon": null, "order": 5, @@ -79,7 +79,7 @@ "type": 3, "subtype": 1, "name": "List", - "uri": "{/base}/accounting/costobject/list", + "uri": "{/base}/accounting/costobject/list?{?}", "target": "self", "icon": null, "order": 1, @@ -111,7 +111,7 @@ "type": 2, "subtype": 1, "name": "Accounts", - "uri": "{/base}/accounting/coa/list", + "uri": "{/base}/accounting/coa/list?{?}", "target": "self", "icon": null, "order": 5, @@ -125,7 +125,7 @@ "type": 3, "subtype": 1, "name": "List", - "uri": "{/base}/accounting/coa/list", + "uri": "{/base}/accounting/coa/list?{?}", "target": "self", "icon": null, "order": 1, @@ -157,7 +157,7 @@ "type": 2, "subtype": 1, "name": "BatchPostings", - "uri": "{/base}/accounting/stack/list", + "uri": "{/base}/accounting/stack/list?{?}", "target": "self", "icon": null, "order": 10, @@ -171,7 +171,7 @@ "type": 3, "subtype": 1, "name": "List", - "uri": "{/base}/accounting/stack/list", + "uri": "{/base}/accounting/stack/list?{?}", "target": "self", "icon": null, "order": 5, @@ -186,7 +186,7 @@ "type": 3, "subtype": 1, "name": "Archive", - "uri": "{/base}/accounting/stack/archive/list", + "uri": "{/base}/accounting/stack/archive/list?{?}", "target": "self", "icon": null, "order": 10, @@ -201,7 +201,7 @@ "type": 3, "subtype": 1, "name": "Predefined", - "uri": "{/base}/accounting/stack/predefined/list", + "uri": "{/base}/accounting/stack/predefined/list?{?}", "target": "self", "icon": null, "order": 10, @@ -249,7 +249,7 @@ "type": 2, "subtype": 1, "name": "Suppliers", - "uri": "{/base}/accounting/supplier/list", + "uri": "{/base}/accounting/supplier/list?{?}", "target": "self", "icon": null, "order": 1, @@ -265,7 +265,7 @@ "type": 2, "subtype": 1, "name": "Clients", - "uri": "{/base}/accounting/client/list", + "uri": "{/base}/accounting/client/list?{?}", "target": "self", "icon": null, "order": 1, diff --git a/Admin/Install/db.json b/Admin/Install/db.json index 6bc02cc..dc6683a 100755 --- a/Admin/Install/db.json +++ b/Admin/Install/db.json @@ -32,6 +32,14 @@ "null": true, "foreignTable": "account", "foreignKey": "account_id" + }, + "accounting_account_unit": { + "name": "accounting_account_unit", + "type": "INT", + "null": true, + "default": null, + "foreignTable": "unit", + "foreignKey": "unit_id" } } }, @@ -90,7 +98,8 @@ "accounting_costcenter_unit": { "name": "accounting_costcenter_unit", "type": "INT", - "null": false, + "null": true, + "default": null, "foreignTable": "unit", "foreignKey": "unit_id" } @@ -157,7 +166,8 @@ "accounting_costobject_unit": { "name": "accounting_costobject_unit", "type": "INT", - "null": false, + "null": true, + "default": null, "foreignTable": "unit", "foreignKey": "unit_id" } diff --git a/Admin/Installer.php b/Admin/Installer.php index 9d44c2b..55b9414 100755 --- a/Admin/Installer.php +++ b/Admin/Installer.php @@ -63,7 +63,7 @@ final class Installer extends InstallerAbstract private static function importAccounts(ApplicationAbstract $app) : void { /** @var \Modules\Accounting\Controller\ApiController $module */ - $module = $app->moduleManager->getModuleInstance('Accounting', 'Api'); + $module = $app->moduleManager->get('Accounting', 'Api'); $fp = \fopen(__DIR__ . '/Install/Coa/SKR03_DE_GAAP.csv', 'r'); if ($fp === false) { @@ -134,7 +134,7 @@ final class Installer extends InstallerAbstract public static function importPersonalAccounts(ApplicationAbstract $app, string $type) : void { /** @var \Modules\Accounting\Controller\ApiController $module */ - $module = $app->moduleManager->getModuleInstance('Accounting', 'Api'); + $module = $app->moduleManager->get('Accounting', 'Api'); $mapper = $type === 'client' ? \Modules\ClientManagement\Models\ClientMapper::class diff --git a/Controller/ApiController.php b/Controller/ApiController.php index 1449f1d..0e4fb1c 100755 --- a/Controller/ApiController.php +++ b/Controller/ApiController.php @@ -28,6 +28,7 @@ use Modules\Accounting\Models\PostingMapper; use Modules\Accounting\Models\PostingSide; use Modules\Admin\Models\AccountMapper; use Modules\Admin\Models\NullAccount; +use Modules\Billing\Models\BillStatus; use Modules\ItemManagement\Models\Attribute\ItemAttributeTypeMapper; use Modules\ItemManagement\Models\Attribute\ItemAttributeValueMapper; use phpOMS\Localization\BaseStringL11n; @@ -82,7 +83,27 @@ final class ApiController extends Controller ?string $ip = null ) : void { - if (!$new->type->isAccounting) { + if (!$new->type->isAccounting + || $new->status !== BillStatus::ARCHIVED + ) { + return; + } + + $posting = PostingMapper::get() + ->where('bill', $new->id) + ->limit(1) + ->execute(); + + // Posting already created + if ($posting->id !== 0) { + \phpOMS\Log\FileLogger::getInstance()->warning( + \phpOMS\Log\FileLogger::MSG_FULL, [ + 'message' => 'Posting for bill "' . $new->id . '" already created', + 'line' => __LINE__, + 'file' => self::class, + ] + ); + return; } @@ -111,6 +132,7 @@ final class ApiController extends Controller ->execute(); $posting = new Posting(); + $posting->bill = $new->id; $posting->createdBy = new NullAccount($account); $posting->unit = $new->unit; $posting->account = AccountAbstractMapper::get() @@ -470,7 +492,7 @@ final class ApiController extends Controller $request->getDataString('content') ?? '', ISO639x1Enum::tryFromValue($request->getDataString('language')) ?? ISO639x1Enum::_EN ); - $costcenter->unit = $request->getDataInt('unit') ?? 1; + $costcenter->unit = $request->getDataInt('unit'); return $costcenter; } @@ -587,7 +609,7 @@ final class ApiController extends Controller $request->getDataString('content') ?? '', ISO639x1Enum::tryFromValue($request->getDataString('language')) ?? ISO639x1Enum::_EN ); - $costobject->unit = $request->getDataInt('unit') ?? 1; + $costobject->unit = $request->getDataInt('unit'); return $costobject; } diff --git a/Controller/BackendController.php b/Controller/BackendController.php index 215430f..bc3296e 100755 --- a/Controller/BackendController.php +++ b/Controller/BackendController.php @@ -429,10 +429,10 @@ final class BackendController extends Controller $head = $response->data['Content']->head; $nonce = $this->app->appSettings->getOption('script-nonce'); - $head->addAsset(AssetType::CSS, 'Resources/chartjs/chart.css'); - $head->addAsset(AssetType::JSLATE, 'Resources/chartjs/chart.js', ['nonce' => $nonce]); - $head->addAsset(AssetType::JSLATE, 'Resources/OpenLayers/OpenLayers.js', ['nonce' => $nonce]); - $head->addAsset(AssetType::JSLATE, 'Modules/Accounting/Controller.js', ['nonce' => $nonce, 'type' => 'module']); + $head->addAsset(AssetType::CSS, 'Resources/chartjs/chart.css?v=' . $this->app->version); + $head->addAsset(AssetType::JSLATE, 'Resources/chartjs/chart.js?v=' . $this->app->version, ['nonce' => $nonce]); + $head->addAsset(AssetType::JSLATE, 'Resources/OpenLayers/OpenLayers.js?v=' . $this->app->version, ['nonce' => $nonce]); + $head->addAsset(AssetType::JSLATE, 'Modules/Accounting/Controller.js?v=' . self::VERSION, ['nonce' => $nonce, 'type' => 'module']); $view = new View($this->app->l11nManager, $request, $response); $view->setTemplate('/Modules/Accounting/Theme/Backend/personal-view'); @@ -494,10 +494,10 @@ final class BackendController extends Controller $head = $response->data['Content']->head; $nonce = $this->app->appSettings->getOption('script-nonce'); - $head->addAsset(AssetType::CSS, 'Resources/chartjs/chart.css'); - $head->addAsset(AssetType::JSLATE, 'Resources/chartjs/chart.js', ['nonce' => $nonce]); - $head->addAsset(AssetType::JSLATE, 'Resources/OpenLayers/OpenLayers.js', ['nonce' => $nonce]); - $head->addAsset(AssetType::JSLATE, 'Modules/Accounting/Controller.js', ['nonce' => $nonce, 'type' => 'module']); + $head->addAsset(AssetType::CSS, 'Resources/chartjs/chart.css?v=' . $this->app->version); + $head->addAsset(AssetType::JSLATE, 'Resources/chartjs/chart.js?v=' . $this->app->version, ['nonce' => $nonce]); + $head->addAsset(AssetType::JSLATE, 'Resources/OpenLayers/OpenLayers.js?v=' . $this->app->version, ['nonce' => $nonce]); + $head->addAsset(AssetType::JSLATE, 'Modules/Accounting/Controller.js?v=' . self::VERSION, ['nonce' => $nonce, 'type' => 'module']); $view = new View($this->app->l11nManager, $request, $response); $view->setTemplate('/Modules/Accounting/Theme/Backend/personal-view'); diff --git a/Models/AccountAbstract.php b/Models/AccountAbstract.php index 3e1acc7..b8e8eaf 100755 --- a/Models/AccountAbstract.php +++ b/Models/AccountAbstract.php @@ -73,6 +73,8 @@ class AccountAbstract */ public array $entries = []; + public ?int $unit = null; + /** * Get entry. * diff --git a/Models/AccountAbstractMapper.php b/Models/AccountAbstractMapper.php index 0a1a66f..5090928 100644 --- a/Models/AccountAbstractMapper.php +++ b/Models/AccountAbstractMapper.php @@ -41,6 +41,7 @@ class AccountAbstractMapper extends DataMapperFactory 'accounting_account_type' => ['name' => 'accounting_account_type', 'type' => 'int', 'internal' => 'type'], 'accounting_account_parent' => ['name' => 'accounting_account_parent', 'type' => 'int', 'internal' => 'parent'], 'accounting_account_account' => ['name' => 'accounting_account_account', 'type' => 'int', 'internal' => 'account'], + 'accounting_account_unit' => ['name' => 'accounting_account_unit', 'type' => 'int', 'internal' => 'unit'], ]; /** diff --git a/Models/CostCenter.php b/Models/CostCenter.php index 31702aa..82ca369 100755 --- a/Models/CostCenter.php +++ b/Models/CostCenter.php @@ -59,7 +59,7 @@ class CostCenter */ public $parent = null; - public int $unit = 0; + public ?int $unit = null; /** * Set l11n diff --git a/Models/CostObject.php b/Models/CostObject.php index 1f3636d..f5c6d62 100755 --- a/Models/CostObject.php +++ b/Models/CostObject.php @@ -59,7 +59,7 @@ class CostObject */ public $parent = null; - public int $unit = 0; + public ?int $unit = null; /** * Set l11n diff --git a/Theme/Backend/Lang/Navigation.de.lang.php b/Theme/Backend/Lang/Navigation.de.lang.php index deaa8fa..11c1402 100755 --- a/Theme/Backend/Lang/Navigation.de.lang.php +++ b/Theme/Backend/Lang/Navigation.de.lang.php @@ -24,4 +24,6 @@ return ['Navigation' => [ 'Entries' => 'Einträge', 'Postings' => 'Buchungen', 'Predefined' => 'Vordefiniert', + 'Suppliers' => 'Lieferanten', + 'Clients' => 'Kunden', ]]; diff --git a/Theme/Backend/Lang/Navigation.en.lang.php b/Theme/Backend/Lang/Navigation.en.lang.php index d84a61a..5418c40 100755 --- a/Theme/Backend/Lang/Navigation.en.lang.php +++ b/Theme/Backend/Lang/Navigation.en.lang.php @@ -24,4 +24,6 @@ return ['Navigation' => [ 'Entries' => 'Entries', 'Postings' => 'Postings', 'Predefined' => 'Predefined', + 'Suppliers' => 'Suppliers', + 'Clients' => 'Clients', ]]; diff --git a/Theme/Backend/personal-profile.tpl.php b/Theme/Backend/personal-profile.tpl.php index 50fcaab..6a6a221 100644 --- a/Theme/Backend/personal-profile.tpl.php +++ b/Theme/Backend/personal-profile.tpl.php @@ -189,7 +189,7 @@ echo $this->data['nav']->render(); ?> -
+
@@ -200,7 +200,7 @@ echo $this->data['nav']->render(); ?>
-
+
printHtml($warning->plain); ?>
@@ -210,7 +210,7 @@ echo $this->data['nav']->render(); ?> data['hasBilling']) : ?>
-
+
getHtml('YTDSales'); ?>: @@ -225,7 +225,7 @@ echo $this->data['nav']->render(); ?>
-
+
getHtml('LastContact'); ?>: @@ -240,7 +240,7 @@ echo $this->data['nav']->render(); ?>
-
+
getHtml('DSO'); ?>: diff --git a/Theme/Backend/personal-view.tpl.php b/Theme/Backend/personal-view.tpl.php index 50fcaab..6a6a221 100644 --- a/Theme/Backend/personal-view.tpl.php +++ b/Theme/Backend/personal-view.tpl.php @@ -189,7 +189,7 @@ echo $this->data['nav']->render(); ?> -
+
@@ -200,7 +200,7 @@ echo $this->data['nav']->render(); ?>
-
+
printHtml($warning->plain); ?>
@@ -210,7 +210,7 @@ echo $this->data['nav']->render(); ?> data['hasBilling']) : ?>
-
+
getHtml('YTDSales'); ?>: @@ -225,7 +225,7 @@ echo $this->data['nav']->render(); ?>
-
+
getHtml('LastContact'); ?>: @@ -240,7 +240,7 @@ echo $this->data['nav']->render(); ?>
-
+
getHtml('DSO'); ?>: