From 3751379f1e9a4c215fb6eb898b4ccc67659b9ace Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Tue, 10 May 2022 21:51:50 +0700 Subject: initial commit 2 --- addons/l10n_in/report/__init__.py | 7 + addons/l10n_in/report/account_invoice_report.py | 325 ++++++++++++++++++++++++ addons/l10n_in/report/account_payment_report.py | 196 ++++++++++++++ addons/l10n_in/report/exempted_gst_report.py | 95 +++++++ addons/l10n_in/report/hsn_gst_report.py | 112 ++++++++ 5 files changed, 735 insertions(+) create mode 100644 addons/l10n_in/report/__init__.py create mode 100644 addons/l10n_in/report/account_invoice_report.py create mode 100644 addons/l10n_in/report/account_payment_report.py create mode 100644 addons/l10n_in/report/exempted_gst_report.py create mode 100644 addons/l10n_in/report/hsn_gst_report.py (limited to 'addons/l10n_in/report') diff --git a/addons/l10n_in/report/__init__.py b/addons/l10n_in/report/__init__.py new file mode 100644 index 00000000..528be7c1 --- /dev/null +++ b/addons/l10n_in/report/__init__.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import account_invoice_report +from . import account_payment_report +from . import hsn_gst_report +from . import exempted_gst_report diff --git a/addons/l10n_in/report/account_invoice_report.py b/addons/l10n_in/report/account_invoice_report.py new file mode 100644 index 00000000..59a86695 --- /dev/null +++ b/addons/l10n_in/report/account_invoice_report.py @@ -0,0 +1,325 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import api, fields, models, tools + + +class L10nInAccountInvoiceReport(models.Model): + _name = "l10n_in.account.invoice.report" + _description = "Account Invoice Statistics" + _auto = False + _order = 'date desc' + + account_move_id = fields.Many2one('account.move', string="Account Move") + company_id = fields.Many2one('res.company', string="Company") + date = fields.Date(string="Accounting Date") + name = fields.Char(string="Invoice Number") + partner_id = fields.Many2one('res.partner', string="Customer") + is_reverse_charge = fields.Char("Reverse Charge") + l10n_in_gst_treatment = fields.Selection([ + ('regular', 'Registered Business - Regular'), + ('composition', 'Registered Business - Composition'), + ('unregistered', 'Unregistered Business'), + ('consumer', 'Consumer'), + ('overseas', 'Overseas'), + ('special_economic_zone', 'Special Economic Zone'), + ('deemed_export', 'Deemed Export'), + ], string="GST Treatment") + journal_id = fields.Many2one('account.journal', string="Journal") + state = fields.Selection([('draft', 'Unposted'), ('posted', 'Posted')], string='Status') + igst_amount = fields.Float(string="IGST Amount") + cgst_amount = fields.Float(string="CGST Amount") + sgst_amount = fields.Float(string="SGST Amount") + cess_amount = fields.Float(string="Cess Amount") + price_total = fields.Float(string='Total Without Tax') + total = fields.Float(string="Invoice Total") + reversed_entry_id = fields.Many2one('account.move', string="Refund Invoice", help="From where this Refund is created") + shipping_bill_number = fields.Char(string="Shipping Bill Number") + shipping_bill_date = fields.Date(string="Shipping Bill Date") + shipping_port_code_id = fields.Many2one('l10n_in.port.code', string='Shipping port code') + ecommerce_partner_id = fields.Many2one('res.partner', string="E-commerce") + move_type = fields.Selection(selection=[ + ('entry', 'Journal Entry'), + ('out_invoice', 'Customer Invoice'), + ('out_refund', 'Customer Credit Note'), + ('in_invoice', 'Vendor Bill'), + ('in_refund', 'Vendor Credit Note'), + ('out_receipt', 'Sales Receipt'), + ('in_receipt', 'Purchase Receipt')]) + partner_vat = fields.Char(string="Customer GSTIN") + ecommerce_vat = fields.Char(string="E-commerce GSTIN") + tax_rate = fields.Float(string="Rate") + place_of_supply = fields.Char(string="Place of Supply") + is_pre_gst = fields.Char(string="Is Pre GST") + is_ecommerce = fields.Char(string="Is E-commerce") + b2cl_is_ecommerce = fields.Char(string="B2CL Is E-commerce") + b2cs_is_ecommerce = fields.Char(string="B2CS Is E-commerce") + supply_type = fields.Char(string="Supply Type") + export_type = fields.Char(string="Export Type") # String from GSTR column. + refund_export_type = fields.Char(string="UR Type") # String from GSTR column. + b2b_type = fields.Char(string="B2B Invoice Type") + refund_invoice_type = fields.Char(string="Document Type") + gst_format_date = fields.Char(string="Formated Date") + gst_format_refund_date = fields.Char(string="Formated Refund Date") + gst_format_shipping_bill_date = fields.Char(string="Formated Shipping Bill Date") + tax_id = fields.Many2one('account.tax', string="Tax") + + def _select(self): + select_str = """ + SELECT min(sub.id) as id, + sub.move_id, + sub.account_move_id, + sub.name, + sub.state, + sub.partner_id, + sub.date, + sub.l10n_in_gst_treatment, + sub.ecommerce_partner_id, + sub.shipping_bill_number, + sub.shipping_bill_date, + sub.shipping_port_code_id, + sub.total * sub.b2cs_refund_sign as total, + sub.journal_id, + sub.company_id, + sub.move_type, + sub.reversed_entry_id, + sub.partner_vat, + sub.ecommerce_vat, + sub.tax_rate as tax_rate, + (CASE WHEN count(sub.is_reverse_charge) > 0 + THEN 'Y' + ELSE 'N' + END) AS is_reverse_charge, + sub.place_of_supply, + sub.is_pre_gst, + sub.is_ecommerce, + sub.b2cl_is_ecommerce, + sub.b2cs_is_ecommerce, + sub.supply_type, + sub.export_type, + sub.refund_export_type, + sub.b2b_type, + sub.refund_invoice_type, + sub.gst_format_date, + sub.gst_format_refund_date, + sub.gst_format_shipping_bill_date, + sum(sub.igst_amount) * sub.amount_sign * sub.b2cs_refund_sign AS igst_amount, + sum(sub.cgst_amount) * sub.amount_sign * sub.b2cs_refund_sign AS cgst_amount, + sum(sub.sgst_amount) * sub.amount_sign * sub.b2cs_refund_sign AS sgst_amount, + avg(sub.cess_amount) * sub.amount_sign * sub.b2cs_refund_sign AS cess_amount, + sum(sub.price_total) * sub.amount_sign * sub.b2cs_refund_sign AS price_total, + sub.tax_id + """ + return select_str + + def _sub_select(self): + sub_select_str = """ + SELECT aml.id AS id, + aml.move_id, + aml.partner_id, + am.id AS account_move_id, + am.name, + am.state, + am.date, + am.l10n_in_gst_treatment AS l10n_in_gst_treatment, + am.l10n_in_reseller_partner_id AS ecommerce_partner_id, + am.l10n_in_shipping_bill_number AS shipping_bill_number, + am.l10n_in_shipping_bill_date AS shipping_bill_date, + am.l10n_in_shipping_port_code_id AS shipping_port_code_id, + ABS(am.amount_total_signed) AS total, + am.journal_id, + aj.company_id, + am.move_type AS move_type, + am.reversed_entry_id AS reversed_entry_id, + am.l10n_in_gstin AS partner_vat, + CASE WHEN rp.vat IS NULL THEN '' ELSE rp.vat END AS ecommerce_vat, + (CASE WHEN at.l10n_in_reverse_charge = True + THEN True + ELSE NULL + END) AS is_reverse_charge, + (CASE WHEN ps.l10n_in_tin IS NOT NULL + THEN concat(ps.l10n_in_tin,'-',ps.name) + WHEN ps.id IS NULL and cps.l10n_in_tin IS NOT NULL + THEN concat(cps.l10n_in_tin,'-',cps.name) + ELSE '' + END) AS place_of_supply, + (CASE WHEN am.move_type in ('out_refund', 'in_refund') and refund_am.date <= to_date('2017-07-01', 'YYYY-MM-DD') + THEN 'Y' + ELSE 'N' + END) as is_pre_gst, + + (CASE WHEN am.l10n_in_reseller_partner_id IS NOT NULL + THEN 'Y' + ELSE 'N' + END) as is_ecommerce, + (CASE WHEN am.l10n_in_reseller_partner_id IS NOT NULL + THEN 'Y' + ELSE 'N' + END) as b2cl_is_ecommerce, + (CASE WHEN am.l10n_in_reseller_partner_id IS NOT NULL + THEN 'E' + ELSE 'OE' + END) as b2cs_is_ecommerce, + (CASE WHEN am.l10n_in_state_id = cp.state_id or p.id IS NULL + THEN 'Intra State' + WHEN am.l10n_in_state_id != cp.state_id and p.id IS NOT NULL + THEN 'Inter State' + END) AS supply_type, + (CASE WHEN am.l10n_in_gst_treatment in ('deemed_export', 'overseas') and am.amount_tax > 0.00 + THEN 'EXPWP' + WHEN am.l10n_in_gst_treatment in ('deemed_export', 'overseas') and am.amount_tax <= 0.00 + THEN 'EXPWOP' + ELSE '' + END) AS export_type, + (CASE WHEN am.l10n_in_gst_treatment in ('deemed_export', 'overseas') and am.amount_tax > 0.00 + THEN 'EXPWP' + WHEN am.l10n_in_gst_treatment in ('deemed_export', 'overseas') and am.amount_tax <= 0.00 + THEN 'EXPWOP' + ELSE 'B2CL' + END) AS refund_export_type, + (CASE WHEN am.l10n_in_gst_treatment = 'regular' + THEN 'Regular' + WHEN am.l10n_in_gst_treatment = 'deemed_export' + THEN 'Deemed' + WHEN am.l10n_in_gst_treatment = 'overseas' and am.amount_tax > 0.00 + THEN 'Export with IGST' + WHEN am.l10n_in_gst_treatment = 'special_economic_zone' and am.amount_tax > 0.00 + THEN 'SEZ with IGST payment' + WHEN am.l10n_in_gst_treatment = 'special_economic_zone' and am.amount_tax <= 0.00 + THEN 'SEZ without IGST payment' + END) AS b2b_type, + (CASE WHEN am.move_type = 'out_refund' + THEN 'C' + WHEN am.move_type = 'in_refund' + THEN 'D' + ELSE '' + END) as refund_invoice_type, + (CASE WHEN am.date IS NOT NULL + THEN TO_CHAR(am.date, 'DD-MON-YYYY') + ELSE '' + END) as gst_format_date, + (CASE WHEN refund_am.date IS NOT NULL + THEN TO_CHAR(refund_am.date, 'DD-MON-YYYY') + ELSE '' + END) as gst_format_refund_date, + (CASE WHEN am.l10n_in_shipping_bill_date IS NOT NULL + THEN TO_CHAR(am.l10n_in_shipping_bill_date, 'DD-MON-YYYY') + ELSE '' + END) as gst_format_shipping_bill_date, + CASE WHEN tag_rep_ln.account_tax_report_line_id IN + (SELECT res_id FROM ir_model_data WHERE module='l10n_in' AND name in ('tax_report_line_igst', 'tax_report_line_igst_rc')) + THEN aml.balance + ELSE 0 + END AS igst_amount, + CASE WHEN tag_rep_ln.account_tax_report_line_id IN + (SELECT res_id FROM ir_model_data WHERE module='l10n_in' AND name in ('tax_report_line_cgst', 'tax_report_line_cgst_rc')) + THEN aml.balance + ELSE 0 + END AS cgst_amount, + CASE WHEN tag_rep_ln.account_tax_report_line_id IN + (SELECT res_id FROM ir_model_data WHERE module='l10n_in' AND name in ('tax_report_line_sgst', 'tax_report_line_sgst_rc')) + THEN aml.balance + ELSE 0 + END AS sgst_amount, + (SELECT sum(temp_aml.balance) from account_move_line temp_aml + JOIN account_account_tag_account_move_line_rel aat_aml_rel_temp ON aat_aml_rel_temp.account_move_line_id = temp_aml.id + JOIN account_account_tag aat_temp ON aat_temp.id = aat_aml_rel_temp.account_account_tag_id + JOIN account_tax_report_line_tags_rel tag_rep_ln_temp ON aat_temp.id = tag_rep_ln_temp.account_account_tag_id + where temp_aml.move_id = aml.move_id and temp_aml.product_id = aml.product_id + and tag_rep_ln_temp.account_tax_report_line_id IN (SELECT res_id FROM ir_model_data WHERE module='l10n_in' AND name in ('tax_report_line_cess', 'tax_report_line_cess_rc')) + ) AS cess_amount, + CASE WHEN tag_rep_ln.account_tax_report_line_id IN + (SELECT res_id FROM ir_model_data WHERE module='l10n_in' AND name in ('tax_report_line_sgst', 'tax_report_line_sgst_rc')) + THEN NULL + ELSE (CASE WHEN aml.tax_base_amount <> 0 THEN aml.tax_base_amount * (CASE WHEN aml.balance < 0 THEN -1 ELSE 1 END) ELSE NULL END) + END AS price_total, + (CASE WHEN (aj.type = 'sale' AND am.move_type != 'out_refund') or (aj.type = 'purchase' AND at.l10n_in_reverse_charge AND am.move_type != 'in_refund') THEN -1 ELSE 1 END) AS amount_sign, + (CASE WHEN am.move_type in ('in_refund','out_refund') + AND p.vat IS NULL + AND am.l10n_in_gst_treatment != 'overseas' + AND (ABS(am.amount_total_signed) <= 250000 OR + (ps.id = cp.state_id OR p.id IS NULL)) + THEN -1 + ELSE 1 END) AS b2cs_refund_sign, + (CASE WHEN atr.parent_tax IS NOT NULL THEN atr.parent_tax + ELSE at.id END) AS tax_id, + (CASE WHEN atr.parent_tax IS NOT NULL THEN parent_at.amount + ELSE at.amount END) AS tax_rate + """ + return sub_select_str + + def _from(self): + from_str = """ + FROM account_move_line aml + JOIN account_move am ON am.id = aml.move_id + JOIN account_journal aj ON aj.id = am.journal_id + JOIN res_company c ON c.id = aj.company_id + LEFT JOIN account_tax at ON at.id = aml.tax_line_id + JOIN account_account_tag_account_move_line_rel aat_aml_rel ON aat_aml_rel.account_move_line_id = aml.id + JOIN account_account_tag aat ON aat.id = aat_aml_rel.account_account_tag_id + JOIN account_tax_report_line_tags_rel tag_rep_ln ON aat.id = tag_rep_ln.account_account_tag_id + LEFT JOIN res_partner cp ON cp.id = COALESCE(aj.l10n_in_gstin_partner_id, c.partner_id) + LEFT JOIN res_country_state cps ON cps.id = cp.state_id + LEFT JOIN account_move refund_am ON refund_am.id = am.reversed_entry_id + LEFT JOIN res_partner p ON p.id = aml.partner_id + LEFT JOIN res_country_state ps ON ps.id = am.l10n_in_state_id + LEFT JOIN res_partner rp ON rp.id = am.l10n_in_reseller_partner_id + LEFT JOIN account_tax_filiation_rel atr ON atr.child_tax = at.id + LEFT JOIN account_tax parent_at ON parent_at.id = atr.parent_tax + """ + return from_str + + def _where(self): + return """ + WHERE am.state = 'posted' + AND tag_rep_ln.account_tax_report_line_id in (SELECT res_id FROM ir_model_data WHERE module='l10n_in' AND name in ('tax_report_line_igst', 'tax_report_line_cgst', 'tax_report_line_sgst', 'tax_report_line_zero_rated', 'tax_report_line_igst_rc', 'tax_report_line_cgst_rc', 'tax_report_line_sgst_rc')) + """ + + def _group_by(self): + group_by_str = """ + GROUP BY sub.move_id, + sub.account_move_id, + sub.name, + sub.state, + sub.partner_id, + sub.date, + sub.l10n_in_gst_treatment, + sub.ecommerce_partner_id, + sub.shipping_bill_number, + sub.shipping_bill_date, + sub.shipping_port_code_id, + sub.total, + sub.journal_id, + sub.company_id, + sub.move_type, + sub.reversed_entry_id, + sub.partner_vat, + sub.ecommerce_vat, + sub.place_of_supply, + sub.is_pre_gst, + sub.is_ecommerce, + sub.b2cl_is_ecommerce, + sub.b2cs_is_ecommerce, + sub.supply_type, + sub.export_type, + sub.refund_export_type, + sub.b2b_type, + sub.refund_invoice_type, + sub.gst_format_date, + sub.gst_format_refund_date, + sub.gst_format_shipping_bill_date, + sub.amount_sign, + sub.tax_id, + sub.tax_rate, + sub.b2cs_refund_sign + """ + return group_by_str + + def init(self): + tools.drop_view_if_exists(self.env.cr, self._table) + self.env.cr.execute("""CREATE or REPLACE VIEW %s AS ( + %s + FROM ( + %s %s %s + ) AS sub %s)""" % (self._table, self._select(), self._sub_select(), + self._from(), self._where(), self._group_by())) diff --git a/addons/l10n_in/report/account_payment_report.py b/addons/l10n_in/report/account_payment_report.py new file mode 100644 index 00000000..db02965b --- /dev/null +++ b/addons/l10n_in/report/account_payment_report.py @@ -0,0 +1,196 @@ +# -*- coding:utf-8 -*- +#az Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import api, fields, models, tools + + +class L10nInPaymentReport(models.AbstractModel): + _name = "l10n_in.payment.report" + _description = "Indian accounting payment report" + + account_move_id = fields.Many2one('account.move', string="Account Move") + payment_id = fields.Many2one('account.payment', string='Payment') + currency_id = fields.Many2one('res.currency', string="Currency") + amount = fields.Float(string="Amount") + payment_amount = fields.Float(string="Payment Amount") + partner_id = fields.Many2one('res.partner', string="Customer") + payment_type = fields.Selection([('outbound', 'Send Money'), ('inbound', 'Receive Money')], string='Payment Type') + journal_id = fields.Many2one('account.journal', string="Journal") + company_id = fields.Many2one(related="journal_id.company_id", string="Company") + place_of_supply = fields.Char(string="Place of Supply") + supply_type = fields.Char(string="Supply Type") + + l10n_in_tax_id = fields.Many2one('account.tax', string="Tax") + tax_rate = fields.Float(string="Rate") + igst_amount = fields.Float(compute="_compute_tax_amount", string="IGST amount") + cgst_amount = fields.Float(compute="_compute_tax_amount", string="CGST amount") + sgst_amount = fields.Float(compute="_compute_tax_amount", string="SGST amount") + cess_amount = fields.Float(compute="_compute_tax_amount", string="CESS amount") + gross_amount = fields.Float(compute="_compute_tax_amount", string="Gross advance") + + def _compute_l10n_in_tax(self, taxes, price_unit, currency=None, quantity=1.0, product=None, partner=None): + """common method to compute gst tax amount base on tax group""" + res = {'igst_amount': 0.0, 'sgst_amount': 0.0, 'cgst_amount': 0.0, 'cess_amount': 0.0} + AccountTaxRepartitionLine = self.env['account.tax.repartition.line'] + tax_report_line_igst = self.env.ref('l10n_in.tax_report_line_igst', False) + tax_report_line_cgst = self.env.ref('l10n_in.tax_report_line_cgst', False) + tax_report_line_sgst = self.env.ref('l10n_in.tax_report_line_sgst', False) + tax_report_line_cess = self.env.ref('l10n_in.tax_report_line_cess', False) + filter_tax = taxes.filtered(lambda t: t.type_tax_use != 'none') + tax_compute = filter_tax.compute_all(price_unit, currency=currency, quantity=quantity, product=product, partner=partner) + for tax_data in tax_compute['taxes']: + tax_report_lines = AccountTaxRepartitionLine.browse(tax_data['tax_repartition_line_id']).mapped('tag_ids.tax_report_line_ids') + if tax_report_line_sgst in tax_report_lines: + res['sgst_amount'] += tax_data['amount'] + if tax_report_line_cgst in tax_report_lines: + res['cgst_amount'] += tax_data['amount'] + if tax_report_line_igst in tax_report_lines: + res['igst_amount'] += tax_data['amount'] + if tax_report_line_cess in tax_report_lines: + res['cess_amount'] += tax_data['amount'] + res.update(tax_compute) + return res + + #TO BE OVERWRITTEN + @api.depends('currency_id') + def _compute_tax_amount(self): + """Calculate tax amount base on default tax set in company""" + + def _select(self): + return """SELECT aml.id AS id, + aml.move_id as account_move_id, + ap.id AS payment_id, + ap.payment_type, + tax.id as l10n_in_tax_id, + tax.amount AS tax_rate, + am.partner_id, + am.amount_total AS payment_amount, + am.journal_id, + aml.currency_id, + (CASE WHEN ps.l10n_in_tin IS NOT NULL + THEN concat(ps.l10n_in_tin,'-',ps.name) + WHEN p.id IS NULL and cps.l10n_in_tin IS NOT NULL + THEN concat(cps.l10n_in_tin,'-',cps.name) + ELSE '' + END) AS place_of_supply, + (CASE WHEN ps.id = cp.state_id or p.id IS NULL + THEN 'Intra State' + WHEN ps.id != cp.state_id and p.id IS NOT NULL + THEN 'Inter State' + END) AS supply_type""" + + def _from(self): + return """FROM account_move_line aml + JOIN account_move am ON am.id = aml.move_id + JOIN account_payment ap ON ap.id = aml.payment_id + JOIN account_account AS ac ON ac.id = aml.account_id + JOIN account_journal AS aj ON aj.id = am.journal_id + JOIN res_company AS c ON c.id = aj.company_id + JOIN account_tax AS tax ON tax.id = ( + CASE WHEN ap.payment_type = 'inbound' + THEN c.account_sale_tax_id + ELSE c.account_purchase_tax_id END) + JOIN res_partner p ON p.id = aml.partner_id + LEFT JOIN res_country_state ps ON ps.id = p.state_id + LEFT JOIN res_partner cp ON cp.id = COALESCE(aj.l10n_in_gstin_partner_id, c.partner_id) + LEFT JOIN res_country_state cps ON cps.id = cp.state_id + """ + + def _where(self): + return """WHERE aml.payment_id IS NOT NULL + AND tax.tax_group_id in (SELECT res_id FROM ir_model_data WHERE module='l10n_in' AND name in ('igst_group','gst_group')) + AND ac.internal_type IN ('receivable', 'payable') AND am.state = 'posted'""" + + def init(self): + tools.drop_view_if_exists(self.env.cr, self._table) + self.env.cr.execute("""CREATE or REPLACE VIEW %s AS ( + %s %s %s)""" % (self._table, self._select(), self._from(), self._where())) + + +class AdvancesPaymentReport(models.Model): + _name = "l10n_in.advances.payment.report" + _inherit = 'l10n_in.payment.report' + _description = "Advances Payment Analysis" + _auto = False + + date = fields.Date(string="Payment Date") + reconcile_amount = fields.Float(string="Reconcile amount in Payment month") + + @api.depends('payment_amount', 'reconcile_amount', 'currency_id') + def _compute_tax_amount(self): + """Calculate tax amount base on default tax set in company""" + account_move_line = self.env['account.move.line'] + for record in self: + base_amount = record.payment_amount - record.reconcile_amount + taxes_data = self._compute_l10n_in_tax( + taxes=record.l10n_in_tax_id, + price_unit=base_amount, + currency=record.currency_id or None, + quantity=1, + partner=record.partner_id or None) + record.igst_amount = taxes_data['igst_amount'] + record.cgst_amount = taxes_data['cgst_amount'] + record.sgst_amount = taxes_data['sgst_amount'] + record.cess_amount = taxes_data['cess_amount'] + record.gross_amount = taxes_data['total_excluded'] + + def _select(self): + select_str = super(AdvancesPaymentReport, self)._select() + select_str += """, + am.date as date, + (SELECT sum(amount) FROM account_partial_reconcile AS apr + WHERE (apr.credit_move_id = aml.id OR apr.debit_move_id = aml.id) + AND (to_char(apr.max_date, 'MM-YYYY') = to_char(aml.date, 'MM-YYYY')) + ) AS reconcile_amount, + (am.amount_total - (SELECT (CASE WHEN SUM(amount) IS NULL THEN 0 ELSE SUM(amount) END) FROM account_partial_reconcile AS apr + WHERE (apr.credit_move_id = aml.id OR apr.debit_move_id = aml.id) + AND (to_char(apr.max_date, 'MM-YYYY') = to_char(aml.date, 'MM-YYYY')) + )) AS amount""" + return select_str + + +class L10nInAdvancesPaymentAdjustmentReport(models.Model): + _name = "l10n_in.advances.payment.adjustment.report" + _inherit = 'l10n_in.payment.report' + _description = "Advances Payment Adjustment Analysis" + _auto = False + + date = fields.Date('Reconcile Date') + + @api.depends('amount', 'currency_id', 'partner_id') + def _compute_tax_amount(self): + account_move_line = self.env['account.move.line'] + for record in self: + taxes_data = self._compute_l10n_in_tax( + taxes=record.l10n_in_tax_id, + price_unit=record.amount, + currency=record.currency_id or None, + quantity=1, + partner=record.partner_id or None) + record.igst_amount = taxes_data['igst_amount'] + record.cgst_amount = taxes_data['cgst_amount'] + record.sgst_amount = taxes_data['sgst_amount'] + record.cess_amount = taxes_data['cess_amount'] + record.gross_amount = taxes_data['total_excluded'] + + def _select(self): + select_str = super(L10nInAdvancesPaymentAdjustmentReport, self)._select() + select_str += """, + apr.max_date AS date, + apr.amount AS amount + """ + return select_str + + def _from(self): + from_str = super(L10nInAdvancesPaymentAdjustmentReport, self)._from() + from_str += """ + JOIN account_partial_reconcile apr ON apr.credit_move_id = aml.id OR apr.debit_move_id = aml.id + """ + return from_str + + def _where(self): + where_str = super(L10nInAdvancesPaymentAdjustmentReport, self)._where() + where_str += """ + AND (apr.max_date > aml.date) + """ + return where_str diff --git a/addons/l10n_in/report/exempted_gst_report.py b/addons/l10n_in/report/exempted_gst_report.py new file mode 100644 index 00000000..661a5c08 --- /dev/null +++ b/addons/l10n_in/report/exempted_gst_report.py @@ -0,0 +1,95 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import api, fields, models, tools + + +class L10nInExemptedReport(models.Model): + _name = "l10n_in.exempted.report" + _description = "Exempted Gst Supplied Statistics" + _auto = False + + account_move_id = fields.Many2one('account.move', string="Account Move") + partner_id = fields.Many2one('res.partner', string="Customer") + out_supply_type = fields.Char(string="Outward Supply Type") + in_supply_type = fields.Char(string="Inward Supply Type") + nil_rated_amount = fields.Float("Nil rated supplies") + exempted_amount = fields.Float("Exempted") + non_gst_supplies = fields.Float("Non GST Supplies") + date = fields.Date("Date") + company_id = fields.Many2one('res.company', string="Company") + journal_id = fields.Many2one('account.journal', string="Journal") + + def _select(self): + select_str = """SELECT aml.id AS id, + aml.partner_id AS partner_id, + am.date, + aml.balance * (CASE WHEN aj.type = 'sale' THEN -1 ELSE 1 END) AS price_total, + am.journal_id, + aj.company_id, + aml.move_id as account_move_id, + + (CASE WHEN p.state_id = cp.state_id + THEN (CASE WHEN p.vat IS NOT NULL + THEN 'Intra-State supplies to registered persons' + ELSE 'Intra-State supplies to unregistered persons' + END) + WHEN p.state_id != cp.state_id + THEN (CASE WHEN p.vat IS NOT NULL + THEN 'Inter-State supplies to registered persons' + ELSE 'Inter-State supplies to unregistered persons' + END) + END) AS out_supply_type, + (CASE WHEN p.state_id = cp.state_id + THEN 'Intra-State supplies' + WHEN p.state_id != cp.state_id + THEN 'Inter-State supplies' + END) AS in_supply_type, + + (CASE WHEN ( + SELECT MAX(account_tax_id) FROM account_move_line_account_tax_rel + JOIN account_tax at ON at.id = account_tax_id + WHERE account_move_line_id = aml.id AND at.tax_group_id IN + ((SELECT res_id FROM ir_model_data WHERE module='l10n_in' AND name='nil_rated_group')) + ) IS NOT NULL + THEN aml.balance * (CASE WHEN aj.type = 'sale' THEN -1 ELSE 1 END) + ELSE 0 + END) AS nil_rated_amount, + + (CASE WHEN ( + SELECT MAX(account_tax_id) FROM account_move_line_account_tax_rel + JOIN account_tax at ON at.id = account_tax_id + WHERE account_move_line_id = aml.id AND at.tax_group_id IN + ((SELECT res_id FROM ir_model_data WHERE module='l10n_in' AND name='exempt_group')) + ) IS NOT NULL + THEN aml.balance * (CASE WHEN aj.type = 'sale' THEN -1 ELSE 1 END) + ELSE 0 + END) AS exempted_amount, + + (CASE WHEN ( + SELECT MAX(account_tax_id) FROM account_move_line_account_tax_rel + WHERE account_move_line_id = aml.id + ) IS NULL + THEN aml.balance * (CASE WHEN aj.type = 'sale' THEN -1 ELSE 1 END) + ELSE 0 + END) AS non_gst_supplies + """ + return select_str + + def _from(self): + from_str = """FROM account_move_line aml + JOIN account_move am ON am.id = aml.move_id + JOIN account_account aa ON aa.id = aml.account_id + JOIN account_journal aj ON aj.id = am.journal_id + JOIN res_company c ON c.id = aj.company_id + LEFT JOIN res_partner cp ON cp.id = COALESCE(aj.l10n_in_gstin_partner_id, c.partner_id) + LEFT JOIN res_partner p ON p.id = am.partner_id + LEFT JOIN res_country pc ON pc.id = p.country_id + WHERE aa.internal_type = 'other' and aml.tax_line_id IS NULL + """ + return from_str + + def init(self): + tools.drop_view_if_exists(self.env.cr, self._table) + self._cr.execute("""CREATE OR REPLACE VIEW %s AS (%s %s)""" % ( + self._table, self._select(), self._from())) diff --git a/addons/l10n_in/report/hsn_gst_report.py b/addons/l10n_in/report/hsn_gst_report.py new file mode 100644 index 00000000..2d121a5b --- /dev/null +++ b/addons/l10n_in/report/hsn_gst_report.py @@ -0,0 +1,112 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import api, fields, models, tools + + +class L10nInProductHsnReport(models.Model): + _name = "l10n_in.product.hsn.report" + _description = "Product HSN Statistics" + _auto = False + _order = 'date desc' + + account_move_id = fields.Many2one('account.move', string="Account Move") + partner_id = fields.Many2one('res.partner', string="Customer") + product_id = fields.Many2one("product.product", string="Product") + uom_id = fields.Many2one('uom.uom', string="UOM") + quantity = fields.Float(string="Product Qty") + date = fields.Date(string="Date") + price_total = fields.Float(string='Taxable Value') + total = fields.Float(string="Total Value") + igst_amount = fields.Float(string="Integrated Tax Amount") + cgst_amount = fields.Float(string="Central Tax Amount") + sgst_amount = fields.Float(string="State/UT Tax Amount") + cess_amount = fields.Float(string="Cess Amount") + company_id = fields.Many2one('res.company', string="Company") + journal_id = fields.Many2one('account.journal', string="Journal") + + hsn_code = fields.Char(string="HSN") + hsn_description = fields.Char(string="HSN description") + + l10n_in_uom_code = fields.Char(string="UQC") + + def _select(self): + select_str = """SELECT aml.id AS id, + aml.move_id AS account_move_id, + aml.partner_id AS partner_id, + aml.product_id, + aml.product_uom_id AS uom_id, + am.date, + am.journal_id, + aj.company_id, + CASE WHEN pt.l10n_in_hsn_code IS NULL THEN '' ELSE pt.l10n_in_hsn_code END AS hsn_code, + CASE WHEN pt.l10n_in_hsn_description IS NULL THEN '' ELSE pt.l10n_in_hsn_description END AS hsn_description, + CASE WHEN uom.l10n_in_code IS NULL THEN '' ELSE uom.l10n_in_code END AS l10n_in_uom_code, + CASE WHEN tag_rep_ln.account_tax_report_line_id IN + (SELECT res_id FROM ir_model_data WHERE module='l10n_in' AND name in ('tax_report_line_sgst', 'tax_report_line_sgst_rc')) OR at.l10n_in_reverse_charge = True + THEN 0 + ELSE aml.quantity + END * (CASE WHEN am.move_type in ('in_refund','out_refund') THEN -1 ELSE 1 END) + AS quantity, + CASE WHEN tag_rep_ln.account_tax_report_line_id IN + (SELECT res_id FROM ir_model_data WHERE module='l10n_in' AND name in ('tax_report_line_igst', 'tax_report_line_igst_rc')) + THEN aml.balance * (CASE WHEN aj.type = 'sale' and am.move_type != 'out_refund' THEN -1 ELSE 1 END) + ELSE 0 + END * (CASE WHEN am.move_type in ('in_refund','out_refund') THEN -1 ELSE 1 END) + AS igst_amount, + CASE WHEN tag_rep_ln.account_tax_report_line_id IN + (SELECT res_id FROM ir_model_data WHERE module='l10n_in' AND name in ('tax_report_line_cgst', 'tax_report_line_cgst_rc')) + THEN aml.balance * (CASE WHEN aj.type = 'sale' and am.move_type != 'out_refund' THEN -1 ELSE 1 END) + ELSE 0 + END * (CASE WHEN am.move_type in ('in_refund','out_refund') THEN -1 ELSE 1 END) + AS cgst_amount, + CASE WHEN tag_rep_ln.account_tax_report_line_id IN + (SELECT res_id FROM ir_model_data WHERE module='l10n_in' AND name in ('tax_report_line_sgst', 'tax_report_line_sgst_rc')) + THEN aml.balance * (CASE WHEN aj.type = 'sale' and am.move_type != 'out_refund' THEN -1 ELSE 1 END) + ELSE 0 + END * (CASE WHEN am.move_type in ('in_refund','out_refund') THEN -1 ELSE 1 END) + AS sgst_amount, + CASE WHEN tag_rep_ln.account_tax_report_line_id IN + (SELECT res_id FROM ir_model_data WHERE module='l10n_in' AND name in ('tax_report_line_cess', 'tax_report_line_cess_rc')) + THEN aml.balance * (CASE WHEN aj.type = 'sale' and am.move_type != 'out_refund' THEN -1 ELSE 1 END) + ELSE 0 + END * (CASE WHEN am.move_type in ('in_refund','out_refund') THEN -1 ELSE 1 END) + AS cess_amount, + CASE WHEN tag_rep_ln.account_tax_report_line_id IN + (SELECT res_id FROM ir_model_data WHERE module='l10n_in' AND name in ('tax_report_line_sgst', 'tax_report_line_sgst_rc')) + THEN 0 + ELSE (CASE WHEN aml.tax_line_id IS NOT NULL THEN aml.tax_base_amount ELSE aml.balance * (CASE WHEN aj.type = 'sale' THEN -1 ELSE 1 END) END) + END * (CASE WHEN am.move_type in ('in_refund','out_refund') THEN -1 ELSE 1 END) + AS price_total, + ((CASE WHEN tag_rep_ln.account_tax_report_line_id IN + (SELECT res_id FROM ir_model_data WHERE module='l10n_in' AND name in ('tax_report_line_sgst', 'tax_report_line_sgst_rc')) + THEN 0 + ELSE (CASE WHEN aml.tax_line_id IS NOT NULL THEN aml.tax_base_amount ELSE 1 END) + END) + (aml.balance * (CASE WHEN aj.type = 'sale' and am.move_type != 'out_refund' THEN -1 ELSE 1 END)) + )* (CASE WHEN am.move_type in ('in_refund','out_refund') THEN -1 ELSE 1 END) + AS total + """ + return select_str + + def _from(self): + from_str = """FROM account_move_line aml + JOIN account_move am ON am.id = aml.move_id + JOIN account_account aa ON aa.id = aml.account_id + JOIN account_journal aj ON aj.id = am.journal_id + JOIN product_product pp ON pp.id = aml.product_id + JOIN product_template pt ON pt.id = pp.product_tmpl_id + LEFT JOIN account_tax at ON at.id = aml.tax_line_id + LEFT JOIN account_account_tag_account_move_line_rel aat_aml_rel ON aat_aml_rel.account_move_line_id = aml.id + LEFT JOIN account_account_tag aat ON aat.id = aat_aml_rel.account_account_tag_id + LEFT JOIN account_tax_report_line_tags_rel tag_rep_ln ON aat.id = tag_rep_ln.account_account_tag_id + LEFT JOIN account_move_line_account_tax_rel mt ON mt.account_move_line_id = aml.id + LEFT JOIN uom_uom uom ON uom.id = aml.product_uom_id + WHERE aa.internal_type = 'other' AND (aml.tax_line_id IS NOT NULL OR mt.account_tax_id IS NULL) + AND am.state = 'posted' + """ + return from_str + + def init(self): + tools.drop_view_if_exists(self.env.cr, self._table) + self.env.cr.execute("""CREATE OR REPLACE VIEW %s AS (%s %s)""" % ( + self._table, self._select(), self._from())) -- cgit v1.2.3