Skip to content
Extraits de code Groupes Projets
scop_cotisation.py 7,21 ko
Newer Older
  • Learn to ignore specific revisions
  • jordan's avatar
    jordan a validé
    # © 2021 Le Filament (<http://www.le-filament.com>)
    # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
    
    
    from odoo import models, fields, api
    
    from datetime import date
    
    jordan's avatar
    jordan a validé
    
    
    class ScopCotisation(models.AbstractModel):
        _name = "scop.cotisation"
        _description = "Base des cotisations"
    
    
        @api.model
        def default_get(self, fields):
            """
            Attribue la valeur des conditions de paiments par
            défault à la base de cotisation
            :param fields:
            :return:
            """
            res = super(ScopCotisation, self).default_get(fields)
            res['payment_term_id'] = self.env.user.company_id.\
                contribution_default_payment_term_id.id
            return res
    
    
    jordan's avatar
    jordan a validé
        year = fields.Selection(
            [(year, str(year)) for year in range(
                fields.Datetime.now().year - 1, fields.Datetime.now().year + 2)],
            string='Année de cotisation',
            required=True)
        company_id = fields.Many2one(
            comodel_name='res.company',
            string='Company', change_default=True,
            required=True, readonly=True,
            default=lambda self: self.env.user.company_id)
    
        company_currency_id = fields.Many2one(
            comodel_name='res.currency', related='company_id.currency_id',
            string="Company Currency", readonly=True)
        payment_term_id = fields.Many2one(
            comodel_name='account.payment.term',
            string="Conditions de paiement",
    
            domain=[('is_contribution', '=', True)],
            required=True,
    
    jordan's avatar
    jordan a validé
        )
        date_cotisation = fields.Date("Date de cotisation", required=True)
    
    
        member_count = fields.Integer(
            "Adhérents renouvelés",
            compute='_compute_member_count')
        new_member_count = fields.Integer(
            "Nouveaux adhérents",
            compute='_compute_new_member_count')
    
        invoiced_member_count = fields.Integer(
            "Cotisations créées",
            compute='_compute_invoiced_member_count')
    
        trimester_1 = fields.Date('1er Trimestre')
        trimester_2 = fields.Date('2ème Trimestre')
        trimester_3 = fields.Date('3ème Trimestre')
        trimester_4 = fields.Date('4ème Trimestre')
    
    
        # ------------------------------------------------------
        # Compute fields
        # ------------------------------------------------------
        @api.multi
        def _compute_member_count(self):
            for cotiz in self:
                cotiz.member_count = len(cotiz.get_members())
    
        @api.multi
        def _compute_new_member_count(self):
            for cotiz in self:
                cotiz.new_member_count = len(cotiz.get_new_members())
    
    
        @api.multi
        def _compute_invoiced_member_count(self):
            for cotiz in self:
                cotiz.invoiced_member_count = len(
                    cotiz.invoice_ids.mapped('partner_id'))
    
    
        # ------------------------------------------------------
        # Global functions
        # ------------------------------------------------------
    
        def create_contribution(
                self, product, partner, type_contribution, liasse=None, amount=0,
                date=False, journal_id=False, account_id=False,
    
                type_invoice='out_invoice', is_regul=False, bordereau=False):
    
            """
            Create invoice from Contribution Base
            :param product: product_id
            :param partner: partner_id
            :param type_contribution: type_contribution (CG, UR, Fédé)
            :param liasse: liasse_fiscale_id (reference)
            :param amount: contribution amount (float)
            :param date: date invoice
            :param journal_id: journal
            :param account_id: customer_account_id
            :param type_invoice: invoice or refund
            :param is_regul: used for CG Scop regul
            :return: invoice
            """
    
    jordan's avatar
    jordan a validé
            Invoice = self.env['account.invoice']
            InvoiceLine = self.env['account.invoice.line']
    
            domain = [
    
                ('partner_id', '=', partner.id),
                ('year', '=', self.year),
    
                ('type_contribution_id', '=', type_contribution),
    
            ]
            if bordereau:
                domain.append(('bordereau_id', '=', bordereau.id))
    
            exisiting_invoice = Invoice.search(domain)
    
            if not exisiting_invoice or is_regul:
    
                date_invoice = date if date else self.date_cotisation
                journal_id = self.company_id.contribution_journal_id \
                    if not journal_id else journal_id
                account_id = partner.property_account_receivable_id \
                    if not account_id else account_id
    
                member_invoice = Invoice.create({
                    'partner_id': partner.id,
                    'liasse_fiscale_id': liasse.id,
    
                    'type': type_invoice,
    
                    'year': self.year,
                    'is_contribution': True,
                    'type_contribution_id': type_contribution,
    
                    'journal_id': journal_id.id,
    
                    'account_id': account_id.id,
    
                    'payment_term_id': self.payment_term_id.id,
                    'payment_mode_id': partner.customer_payment_mode_id.id,
    
                    'date_invoice': date_invoice,
    
    jordan's avatar
    jordan a validé
    
            # Création de la ligne CG Scop
    
            exisiting_invoice_line_ids = InvoiceLine.search([
                ('invoice_id', '=', member_invoice.id),
                ('product_id', '=', product.id)
            ])
    
            if not exisiting_invoice_line_ids or is_regul:
    
                InvoiceLine.create({
                    'invoice_id': member_invoice.id,
                    'product_id': product.id,
                    'account_id': product.property_account_income_id.id,
                    'invoice_line_tax_ids': [(6, 0, product.taxes_id.ids)],
                    'name': product.name,
                    'price_unit': amount
                })
            else:
                exisiting_invoice_line_ids[0].write({
                    'price_unit': amount
                })
    
    
            return member_invoice
    
    
        @api.multi
        def get_members(self):
            self.ensure_one()
            members = self.env['scop.membership.period'].search([
                ('type_id', '=', self.env.ref(
                    'cgscop_partner.membership_type_1').id),
    
                ('start', '<', date(self.year, 1, 1)),
    
                ('end', '=', None),
            ]).mapped('partner_id')
            return members
    
        @api.multi
    
        def get_new_members(self, limit_start_date=None):
            if not limit_start_date:
                limit_start_date = date(self.year, 12, 31)
    
            self.ensure_one()
            members = self.env['scop.membership.period'].search([
                ('type_id', '=', self.env.ref(
                    'cgscop_partner.membership_type_1').id),
                ('start', '>=', date(self.year, 1, 1)),
    
                ('start', '<=', limit_start_date),
    
                '|',
                ('end', '=', None),
                ('end', '>', date(self.year, 1, 1))
            ]).mapped('partner_id')
            return members
    
    
        def round_to_closest_multiple(self, float_to_round, multiple):
            """
            :param float_to_round:
            :param multiple:
            :return: closest_multiple
            """
            small_multiple = (float_to_round // multiple) * multiple
            large_multiple = small_multiple + multiple
    
            # Return the closest of two
    
            if abs(float_to_round - small_multiple) < \
                    abs(float_to_round - large_multiple):
    
                return small_multiple
            else:
                return large_multiple