From 736cb91f3bbcd5d1cb3990e509efe4f89b207d5c Mon Sep 17 00:00:00 2001 From: Steve Blamey Date: Thu, 5 Nov 2020 13:40:36 +0000 Subject: [PATCH 01/25] Model TaxStatus, add postponed_vat_accounting field --- .../ledger/ledger_setup/models/TaxStatus.php | 5 +++- .../ledger_setup/templates/taxstatuss/new.tpl | 1 + .../20201105123420_add_pva_to_tax_status.php | 27 +++++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 schema/phinx/migrations/20201105123420_add_pva_to_tax_status.php diff --git a/modules/public_pages/erp/ledger/ledger_setup/models/TaxStatus.php b/modules/public_pages/erp/ledger/ledger_setup/models/TaxStatus.php index c476582a..bcdcccc5 100755 --- a/modules/public_pages/erp/ledger/ledger_setup/models/TaxStatus.php +++ b/modules/public_pages/erp/ledger/ledger_setup/models/TaxStatus.php @@ -9,7 +9,10 @@ class TaxStatus extends DataObject { - protected $version='$Revision: 1.6 $'; + protected $defaultDisplayFields = ['description', + 'apply_tax', + 'eu_tax', + 'postponed_vat_accounting' => 'PVA']; function __construct($tablename='tax_statuses') { diff --git a/modules/public_pages/erp/ledger/ledger_setup/templates/taxstatuss/new.tpl b/modules/public_pages/erp/ledger/ledger_setup/templates/taxstatuss/new.tpl index d1e5961b..75a368e8 100755 --- a/modules/public_pages/erp/ledger/ledger_setup/templates/taxstatuss/new.tpl +++ b/modules/public_pages/erp/ledger/ledger_setup/templates/taxstatuss/new.tpl @@ -12,6 +12,7 @@ {input type='text' attribute='description' class="compulsory" } {input type='checkbox' attribute='apply_tax' class="compulsory" } {input type='checkbox' label='EU Tax' attribute='eu_tax' class="compulsory" } + {input type='checkbox' label='PVA' attribute='postponed_vat_accounting' class="compulsory" } {/with} {submit} {/form} diff --git a/schema/phinx/migrations/20201105123420_add_pva_to_tax_status.php b/schema/phinx/migrations/20201105123420_add_pva_to_tax_status.php new file mode 100644 index 00000000..526a7e60 --- /dev/null +++ b/schema/phinx/migrations/20201105123420_add_pva_to_tax_status.php @@ -0,0 +1,27 @@ + + * @license GPLv3 or later + * @copyright (c) 2020 uzERP LLP (support#uzerp.com). All rights reserved. + */ +class AddPvaToTaxStatus extends UzerpMigration +{ + public function change() + { + $table = $this->table('tax_statuses'); + $table->addColumn('postponed_vat_accounting', 'boolean', ['default' => false, 'null' => true]) + ->save(); + + // Prevent eu_tax and postponed_vat_accounting both being true + $this->query("ALTER TABLE public.tax_statuses DROP CONSTRAINT IF EXISTS exclusive_eu_pva"); + $this->query("ALTER TABLE public.tax_statuses + ADD CONSTRAINT exclusive_eu_pva CHECK ((eu_tax IS TRUE AND postponed_vat_accounting IS FALSE) OR (eu_tax is FALSE AND postponed_vat_accounting IS true)) + NOT VALID;"); + } +} From 07d97a7f9f5060bb0417424af777b193e689cfd2 Mon Sep 17 00:00:00 2001 From: Steve Blamey Date: Fri, 6 Nov 2020 12:17:33 +0000 Subject: [PATCH 02/25] Model TaxStatus, add reverse_charge field --- .../erp/ledger/ledger_setup/models/TaxStatus.php | 3 ++- .../erp/ledger/ledger_setup/templates/taxstatuss/new.tpl | 1 + .../migrations/20201105123420_add_pva_to_tax_status.php | 6 +++++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/modules/public_pages/erp/ledger/ledger_setup/models/TaxStatus.php b/modules/public_pages/erp/ledger/ledger_setup/models/TaxStatus.php index bcdcccc5..184f296e 100755 --- a/modules/public_pages/erp/ledger/ledger_setup/models/TaxStatus.php +++ b/modules/public_pages/erp/ledger/ledger_setup/models/TaxStatus.php @@ -12,7 +12,8 @@ class TaxStatus extends DataObject protected $defaultDisplayFields = ['description', 'apply_tax', 'eu_tax', - 'postponed_vat_accounting' => 'PVA']; + 'postponed_vat_accounting' => 'PVA', + 'reverse_charge']; function __construct($tablename='tax_statuses') { diff --git a/modules/public_pages/erp/ledger/ledger_setup/templates/taxstatuss/new.tpl b/modules/public_pages/erp/ledger/ledger_setup/templates/taxstatuss/new.tpl index 75a368e8..9a0fe238 100755 --- a/modules/public_pages/erp/ledger/ledger_setup/templates/taxstatuss/new.tpl +++ b/modules/public_pages/erp/ledger/ledger_setup/templates/taxstatuss/new.tpl @@ -13,6 +13,7 @@ {input type='checkbox' attribute='apply_tax' class="compulsory" } {input type='checkbox' label='EU Tax' attribute='eu_tax' class="compulsory" } {input type='checkbox' label='PVA' attribute='postponed_vat_accounting' class="compulsory" } + {input type='checkbox' attribute='reverse_charge' class="compulsory" } {/with} {submit} {/form} diff --git a/schema/phinx/migrations/20201105123420_add_pva_to_tax_status.php b/schema/phinx/migrations/20201105123420_add_pva_to_tax_status.php index 526a7e60..ee50c725 100644 --- a/schema/phinx/migrations/20201105123420_add_pva_to_tax_status.php +++ b/schema/phinx/migrations/20201105123420_add_pva_to_tax_status.php @@ -16,12 +16,16 @@ public function change() { $table = $this->table('tax_statuses'); $table->addColumn('postponed_vat_accounting', 'boolean', ['default' => false, 'null' => true]) + ->addColumn('reverse_charge', 'boolean', ['default' => false, 'null' => true]) ->save(); // Prevent eu_tax and postponed_vat_accounting both being true $this->query("ALTER TABLE public.tax_statuses DROP CONSTRAINT IF EXISTS exclusive_eu_pva"); + $this->query("ALTER TABLE public.tax_statuses DROP CONSTRAINT IF EXISTS exclusive_eu_rc"); $this->query("ALTER TABLE public.tax_statuses - ADD CONSTRAINT exclusive_eu_pva CHECK ((eu_tax IS TRUE AND postponed_vat_accounting IS FALSE) OR (eu_tax is FALSE AND postponed_vat_accounting IS true)) + ADD CONSTRAINT exclusive_eu_pva CHECK (((eu_tax IS TRUE AND postponed_vat_accounting IS FALSE AND reverse_charge IS FALSE) + OR (eu_tax is FALSE AND postponed_vat_accounting IS true AND reverse_charge IS false)) + OR (eu_tax is FALSE AND postponed_vat_accounting IS false AND reverse_charge IS true)) NOT VALID;"); } } From d5ea5e35c0567b5651b17e8c54f54772e74e3a30 Mon Sep 17 00:00:00 2001 From: Steve Blamey Date: Fri, 6 Nov 2020 12:18:24 +0000 Subject: [PATCH 03/25] Model GLparams, add params for Postponed VAT and Reverse charge control accounts --- .../erp/ledger/general_ledger/models/GLParams.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/modules/public_pages/erp/ledger/general_ledger/models/GLParams.php b/modules/public_pages/erp/ledger/general_ledger/models/GLParams.php index dbb22304..261c64a5 100755 --- a/modules/public_pages/erp/ledger/general_ledger/models/GLParams.php +++ b/modules/public_pages/erp/ledger/general_ledger/models/GLParams.php @@ -41,6 +41,8 @@ class GLParams extends DataObject { public $vat_control_account = "VAT Control Account"; public $vat_payee_company = "VAT Payee"; public $vat_eu_acquisitions = "VAT EU Acquisitions"; + public $vat_postponed = "VAT Postponed Account"; + public $vat_reverse_charge = "VAT Reverse Charge Account"; public $intrastat_net_mass = "UoM for Intrastat Net Mass"; // Array containing 'soft' fk references @@ -80,6 +82,8 @@ function __construct($tablename = 'gl_params') ,$this->vat_eu_acquisitions=>$this->vat_eu_acquisitions ,$this->vat_payee_company=>$this->vat_payee_company ,$this->intrastat_net_mass=>$this->intrastat_net_mass + ,$this->vat_postponed => $this->vat_postponed + ,$this->vat_reverse_charge => $this->vat_reverse_charge ) ); @@ -101,6 +105,8 @@ function __construct($tablename = 'gl_params') $this->hasMany('GLAccount', $this->vat_output, 'account', $control_account); $this->hasMany('GLAccount', $this->vat_control_account, 'account', $control_account); $this->hasMany('GLAccount', $this->vat_eu_acquisitions, 'account', $control_account); + $this->hasMany('GLAccount', $this->vat_postponed, 'account', $control_account); + $this->hasMany('GLAccount', $this->vat_reverse_charge, 'account', $control_account); $this->hasMany('Company', $this->vat_payee_company, 'name'); $this->hasMany('GLAccount', $this->product_account, 'account'); $this->hasMany('GLCentre', $this->product_centre, 'cost_centre'); @@ -343,6 +349,14 @@ public function eu_acquisitions () { return $this->getParam($this->vat_eu_acquisitions); } + public function vat_postponed_account () { + return $this->getParam($this->vat_postponed); + } + + public function vat_reverse_charge_account () { + return $this->getParam($this->vat_reverse_charge); + } + public function vat_payee_company () { return $this->getParam($this->vat_payee_company); } From d6f88436832b4e8b5af72fe35be75c2bb07985d9 Mon Sep 17 00:00:00 2001 From: Steve Blamey Date: Fri, 6 Nov 2020 12:19:33 +0000 Subject: [PATCH 04/25] Handle postponed VAT and reverse charge hwne posting Purchase Invoices --- .../purchase_invoicing/models/PInvoice.php | 38 +++++++++++++- .../general_ledger/models/GLTransaction.php | 49 +++++++++++++++++++ 2 files changed, 85 insertions(+), 2 deletions(-) diff --git a/modules/public_pages/erp/invoicing/purchase_invoicing/models/PInvoice.php b/modules/public_pages/erp/invoicing/purchase_invoicing/models/PInvoice.php index 3e671045..acf59c0b 100644 --- a/modules/public_pages/erp/invoicing/purchase_invoicing/models/PInvoice.php +++ b/modules/public_pages/erp/invoicing/purchase_invoicing/models/PInvoice.php @@ -376,6 +376,8 @@ protected function makeGLTransactionLines($gl_data, &$gl_transactions, &$errors if ($tax_status->load($this->tax_status_id)) { $eu_acquisition = ($tax_status->eu_tax == 't'); + $vat_postponed = ($tax_status->postponed_vat_accounting == 't'); + $reverse_charge = ($tax_status->reverse_charge == 't'); } else { @@ -383,7 +385,7 @@ protected function makeGLTransactionLines($gl_data, &$gl_transactions, &$errors return FALSE; } - if ($eu_acquisition) + if ($eu_acquisition || $vat_postponed || $reverse_charge) { $eu_gl_data = $gl_data; $eu_gl_data['value'] = 0; @@ -469,7 +471,7 @@ protected function makeGLTransactionLines($gl_data, &$gl_transactions, &$errors } // Calculate tax value if EU acquisition - if (($eu_acquisition) && ($line->tax_rate_id)) + if (($eu_acquisition || $vat_postponed || $reverse_charge) && ($line->tax_rate_id)) { if (isset($tax_rates[$line->tax_rate_id]) && ($tax_rates[$line->tax_rate_id] > 0)) { @@ -508,6 +510,38 @@ protected function makeGLTransactionLines($gl_data, &$gl_transactions, &$errors $gl_transactions[] = $eu_tax_element; } } + + if ($vat_postponed) + { + + $eu_tax_elements = GLTransaction::makeTax($eu_gl_data, 'PVA', $newerrors); + + foreach ($eu_tax_elements as $eu_tax_element) + { + if ($eu_tax_element === false) + { + $errors+=$newerrors; + return false; + } + $gl_transactions[] = $eu_tax_element; + } + } + + if ($reverse_charge) + { + + $eu_tax_elements = GLTransaction::makeTax($eu_gl_data, 'RC', $newerrors); + + foreach ($eu_tax_elements as $eu_tax_element) + { + if ($eu_tax_element === false) + { + $errors+=$newerrors; + return false; + } + $gl_transactions[] = $eu_tax_element; + } + } if (count($errors)>0) { diff --git a/modules/public_pages/erp/ledger/general_ledger/models/GLTransaction.php b/modules/public_pages/erp/ledger/general_ledger/models/GLTransaction.php index b64f9267..682f1ada 100755 --- a/modules/public_pages/erp/ledger/general_ledger/models/GLTransaction.php +++ b/modules/public_pages/erp/ledger/general_ledger/models/GLTransaction.php @@ -1012,6 +1012,55 @@ public static function makeEuTax($transaction, &$errors = array()) return $eu_tax_elements; } + /** + * Handle tax for PVA and Reverse Charge + * + * @param $transaction + * @param $type 'RC' = Reverse Charge, 'PVA' = Postponed VAT Accounting + * @param array $errors + * @return void + */ + public static function makeTax($transaction, $tax_type='none', &$errors = array()) + { + $mult = self::$multipliers[$transaction['source']][$transaction['type']]; + $eu_tax_element = $transaction; + + $glparams = DataObjectFactory::Factory('GLParams'); + + switch ($tax_type) { + case 'PVA': + $eu_tax_element['glaccount_id'] = $glparams->vat_postponed_account(); + break; + case 'RC': + $eu_tax_element['glaccount_id'] = $glparams->vat_reverse_charge_account(); + break; + default: + $errors[] = "Tax type not specified"; + } + + if ($eu_tax_element['glaccount_id'] === false) { + $errors[] = "Account Code for tax '{$tax_type}' not found"; + } + + $eu_tax_element['glcentre_id'] = $glparams->balance_sheet_cost_centre(); + + if ($eu_tax_element['glcentre_id'] === false) { + $errors[] = 'Balance Sheet Cost Centre Code not found'; + } + + $eu_tax_element['value'] = bcmul($mult, $eu_tax_element['value']); + $eu_tax_element['twinvalue'] = bcmul($mult, $eu_tax_element['twinvalue']); + + $eu_tax_elements = array(); + $eu_tax_elements[] = GLTransaction::Factory($eu_tax_element, $errors); + + $eu_tax_element['value'] *= - 1; + $eu_tax_element['twinvalue'] *= - 1; + $eu_tax_elements[] = GLTransaction::Factory($eu_tax_element, $errors); + + return $eu_tax_elements; + } + public static function makeCBLine($transaction, &$errors = array()) { $mult = self::$multipliers[$transaction['source']][$transaction['type']]; From 1c4efbcfba77687207c1b16986100b5005b0b449 Mon Sep 17 00:00:00 2001 From: Steve Blamey Date: Mon, 9 Nov 2020 15:22:22 +0000 Subject: [PATCH 05/25] Model TaxStatus, allow flags to be false --- .../migrations/20201105123420_add_pva_to_tax_status.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/schema/phinx/migrations/20201105123420_add_pva_to_tax_status.php b/schema/phinx/migrations/20201105123420_add_pva_to_tax_status.php index ee50c725..5d77dc6e 100644 --- a/schema/phinx/migrations/20201105123420_add_pva_to_tax_status.php +++ b/schema/phinx/migrations/20201105123420_add_pva_to_tax_status.php @@ -22,10 +22,12 @@ public function change() // Prevent eu_tax and postponed_vat_accounting both being true $this->query("ALTER TABLE public.tax_statuses DROP CONSTRAINT IF EXISTS exclusive_eu_pva"); $this->query("ALTER TABLE public.tax_statuses DROP CONSTRAINT IF EXISTS exclusive_eu_rc"); + $this->query("ALTER TABLE public.tax_statuses DROP CONSTRAINT IF EXISTS exclusive_eu"); $this->query("ALTER TABLE public.tax_statuses - ADD CONSTRAINT exclusive_eu_pva CHECK (((eu_tax IS TRUE AND postponed_vat_accounting IS FALSE AND reverse_charge IS FALSE) - OR (eu_tax is FALSE AND postponed_vat_accounting IS true AND reverse_charge IS false)) - OR (eu_tax is FALSE AND postponed_vat_accounting IS false AND reverse_charge IS true)) + ADD CONSTRAINT exclusive_eu CHECK ((eu_tax IS TRUE AND postponed_vat_accounting IS FALSE AND reverse_charge IS FALSE) + OR (eu_tax is FALSE AND postponed_vat_accounting IS TRUE AND reverse_charge IS FALSE) + OR (eu_tax is FALSE AND postponed_vat_accounting IS FALSE AND reverse_charge IS TRUE) + OR (eu_tax IS FALSE AND postponed_vat_accounting IS FALSE AND reverse_charge IS FALSE)) NOT VALID;"); } } From 5b696538880f9f4340302555d7b6ae3e2042edfb Mon Sep 17 00:00:00 2001 From: Steve Blamey Date: Mon, 9 Nov 2020 15:23:32 +0000 Subject: [PATCH 06/25] SLCustomer::new, only show valid tax statuses when adding a new SLCustomer --- .../ledger/ledger_setup/models/TaxStatus.php | 14 +++++++++ .../controllers/SlcustomersController.php | 31 +++++++++++-------- .../templates/slcustomers/new.tpl | 6 ++-- 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/modules/public_pages/erp/ledger/ledger_setup/models/TaxStatus.php b/modules/public_pages/erp/ledger/ledger_setup/models/TaxStatus.php index 184f296e..afd90bac 100755 --- a/modules/public_pages/erp/ledger/ledger_setup/models/TaxStatus.php +++ b/modules/public_pages/erp/ledger/ledger_setup/models/TaxStatus.php @@ -25,6 +25,20 @@ function __construct($tablename='tax_statuses') } + /** + * Return an array of tax status options valid for an SLCustomer + * + * @return array Status options + */ + public function get_customer_tax_statuses() + { + $cc = new ConstraintChain(); + $cc->add(new Constraint('postponed_vat_accounting', 'IS', false)); + $cc->add(new Constraint('reverse_charge', 'IS', false)); + $statuses = $this->getAll($cc); + return $statuses; + } + } // End of TaxStatus diff --git a/modules/public_pages/erp/ledger/sales_ledger/controllers/SlcustomersController.php b/modules/public_pages/erp/ledger/sales_ledger/controllers/SlcustomersController.php index 58db0377..d8e2ac9d 100755 --- a/modules/public_pages/erp/ledger/sales_ledger/controllers/SlcustomersController.php +++ b/modules/public_pages/erp/ledger/sales_ledger/controllers/SlcustomersController.php @@ -60,7 +60,7 @@ public function __construct($module = null, $action = null) $system_prefs = SystemPreferences::instance(); $module_prefs = $system_prefs->getModulePreferences('ledger_setup'); if (! isset($module_prefs['sales-invoice-report-type'])) { - $module_prefs['sales-invoice-report-type'] = ''; + $module_prefs['sales-invoice-report-type'] = ''; } $this->module_prefs = $module_prefs; $this->view->set('module_prefs', $module_prefs); @@ -589,8 +589,8 @@ public function make_inactive() { $flash->addWarning($e->getMessage()); if ($e->getCode == 1) { - $db->FailTrans(); - } + $db->FailTrans(); + } } @@ -1227,12 +1227,17 @@ public function _new() } if (is_null($customer->cb_account_id)) - { - $cbaccount = CBAccount::getPrimaryAccount(); - $customer->cb_account_id = $cbaccount->{$cbaccount->idField}; - } + { + $cbaccount = CBAccount::getPrimaryAccount(); + $customer->cb_account_id = $cbaccount->{$cbaccount->idField}; + } + + $taxstatus = new TaxStatus(); + $taxstatuses = $taxstatus->get_customer_tax_statuses(); + + $this->view->set('f_taxstatuses', $taxstatuses); - $this->view->set('bank_account', $customer->cb_account_id); + $this->view->set('bank_account', $customer->cb_account_id); $this->view->set('bank_accounts', $this->getbankAccounts($customer->id)); $this->view->set('billing_addresses', $customer->getInvoiceAddresses()); @@ -1544,11 +1549,11 @@ public function getbankAccounts($_customer_id = '') $currency_id = $customer->currency_id; // If the user has selected a new currency - // the id will be in the request, - // so set the selected currency id. - if(isset($this->_data['ajax'])) { - $currency_id = $this->_data['id']; - } + // the id will be in the request, + // so set the selected currency id. + if(isset($this->_data['ajax'])) { + $currency_id = $this->_data['id']; + } $cc = new ConstraintChain(); diff --git a/modules/public_pages/erp/ledger/sales_ledger/templates/slcustomers/new.tpl b/modules/public_pages/erp/ledger/sales_ledger/templates/slcustomers/new.tpl index 274a73ee..11e6ddab 100755 --- a/modules/public_pages/erp/ledger/sales_ledger/templates/slcustomers/new.tpl +++ b/modules/public_pages/erp/ledger/sales_ledger/templates/slcustomers/new.tpl @@ -36,10 +36,12 @@ {select attribute='payment_type_id' } {select attribute='so_price_type_id' } {if $action=='new' } - {select attribute='tax_status_id' } + {select attribute='tax_status_id' options=$f_taxstatuses} {else} {if $transaction_count == 0} - {select attribute='tax_status_id' } + {select attribute='tax_status_id' options=$f_taxstatuses} + {else} + {view_data attribute='tax_status_id'} {/if} {/if} {select attribute='delivery_term_id' } From 45914151cfd69ee25f37f9065aca56d88afedc0e Mon Sep 17 00:00:00 2001 From: Martyn Shiner Date: Tue, 10 Nov 2020 10:47:48 +0000 Subject: [PATCH 07/25] Models for postponed and reverse charge VAT --- .../erp/ledger/vat/models/VatPVPurchases.php | 36 +++++++++++++++++++ .../vat/models/VatPVPurchasesCollection.php | 20 +++++++++++ .../erp/ledger/vat/models/VatRCPurchases.php | 36 +++++++++++++++++++ .../vat/models/VatRCPurchasesCollection.php | 20 +++++++++++ 4 files changed, 112 insertions(+) create mode 100644 modules/public_pages/erp/ledger/vat/models/VatPVPurchases.php create mode 100644 modules/public_pages/erp/ledger/vat/models/VatPVPurchasesCollection.php create mode 100644 modules/public_pages/erp/ledger/vat/models/VatRCPurchases.php create mode 100644 modules/public_pages/erp/ledger/vat/models/VatRCPurchasesCollection.php diff --git a/modules/public_pages/erp/ledger/vat/models/VatPVPurchases.php b/modules/public_pages/erp/ledger/vat/models/VatPVPurchases.php new file mode 100644 index 00000000..34262829 --- /dev/null +++ b/modules/public_pages/erp/ledger/vat/models/VatPVPurchases.php @@ -0,0 +1,36 @@ + + * @license GPLv3 or later + * @copyright (c) 2019 uzERP LLP (support#uzerp.com). All rights reserved. + * + * uzERP is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + */ +class VatPVPurchases extends DataObject { + protected $defaultDisplayFields = [ + 'transaction_date', + 'gl_id', + 'docref', + 'ext_reference', + 'supplier', + 'comment', + 'vat', + 'net', + 'source', + 'type' + ]; + + function __construct($tablename='gl_taxpvpurchases') { + parent::__construct($tablename); + $this->orderby = ['transaction_date']; + + // Use enumerators from the GLT model + $glt = new GLTransaction; + $this->setEnum('type', $glt->enums['type']); + $this->setEnum('source', $glt->enums['source']); + } +} +?> \ No newline at end of file diff --git a/modules/public_pages/erp/ledger/vat/models/VatPVPurchasesCollection.php b/modules/public_pages/erp/ledger/vat/models/VatPVPurchasesCollection.php new file mode 100644 index 00000000..c88bc9e1 --- /dev/null +++ b/modules/public_pages/erp/ledger/vat/models/VatPVPurchasesCollection.php @@ -0,0 +1,20 @@ + + * @license GPLv3 or later + * @copyright (c) 2019 uzERP LLP (support#uzerp.com). All rights reserved. + * + * uzERP is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + */ +class VatPVPurchasesCollection extends DataObjectCollection { + + public $field; + + function __construct($do='VatPVPurchases', $tablename='gl_taxpvpurchases') { + parent::__construct($do, $tablename); + } +} +?> \ No newline at end of file diff --git a/modules/public_pages/erp/ledger/vat/models/VatRCPurchases.php b/modules/public_pages/erp/ledger/vat/models/VatRCPurchases.php new file mode 100644 index 00000000..5616591d --- /dev/null +++ b/modules/public_pages/erp/ledger/vat/models/VatRCPurchases.php @@ -0,0 +1,36 @@ + + * @license GPLv3 or later + * @copyright (c) 2019 uzERP LLP (support#uzerp.com). All rights reserved. + * + * uzERP is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + */ +class VatRCPurchases extends DataObject { + protected $defaultDisplayFields = [ + 'transaction_date', + 'gl_id', + 'docref', + 'ext_reference', + 'supplier', + 'comment', + 'vat', + 'net', + 'source', + 'type' + ]; + + function __construct($tablename='gl_taxrcpurchases') { + parent::__construct($tablename); + $this->orderby = ['transaction_date']; + + // Use enumerators from the GLT model + $glt = new GLTransaction; + $this->setEnum('type', $glt->enums['type']); + $this->setEnum('source', $glt->enums['source']); + } +} +?> \ No newline at end of file diff --git a/modules/public_pages/erp/ledger/vat/models/VatRCPurchasesCollection.php b/modules/public_pages/erp/ledger/vat/models/VatRCPurchasesCollection.php new file mode 100644 index 00000000..894fd505 --- /dev/null +++ b/modules/public_pages/erp/ledger/vat/models/VatRCPurchasesCollection.php @@ -0,0 +1,20 @@ + + * @license GPLv3 or later + * @copyright (c) 2019 uzERP LLP (support#uzerp.com). All rights reserved. + * + * uzERP is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + */ +class VatRCPurchasesCollection extends DataObjectCollection { + + public $field; + + function __construct($do='VatRCPurchases', $tablename='gl_taxrcpurchases') { + parent::__construct($do, $tablename); + } +} +?> \ No newline at end of file From 45b01e6f5df0df43f177c0b77efdad68ba709349 Mon Sep 17 00:00:00 2001 From: Martyn Shiner Date: Tue, 10 Nov 2020 10:51:20 +0000 Subject: [PATCH 08/25] Add ctrl accs PV/RC change getVATvalues function --- modules/public_pages/erp/ledger/vat/models/Vat.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/modules/public_pages/erp/ledger/vat/models/Vat.php b/modules/public_pages/erp/ledger/vat/models/Vat.php index d324fab8..388a8eb6 100755 --- a/modules/public_pages/erp/ledger/vat/models/Vat.php +++ b/modules/public_pages/erp/ledger/vat/models/Vat.php @@ -109,6 +109,8 @@ private function getControlAccounts (&$errors=array()) 'retained_profits' => $glparams->retained_profits_account(), 'vat_control' => $glparams->vat_control_account(), 'eu_acquisitions' => $glparams->eu_acquisitions(), + 'vat_postponed' => $glparams->vat_postponed_account(), + 'vat_reverse_charge'=> $glparams->vat_reverse_charge_account(), ); if (in_array(false, $this->control_accounts, true)) { @@ -270,11 +272,10 @@ function getVATvalues($year=null, $tax_period=null) $qparams = [$year, $tax_period]; $query = <<<'QUERY' select tax_period, -coalesce(sum((select sum(vat) from gltransactions_vat_outputs where glperiods_id=glp.id)), 0.00) as "Box1", +coalesce(sum((select sum(vat) from gltransactions_vat_outputs vo where vo.glperiods_id=glp.id)) + coalesce(sum((select sum(vat) from gl_taxpvpurchases vo where vo.glperiods_id=glp.id)),0.00)+ coalesce(sum((select sum(vat) from gl_taxrcpurchases vo where vo.glperiods_id=glp.id)),0.00), 0.00) as "Box1", coalesce(sum((select sum(vat) from gl_taxeupurchases vo where vo.glperiods_id=glp.id)), 0.00) as "Box2", -coalesce(sum((select sum(vat) from gltransactions_vat_inputs vo where vo.glperiods_id=glp.id)) + coalesce(sum((select sum(vat) from gl_taxeupurchases vo where vo.glperiods_id=glp.id)),0.00), 0.00) as "Box4", -coalesce(sum((select sum(vat) from gltransactions_vat_inputs vo where vo.glperiods_id=glp.id)), 0.00) as "inputs", -coalesce(sum((select sum(net) from gltransactions_vat_outputs vo where vo.glperiods_id=glp.id)), 0.00) as "Box6", +coalesce(sum((select sum(vat) from gltransactions_vat_inputs vo where vo.glperiods_id=glp.id)) + coalesce(sum((select sum(vat) from gl_taxeupurchases vo where vo.glperiods_id=glp.id)),0.00)+ coalesce(sum((select sum(vat) from gl_taxpvpurchases vo where vo.glperiods_id=glp.id)),0.00)+ coalesce(sum((select sum(vat) from gl_taxrcpurchases vo where vo.glperiods_id=glp.id)),0.00), 0.00) as "Box4", +coalesce(sum((select sum(net) from gltransactions_vat_outputs vo where vo.glperiods_id=glp.id))+coalesce(sum((select sum(net) from gl_taxrcpurchases vo where vo.glperiods_id=glp.id)), 0.00), 0.00) as "Box6", coalesce(sum((select sum(net) from gltransactions_vat_inputs vo where vo.glperiods_id=glp.id)), 0.00) as "Box7", coalesce(sum((select sum(net) from gltransactions_vat_outputs vo where vo.glperiods_id=glp.id and eutaxstatus='T')), 0.00) as "Box8", coalesce(sum((select sum(net) from gltransactions_vat_inputs vo where vo.glperiods_id=glp.id and eutaxstatus='T')), 0.00) as "Box9" From f002df335919deb6a863613df14d69c304855af6 Mon Sep 17 00:00:00 2001 From: Martyn Shiner Date: Tue, 10 Nov 2020 10:53:20 +0000 Subject: [PATCH 09/25] Add PV and RC VAT to transaction sidebar --- .../ledger/vat/controllers/VatController.php | 48 ++++++++++++++++++- .../vat/templates/vat/viewtransactions.tpl | 10 ++-- 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/modules/public_pages/erp/ledger/vat/controllers/VatController.php b/modules/public_pages/erp/ledger/vat/controllers/VatController.php index 8fd5d6f5..430a2277 100644 --- a/modules/public_pages/erp/ledger/vat/controllers/VatController.php +++ b/modules/public_pages/erp/ledger/vat/controllers/VatController.php @@ -24,7 +24,7 @@ public function __construct($module = null, $action = null) $this->uses($this->_templateobject); - $this->titles=array(4=>'Inputs', 6=>'Outputs', 8=>'EU Sales', 9=>'EU Purchases'); + $this->titles=array(4=>'Inputs', 6=>'Outputs', 8=>'EU Sales', 9=>'EU Purchases', 98=>'Postponed VAT Purchases',99=>'Reverse Charge Purchases'); } @@ -348,6 +348,16 @@ public function viewTransactions() $this->uses($this->_templateobject); parent::index(new VatEuPurchasesCollection($this->_templateobject)); break; + case '98': // postponed VAT + $this->_templateobject = DataObjectFactory::Factory('VatPVPurchases'); + $this->uses($this->_templateobject); + parent::index(new VatPVPurchasesCollection($this->_templateobject)); + break; + case '99': // reverse charge VAT + $this->_templateobject = DataObjectFactory::Factory('VatRCPurchases'); + $this->uses($this->_templateobject); + parent::index(new VatRCPurchasesCollection($this->_templateobject)); + break; } $this->view->set('box',$this->_data['box']); $this->view->set('page_title',"VAT Transactions {$year}/{$tax_period} - ".$this->titles[$this->_data['box']]); @@ -644,6 +654,26 @@ private function reportSidebar($titles, $year, $tax_period) ,'tax_period'=>$tax_period ), 'tag'=>$titles[9] + ), + 'box98'=>array( + 'link'=>array('modules'=>$this->_modules + ,'controller'=>$this->name + ,'action'=>'viewTransactions' + ,'box'=>98 + ,'year'=>$year + ,'tax_period'=>$tax_period + ), + 'tag'=>$titles[98] + ), + 'box99'=>array( + 'link'=>array('modules'=>$this->_modules + ,'controller'=>$this->name + ,'action'=>'viewTransactions' + ,'box'=>99 + ,'year'=>$year + ,'tax_period'=>$tax_period + ), + 'tag'=>$titles[99] ) ); return $list; @@ -910,6 +940,14 @@ public function printTransactions($status = 'generate') $gltransaction = DataObjectFactory::Factory('VatEuPurchases'); $gltransactions = new VatEuPurchasesCollection($gltransaction); break; + case '98': // postponed VAT + $gltransaction = DataObjectFactory::Factory('VatPVPurchases'); + $gltransactions = new VatPVPurchasesCollection($gltransaction); + break; + case '99': // reverse charge VAT + $gltransaction = DataObjectFactory::Factory('VatRCPurchases'); + $gltransactions = new VatRCPurchasesCollection($gltransaction); + break; } } @@ -966,6 +1004,12 @@ public function printTransactions($status = 'generate') case 9: $title = "VAT EU Purchases {$title}"; break; + case 98: + $title = "Postponed VAT Purchases {$title}"; + break; + case 99: + $title = "Reverse Charge Purchases {$title}"; + break; } $extra = array( @@ -1151,7 +1195,7 @@ public function view() { ), 'tag'=>'View Transactions' ); - + $returns_sidebar['all'] = [ 'link' => [ 'modules' => $this->_modules, diff --git a/modules/public_pages/erp/ledger/vat/templates/vat/viewtransactions.tpl b/modules/public_pages/erp/ledger/vat/templates/vat/viewtransactions.tpl index 8b89b1b0..68fb8dde 100644 --- a/modules/public_pages/erp/ledger/vat/templates/vat/viewtransactions.tpl +++ b/modules/public_pages/erp/ledger/vat/templates/vat/viewtransactions.tpl @@ -11,6 +11,10 @@ {assign var=data value=$vateusaless} {else if $box == '9'} {assign var=data value=$vateupurchasess} +{else if $box == '98'} + {assign var=data value=$vatpvpurchasess} +{else if $box == '99'} + {assign var=data value=$vatrcpurchasess} {/if} {content_wrapper} {paging} @@ -20,7 +24,7 @@ Date {heading_cell field="docref"} - Doc Ref: + Doc Ref. {/heading_cell} Ext Ref. @@ -68,10 +72,10 @@ {/if} {/if} {/grid_cell} - {grid_cell model=$model cell_num=7 field="type"} + {grid_cell model=$model cell_num=7 field="ext_reference"} {$model->ext_reference} {/grid_cell} - {grid_cell model=$model cell_num=7 field="type"} + {grid_cell model=$model cell_num=7 field="company"} {if $model->supplier} {$model->supplier} {else if $model->customer} From 83c942164ac81be2a74af285af92815a9570d1d3 Mon Sep 17 00:00:00 2001 From: Steve Blamey Date: Tue, 10 Nov 2020 13:34:30 +0000 Subject: [PATCH 10/25] Migration: Adds VAT report module components for PVA and Reverse Charge --- ...32624_add_vat_module_report_components.php | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 schema/phinx/migrations/20201110132624_add_vat_module_report_components.php diff --git a/schema/phinx/migrations/20201110132624_add_vat_module_report_components.php b/schema/phinx/migrations/20201110132624_add_vat_module_report_components.php new file mode 100644 index 00000000..5babea02 --- /dev/null +++ b/schema/phinx/migrations/20201110132624_add_vat_module_report_components.php @@ -0,0 +1,51 @@ + + * @license GPLv3 or later + * @copyright (c) 2020 uzERP LLP (support#uzerp.com). All rights reserved. + */ +class AddVatModuleReportComponents extends UzerpMigration +{ + protected $module_components = [ + [ + 'module' => 'vat', + 'name' => 'vatpvpurchases', + 'type' => 'M', + 'location' => 'modules/public_pages/erp/ledger/vat/models/VatPVPurchases.php' + ], + [ + 'module' => 'vat', + 'name' => 'vatpvpurchasescollection', + 'type' => 'M', + 'location' => 'modules/public_pages/erp/ledger/vat/models/VatPVPurchasesCollection.php' + ], + [ + 'module' => 'vat', + 'name' => 'vatrcpurchases', + 'type' => 'M', + 'location' => 'modules/public_pages/erp/ledger/vat/models/VatRCPurchases.php' + ], + [ + 'module' => 'vat', + 'name' => 'vatrcpurchasescollection', + 'type' => 'M', + 'location' => 'modules/public_pages/erp/ledger/vat/models/VatRCPurchasesCollection.php' + ], + ]; + + public function up() + { + $this->addModuleComponents(); + } + + public function down() + { + $this->removeModuleComponents(); + } +} From c195622e62b03f39ae23fc440a1d5b2abf5a67df Mon Sep 17 00:00:00 2001 From: Steve Blamey Date: Tue, 10 Nov 2020 14:42:14 +0000 Subject: [PATCH 11/25] VatController::savejournal, restrict GL Period selection and allow 0 Net Value Closes #207 --- .../ledger/general_ledger/models/GLPeriod.php | 16 ++++++++++++++++ .../erp/ledger/vat/controllers/VatController.php | 16 ++++++++++++---- .../ledger/vat/templates/vat/enter_journal.tpl | 2 +- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/modules/public_pages/erp/ledger/general_ledger/models/GLPeriod.php b/modules/public_pages/erp/ledger/general_ledger/models/GLPeriod.php index 05386c18..4eab1e68 100755 --- a/modules/public_pages/erp/ledger/general_ledger/models/GLPeriod.php +++ b/modules/public_pages/erp/ledger/general_ledger/models/GLPeriod.php @@ -268,6 +268,22 @@ public static function getFuturePeriods($period, $year) return $glperiod->getAll($cc); } + + /** + * Return a list of open GL Periods + * + * @param boolean $ledger true = all open periods, false = periods open for VAT + * @return array options array + */ + public function getOpenPeriods($ledger=true) { + $cc = new ConstraintChain(); + if ($ledger === true) { + $cc->add(new Constraint('closed', 'IS', false)); + } else { + $cc->add(new Constraint('tax_period_closed', 'IS', false)); + } + return $this->getAll($cc); + } public static function getIdsForTaxPeriod($tax_period, $year) { diff --git a/modules/public_pages/erp/ledger/vat/controllers/VatController.php b/modules/public_pages/erp/ledger/vat/controllers/VatController.php index 430a2277..523270fd 100644 --- a/modules/public_pages/erp/ledger/vat/controllers/VatController.php +++ b/modules/public_pages/erp/ledger/vat/controllers/VatController.php @@ -86,9 +86,9 @@ public function index() public function enter_journal() { - $flash=Flash::Instance(); + //$flash=Flash::Instance(); - $errors=array(); + //$errors=array(); if (!$this->checkParams('vat_type')) { @@ -111,6 +111,11 @@ public function enter_journal() $gl_account->load($account_id); $this->view->set('gl_centres',$gl_account->getCentres()); + + $period = DataObjectFactory::Factory('GLPeriod'); + $current = $period->getPeriod(un_fix_date(fix_date(date(DATE_FORMAT)))); + $this->view->set('periods', $period->getOpenPeriods(false)); + $this->view->set('current_period', $current['id']); $this->view->set('vat_type', $this->_data['vat_type']); $this->view->set('vat', DataObjectFactory::Factory('Vat')); @@ -131,9 +136,12 @@ public function savejournal () $data = $this->_data['Vat']; - if ($data['value']['net']<=0 || $data['value']['vat']<=0) + if ($data['value']['vat']<=0) { - $errors[]='Net and Vat values must be greater than zero'; + $errors[]='Vat Value must be greater than zero'; + } + elseif ($data['value']['net']<=0) { + $flash->addWarning('Transaction saved with Net Value of zero'); } else { diff --git a/modules/public_pages/erp/ledger/vat/templates/vat/enter_journal.tpl b/modules/public_pages/erp/ledger/vat/templates/vat/enter_journal.tpl index 12a5e314..4496d18d 100755 --- a/modules/public_pages/erp/ledger/vat/templates/vat/enter_journal.tpl +++ b/modules/public_pages/erp/ledger/vat/templates/vat/enter_journal.tpl @@ -13,7 +13,7 @@ {input type="hidden" attribute="vat_type" value=$vat_type} {input type="text" attribute='net' number='value' value='0.00' label='Net Value '} {input type="text" attribute='vat' number='value' value='0.00' label='Vat Value '} - {select attribute="glperiods_id" label="Post to Period"} + {select attribute="glperiods_id" label="Post to Period" options=$periods value=$current_period} {input type="text" attribute="reference"} {input type="text" attribute="comment"} {select attribute='glaccount_id' label='Account' force=true options=$gl_accounts} From 853034c3c2ac83b4c2ca1f50338ea0b5778b7180 Mon Sep 17 00:00:00 2001 From: Martyn Shiner Date: Wed, 11 Nov 2020 09:13:19 +0000 Subject: [PATCH 12/25] NumericFormatter VAT and NET on transaction models --- .../ledger/general_ledger/models/GLPeriod.php | 16 ++++++ .../ledger/vat/controllers/VatController.php | 16 ++++-- .../erp/ledger/vat/models/VatEuPurchases.php | 4 ++ .../erp/ledger/vat/models/VatEuSales.php | 4 ++ .../erp/ledger/vat/models/VatInputs.php | 4 ++ .../erp/ledger/vat/models/VatOutputs.php | 4 ++ .../erp/ledger/vat/models/VatPVPurchases.php | 4 ++ .../erp/ledger/vat/models/VatRCPurchases.php | 4 ++ .../vat/templates/vat/enter_journal.tpl | 2 +- ...32624_add_vat_module_report_components.php | 51 +++++++++++++++++++ 10 files changed, 104 insertions(+), 5 deletions(-) create mode 100644 schema/phinx/migrations/20201110132624_add_vat_module_report_components.php diff --git a/modules/public_pages/erp/ledger/general_ledger/models/GLPeriod.php b/modules/public_pages/erp/ledger/general_ledger/models/GLPeriod.php index 05386c18..4eab1e68 100755 --- a/modules/public_pages/erp/ledger/general_ledger/models/GLPeriod.php +++ b/modules/public_pages/erp/ledger/general_ledger/models/GLPeriod.php @@ -268,6 +268,22 @@ public static function getFuturePeriods($period, $year) return $glperiod->getAll($cc); } + + /** + * Return a list of open GL Periods + * + * @param boolean $ledger true = all open periods, false = periods open for VAT + * @return array options array + */ + public function getOpenPeriods($ledger=true) { + $cc = new ConstraintChain(); + if ($ledger === true) { + $cc->add(new Constraint('closed', 'IS', false)); + } else { + $cc->add(new Constraint('tax_period_closed', 'IS', false)); + } + return $this->getAll($cc); + } public static function getIdsForTaxPeriod($tax_period, $year) { diff --git a/modules/public_pages/erp/ledger/vat/controllers/VatController.php b/modules/public_pages/erp/ledger/vat/controllers/VatController.php index 430a2277..523270fd 100644 --- a/modules/public_pages/erp/ledger/vat/controllers/VatController.php +++ b/modules/public_pages/erp/ledger/vat/controllers/VatController.php @@ -86,9 +86,9 @@ public function index() public function enter_journal() { - $flash=Flash::Instance(); + //$flash=Flash::Instance(); - $errors=array(); + //$errors=array(); if (!$this->checkParams('vat_type')) { @@ -111,6 +111,11 @@ public function enter_journal() $gl_account->load($account_id); $this->view->set('gl_centres',$gl_account->getCentres()); + + $period = DataObjectFactory::Factory('GLPeriod'); + $current = $period->getPeriod(un_fix_date(fix_date(date(DATE_FORMAT)))); + $this->view->set('periods', $period->getOpenPeriods(false)); + $this->view->set('current_period', $current['id']); $this->view->set('vat_type', $this->_data['vat_type']); $this->view->set('vat', DataObjectFactory::Factory('Vat')); @@ -131,9 +136,12 @@ public function savejournal () $data = $this->_data['Vat']; - if ($data['value']['net']<=0 || $data['value']['vat']<=0) + if ($data['value']['vat']<=0) { - $errors[]='Net and Vat values must be greater than zero'; + $errors[]='Vat Value must be greater than zero'; + } + elseif ($data['value']['net']<=0) { + $flash->addWarning('Transaction saved with Net Value of zero'); } else { diff --git a/modules/public_pages/erp/ledger/vat/models/VatEuPurchases.php b/modules/public_pages/erp/ledger/vat/models/VatEuPurchases.php index b66b0cd4..92444187 100644 --- a/modules/public_pages/erp/ledger/vat/models/VatEuPurchases.php +++ b/modules/public_pages/erp/ledger/vat/models/VatEuPurchases.php @@ -31,6 +31,10 @@ function __construct($tablename='gl_taxeupurchases') { $glt = new GLTransaction; $this->setEnum('type', $glt->enums['type']); $this->setEnum('source', $glt->enums['source']); + + // Define field formats + $this->getField('vat')->setFormatter(new NumericFormatter()); + $this->getField('net')->setFormatter(new NumericFormatter()); } } ?> \ No newline at end of file diff --git a/modules/public_pages/erp/ledger/vat/models/VatEuSales.php b/modules/public_pages/erp/ledger/vat/models/VatEuSales.php index 0ef4571b..8b77bbac 100644 --- a/modules/public_pages/erp/ledger/vat/models/VatEuSales.php +++ b/modules/public_pages/erp/ledger/vat/models/VatEuSales.php @@ -31,6 +31,10 @@ function __construct($tablename='gl_taxeusales') { $glt = new GLTransaction; $this->setEnum('type', $glt->enums['type']); $this->setEnum('source', $glt->enums['source']); + + // Define field formats + $this->getField('vat')->setFormatter(new NumericFormatter()); + $this->getField('net')->setFormatter(new NumericFormatter()); } } ?> \ No newline at end of file diff --git a/modules/public_pages/erp/ledger/vat/models/VatInputs.php b/modules/public_pages/erp/ledger/vat/models/VatInputs.php index e390c4cb..1e0972c6 100644 --- a/modules/public_pages/erp/ledger/vat/models/VatInputs.php +++ b/modules/public_pages/erp/ledger/vat/models/VatInputs.php @@ -31,6 +31,10 @@ function __construct($tablename='gltransactions_vat_inputs') { $glt = new GLTransaction; $this->setEnum('type', $glt->enums['type']); $this->setEnum('source', $glt->enums['source']); + + // Define field formats + $this->getField('vat')->setFormatter(new NumericFormatter()); + $this->getField('net')->setFormatter(new NumericFormatter()); } } ?> \ No newline at end of file diff --git a/modules/public_pages/erp/ledger/vat/models/VatOutputs.php b/modules/public_pages/erp/ledger/vat/models/VatOutputs.php index 2a71857d..b346639e 100644 --- a/modules/public_pages/erp/ledger/vat/models/VatOutputs.php +++ b/modules/public_pages/erp/ledger/vat/models/VatOutputs.php @@ -31,6 +31,10 @@ function __construct($tablename='gltransactions_vat_outputs') { $glt = new GLTransaction; $this->setEnum('type', $glt->enums['type']); $this->setEnum('source', $glt->enums['source']); + + // Define field formats + $this->getField('vat')->setFormatter(new NumericFormatter()); + $this->getField('net')->setFormatter(new NumericFormatter()); } } ?> \ No newline at end of file diff --git a/modules/public_pages/erp/ledger/vat/models/VatPVPurchases.php b/modules/public_pages/erp/ledger/vat/models/VatPVPurchases.php index 34262829..8c8a6d98 100644 --- a/modules/public_pages/erp/ledger/vat/models/VatPVPurchases.php +++ b/modules/public_pages/erp/ledger/vat/models/VatPVPurchases.php @@ -31,6 +31,10 @@ function __construct($tablename='gl_taxpvpurchases') { $glt = new GLTransaction; $this->setEnum('type', $glt->enums['type']); $this->setEnum('source', $glt->enums['source']); + + // Define field formats + $this->getField('vat')->setFormatter(new NumericFormatter()); + $this->getField('net')->setFormatter(new NumericFormatter()); } } ?> \ No newline at end of file diff --git a/modules/public_pages/erp/ledger/vat/models/VatRCPurchases.php b/modules/public_pages/erp/ledger/vat/models/VatRCPurchases.php index 5616591d..9b084f9b 100644 --- a/modules/public_pages/erp/ledger/vat/models/VatRCPurchases.php +++ b/modules/public_pages/erp/ledger/vat/models/VatRCPurchases.php @@ -31,6 +31,10 @@ function __construct($tablename='gl_taxrcpurchases') { $glt = new GLTransaction; $this->setEnum('type', $glt->enums['type']); $this->setEnum('source', $glt->enums['source']); + + // Define field formats + $this->getField('vat')->setFormatter(new NumericFormatter()); + $this->getField('net')->setFormatter(new NumericFormatter()); } } ?> \ No newline at end of file diff --git a/modules/public_pages/erp/ledger/vat/templates/vat/enter_journal.tpl b/modules/public_pages/erp/ledger/vat/templates/vat/enter_journal.tpl index 12a5e314..4496d18d 100755 --- a/modules/public_pages/erp/ledger/vat/templates/vat/enter_journal.tpl +++ b/modules/public_pages/erp/ledger/vat/templates/vat/enter_journal.tpl @@ -13,7 +13,7 @@ {input type="hidden" attribute="vat_type" value=$vat_type} {input type="text" attribute='net' number='value' value='0.00' label='Net Value '} {input type="text" attribute='vat' number='value' value='0.00' label='Vat Value '} - {select attribute="glperiods_id" label="Post to Period"} + {select attribute="glperiods_id" label="Post to Period" options=$periods value=$current_period} {input type="text" attribute="reference"} {input type="text" attribute="comment"} {select attribute='glaccount_id' label='Account' force=true options=$gl_accounts} diff --git a/schema/phinx/migrations/20201110132624_add_vat_module_report_components.php b/schema/phinx/migrations/20201110132624_add_vat_module_report_components.php new file mode 100644 index 00000000..5babea02 --- /dev/null +++ b/schema/phinx/migrations/20201110132624_add_vat_module_report_components.php @@ -0,0 +1,51 @@ + + * @license GPLv3 or later + * @copyright (c) 2020 uzERP LLP (support#uzerp.com). All rights reserved. + */ +class AddVatModuleReportComponents extends UzerpMigration +{ + protected $module_components = [ + [ + 'module' => 'vat', + 'name' => 'vatpvpurchases', + 'type' => 'M', + 'location' => 'modules/public_pages/erp/ledger/vat/models/VatPVPurchases.php' + ], + [ + 'module' => 'vat', + 'name' => 'vatpvpurchasescollection', + 'type' => 'M', + 'location' => 'modules/public_pages/erp/ledger/vat/models/VatPVPurchasesCollection.php' + ], + [ + 'module' => 'vat', + 'name' => 'vatrcpurchases', + 'type' => 'M', + 'location' => 'modules/public_pages/erp/ledger/vat/models/VatRCPurchases.php' + ], + [ + 'module' => 'vat', + 'name' => 'vatrcpurchasescollection', + 'type' => 'M', + 'location' => 'modules/public_pages/erp/ledger/vat/models/VatRCPurchasesCollection.php' + ], + ]; + + public function up() + { + $this->addModuleComponents(); + } + + public function down() + { + $this->removeModuleComponents(); + } +} From 6f1c7e670b9ebb92095c120c352dcd3a59b19c64 Mon Sep 17 00:00:00 2001 From: Steve Blamey Date: Wed, 11 Nov 2020 15:52:57 +0000 Subject: [PATCH 13/25] Phinx Migration - Add utility views to lookup VAT GL Params --- ...01111153513_add_vat_param_lookup_views.php | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 schema/phinx/migrations/20201111153513_add_vat_param_lookup_views.php diff --git a/schema/phinx/migrations/20201111153513_add_vat_param_lookup_views.php b/schema/phinx/migrations/20201111153513_add_vat_param_lookup_views.php new file mode 100644 index 00000000..7e04960c --- /dev/null +++ b/schema/phinx/migrations/20201111153513_add_vat_param_lookup_views.php @@ -0,0 +1,43 @@ + + * @license GPLv3 or later + * @copyright (c) 2020 uzERP LLP (support#uzerp.com). All rights reserved. + */ +class AddVatParamLookupViews extends UzerpMigration +{ + public function up() + { + $view_name = ['glparams_vat_pv', 'glparams_vat_rc']; + $view_owner = 'www-data'; + $view1 = <<<'VIEW' + CREATE OR REPLACE VIEW glparams_vat_pv AS + SELECT p.paramvalue_id, + p.usercompanyid + FROM gl_params p + WHERE p.paramdesc::text = 'VAT Postponed Account'::text; + + VIEW; + + $view2 = <<<'VIEW' + CREATE OR REPLACE VIEW glparams_vat_rc AS + SELECT p.paramvalue_id, + p.usercompanyid + FROM gl_params p + WHERE p.paramdesc::text = 'VAT Reverse Charge Account'::text; + VIEW; + + $this->query($view1); + $this->query($view2); + foreach ($view_name as $view_n) { + $this->query("ALTER TABLE {$view_n} OWNER TO \"{$view_owner}\""); + } + } +} From f06d233c34d5e6228cbc361a704da2090f4728ae Mon Sep 17 00:00:00 2001 From: Steve Blamey Date: Wed, 11 Nov 2020 16:08:56 +0000 Subject: [PATCH 14/25] Phinx Migrations - Add views for postponed VAT and reverse charge purchase reporting --- ...111155541_add_view_gl_tax_pv_purchases.php | 57 +++++++++++++++++++ ...111155951_add_view_gl_tax_rc_purchases.php | 57 +++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 schema/phinx/migrations/20201111155541_add_view_gl_tax_pv_purchases.php create mode 100644 schema/phinx/migrations/20201111155951_add_view_gl_tax_rc_purchases.php diff --git a/schema/phinx/migrations/20201111155541_add_view_gl_tax_pv_purchases.php b/schema/phinx/migrations/20201111155541_add_view_gl_tax_pv_purchases.php new file mode 100644 index 00000000..f2eae633 --- /dev/null +++ b/schema/phinx/migrations/20201111155541_add_view_gl_tax_pv_purchases.php @@ -0,0 +1,57 @@ + + * @license GPLv3 or later + * @copyright (c) 2020 uzERP LLP (support#uzerp.com). All rights reserved. + */ +class AddViewGlTaxPvPurchases extends UzerpMigration +{ + public function up() + { + $view_name = 'gl_taxpvpurchases'; + $view_owner = 'www-data'; + $view = <<<'VIEW' + CREATE OR REPLACE VIEW gl_taxpvpurchases AS + SELECT row_number() OVER () AS id, + tr1.id AS gl_id, + tr1.docref, + tr1.glaccount_id, + tr1.glcentre_id, + tr1.glperiods_id, + glp.year, + glp.tax_period, + tr1.transaction_date, + tr1.source, + tr1.comment, + tr1.type, + tr1.value AS vat, + CASE + WHEN tr1.type::text = 'C'::text THEN 0::numeric - pih.base_net_value + ELSE pih.base_net_value + END AS net, + tr1.usercompanyid, + a.account, + c.name AS supplier, + pih.ext_reference, + ts.postponed_vat_accounting AS pvtaxstatus + FROM gl_transactions tr1 + JOIN glparams_vat_pv vi ON vi.paramvalue_id = tr1.glaccount_id + JOIN gl_accounts a ON a.id = tr1.glaccount_id + JOIN pi_header pih ON tr1.docref::text = pih.invoice_number::text AND tr1.type::text = pih.transaction_type::text AND tr1.source::text = 'P'::text + JOIN plmaster plm ON pih.plmaster_id = plm.id + JOIN company c ON plm.company_id = c.id + JOIN tax_statuses ts ON ts.id = pih.tax_status_id AND ts.postponed_vat_accounting = true + JOIN gl_periods glp ON glp.id = tr1.glperiods_id + WHERE tr1.source::text = 'P'::text AND (tr1.type::text = 'I'::text AND tr1.value > 0::numeric OR tr1.type::text = 'C'::text AND tr1.value < 0::numeric) + ORDER BY (row_number() OVER ()); + VIEW; + $this->query($view); + $this->query("ALTER TABLE {$view_name} OWNER TO \"{$view_owner}\""); + } +} diff --git a/schema/phinx/migrations/20201111155951_add_view_gl_tax_rc_purchases.php b/schema/phinx/migrations/20201111155951_add_view_gl_tax_rc_purchases.php new file mode 100644 index 00000000..8e79b442 --- /dev/null +++ b/schema/phinx/migrations/20201111155951_add_view_gl_tax_rc_purchases.php @@ -0,0 +1,57 @@ + + * @license GPLv3 or later + * @copyright (c) 2020 uzERP LLP (support#uzerp.com). All rights reserved. + */ +class AddViewGlTaxRcPurchases extends UzerpMigration +{ + public function up() + { + $view_name = 'gl_taxrcpurchases'; + $view_owner = 'www-data'; + $view = <<<'VIEW' + CREATE OR REPLACE VIEW gl_taxrcpurchases AS + SELECT row_number() OVER () AS id, + tr1.id AS gl_id, + tr1.docref, + tr1.glaccount_id, + tr1.glcentre_id, + tr1.glperiods_id, + glp.year, + glp.tax_period, + tr1.transaction_date, + tr1.source, + tr1.comment, + tr1.type, + tr1.value AS vat, + CASE + WHEN tr1.type::text = 'C'::text THEN 0::numeric - pih.base_net_value + ELSE pih.base_net_value + END AS net, + tr1.usercompanyid, + a.account, + c.name AS supplier, + pih.ext_reference, + ts.reverse_charge AS rctaxstatus + FROM gl_transactions tr1 + JOIN glparams_vat_rc vi ON vi.paramvalue_id = tr1.glaccount_id + JOIN gl_accounts a ON a.id = tr1.glaccount_id + JOIN pi_header pih ON tr1.docref::text = pih.invoice_number::text AND tr1.type::text = pih.transaction_type::text AND tr1.source::text = 'P'::text + JOIN plmaster plm ON pih.plmaster_id = plm.id + JOIN company c ON plm.company_id = c.id + JOIN tax_statuses ts ON ts.id = pih.tax_status_id AND ts.reverse_charge = true + JOIN gl_periods glp ON glp.id = tr1.glperiods_id + WHERE tr1.source::text = 'P'::text AND (tr1.type::text = 'I'::text AND tr1.value > 0::numeric OR tr1.type::text = 'C'::text AND tr1.value < 0::numeric) + ORDER BY (row_number() OVER ()); + VIEW; + $this->query($view); + $this->query("ALTER TABLE {$view_name} OWNER TO \"{$view_owner}\""); + } +} From 12a261c0dfb1672964079f493adffe4148ca3708 Mon Sep 17 00:00:00 2001 From: Martyn Shiner Date: Wed, 11 Nov 2020 17:27:08 +0000 Subject: [PATCH 15/25] VAT amend transaction printing and add csv output --- .../ledger/vat/controllers/VatController.php | 95 ++++++++++++++++--- 1 file changed, 84 insertions(+), 11 deletions(-) diff --git a/modules/public_pages/erp/ledger/vat/controllers/VatController.php b/modules/public_pages/erp/ledger/vat/controllers/VatController.php index 523270fd..cfb45595 100644 --- a/modules/public_pages/erp/ledger/vat/controllers/VatController.php +++ b/modules/public_pages/erp/ledger/vat/controllers/VatController.php @@ -307,6 +307,14 @@ public function viewEuSalesList () return $this->viewEUTransactions($collection, $sh); } + + /** + * View the list of transactions of each type for this VAT return + * + * Calls private function printTransactions() for printing + * + * Exporting to csv is handled here not in the print section + */ public function viewTransactions() { $errors = array(); @@ -334,46 +342,96 @@ public function viewTransactions() $year = $this->search->getValue('year'); if (isset($this->_data['box'])) + // switch the model/collection based on the 'box' (sic) { switch ($this->_data['box']) { case '4': // inputs $this->_templateobject = DataObjectFactory::Factory('VatInputs'); $this->uses($this->_templateobject); - parent::index(new VatInputsCollection($this->_templateobject)); + $vatTransactions = new VatInputsCollection($this->_templateobject); break; case '6': // outputs $this->_templateobject = DataObjectFactory::Factory('VatOutputs'); $this->uses($this->_templateobject); - parent::index(new VatOutputsCollection($this->_templateobject)); + $vatTransactions = new VatOutputsCollection($this->_templateobject); break; case '8': // eu sales $this->_templateobject = DataObjectFactory::Factory('VatEuSales'); $this->uses($this->_templateobject); - parent::index(new VatEuSalesCollection($this->_templateobject)); + $vatTransactions = new VatEuSalesCollection($this->_templateobject); break; case '9': // eu purchases $this->_templateobject = DataObjectFactory::Factory('VatEuPurchases'); $this->uses($this->_templateobject); - parent::index(new VatEuPurchasesCollection($this->_templateobject)); + $vatTransactions = new VatEuPurchasesCollection($this->_templateobject); break; case '98': // postponed VAT $this->_templateobject = DataObjectFactory::Factory('VatPVPurchases'); $this->uses($this->_templateobject); - parent::index(new VatPVPurchasesCollection($this->_templateobject)); + $vatTransactions = new VatPVPurchasesCollection($this->_templateobject); break; case '99': // reverse charge VAT $this->_templateobject = DataObjectFactory::Factory('VatRCPurchases'); $this->uses($this->_templateobject); - parent::index(new VatRCPurchasesCollection($this->_templateobject)); + $vatTransactions = new VatRCPurchasesCollection($this->_templateobject); break; } + // Show the data in the index + parent::index($vatTransactions); $this->view->set('box',$this->_data['box']); $this->view->set('page_title',"VAT Transactions {$year}/{$tax_period} - ".$this->titles[$this->_data['box']]); } + // Not sure we need to load the vat return here... Steve? $return = new VatReturn(); $return->loadVatReturn($year, $tax_period); + // Here be dragons! Output the transactions csv + if ($this->_data['format'] == 'csv') { + + $sh = new SearchHandler($vatTransactions, FALSE); + $sh->addConstraintChain(new Constraint('year', '=', $s_data['year'])); + $sh->addConstraintChain(new Constraint('tax_period', '=', $s_data['tax_period'])); + $csvExports = $vatTransactions->load($sh,'',3); + + // these are the columns we want + $column_order = ['transaction_date', + 'docref', + 'ext_reference', + 'company', + 'comment', + 'vat', + 'net', + 'source', + 'type']; + + // output headers so that the file is downloaded rather than displayed + header('Content-Type: text/csv; charset=utf-8'); + header('Content-Disposition: attachment; filename=vat_transactions.csv'); + + // create a file pointer connected to the output stream + $handle = fopen('php://output', 'w'); + + // output the column headings to match the index view + fputcsv($handle, ['Date', + 'Doc Ref', + 'Ext Ref', + 'Company', + 'Comment', + 'VAT', + 'Net', + 'Source', + 'Type']); + + // loop over the rows, outputting only the columns we want + foreach($csvExports as $csvrow) { + $csvrow = array_slice(array_merge(array_flip($column_order), $csvrow),0,9); + fputcsv($handle, $csvrow); + } + fclose($handle); + exit(); + } + $sidebar = new SidebarController($this->view); $returns_sidebar['all'] = [ @@ -405,7 +463,7 @@ public function viewTransactions() } $sidebar->addList( - 'Actions', + 'Output', array( 'printtransactions'=>array( 'link'=>array_merge(array('modules'=>$this->_modules @@ -415,8 +473,17 @@ public function viewTransactions() ,'filename'=>'Transactions_'.$year.'-'.$tax_period ) ,$print_params), - 'tag'=>'Output Transactions' + 'tag'=>'Print Transactions' ), + 'exporttransactions'=>array( + 'link'=>array_merge(array('modules'=>$this->_modules + ,'controller'=>$this->name + ,'action'=>'viewTransactions' + ,'format'=>'csv' + ) + ,$print_params), + 'tag'=>'Export Transactions to CSV' + ) ) ); @@ -901,8 +968,7 @@ public function printTransactions($status = 'generate') $options = array( 'type' => array( 'pdf' => '', - 'xml' => '', - 'csv' => '' + 'xml' => '' ), 'output' => array( 'print' => '', @@ -962,7 +1028,11 @@ public function printTransactions($status = 'generate') $sh = new SearchHandler($gltransactions, false); $sh->addConstraint($cc); $gltransactions->load($sh); - + // Need the underling view here so we can get the sum + $viewname=$gltransactions->_tablename; + $totalvat = $this->_templateobject->getSum('vat', $cc, $viewname); + $totalnet = $this->_templateobject->getSum('net', $cc, $viewname); + if (count($errors) > 0) { echo $this->build_print_dialog_response( @@ -1022,6 +1092,9 @@ public function printTransactions($status = 'generate') $extra = array( 'title' => $title + ,'totalvat' => $totalvat + ,'totalnet' => $totalnet + ); // generate the xml and add it to the options array From d309c5bff8e3a5c6be302646b39164a8fb175906 Mon Sep 17 00:00:00 2001 From: Martyn Shiner Date: Thu, 12 Nov 2020 08:32:15 +0000 Subject: [PATCH 16/25] Number format report totals --- .../public_pages/erp/ledger/vat/controllers/VatController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/public_pages/erp/ledger/vat/controllers/VatController.php b/modules/public_pages/erp/ledger/vat/controllers/VatController.php index cfb45595..2d0eace3 100644 --- a/modules/public_pages/erp/ledger/vat/controllers/VatController.php +++ b/modules/public_pages/erp/ledger/vat/controllers/VatController.php @@ -1092,8 +1092,8 @@ public function printTransactions($status = 'generate') $extra = array( 'title' => $title - ,'totalvat' => $totalvat - ,'totalnet' => $totalnet + ,'totalvat' => number_format($totalvat,2) + ,'totalnet' => number_format($totalnet,2) ); From 9eadd598fe283a8c314c0aadfe6412ad4c3878f0 Mon Sep 17 00:00:00 2001 From: Steve Blamey Date: Thu, 12 Nov 2020 11:30:17 +0000 Subject: [PATCH 17/25] Report definition: VatTransactions, add total row --- ...2426_vat_transaction_report_add_totals.php | 178 ++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 schema/phinx/migrations/20201112112426_vat_transaction_report_add_totals.php diff --git a/schema/phinx/migrations/20201112112426_vat_transaction_report_add_totals.php b/schema/phinx/migrations/20201112112426_vat_transaction_report_add_totals.php new file mode 100644 index 00000000..44f48999 --- /dev/null +++ b/schema/phinx/migrations/20201112112426_vat_transaction_report_add_totals.php @@ -0,0 +1,178 @@ + + * @license GPLv3 or later + * @copyright (c) 2020 uzERP LLP (support#uzerp.com). All rights reserved. + */ +class VatTransactionReportAddTotals extends UzerpMigration +{ + public function up() + { + $xsl = <<<'XMLDOC' + + + + + + + + + + + + + + + + + + + + + + + + + Page + + + + + + + + + + + + + + + + + + Date + + + Doc Ref + + + Ext Ref + + + Company + + + Comment + + + VAT + + + Net + + + Source + + + Type + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Report Total + + + + + + + + + + + + + + + + + + + + + + +XMLDOC; + + $date = new DateTime(); + $update_time = $date->format('Y-m-d H:i:s.u'); + $rows = $this->query("UPDATE report_definitions SET definition='${xsl}', lastupdated='${update_time}', alteredby='admin' WHERE name='VatTransaction'"); + } +} From c9e9f47f9bda743bb16d7604815fb13a81630774 Mon Sep 17 00:00:00 2001 From: Martyn Shiner Date: Thu, 12 Nov 2020 12:13:19 +0000 Subject: [PATCH 18/25] Set NumericFormatter 'boxes' in VatReturn model --- .../public_pages/erp/ledger/vat/models/VatReturn.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/modules/public_pages/erp/ledger/vat/models/VatReturn.php b/modules/public_pages/erp/ledger/vat/models/VatReturn.php index 31083cdb..12cc5e5a 100644 --- a/modules/public_pages/erp/ledger/vat/models/VatReturn.php +++ b/modules/public_pages/erp/ledger/vat/models/VatReturn.php @@ -61,6 +61,17 @@ public function __construct($tablename='vat_return') { // Output to smarty from the formatter will be html, // flag as html to prevent escaping $this->getField('tax_period_closed')->type = 'html'; + + // Define field formats + $this->getField('vat_due_sales')->setFormatter(new NumericFormatter()); + $this->getField('vat_due_acquisitions')->setFormatter(new NumericFormatter()); + $this->getField('total_vat_due')->setFormatter(new NumericFormatter()); + $this->getField('vat_reclaimed_curr_period')->setFormatter(new NumericFormatter()); + $this->getField('net_vat_due')->setFormatter(new NumericFormatter()); + $this->getField('total_value_sales_ex_vat')->setFormatter(new NumericFormatter()); + $this->getField('total_value_purchase_ex_vat')->setFormatter(new NumericFormatter()); + $this->getField('total_value_goods_supplied_ex_vat')->setFormatter(new NumericFormatter()); + $this->getField('total_acquisitions_ex_vat')->setFormatter(new NumericFormatter()); } From 350a26285f38b6844a60db727c553969a87b2d2a Mon Sep 17 00:00:00 2001 From: Martyn Shiner Date: Thu, 12 Nov 2020 12:30:33 +0000 Subject: [PATCH 19/25] Set company type VAT transactions export to csv --- .../erp/ledger/vat/controllers/VatController.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/modules/public_pages/erp/ledger/vat/controllers/VatController.php b/modules/public_pages/erp/ledger/vat/controllers/VatController.php index 2d0eace3..b03abf17 100644 --- a/modules/public_pages/erp/ledger/vat/controllers/VatController.php +++ b/modules/public_pages/erp/ledger/vat/controllers/VatController.php @@ -349,31 +349,37 @@ public function viewTransactions() $this->_templateobject = DataObjectFactory::Factory('VatInputs'); $this->uses($this->_templateobject); $vatTransactions = new VatInputsCollection($this->_templateobject); + $company_type='supplier'; break; case '6': // outputs $this->_templateobject = DataObjectFactory::Factory('VatOutputs'); $this->uses($this->_templateobject); $vatTransactions = new VatOutputsCollection($this->_templateobject); + $company_type='customer'; break; case '8': // eu sales $this->_templateobject = DataObjectFactory::Factory('VatEuSales'); $this->uses($this->_templateobject); $vatTransactions = new VatEuSalesCollection($this->_templateobject); + $company_type='customer'; break; case '9': // eu purchases $this->_templateobject = DataObjectFactory::Factory('VatEuPurchases'); $this->uses($this->_templateobject); $vatTransactions = new VatEuPurchasesCollection($this->_templateobject); + $company_type='supplier'; break; case '98': // postponed VAT $this->_templateobject = DataObjectFactory::Factory('VatPVPurchases'); $this->uses($this->_templateobject); - $vatTransactions = new VatPVPurchasesCollection($this->_templateobject); + $vatTransactions = new VatPVPurchasesCollection($this->_templateobject); + $company_type='supplier'; break; case '99': // reverse charge VAT $this->_templateobject = DataObjectFactory::Factory('VatRCPurchases'); $this->uses($this->_templateobject); $vatTransactions = new VatRCPurchasesCollection($this->_templateobject); + $company_type='supplier'; break; } // Show the data in the index @@ -398,7 +404,7 @@ public function viewTransactions() $column_order = ['transaction_date', 'docref', 'ext_reference', - 'company', + $company_type, 'comment', 'vat', 'net', From f9308193567dff69ef474027be17ea3f17719879 Mon Sep 17 00:00:00 2001 From: Steve Blamey Date: Fri, 13 Nov 2020 12:05:05 +0000 Subject: [PATCH 20/25] VatController, remove comments --- .../erp/ledger/vat/controllers/VatController.php | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/modules/public_pages/erp/ledger/vat/controllers/VatController.php b/modules/public_pages/erp/ledger/vat/controllers/VatController.php index b03abf17..26c36e7f 100644 --- a/modules/public_pages/erp/ledger/vat/controllers/VatController.php +++ b/modules/public_pages/erp/ledger/vat/controllers/VatController.php @@ -388,19 +388,16 @@ public function viewTransactions() $this->view->set('page_title',"VAT Transactions {$year}/{$tax_period} - ".$this->titles[$this->_data['box']]); } - // Not sure we need to load the vat return here... Steve? $return = new VatReturn(); $return->loadVatReturn($year, $tax_period); - // Here be dragons! Output the transactions csv if ($this->_data['format'] == 'csv') { $sh = new SearchHandler($vatTransactions, FALSE); $sh->addConstraintChain(new Constraint('year', '=', $s_data['year'])); $sh->addConstraintChain(new Constraint('tax_period', '=', $s_data['tax_period'])); $csvExports = $vatTransactions->load($sh,'',3); - - // these are the columns we want + $column_order = ['transaction_date', 'docref', 'ext_reference', @@ -410,7 +407,7 @@ public function viewTransactions() 'net', 'source', 'type']; - + // output headers so that the file is downloaded rather than displayed header('Content-Type: text/csv; charset=utf-8'); header('Content-Disposition: attachment; filename=vat_transactions.csv'); @@ -429,9 +426,8 @@ public function viewTransactions() 'Source', 'Type']); - // loop over the rows, outputting only the columns we want foreach($csvExports as $csvrow) { - $csvrow = array_slice(array_merge(array_flip($column_order), $csvrow),0,9); + $csvrow = array_slice(array_merge(array_flip($column_order), $csvrow),0,9); fputcsv($handle, $csvrow); } fclose($handle); From 5e8f92bed266cf648483a59c1b904f953e0bc88c Mon Sep 17 00:00:00 2001 From: Steve Blamey Date: Fri, 13 Nov 2020 12:53:07 +0000 Subject: [PATCH 21/25] Migration: add 'active' column to tax statuses --- ...20201113122425_add_vat_status_active_column.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 schema/phinx/migrations/20201113122425_add_vat_status_active_column.php diff --git a/schema/phinx/migrations/20201113122425_add_vat_status_active_column.php b/schema/phinx/migrations/20201113122425_add_vat_status_active_column.php new file mode 100644 index 00000000..fa5b8b69 --- /dev/null +++ b/schema/phinx/migrations/20201113122425_add_vat_status_active_column.php @@ -0,0 +1,14 @@ +table('tax_statuses'); + $table->addColumn('active', 'boolean', ['default' => true]) + ->save(); + } +} From 924e72a3f00593d73cbd6e2c4f68f8cb2feabdb7 Mon Sep 17 00:00:00 2001 From: Steve Blamey Date: Fri, 13 Nov 2020 12:53:52 +0000 Subject: [PATCH 22/25] Model TaxStatus, add active field --- .../erp/ledger/ledger_setup/models/TaxStatus.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/modules/public_pages/erp/ledger/ledger_setup/models/TaxStatus.php b/modules/public_pages/erp/ledger/ledger_setup/models/TaxStatus.php index afd90bac..918b1fee 100755 --- a/modules/public_pages/erp/ledger/ledger_setup/models/TaxStatus.php +++ b/modules/public_pages/erp/ledger/ledger_setup/models/TaxStatus.php @@ -10,6 +10,7 @@ class TaxStatus extends DataObject { protected $defaultDisplayFields = ['description', + 'active', 'apply_tax', 'eu_tax', 'postponed_vat_accounting' => 'PVA', @@ -35,6 +36,20 @@ public function get_customer_tax_statuses() $cc = new ConstraintChain(); $cc->add(new Constraint('postponed_vat_accounting', 'IS', false)); $cc->add(new Constraint('reverse_charge', 'IS', false)); + $cc->add(new Constraint('active', 'IS', true)); + $statuses = $this->getAll($cc); + return $statuses; + } + + /** + * Return an array of tax status options + * + * @return array Status options + */ + public function get_active_tax_statuses() + { + $cc = new ConstraintChain(); + $cc->add(new Constraint('active', 'IS', true)); $statuses = $this->getAll($cc); return $statuses; } From 993ed2002d99b6f8ca55299985393fa360ffcfaa Mon Sep 17 00:00:00 2001 From: Steve Blamey Date: Fri, 13 Nov 2020 12:54:54 +0000 Subject: [PATCH 23/25] Use TaxStatus active flag in UI --- .../erp/ledger/ledger_setup/templates/taxstatuss/new.tpl | 1 + .../purchase_ledger/controllers/PlsuppliersController.php | 5 +++++ .../ledger/purchase_ledger/templates/plsuppliers/new.tpl | 6 ++++-- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/modules/public_pages/erp/ledger/ledger_setup/templates/taxstatuss/new.tpl b/modules/public_pages/erp/ledger/ledger_setup/templates/taxstatuss/new.tpl index 9a0fe238..3c6f6de0 100755 --- a/modules/public_pages/erp/ledger/ledger_setup/templates/taxstatuss/new.tpl +++ b/modules/public_pages/erp/ledger/ledger_setup/templates/taxstatuss/new.tpl @@ -10,6 +10,7 @@ {input type='hidden' attribute='id' } {include file='elements/auditfields.tpl' } {input type='text' attribute='description' class="compulsory" } + {input type='checkbox' attribute='active' class="compulsory" } {input type='checkbox' attribute='apply_tax' class="compulsory" } {input type='checkbox' label='EU Tax' attribute='eu_tax' class="compulsory" } {input type='checkbox' label='PVA' attribute='postponed_vat_accounting' class="compulsory" } diff --git a/modules/public_pages/erp/ledger/purchase_ledger/controllers/PlsuppliersController.php b/modules/public_pages/erp/ledger/purchase_ledger/controllers/PlsuppliersController.php index 1c226ddf..be45b073 100644 --- a/modules/public_pages/erp/ledger/purchase_ledger/controllers/PlsuppliersController.php +++ b/modules/public_pages/erp/ledger/purchase_ledger/controllers/PlsuppliersController.php @@ -112,6 +112,11 @@ public function _new() $supplier->cb_account_id = $cbaccount->{$cbaccount->idField}; } + $taxstatus = new TaxStatus(); + $taxstatuses = $taxstatus->get_active_tax_statuses(); + + $this->view->set('f_taxstatuses', $taxstatuses); + $this->view->set('bank_account', $supplier->cb_account_id); $this->view->set('bank_accounts', $this->getbankAccounts($supplier->id)); diff --git a/modules/public_pages/erp/ledger/purchase_ledger/templates/plsuppliers/new.tpl b/modules/public_pages/erp/ledger/purchase_ledger/templates/plsuppliers/new.tpl index 9f9b6f5b..e1950d1a 100755 --- a/modules/public_pages/erp/ledger/purchase_ledger/templates/plsuppliers/new.tpl +++ b/modules/public_pages/erp/ledger/purchase_ledger/templates/plsuppliers/new.tpl @@ -36,10 +36,12 @@ {select attribute='payment_term_id' } {select attribute='payment_type_id' } {if $action=='new' } - {select attribute='tax_status_id' } + {select attribute='tax_status_id' options=$f_taxstatuses} {else} {if $transaction_count == 0} - {select attribute='tax_status_id' } + {select attribute='tax_status_id' options=$f_taxstatuses} + {else} + {view_data attribute='tax_status_id'} {/if} {/if} {select attribute='delivery_term_id' } From be5b0558b073a3c02153cd3aa46868c87e49cb9c Mon Sep 17 00:00:00 2001 From: Steve Blamey Date: Mon, 16 Nov 2020 10:39:10 +0000 Subject: [PATCH 24/25] MTD, Handle Gov-Client-Browser-Plugins fraud prevention header --- lib/classes/standard/MTD.php | 14 +++--- .../erp/ledger/vat/resources/js/vat.js | 49 ++++++++++++++++++- 2 files changed, 56 insertions(+), 7 deletions(-) diff --git a/lib/classes/standard/MTD.php b/lib/classes/standard/MTD.php index ba5c9ed1..00e5c2a0 100644 --- a/lib/classes/standard/MTD.php +++ b/lib/classes/standard/MTD.php @@ -59,7 +59,6 @@ function __construct($client_fp_info='', $config_key='mtd-vat') { ]); $config = Config::Instance(); - $device_uuid = $oauth_config['clientuuid']; $current = timezone_open('Europe/London'); $utcTime = new \DateTime('now', new \DateTimeZone('UTC')); $offsetInSecs = $current->getOffset($utcTime); @@ -108,7 +107,14 @@ function __construct($client_fp_info='', $config_key='mtd-vat') { // Gov-Client-Browser-Plugins // Modern browsers return an empty list - //$browser_plugins = get_object_vars($this->client_fp_info->plugins); + $browser_plugins = get_object_vars($this->client_fp_info->plugins); + if (count($browser_plugins) > 0) { + $plugin_names = []; + foreach ($browser_plugins as $plugin) { + $plugin_names[] = rawurlencode($plugin->name); + } + $this->fraud_protection_headers['Gov-Client-Browser-Plugins'] = implode(',', $plugin_names); + } // Gov-Client-Browser-JS-User-Agent $this->fraud_protection_headers['Gov-Client-Browser-JS-User-Agent'] = $this->client_fp_info->userAgent; @@ -116,10 +122,6 @@ function __construct($client_fp_info='', $config_key='mtd-vat') { // Gov-Client-Browser-Do-Not-Track $this->fraud_protection_headers['Gov-Client-Browser-Do-Not-Track'] = $this->client_fp_info->dnt; - - // Gov-Client-Multi-Factor - //N/a - // Gov-Vendor-Public-IP // The public IP address of the servers the originating device sent their requests to. // Public networks only diff --git a/modules/public_pages/erp/ledger/vat/resources/js/vat.js b/modules/public_pages/erp/ledger/vat/resources/js/vat.js index b7a6f634..0cd0f42f 100755 --- a/modules/public_pages/erp/ledger/vat/resources/js/vat.js +++ b/modules/public_pages/erp/ledger/vat/resources/js/vat.js @@ -28,6 +28,53 @@ $(document).ready(function(){ dnt: '' } + var getBrowserPlugins = function(navigator) { + var rdls = function (vals) { + var res = []; + var tmp = vals.sort(); + + for (var i = 0; i < tmp.length; i++) { + res.push(tmp[i]); + while (JSON.stringify(tmp[i]) == JSON.stringify(tmp[i + 1])) { + i++; + } + } + + return res; + }; + + var res = []; + if (!navigator || !navigator.plugins) { + return res; + } + + for (var p in navigator.plugins) { + var plugin = navigator.plugins[p]; + + for (var j = 0; j < plugin.length; j++) { + var mime = plugin[j]; + + if (!mime) { + continue; + } + + var ep = mime.enabledPlugin; + if (ep) { + var item = { + mime: mime.type, + name: ep.name, + description: ep.description, + filename: ep.filename + }; + + res.push(item); + } + } + } + + return rdls(res); + }; + const ip = new Promise((resolve, reject) => { const conn = new RTCPeerConnection() conn.createDataChannel('') @@ -51,7 +98,7 @@ $(document).ready(function(){ fp.windowWidth = window.outerWidth; fp.windowHeight = window.outerHeight; - fp.plugins = navigator.plugins; + fp.plugins = getBrowserPlugins(navigator); fp.userAgent = navigator.userAgent; From ca173f7c4d083461845018920fdd888889780893 Mon Sep 17 00:00:00 2001 From: Steve Blamey Date: Mon, 16 Nov 2020 10:47:22 +0000 Subject: [PATCH 25/25] Update changelog --- CHANGELOG.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0568272b..b4f62303 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,10 +4,16 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +### Added + +- Support for Postponed VAT Accounting for goods +- Suppport for VAT Reverse Charge on services +- Allow a VAT status to be inactive (not available when adding new customer or supplier ledger accounts) + ### Fixed - Cashbook payments not saved when entering invalid combination of values with tax rate 'None' -- Cashbook payments no longer allow payments to inactive companies or people +- Cashbook no longer allows payments to inactive companies or people - Output VAT transactions for the selected period ## [1.25.1] 2020-08-12