diff --git a/addons/account/views/account_view.xml b/addons/account/views/account_view.xml index 49999d11..4e984b30 100644 --- a/addons/account/views/account_view.xml +++ b/addons/account/views/account_view.xml @@ -1063,6 +1063,7 @@ + diff --git a/addons/account/views/res_config_settings_views.xml b/addons/account/views/res_config_settings_views.xml index 07a12cb9..bccd1950 100644 --- a/addons/account/views/res_config_settings_views.xml +++ b/addons/account/views/res_config_settings_views.xml @@ -117,7 +117,7 @@ -

Currencies

+

Currencies

diff --git a/addons/hr/security/hr_security.xml b/addons/hr/security/hr_security.xml index 441d1d73..e1dac20c 100644 --- a/addons/hr/security/hr_security.xml +++ b/addons/hr/security/hr_security.xml @@ -28,6 +28,13 @@ ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + + Employee multi company rule + + + ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + + Job multi company rule diff --git a/addons/hr_contract/__manifest__.py b/addons/hr_contract/__manifest__.py index c711d627..8ee61f2c 100644 --- a/addons/hr_contract/__manifest__.py +++ b/addons/hr_contract/__manifest__.py @@ -20,6 +20,7 @@ You can assign several contracts per employee. 'website': 'https://flectrahq.com/page/employees', 'depends': ['hr'], 'data': [ + 'security/contract_security.xml', 'security/ir.model.access.csv', 'data/hr_contract_data.xml', 'views/hr_contract_views.xml', diff --git a/addons/hr_contract/security/contract_security.xml b/addons/hr_contract/security/contract_security.xml new file mode 100644 index 00000000..4b976a59 --- /dev/null +++ b/addons/hr_contract/security/contract_security.xml @@ -0,0 +1,14 @@ + + + + + + Hr Contract Multicompany + + + ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + + + + + diff --git a/addons/hr_payroll/models/hr_salary_rule.py b/addons/hr_payroll/models/hr_salary_rule.py index 85a99284..a0ebcd8e 100644 --- a/addons/hr_payroll/models/hr_salary_rule.py +++ b/addons/hr_payroll/models/hr_salary_rule.py @@ -19,7 +19,10 @@ class HrPayrollStructure(models.Model): @api.model def _get_parent(self): - return self.env.ref('hr_payroll.structure_base', False) + if self.env.user.company_id.id == self.env.ref( + 'base.base.main_company', False): + return self.env.ref('hr_payroll.structure_base', False) + return False name = fields.Char(required=True) code = fields.Char(string='Reference', required=True) diff --git a/addons/hr_payroll/security/hr_payroll_security.xml b/addons/hr_payroll/security/hr_payroll_security.xml index 5c25f0ef..1dbfadc8 100644 --- a/addons/hr_payroll/security/hr_payroll_security.xml +++ b/addons/hr_payroll/security/hr_payroll_security.xml @@ -33,5 +33,29 @@ + + Payslip Multicompany + + ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + + + + Payroll Structure Multicompany + + ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + + + + Hr Salary Rule Multicompany + + ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + + + + Hr Contribution Register Multicompany + + ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + + diff --git a/addons/l10n_ae/data/l10n_ae_chart_data.xml b/addons/l10n_ae/data/l10n_ae_chart_data.xml index e2103cbd..f5493717 100644 --- a/addons/l10n_ae/data/l10n_ae_chart_data.xml +++ b/addons/l10n_ae/data/l10n_ae_chart_data.xml @@ -1643,7 +1643,6 @@ customs - 0 diff --git a/addons/l10n_ae_extend/__manifest__.py b/addons/l10n_ae_extend/__manifest__.py index 3334f115..9c3a3420 100644 --- a/addons/l10n_ae_extend/__manifest__.py +++ b/addons/l10n_ae_extend/__manifest__.py @@ -19,7 +19,7 @@ United Arab Emirates accounting chart and localization. 'views/report_vat_201_view.xml', 'views/report_menu_view.xml', 'views/vat_config_type.xml', - 'views/company_view.xml', + 'views/res_config_view.xml', 'views/purchase_order_view.xml', 'views/sale_order_view.xml', 'views/account_invoice_view.xml', diff --git a/addons/l10n_ae_extend/data/journal_data.xml b/addons/l10n_ae_extend/data/journal_data.xml index 0b108d19..1a2abaa5 100644 --- a/addons/l10n_ae_extend/data/journal_data.xml +++ b/addons/l10n_ae_extend/data/journal_data.xml @@ -60,7 +60,7 @@ 205301 - Reverse Charge(Vat) + Reverse Charge(VAT) @@ -70,12 +70,6 @@ - - - - - - 571001 diff --git a/addons/l10n_ae_extend/demo/account_invoice_demo.xml b/addons/l10n_ae_extend/demo/account_invoice_demo.xml index 9592453e..2700af50 100644 --- a/addons/l10n_ae_extend/demo/account_invoice_demo.xml +++ b/addons/l10n_ae_extend/demo/account_invoice_demo.xml @@ -25,7 +25,7 @@ 885.0 - 2.0 + 18.0 885.0 - 1.0 + 5.0 + + + + + + out_invoice + + + + + + + + + Graphics Card + + + 885.0 + 20.0 + + + + + Basic Computer + + + 23500.0 + 2.0 + + + + + + + + + + + + + + + out_refund + + + + + + + + + + Graphics Card + + 800.0 + + 3.0 + + + + + Basic Computer + + + 23000.0 + 1.0 + + + + + + + + + + + + + + out_invoice + + + + + + + + + Graphics Card + + + 885.0 + 15.0 + + + + + Basic Computer + + + 23500.0 + 4.0 + + + + + + + + + + + + + + + out_refund + + + + + + + + + + Graphics Card + + 800.0 + + 5.0 + + + + + Basic Computer + + + 23500.0 + 2.0 + + + + + + + + + + + + + + out_invoice + + + + + + + + + Little server + + + 40000 + 5.0 + + + + + + + + + + + + + + out_refund + + + + + + + + + + Little server + + + 40000 + 1.0 + + + + + + + + @@ -194,4 +419,106 @@ + + + + + + in_invoice + + + + + + + + + Graphics Card + + + 876.0 + 5.0 + + + + + Basic Computer + + + 23500.0 + 2.0 + + + + + + Little server + + + 40000 + 3.0 + + + + + + + + + + + + + + + in_refund + + + + + + + + + + Graphics Card + + + 876.0 + 3.0 + + + + + Basic Computer + + + 23500.0 + 1.0 + + + + + + Little server + + + 40000 + 1.0 + + + + + + + + \ No newline at end of file diff --git a/addons/l10n_ae_extend/models/__init__.py b/addons/l10n_ae_extend/models/__init__.py index 9252a0a7..b3d23f2e 100644 --- a/addons/l10n_ae_extend/models/__init__.py +++ b/addons/l10n_ae_extend/models/__init__.py @@ -1,7 +1,7 @@ # Part of flectra. See LICENSE file for full copyright and licensing details. from . import vat_config_type -from . import company +from . import res_config from . import sale from . import purchase from . import account_invoice diff --git a/addons/l10n_ae_extend/models/account_invoice.py b/addons/l10n_ae_extend/models/account_invoice.py index 252c6542..0cbadf39 100644 --- a/addons/l10n_ae_extend/models/account_invoice.py +++ b/addons/l10n_ae_extend/models/account_invoice.py @@ -1,7 +1,6 @@ # Part of Flectra. See LICENSE file for full copyright and licensing details. -from flectra import fields, models, api, _ -from flectra.exceptions import Warning +from flectra import fields, models, api class ReverseAccountInvoiceTax(models.Model): @@ -22,7 +21,7 @@ class AccountInvoice(models.Model): return self.vat_config_type.search(domain, limit=1) vat_config_type = fields.Many2one( - 'vat.config.type', 'Vat Type', default=_default_config_type, + 'vat.config.type', 'VAT Type', default=_default_config_type, readonly=True, states={'draft': [('readonly', False)]}) reverse_charge = fields.Boolean( 'Reverse Charge', readonly=True, @@ -63,8 +62,14 @@ class AccountInvoice(models.Model): def action_invoice_open(self): if not self.reverse_charge: return super(AccountInvoice, self).action_invoice_open() - if not self.company_id.rc_vat_account_id: - raise Warning(_('Define Reverse Charge Account in Company!')) + config_id = self.env[ + 'res.config.settings'].search([], order='id desc', limit=1) + rc_account = config_id.rc_vat_account_id or \ + self.env.ref('l10n_ae_extend.rc_vat_account') + vat_account = config_id.vat_expense_account_id or \ + self.env.ref('l10n_ae_extend.rc_vat_expense_account') + customs_account = config_id.customs_duty_account_id or \ + self.env.ref('l10n_ae.uae_account_3694') list_data = [] account_tax_obj = self.env['account.tax'] custom_amount = 0.0 @@ -77,7 +82,7 @@ class AccountInvoice(models.Model): if self.partner_id.vat: account_id = tax_line.account_id.id elif tax_id.tax_type == 'vat': - account_id = self.company_id.vat_expense_account_id.id + account_id = vat_account.id list_data.append((0, 0, { 'name': tax_line.name, 'partner_id': @@ -109,20 +114,22 @@ class AccountInvoice(models.Model): for move_line_id in list_data: move_line_id[2].update({'move_id': self.move_id.id}) list_data.append( - (0, 0, self.get_move_line_vals(total_tax_amount - custom_amount))) + (0, 0, self.get_move_line_vals( + total_tax_amount - custom_amount, rc_account))) if custom_amount: - list_data.append((0, 0, self.get_move_line_vals(custom_amount))) + list_data.append((0, 0, self.get_move_line_vals( + custom_amount, customs_account))) self.move_id.state = 'draft' self.move_id.line_ids = list_data self.move_id.post() return res @api.multi - def get_move_line_vals(self, credit): + def get_move_line_vals(self, credit, account_id): return { 'name': '/', 'partner_id': self.partner_id.parent_id.id or self.partner_id.id, - 'account_id': self.company_id.rc_vat_account_id.id, + 'account_id': account_id.id, 'credit': credit, 'move_id': self.move_id.id, 'invoice_id': self.id, diff --git a/addons/l10n_ae_extend/models/company.py b/addons/l10n_ae_extend/models/company.py deleted file mode 100644 index a1f9e3a1..00000000 --- a/addons/l10n_ae_extend/models/company.py +++ /dev/null @@ -1,12 +0,0 @@ -# Part of Flectra. See LICENSE file for full copyright and licensing details. - -from flectra import fields, models - - -class ResCompany(models.Model): - _inherit = 'res.company' - - rc_vat_account_id = fields.Many2one('account.account', 'Reverse Charge') - customs_duty_account_id = fields.Many2one( - 'account.account', 'Customs Expense') - vat_expense_account_id = fields.Many2one('account.account', 'Vat Expense') diff --git a/addons/l10n_ae_extend/models/purchase.py b/addons/l10n_ae_extend/models/purchase.py index 719ef18c..4b33c03b 100644 --- a/addons/l10n_ae_extend/models/purchase.py +++ b/addons/l10n_ae_extend/models/purchase.py @@ -12,7 +12,7 @@ class PurchaseOrder(models.Model): ('journal_id.type', '=', 'purchase')], limit=1) vat_config_type = fields.Many2one( - 'vat.config.type', 'Vat Type', default=_default_config_type, + 'vat.config.type', 'VAT Type', default=_default_config_type, readonly=True, states={'draft': [('readonly', False)]}) reverse_charge = fields.Boolean( 'Reverse Charge', readonly=True, diff --git a/addons/l10n_ae_extend/models/res_config.py b/addons/l10n_ae_extend/models/res_config.py new file mode 100644 index 00000000..ad5b84cf --- /dev/null +++ b/addons/l10n_ae_extend/models/res_config.py @@ -0,0 +1,34 @@ +# Part of Flectra. See LICENSE file for full copyright and licensing details. + +from flectra import fields, models, api + + +class ResConfigSettings(models.TransientModel): + _inherit = 'res.config.settings' + + rc_vat_account_id = fields.Many2one('account.account', 'Reverse Charge') + customs_duty_account_id = fields.Many2one( + 'account.account', 'Customs Expense') + vat_expense_account_id = fields.Many2one('account.account', 'VAT Expense') + + @api.model + def get_values(self): + res = super(ResConfigSettings, self).get_values() + res.update( + rc_vat_account_id=self.env.ref('l10n_ae_extend.rc_vat_account').id, + customs_duty_account_id=self.env.ref( + 'l10n_ae.uae_account_3694').id, + vat_expense_account_id=self.env.ref( + 'l10n_ae_extend.rc_vat_expense_account').id, + ) + return res + + def set_values(self): + super(ResConfigSettings, self).set_values() + params = self.env['ir.config_parameter'].sudo() + params.set_param('rc_vat_account_id', + self.rc_vat_account_id) + params.set_param('customs_duty_account_id', + self.customs_duty_account_id) + params.set_param('vat_expense_account_id', + self.vat_expense_account_id) diff --git a/addons/l10n_ae_extend/models/sale.py b/addons/l10n_ae_extend/models/sale.py index 6740ebfb..d8709230 100644 --- a/addons/l10n_ae_extend/models/sale.py +++ b/addons/l10n_ae_extend/models/sale.py @@ -12,7 +12,7 @@ class SaleOrder(models.Model): ('journal_id.type', '=', 'sale')], limit=1) vat_config_type = fields.Many2one( - 'vat.config.type', 'Vat Type', default=_default_config_type, + 'vat.config.type', 'VAT Type', default=_default_config_type, readonly=True, states={'draft': [('readonly', False)]}) @api.multi diff --git a/addons/l10n_ae_extend/models/vat_config_type.py b/addons/l10n_ae_extend/models/vat_config_type.py index f9157e57..ed3041c9 100644 --- a/addons/l10n_ae_extend/models/vat_config_type.py +++ b/addons/l10n_ae_extend/models/vat_config_type.py @@ -7,9 +7,9 @@ class JournalConfigType(models.Model): _name = 'vat.config.type' _description = 'Config Type' - name = fields.Char('Name') - code = fields.Char('Code') - journal_id = fields.Many2one('account.journal', 'Journal') + name = fields.Char('Name', required=True) + code = fields.Char('Code', required=True) + journal_id = fields.Many2one('account.journal', 'Journal', required=True) vat_type = fields.Selection([ ('local_sale', 'Local Sale'), ('inside_gcc_sale', 'Inside GCC Sale'), @@ -18,6 +18,7 @@ class JournalConfigType(models.Model): ('local_purchase', 'Local Purchase'), ('inside_gcc_purchase', 'Inside GCC Purchase'), ('outside_gcc_purchase', 'Outside GCC Purchase'), - ('designated_zone_purchase', 'Designated Zone Purchase')]) + ('designated_zone_purchase', 'Designated Zone Purchase')], + 'VAT Type', required=True) type = fields.Selection([ - ('sale', 'Sale'), ('purchase', 'Purchase')], 'Type') + ('sale', 'Sale'), ('purchase', 'Purchase')], 'Type', required=True) diff --git a/addons/l10n_ae_extend/tests/test_account_invoice.py b/addons/l10n_ae_extend/tests/test_account_invoice.py index b7d6b92a..6ffb79de 100644 --- a/addons/l10n_ae_extend/tests/test_account_invoice.py +++ b/addons/l10n_ae_extend/tests/test_account_invoice.py @@ -55,9 +55,13 @@ class TestAccountInvoice(TestAECommon): self.assertEquals(invoice_id.amount_tax, 0) self.assertEquals(len(invoice_id.tax_line_ids), 0) self.assertEquals(len(invoice_id.reverse_tax_line_ids), 1) + config_id = self.env[ + 'res.config.settings'].search([], order='id desc', limit=1) + rc_account = config_id.rc_vat_account_id or \ + self.env.ref('l10n_ae_extend.rc_vat_account') move_line_id = self.env['account.move.line'].search([ ('move_id', '=', invoice_id.move_id.id), - ('account_id', '=', self.main_company.rc_vat_account_id.id)]) + ('account_id', '=', rc_account.id)]) self.assertEquals(move_line_id.credit, amount_tax) def test_report_data(self): @@ -76,11 +80,11 @@ class TestAccountInvoice(TestAECommon): dict_data = report_obj.get_report_values(None, data) self.assertEquals( - dict_data['get_local_sale']['amount'], 1770) - self.assertEquals(dict_data['get_local_sale']['tax_amount'], 88.5) - self.assertEquals(dict_data['get_local_sale']['adjustment'], 885) + dict_data['get_local_sale']['amount'], 15930.0) + self.assertEquals(dict_data['get_local_sale']['tax_amount'], 796.5) + self.assertEquals(dict_data['get_local_sale']['adjustment'], 4425.00) self.assertEquals( - dict_data['get_local_sale']['return_tax_amount'], 44.25) + dict_data['get_local_sale']['return_tax_amount'], 221.25) self.assertEquals(dict_data['get_local_purchase']['amount'], 17520) self.assertEquals(dict_data['get_local_purchase']['tax_amount'], 876) @@ -96,5 +100,5 @@ class TestAccountInvoice(TestAECommon): dict_data['get_reverse_charge_data']['adjustment'], 4380) self.assertEquals( dict_data['get_reverse_charge_data']['return_tax_amount'], 219) - self.assertEquals( - dict_data['get_total_vat_due']['total_tax_amount'], -1050.75) + self.assertEquals(round( + dict_data['get_total_vat_due']['total_tax_amount'], 2), 587.40) diff --git a/addons/l10n_ae_extend/views/account_invoice_view.xml b/addons/l10n_ae_extend/views/account_invoice_view.xml index 81100f23..e7f131fd 100644 --- a/addons/l10n_ae_extend/views/account_invoice_view.xml +++ b/addons/l10n_ae_extend/views/account_invoice_view.xml @@ -15,6 +15,17 @@ + + uae.account.invoice.tree.inherit + account.invoice + + + + + + + + reverse.account.invoice.tax.tree reverse.account.invoice.tax @@ -52,6 +63,17 @@ + + uae.account.invoice.supplier.tree.inherit + account.invoice + + + + + + + + uae.account.tax.form.inherit account.tax diff --git a/addons/l10n_ae_extend/views/company_view.xml b/addons/l10n_ae_extend/views/company_view.xml deleted file mode 100644 index ef2cfd76..00000000 --- a/addons/l10n_ae_extend/views/company_view.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - uae.res.company.form.inherit - res.company - - - - - - - - - - - diff --git a/addons/l10n_ae_extend/views/report_menu_view.xml b/addons/l10n_ae_extend/views/report_menu_view.xml index 88cf4a14..8c41d83a 100644 --- a/addons/l10n_ae_extend/views/report_menu_view.xml +++ b/addons/l10n_ae_extend/views/report_menu_view.xml @@ -3,7 +3,7 @@ VAT 201
- From
- To + Date from :
+ Date to :
@@ -59,7 +59,7 @@ - + @@ -97,28 +97,28 @@ - + - + - + - + diff --git a/addons/l10n_ae_extend/views/res_config_view.xml b/addons/l10n_ae_extend/views/res_config_view.xml new file mode 100644 index 00000000..13f9fee5 --- /dev/null +++ b/addons/l10n_ae_extend/views/res_config_view.xml @@ -0,0 +1,46 @@ + + + + uae.res.config.settings.view.form.inherit + res.config.settings + + + + +

UAE Accounts

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + diff --git a/addons/l10n_ae_extend/views/vat_config_type.xml b/addons/l10n_ae_extend/views/vat_config_type.xml index 870e9f84..c51cbe2e 100644 --- a/addons/l10n_ae_extend/views/vat_config_type.xml +++ b/addons/l10n_ae_extend/views/vat_config_type.xml @@ -7,9 +7,9 @@ + - @@ -22,14 +22,13 @@ - - - + + + - - - + + @@ -38,7 +37,7 @@ - Vat Types + VAT Types vat.config.type form tree,form @@ -48,7 +47,7 @@ diff --git a/addons/l10n_ae_extend/wizard/vat_201.py b/addons/l10n_ae_extend/wizard/vat_201.py index 1ecf28ad..987b6e06 100644 --- a/addons/l10n_ae_extend/wizard/vat_201.py +++ b/addons/l10n_ae_extend/wizard/vat_201.py @@ -1,12 +1,12 @@ # Part of Flectra. See LICENSE file for full copyright and licensing details. -from flectra import fields, models +from flectra import fields, models, api, _ class Vat201Report(models.TransientModel): _name = "vat.201.report" - _description = "Vat 201" + _description = "VAT 201" date_from = fields.Date(string='Start Date') date_to = fields.Date(string='End Date') @@ -15,6 +15,12 @@ class Vat201Report(models.TransientModel): required=True, default=lambda self: self.env.user.company_id) currency_id = fields.Many2one(related='company_id.currency_id') + @api.constrains('date_from', 'date_to') + def _check_date(self): + if self.date_from > self.date_to: + raise ValueError(_("End Date must be greater than " + "Start Date!")) + def print_report(self, data): data['form'] = \ self.read(['date_from', 'date_to', 'company_id', 'currency_id'])[0] diff --git a/addons/l10n_ae_extend/wizard/vat_201_view.xml b/addons/l10n_ae_extend/wizard/vat_201_view.xml index 224d09eb..3522053e 100644 --- a/addons/l10n_ae_extend/wizard/vat_201_view.xml +++ b/addons/l10n_ae_extend/wizard/vat_201_view.xml @@ -5,7 +5,7 @@ Vat 201 vat.201.report -
+ @@ -19,7 +19,7 @@
- Vat 201 + VAT 201 vat.201.report ir.actions.act_window form @@ -29,6 +29,6 @@ new - + diff --git a/addons/l10n_in_gst/__manifest__.py b/addons/l10n_in_gst/__manifest__.py index 3a5b3d56..66be8cfd 100644 --- a/addons/l10n_in_gst/__manifest__.py +++ b/addons/l10n_in_gst/__manifest__.py @@ -17,6 +17,7 @@ 'security/ir.model.access.csv', 'data/product_uom_data.xml', 'data/note_issue_reason_data.xml', + 'data/res_company_data.xml', 'wizard/account_invoice_refund_view.xml', 'views/product_uom_view.xml', 'views/res_partner_view.xml', diff --git a/addons/l10n_in_gst/data/res_company_data.xml b/addons/l10n_in_gst/data/res_company_data.xml new file mode 100644 index 00000000..61ef0ceb --- /dev/null +++ b/addons/l10n_in_gst/data/res_company_data.xml @@ -0,0 +1,14 @@ + + + + + + 205311 + Reverse Charge(GST) + + + + + + + \ No newline at end of file diff --git a/addons/l10n_in_gst/models/account_invoice.py b/addons/l10n_in_gst/models/account_invoice.py index ef40bf6f..83f1e965 100644 --- a/addons/l10n_in_gst/models/account_invoice.py +++ b/addons/l10n_in_gst/models/account_invoice.py @@ -52,6 +52,88 @@ class AccountInvoice(models.Model): readonly=True, states={ 'draft': [('readonly', False)]}) + reverse_charge = fields.Boolean( + 'Reverse Charge', readonly=True, + states={'draft': [('readonly', False)]}) + reverse_tax_line_ids = fields.One2many( + 'reverse.account.invoice.tax', 'invoice_id', string='Tax Lines', + readonly=True, states={'draft': [('readonly', False)]}, copy=False) + + @api.one + @api.depends( + 'state', 'currency_id', 'invoice_line_ids.price_subtotal', + 'move_id.line_ids.amount_residual', + 'move_id.line_ids.currency_id') + def _compute_residual(self): + super(AccountInvoice, self)._compute_residual() + sign = self.type in ['in_refund', 'out_refund'] and -1 or 1 + if self.reverse_charge: + residual = self.residual - self.amount_tax + self.residual_signed = abs(residual) * sign + self.residual = abs(residual) + + @api.multi + def action_invoice_open(self): + if not self.reverse_charge: + return super(AccountInvoice, self).action_invoice_open() + list_data = [] + account_tax_obj = self.env['account.tax'] + custom_amount = 0.0 + self.reverse_tax_line_ids = [[6, 0, []]] + for tax_line in self.tax_line_ids: + tax_id = account_tax_obj.search([('name', '=', tax_line.name)]) + account_id = tax_id.account_id.id + if self.partner_id.vat: + account_id = tax_line.account_id.id + if not account_id: + account_id = tax_line.account_id.id + list_data.append((0, 0, { + 'name': tax_line.name, + 'partner_id': + self.partner_id.parent_id.id or self.partner_id.id, + 'account_id': account_id, + 'debit': tax_line.amount_total, + 'move_id': False, + 'invoice_id': self.id, + 'tax_line_id': tax_id, + 'quantity': 1, + } + )) + + total_tax_amount = self.amount_tax + reverse_list_data = [] + for tax_line_id in self.tax_line_ids: + reverse_list_data.append((0, 0, tax_line_id.read()[0])) + + if reverse_list_data: + self.update({'reverse_tax_line_ids': reverse_list_data}) + for line_id in self.invoice_line_ids: + line_id.reverse_invoice_line_tax_ids = \ + [[6, 0, line_id.invoice_line_tax_ids.ids]] + + self.invoice_line_ids.update({'invoice_line_tax_ids': [[6, 0, []]]}) + self.update({'tax_line_ids': [[6, 0, []]], 'amount_tax': 0.0}) + res = super(AccountInvoice, self).action_invoice_open() + for move_line_id in list_data: + move_line_id[2].update({'move_id': self.move_id.id}) + list_data.append( + (0, 0, self.get_move_line_vals(total_tax_amount - custom_amount))) + self.move_id.state = 'draft' + self.move_id.line_ids = list_data + self.move_id.post() + return res + + @api.multi + def get_move_line_vals(self, credit): + return { + 'name': '/', + 'partner_id': self.partner_id.parent_id.id or self.partner_id.id, + 'account_id': self.company_id.rc_gst_account_id.id, + 'credit': credit, + 'move_id': self.move_id.id, + 'invoice_id': self.id, + 'quantity': 1, + } @api.onchange('partner_id', 'company_id') def _onchange_partner_id(self): @@ -60,12 +142,31 @@ class AccountInvoice(models.Model): self.partner_id.partner_location = \ self.partner_id._get_partner_location_details(self.company_id) - @api.onchange('fiscal_position_id') def _onchange_fiscal_position_id(self): """ Onchange of Fiscal Position update tax values in invoice lines. """ - for line in self.invoice_line_ids: - line._set_taxes() + if self.fiscal_position_id: + for line in self.invoice_line_ids: + line._set_taxes() + + @api.multi + @api.returns('self') + def refund(self, date_invoice=None, + date=None, description=None, journal_id=None): + result = super(AccountInvoice, self).refund( + date_invoice=date_invoice, date=date, + description=description, journal_id=journal_id) + if result.refund_invoice_id.type == 'in_invoice': + result.write( + {'reverse_charge': result.refund_invoice_id.reverse_charge}) + if result.type == 'in_refund' \ + and result.refund_invoice_id.reverse_charge: + for index, line_id in enumerate(result.invoice_line_ids): + line_id.invoice_line_tax_ids = [[ + 6, 0, result.refund_invoice_id.invoice_line_ids[ + index].reverse_invoice_line_tax_ids.ids]] + result._onchange_invoice_line_ids() + return result @api.multi def action_move_create(self): @@ -128,3 +229,14 @@ class AccountInvoice(models.Model): 'gst_type': invoice.gst_type, }) return result + +class ReverseAccountInvoiceTax(models.Model): + _inherit = 'account.invoice.tax' + _name = 'reverse.account.invoice.tax' + + +class AccountInvoiceLine(models.Model): + _inherit = "account.invoice.line" + + reverse_invoice_line_tax_ids = fields.Many2many( + 'account.tax', string='Taxes', copy=False) \ No newline at end of file diff --git a/addons/l10n_in_gst/models/res_company.py b/addons/l10n_in_gst/models/res_company.py index d6cb70b7..b4317764 100644 --- a/addons/l10n_in_gst/models/res_company.py +++ b/addons/l10n_in_gst/models/res_company.py @@ -20,6 +20,7 @@ class Company(models.Model): default=time.strftime('2017-07-01')) company_b2c_limit_line = fields.One2many('res.company.b2c.limit', 'company_id', string='B2C Limit') + rc_gst_account_id = fields.Many2one('account.account', 'Reverse Charge') def onchange_state(self, gst_type, vat, state): result = {'vat': '', 'country_id': False} diff --git a/addons/l10n_in_gst/report/gst_report.py b/addons/l10n_in_gst/report/gst_report.py index 9561acff..11c9aac8 100644 --- a/addons/l10n_in_gst/report/gst_report.py +++ b/addons/l10n_in_gst/report/gst_report.py @@ -135,7 +135,6 @@ class GSTR1Report(models.AbstractModel): ('gst_invoice', '=', 'b2b'), ('vat', '!=', False)] if post.get('gst_invoice') == 'cdnur': final_inv_domain = common_domain + refund_domain + cdnur_domain - final_invoice_ids = acc_invoice.search(final_inv_domain) for inv in final_invoice_ids: inv_data_list = [] @@ -159,15 +158,17 @@ class GSTR1Report(models.AbstractModel): for line in inv.invoice_line_ids: cess_amount = igst_amount = cgst_amount = sgst_amount = 0.0 - - if line.invoice_line_tax_ids: + if inv.reverse_charge: + tax_lines = line.reverse_invoice_line_tax_ids + else: + tax_lines = line.invoice_line_tax_ids + if tax_lines: price_unit = line.price_unit * ( 1 - (line.discount or 0.0) / 100.0) - taxes = line.invoice_line_tax_ids.compute_all( + taxes = tax_lines.compute_all( price_unit, line.invoice_id.currency_id, line.quantity, line.product_id, line.invoice_id.partner_id)['taxes'] - for tax_data in taxes: tax = acc_tax.browse(tax_data['id']) if tax.tax_group_id.name == 'Cess': @@ -185,7 +186,7 @@ class GSTR1Report(models.AbstractModel): 'amount'] > 0): sgst_amount += tax_data['amount'] - for tax in line.invoice_line_tax_ids: + for tax in tax_lines: rate = 0 if tax.id not in tax_list: if tax.tax_group_id.name == 'IGST' \ @@ -213,7 +214,6 @@ class GSTR1Report(models.AbstractModel): line_data = self._prepare_taxable_line_data( line, inv, igst_amount, cgst_amount, sgst_amount, cess_amount, rate, tax) - if post.get('gst_invoice') in \ ['b2b', 'b2cl', 'b2cs', 'b2bur']: line_data.update({ @@ -241,7 +241,7 @@ class GSTR1Report(models.AbstractModel): if post.get('gst_invoice') == 'b2b': line_data.update({ 'inv_type': 'Regular', - 'reverse_charge': 'N', + 'reverse_charge': 'Y' if inv.reverse_charge else 'N', }) if post.get('gst_invoice') == 'b2bur': supply_type = dict(inv.fields_get( @@ -376,10 +376,14 @@ class GSTR1Report(models.AbstractModel): invoice_domain) for line in hsn_invoice_line_ids: igst_amount = cgst_amount = sgst_amount = cess_amount = 0.0 - if line.invoice_line_tax_ids: + if line.invoice_id.reverse_charge: + tax_lines = line.reverse_invoice_line_tax_ids + else: + tax_lines = line.invoice_line_tax_ids + if tax_lines: price_unit = line.price_unit * ( 1 - (line.discount or 0.0) / 100.0) - taxes = line.invoice_line_tax_ids.compute_all( + taxes = tax_lines.compute_all( price_unit, line.invoice_id.currency_id, line.quantity, line.product_id, line.invoice_id.partner_id)['taxes'] @@ -446,10 +450,11 @@ class GSTR1Report(models.AbstractModel): no_of_recepient = 0 for inv in result: - taxable_value_total += float(inv['taxable_value']) - igst_amount += float(inv['igst']) - sgst_amount += float(inv['sgst']) - cgst_amount += float(inv['cgst']) + if inv.get('reverse_charge') != 'Y': + taxable_value_total += float(inv['taxable_value']) + igst_amount += float(inv['igst']) + sgst_amount += float(inv['sgst']) + cgst_amount += float(inv['cgst']) if post.get('gst_invoice') == 'b2b': if inv['reverse_charge'] == 'N': @@ -473,7 +478,7 @@ class GSTR1Report(models.AbstractModel): invoice_value = 0.0 for invoice_id in invoices_list: ids = self.env['account.invoice'].search( - [('number', '=', invoice_id)]) + [('number', '=', invoice_id), ('reverse_charge', '=', False)]) invoice_value += ids.amount_total summary.update({ "no_of_invoices": no_of_invoices, diff --git a/addons/l10n_in_gst/security/ir.model.access.csv b/addons/l10n_in_gst/security/ir.model.access.csv index f0a601b3..2f7ca89d 100644 --- a/addons/l10n_in_gst/security/ir.model.access.csv +++ b/addons/l10n_in_gst/security/ir.model.access.csv @@ -3,3 +3,4 @@ access_note_issue_reason_all,access_note_issue_reason_all,model_note_issue_reaso access_note_issue_reason,access_note_issue_reason,model_note_issue_reason,,1,0,0,0 access_res_company_b2c_limit_all,access_res_company_b2c_limit_all,model_res_company_b2c_limit,base.group_system,1,1,1,1 access_res_company_b2c_limit,access_res_company_b2c_limit,model_res_company_b2c_limit,,1,0,0,0 +access_reverse_account_invoice_tax,access_reverse_account_invoice_tax,model_reverse_account_invoice_tax,,1,0,0,0 \ No newline at end of file diff --git a/addons/l10n_in_gst/views/account_invoice_view.xml b/addons/l10n_in_gst/views/account_invoice_view.xml index 3ef83780..0a6ed72c 100644 --- a/addons/l10n_in_gst/views/account_invoice_view.xml +++ b/addons/l10n_in_gst/views/account_invoice_view.xml @@ -77,6 +77,9 @@ + + + {'invisible': [('tax_line_ids', '=', [])]} + + + + + + + + @@ -112,5 +123,18 @@ Nature of Transaction + + in_reverse.account.invoice.tax.tree + reverse.account.invoice.tax + + + + + + + + + + \ No newline at end of file diff --git a/addons/l10n_in_gst/views/res_company_view.xml b/addons/l10n_in_gst/views/res_company_view.xml index cff18ac4..5887500b 100644 --- a/addons/l10n_in_gst/views/res_company_view.xml +++ b/addons/l10n_in_gst/views/res_company_view.xml @@ -18,6 +18,9 @@ + + + diff --git a/doc/setup/install.rst b/doc/setup/install.rst index 4cf9f71f..cf6d07a1 100644 --- a/doc/setup/install.rst +++ b/doc/setup/install.rst @@ -76,7 +76,7 @@ PostgreSQL server : In order to print PDF reports, you must install wkhtmltopdf_ yourself: the version of wkhtmltopdf_ available in debian repositories does not support headers and footers so it can not be installed automatically. -The recommended version is 0.12.1 and is available on `the wkhtmltopdf download page`_, +The recommended version is 0.12.5 and is available on `the wkhtmltopdf download page`_, in the archive section. Repository @@ -513,7 +513,7 @@ offcial Flectra `docker image `_ pa http://www.enterprisedb.com/products-services-training/pgdownload .. _Quilt: http://en.wikipedia.org/wiki/Quilt_(software) .. _saas: https://www.flectrahq.com -.. _the wkhtmltopdf download page: https://github.com/wkhtmltopdf/wkhtmltopdf/releases/tag/0.12.1 +.. _the wkhtmltopdf download page: https://github.com/wkhtmltopdf/wkhtmltopdf/releases/tag/0.12.5 .. _UAC: http://en.wikipedia.org/wiki/User_Account_Control .. _wkhtmltopdf: http://wkhtmltopdf.org .. _pip: https://pip.pypa.io diff --git a/flectra/addons/base/ir/ir_actions_report.py b/flectra/addons/base/ir/ir_actions_report.py index 4679daca..f322c0a8 100644 --- a/flectra/addons/base/ir/ir_actions_report.py +++ b/flectra/addons/base/ir/ir_actions_report.py @@ -44,6 +44,7 @@ def _get_wkhtmltopdf_bin(): # Check the presence of Wkhtmltopdf and return its version at Flectra start-up wkhtmltopdf_state = 'install' +wkhtmltopdf_dpi_zoom_ratio = False try: process = subprocess.Popen( [_get_wkhtmltopdf_bin(), '--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE @@ -61,6 +62,8 @@ else: wkhtmltopdf_state = 'upgrade' else: wkhtmltopdf_state = 'ok' + if LooseVersion(version) >= LooseVersion('0.12.2'): + wkhtmltopdf_dpi_zoom_ratio = True if config['workers'] == 1: _logger.info('You need to start Flectra with at least two workers to print a pdf version of the reports.') @@ -206,7 +209,7 @@ class IrActionsReport(models.Model): :param set_viewport_size: Enable a viewport sized '1024x1280' or '1280x1024' depending of landscape arg. :return: A list of string representing the wkhtmltopdf process command args. ''' - command_args = [] + command_args = ['--disable-local-file-access'] if set_viewport_size: command_args.extend(['--viewport-size', landscape and '1024x1280' or '1280x1024']) @@ -234,14 +237,19 @@ class IrActionsReport(models.Model): else: command_args.extend(['--margin-top', str(paperformat_id.margin_top)]) + dpi = None if specific_paperformat_args and specific_paperformat_args.get('data-report-dpi'): - command_args.extend(['--dpi', str(specific_paperformat_args['data-report-dpi'])]) + dpi = int(specific_paperformat_args['data-report-dpi']) elif paperformat_id.dpi: if os.name == 'nt' and int(paperformat_id.dpi) <= 95: _logger.info("Generating PDF on Windows platform require DPI >= 96. Using 96 instead.") - command_args.extend(['--dpi', '96']) + dpi = 96 else: - command_args.extend(['--dpi', str(paperformat_id.dpi)]) + dpi = paperformat_id.dpi + if dpi: + command_args.extend(['--dpi', str(dpi)]) + if wkhtmltopdf_dpi_zoom_ratio: + command_args.extend(['--zoom', str(96.0 / dpi)]) if specific_paperformat_args and specific_paperformat_args.get('data-report-header-spacing'): command_args.extend(['--header-spacing', str(specific_paperformat_args['data-report-header-spacing'])])

VAT on PurchasVAT on Purchase Standard rated domestic purchases
Total VAT due for current periodTotal VAT due for current period
Corrections from previous periodCorrections from previous period
VAT credit carried forword from previous period(s)VAT credit carried forword from previous period(s)
Net VAT dueNet VAT due