idg_region_tax_actual.py 6.47 KB
import logging
from datetime import datetime

from psycopg2 import DatabaseError, sql

from odoo import fields, models, api, _
from odoo.exceptions import UserError

# from odoo.tools import sql

_logger = logging.getLogger(__name__)


class IdgRegionTaxPlan(models.Model):
    _name = 'idg.region.tax.actual'
    _description = 'Region Tax Actual'
    country_id = fields.Many2one('res.country', required=True)
    state_id = fields.Many2one('res.country.state', required=True,
                               domain="[('country_id', '=?', country_id)]")

    district_id = fields.Many2one('res.district', required=False,
                                  domain="[('state_id', '=?', state_id)]")
    account_id = fields.Many2one('account.account', required=True)
    year = fields.Integer(compute='_compute_date', store=True)
    month = fields.Integer(compute='_compute_date', store=True)
    day = fields.Integer(compute='_compute_date', store=True)
    date = fields.Date(default=datetime.now().date(), required=True)
    qty = fields.Integer(required=True, default=0)
    amount = fields.Integer(required=True, default=0)

    def _compute_date(self):
        for row in self:
            row.year = row.date.year
            row.month = row.date.month
            row.day = row.date.day

    def update_group(self, vals):
        for r in self:
            query = """
                SELECT id FROM account_group agroup
                WHERE agroup.code_prefix_start <= LEFT('{code}', char_length(agroup.code_prefix_start))
                   AND agroup.code_prefix_end >= LEFT('{code}', char_length(agroup.code_prefix_end))
            """.format(code=r.account_id.code)
            self.env.cr.execute(query)
            group_ids = self.env.cr.fetchall()

            for group_id in group_ids:
                rows = self.env['idg.region.tax.actual.sum']. \
                    search([("country_id", '=', r.country_id.id),
                            ("state_id", '=', r.state_id.id),
                            ("district_id", '=', r.district_id.id),
                            ("account_group_id", '=', group_id[0]),
                            ("year", "=", r.year),
                            ("month", "=", r.month),
                            ("day", "=", r.day),
                            ])
                if not rows:
                    value = {
                        "country_id": r.country_id.id,
                        "state_id": r.state_id.id,
                        "district_id": r.district_id.id,
                        "account_group_id": group_id[0],
                        "year": r.year,
                        "month": r.month,
                        "day": r.day,
                        "date": r.date
                    }
                    _logger.info(value)
                    self.env["idg.region.tax.actual.sum"]. \
                        create(value)

    def name_get(self):
        result = []
        for record in self:
            result.append((record.id, f"{record.account_id.name} ({record.account_id.code})"))
        return result

    def create(self, vals):
        res = super(IdgRegionTaxPlan, self).create(vals)
        self.update_group(vals)
        return res

    def write(self, vals):
        res = super(IdgRegionTaxPlan, self).write(vals)
        self.update_group(vals)
        return res

    @api.onchange('district_id')
    def _onchange_district_id(self):
        if self.district_id and self.district_id.state_id != self.state_id:
            self.state_id = self.district_id.state_id
        if not self.district_id or self.district_id != self.sub_district_id.district_id:
            self.sub_district_id = False

    @api.onchange('state_id')
    def _onchange_state_id(self):
        if not self.state_id or self.state_id != self.district_id.state_id:
            self.district_id = False

    @api.onchange('country_id')
    def _onchange_country_id(self):
        if not self.country_id or self.country_id != self.state_id.country_id:
            self.state_id = False


class IdgRegionTaxPlanSum(models.Model):
    _name = 'idg.region.tax.actual.sum'
    _description = 'Region Tax Actual'
    country_id = fields.Many2one('res.country', required=True)
    state_id = fields.Many2one('res.country.state', required=True,
                               domain="[('country_id', '=?', country_id)]")

    district_id = fields.Many2one('res.district', required=False,
                                  domain="[('state_id', '=?', state_id)]")
    account_group_id = fields.Many2one('account.group', required=True)
    year = fields.Integer(compute='_compute_date', store=True)
    month = fields.Integer(compute='_compute_date', store=True)
    day = fields.Integer(compute='_compute_date', store=True)
    date = fields.Date(default=datetime.now().date(), required=True)
    qty = fields.Integer(compute='_compute_summary', default=0)
    amount = fields.Integer(compute="_compute_summary", default=0)
    level = fields.Integer(compute="_compute_level", store=True)

    def _compute_date(self):
        for row in self:
            row.year = row.date.year
            row.month = row.date.month
            row.day = row.date.day

    def _compute_level(self):
        for r in self:
            r.level = len(r.account_group_id.code_prefix_start)

    def _compute_summary(self):
        for r in self:
            code_prefix_start = r.account_group_id.code_prefix_start
            code_prefix_end = r.account_group_id.code_prefix_end
            if r.district_id:
                district = f"AND idg_rtp.district_id=  {r.district_id.id}"
            else:
                district = "AND idg_rtp.district_id is null"

            query = f"""
            SELECT SUM(idg_rtp.qty) as qty, SUM(idg_rtp.amount) as amount
            FROM idg_region_tax_actual idg_rtp
            JOIN account_account aa on idg_rtp.account_id = aa.id
            WHERE idg_rtp.country_id = {r.country_id.id}
                AND idg_rtp.state_id = {r.state_id.id}
                {district}
                AND '{code_prefix_start}' <= LEFT(aa.code, char_length('{code_prefix_start}'))
                AND '{code_prefix_end}' >= LEFT(aa.code, char_length('{code_prefix_end}'))
                AND  date = '{r.date}'
            """

            self.env.cr.execute(query)
            row = self.env.cr.dictfetchone()
            r.qty = row['qty']
            r.amount = row['amount']