<commit_before># -*- coding: utf-8 -*-
##############################################################################
# For copyright and license notices, see __openerp__.py file in module root
# directory
##############################################################################
from openerp import fields, models, _, api
from openerp.exceptions import UserError
import logging
# import openerp.addons.decimal_precision as dp
_logger = logging.getLogger(__name__)

class AccountPayment(models.Model):

    _inherit = 'account.payment'

    check_ids = fields.Many2many(
        'account.check',
        string='Checks',
        copy=False,
        readonly=True,
        states={'draft': [('readonly', '=', False)]}
    )
    # only for v8 comatibility where more than one check could be received
    # or issued
    check_ids_copy = fields.Many2many(
        related='check_ids',
        readonly=True,
    )
    readonly_currency_id = fields.Many2one(
        related='currency_id',
        readonly=True,
    )
    readonly_amount = fields.Monetary(
        related='amount',
        readonly=True,
    )
    # we add this field for better usability on issue checks and received
    # checks. We keep m2m field for backward compatibility where we allow to
    # use more than one check per payment
    check_id = fields.Many2one(
        'account.check',
        compute='_compute_check',
        string='Check',
    )

    @api.multi
    @api.depends('check_ids')
    def _compute_check(self):
        for rec in self:
            # we only show checks for issue checks or received thid checks
            # if len of checks is 1
            if rec.payment_method_code in (
                    'received_third_check',
                    'issue_check',) and len(rec.check_ids) == 1:
                rec.check_id = rec.check_ids[0].id

# check fields, just to make it easy to load checks without need to create
# them by a m2o record
    check_name = fields.Char(
        'Check Name',
        readonly=True,
        copy=False,
        states={'draft': [('readonly', False)]},
    )
    check_number = fields.Integer(
        'Check Number',
        readonly=True,
        states={'draft': [('readonly', False)]},
        copy=False
    )
    check_issue_date = fields.Date(
        'Check Issue Date',
        readonly=True,
        copy=False,
        states={'draft': [('readonly', False)]},
        default=fields.Date.context_today,
    )
    check_payment_date = fields.Date(
        'Check Payment Date',
        readonly=True,
        help="Only if this check is post dated",
        states={'draft': [('readonly', False)]}
    )
    checkbook_id = fields.Many2one(
        'account.checkbook',
        'Checkbook',
        readonly=True,
        states={'draft': [('readonly', False)]},
    )
    check_subtype = fields.Selection(
        related='checkbook_id.issue_check_subtype',
        readonly=True,
    )
    check_bank_id = fields.Many2one(
        'res.bank',
        'Check Bank',
        readonly=True,
        copy=False,
        states={'draft': [('readonly', False)]}
    )
    check_owner_vat = fields.Char(
        'Check Owner Vat',
        readonly=True,
        copy=False,
        states={'draft': [('readonly', False)]}
    )
    check_owner_name = fields.Char(
        'Check Owner Name',
        readonly=True,
        copy=False,
        states={'draft': [('readonly', False)]}
    )
    # this fields is to help with code and view
    check_type = fields.Char(
        compute='_compute_check_type',
    )
    checkbook_block_manual_number = fields.Boolean(
        related='checkbook_id.block_manual_number',
    )
    check_number_readonly = fields.Integer(
        related='check_number',
        readonly=True,
    )

    @api.multi
    @api.depends('payment_method_code')
    def _compute_check_type(self):
        for rec in self:
            if rec.payment_method_code == 'issue_check':
                rec.check_type = 'issue_check'
            elif rec.payment_method_code in [
                    'received_third_check',
                    'delivered_third_check']:
                rec.check_type = 'third_check'

# on change methods

    # @api.constrains('check_ids')
    @api.onchange('check_ids', 'payment_method_code')
    def onchange_checks(self):
        # we only overwrite if payment method is delivered
        if self.payment_method_code == 'delivered_third_check':
            self.amount = sum(self.check_ids.mapped('amount'))

    # TODo activar
    @api.one
    @api.onchange('check_number')
    def change_check_number(self):
        # TODO make default padding a parameter
        if self.payment_method_code in ['received_third_check']:
            if not self.check_number:
                check_name = False
            else:
                # TODO make optional
                padding = 8
                if len(str(self.check_number)) > padding:
                    padding = len(str(self.check_number))
                # communication = _('Check nbr %s') % (
                check_name = ('%%0%sd' % padding % self.check_number)
            self.check_name = check_name
        elif self.payment_method_code in ['issue_check']:
            if not self.check_number:
                check_name = False
            else:
                sequence = self.checkbook_id.sequence_id
                if self.check_number != sequence.number_next_actual:
                    sequence.write({'number_next_actual': self.check_number})
                check_name = self.checkbook_id.sequence_id.next_by_id()
            self.check_name = check_name

    @api.onchange('check_issue_date', 'check_payment_date')
    def onchange_date(self):
        if (
                self.check_issue_date and self.check_payment_date and
                self.check_issue_date > self.check_payment_date):
            self.check_payment_date = False
            raise UserError(
                _('Check Payment Date must be greater than Issue Date'))

    @api.one
    @api.onchange('partner_id', 'payment_method_code')
    def onchange_partner_check(self):
        commercial_partner = self.partner_id.commercial_partner_id
        if self.payment_method_code == 'received_third_check':
            self.check_bank_id = (
                commercial_partner.bank_ids and
                commercial_partner.bank_ids[0].bank_id or False)
            self.check_owner_name = commercial_partner.name
            vat_field = 'vat'
            # to avoid needed of another module, we add this check to see
            # if l10n_ar cuit field is available
            if 'cuit' in commercial_partner._fields:
                vat_field = 'cuit'
            self.check_owner_vat = commercial_partner[vat_field]
        elif self.payment_method_code == 'issue_check':
            self.check_bank_id = self.journal_id.bank_id
            self.check_owner_name = False
            self.check_owner_vat = False
        # no hace falta else porque no se usa en otros casos

    @api.onchange('payment_method_code')
    def _onchange_payment_method_code(self):
        if self.payment_method_code == 'issue_check':
            checkbook = self.env['account.checkbook'].search([
                ('state', '=', 'active'),
                ('journal_id', '=', self.journal_id.id)],
                limit=1)
            self.checkbook_id = checkbook
        elif self.checkbook_id:
            # TODO ver si interesa implementar volver atras numeracion
            self.checkbook_id = False

    @api.onchange('checkbook_id')
    def onchange_checkbook(self):
        if self.checkbook_id:
            self.check_number = self.checkbook_id.next_number

# post methods
    @api.multi
    def cancel(self):
        res = super(AccountPayment, self).cancel()
        for rec in self:
            rec.do_checks_operations(cancel=True)
        return res

    @api.multi
    def create_check(self, check_type, operation, bank):
        self.ensure_one()

        check_vals = {
            'bank_id': bank.id,
            'owner_name': self.check_owner_name,
            'owner_vat': self.check_owner_vat,
            'number': self.check_number,
            'name': self.check_name,
            'checkbook_id': self.checkbook_id.id,
            'issue_date': self.check_issue_date,
            'type': self.check_type,
            'journal_id': self.journal_id.id,
            'amount': self.amount,
            'payment_date': self.check_payment_date,
            # TODO arreglar que monto va de amount y cual de amount currency
            # 'amount_currency': self.amount,
            'currency_id': self.currency_id.id,
        }
        check = self.env['account.check'].create(check_vals)
        self.check_ids = [(4, check.id, False)]
        check._add_operation(
            operation, self, self.partner_id, date=self.payment_date)
        return check

    @api.multi
    def get_third_check_account(self):
        """
        For third checks, if we use a journal only for third checks, we use
        accounts on journal, if not we use company account
        """
        self.ensure_one()
        if self.payment_type in ('outbound', 'transfer'):
            account = self.journal_id.default_debit_account_id
            methods_field = 'outbound_payment_method_ids'
        else:
            account = self.journal_id.default_credit_account_id
            methods_field = 'inbound_payment_method_ids'
        if len(self.journal_id[methods_field]) > 1 or not account:
            account = self.company_id._get_check_account('holding')
        return account

    @api.multi
    def do_checks_operations(self, vals=None, cancel=False):
        """
        Check attached .ods file on this module to understand checks workflows
        This method is called from:
        * cancellation of payment to execute delete the right operation and
            unlink check if needed
        * from _get_liquidity_move_line_vals to add check operation and, if
            needded, change payment vals and/or create check and
        TODO si queremos todos los del operation podriamos moverlos afuera y
        simplificarlo ya que es el mismo en casi todos
        Tambien podemos simplficiar las distintas opciones y como se recorren
        los if
        """
        self.ensure_one()
        rec = self
        if not rec.check_type:
            # continue
            return vals
        if (
                rec.payment_method_code == 'received_third_check' and
                rec.payment_type == 'inbound'
                # el chequeo de partner type no seria necesario
                # un proveedor nos podria devolver plata con un cheque
                # and rec.partner_type == 'customer'
        ):
            operation = 'holding'
            if cancel:
                _logger.info('Cancel Receive Check')
                rec.check_ids._del_operation(self)
                rec.check_ids.unlink()
                return None

            _logger.info('Receive Check')
            self.create_check('third_check', operation, self.check_bank_id)
            vals['date_maturity'] = self.check_payment_date
            vals['account_id'] = self.get_third_check_account().id
        elif (
                rec.payment_method_code == 'delivered_third_check' and
                rec.payment_type == 'transfer'):
            # si el cheque es entregado en una transferencia tenemos tres
            # opciones
            # TODO we should make this method selectable for transfers
            inbound_method = (
                rec.destination_journal_id.inbound_payment_method_ids)
            # si un solo inbound method y es received third check
            # entonces consideramos que se esta moviendo el cheque de un diario
            # al otro
            if len(inbound_method) == 1 and (
                    inbound_method.code == 'received_third_check'):
                if cancel:
                    _logger.info('Cancel Transfer Check')
                    for check in rec.check_ids:
                        check._del_operation(self)
                        check._del_operation(self)
                        receive_op = check._get_operation('holding')
                        if receive_op.origin._name == 'account.payment':
                            check.journal_id = receive_op.origin.journal_id.id
                    return None

                _logger.info('Transfer Check')
                rec.check_ids._add_operation(
                    'transfered', rec, False, date=rec.payment_date)
                rec.check_ids._add_operation(
                    'holding', rec, False, date=rec.payment_date)
                rec.check_ids.write({
                    'journal_id': rec.destination_journal_id.id})
                vals['account_id'] = self.get_third_check_account().id
            elif rec.destination_journal_id.type == 'cash':
                if cancel:
                    _logger.info('Cancel Sell Check')
                    rec.check_ids._del_operation(self)
                    return None

                _logger.info('Sell Check')
                rec.check_ids._add_operation(
                    'selled', rec, False, date=rec.payment_date)
                vals['account_id'] = self.get_third_check_account().id
            # bank
            else:
                if cancel:
                    _logger.info('Cancel Deposit Check')
                    rec.check_ids._del_operation(self)
                    return None

                _logger.info('Deposit Check')
                rec.check_ids._add_operation(
                    'deposited', rec, False, date=rec.payment_date)
                vals['account_id'] = self.get_third_check_account().id
        elif (
                rec.payment_method_code == 'delivered_third_check' and
                rec.payment_type == 'outbound'
                # el chequeo del partner type no es necesario
                # podriamos entregarlo a un cliente
                # and rec.partner_type == 'supplier'
        ):
            if cancel:
                _logger.info('Cancel Deliver Check')
                rec.check_ids._del_operation(self)
                return None

            _logger.info('Deliver Check')
            rec.check_ids._add_operation(
                'delivered', rec, rec.partner_id, date=rec.payment_date)
            vals['account_id'] = self.get_third_check_account().id
        elif (
                rec.payment_method_code == 'issue_check' and
                rec.payment_type == 'outbound'
                # el chequeo del partner type no es necesario
                # podriamos entregarlo a un cliente
                # and rec.partner_type == 'supplier'
        ):
            if cancel:
                _logger.info('Cancel Hand Check')
                rec.check_ids._del_operation(self)
                rec.check_ids.unlink()
                return None

            _logger.info('Hand Check')
            self.create_check('issue_check', 'handed', self.check_bank_id)
            vals['date_maturity'] = self.check_payment_date
            # if check is deferred, change account
            if self.check_subtype == 'deferred':
                vals['account_id'] = self.company_id._get_check_account(
                    'deferred').id
        elif (
                rec.payment_method_code == 'issue_check' and
                rec.payment_type == 'transfer' and
                rec.destination_journal_id.type == 'cash'):
            if cancel:
                _logger.info('Cancel Withdrawal Check')
                rec.check_ids._del_operation(self)
                rec.check_ids.unlink()
                return None

            _logger.info('Hand Check')
            self.create_check('issue_check', 'withdrawed', self.check_bank_id)
            vals['date_maturity'] = self.check_payment_date
            # if check is deferred, change account
            # si retiramos por caja directamente lo sacamos de banco
            # if self.check_subtype == 'deferred':
            #     vals['account_id'] = self.company_id._get_check_account(
            #         'deferred').id
        else:
            raise UserError(_(
                'This operatios is not implemented for checks:\n'
                '* Payment type: %s\n'
                '* Partner type: %s\n'
                '* Payment method: %s\n'
                '* Destination journal: %s\n' % (
                    rec.payment_type,
                    rec.partner_type,
                    rec.payment_method_code,
                    rec.destination_journal_id.type)))
        return vals

    def _get_liquidity_move_line_vals(self, amount):
        vals = super(AccountPayment, self)._get_liquidity_move_line_vals(
            amount)
        vals = self.do_checks_operations(vals=vals)
        return vals
<commit_msg>IMP checks numbering<commit_after># -*- coding: utf-8 -*-
##############################################################################
# For copyright and license notices, see __openerp__.py file in module root
# directory
##############################################################################
from openerp import fields, models, _, api
from openerp.exceptions import UserError
import logging
# import openerp.addons.decimal_precision as dp
_logger = logging.getLogger(__name__)

class AccountPayment(models.Model):

    _inherit = 'account.payment'

    check_ids = fields.Many2many(
        'account.check',
        string='Checks',
        copy=False,
        readonly=True,
        states={'draft': [('readonly', '=', False)]}
    )
    # only for v8 comatibility where more than one check could be received
    # or issued
    check_ids_copy = fields.Many2many(
        related='check_ids',
        readonly=True,
    )
    readonly_currency_id = fields.Many2one(
        related='currency_id',
        readonly=True,
    )
    readonly_amount = fields.Monetary(
        related='amount',
        readonly=True,
    )
    # we add this field for better usability on issue checks and received
    # checks. We keep m2m field for backward compatibility where we allow to
    # use more than one check per payment
    check_id = fields.Many2one(
        'account.check',
        compute='_compute_check',
        string='Check',
    )

    @api.multi
    @api.depends('check_ids')
    def _compute_check(self):
        for rec in self:
            # we only show checks for issue checks or received thid checks
            # if len of checks is 1
            if rec.payment_method_code in (
                    'received_third_check',
                    'issue_check',) and len(rec.check_ids) == 1:
                rec.check_id = rec.check_ids[0].id

# check fields, just to make it easy to load checks without need to create
# them by a m2o record
    check_name = fields.Char(
        'Check Name',
        readonly=True,
        copy=False,
        states={'draft': [('readonly', False)]},
    )
    check_number = fields.Integer(
        'Check Number',
        readonly=True,
        states={'draft': [('readonly', False)]},
        copy=False
    )
    check_issue_date = fields.Date(
        'Check Issue Date',
        readonly=True,
        copy=False,
        states={'draft': [('readonly', False)]},
        default=fields.Date.context_today,
    )
    check_payment_date = fields.Date(
        'Check Payment Date',
        readonly=True,
        help="Only if this check is post dated",
        states={'draft': [('readonly', False)]}
    )
    checkbook_id = fields.Many2one(
        'account.checkbook',
        'Checkbook',
        readonly=True,
        states={'draft': [('readonly', False)]},
    )
    check_subtype = fields.Selection(
        related='checkbook_id.issue_check_subtype',
        readonly=True,
    )
    check_bank_id = fields.Many2one(
        'res.bank',
        'Check Bank',
        readonly=True,
        copy=False,
        states={'draft': [('readonly', False)]}
    )
    check_owner_vat = fields.Char(
        'Check Owner Vat',
        readonly=True,
        copy=False,
        states={'draft': [('readonly', False)]}
    )
    check_owner_name = fields.Char(
        'Check Owner Name',
        readonly=True,
        copy=False,
        states={'draft': [('readonly', False)]}
    )
    # this fields is to help with code and view
    check_type = fields.Char(
        compute='_compute_check_type',
    )
    checkbook_block_manual_number = fields.Boolean(
        related='checkbook_id.block_manual_number',
    )
    check_number_readonly = fields.Integer(
        related='check_number',
        readonly=True,
    )

    @api.multi
    @api.depends('payment_method_code')
    def _compute_check_type(self):
        for rec in self:
            if rec.payment_method_code == 'issue_check':
                rec.check_type = 'issue_check'
            elif rec.payment_method_code in [
                    'received_third_check',
                    'delivered_third_check']:
                rec.check_type = 'third_check'

# on change methods

    # @api.constrains('check_ids')
    @api.onchange('check_ids', 'payment_method_code')
    def onchange_checks(self):
        # we only overwrite if payment method is delivered
        if self.payment_method_code == 'delivered_third_check':
            self.amount = sum(self.check_ids.mapped('amount'))

    @api.multi
    @api.onchange('check_number')
    def change_check_number(self):
        # TODO make default padding a parameter
        def _get_name_from_number(number):
            padding = 8
            if len(str(number)) > padding:
                padding = len(str(number))
            return ('%%0%sd' % padding % number)

        for rec in self:
            if rec.payment_method_code in ['received_third_check']:
                if not rec.check_number:
                    check_name = False
                else:
                    check_name = _get_name_from_number(rec.check_number)
                rec.check_name = check_name
            elif rec.payment_method_code in ['issue_check']:
                sequence = rec.checkbook_id.sequence_id
                if not rec.check_number:
                    check_name = False
                elif sequence:
                    if rec.check_number != sequence.number_next_actual:
                        sequence.write(
                            {'number_next_actual': rec.check_number})
                    check_name = rec.checkbook_id.sequence_id.next_by_id()
                else:
                    # in sipreco, for eg, no sequence on checkbooks
                    check_name = _get_name_from_number(rec.check_number)
                rec.check_name = check_name

    @api.onchange('check_issue_date', 'check_payment_date')
    def onchange_date(self):
        if (
                self.check_issue_date and self.check_payment_date and
                self.check_issue_date > self.check_payment_date):
            self.check_payment_date = False
            raise UserError(
                _('Check Payment Date must be greater than Issue Date'))

    @api.one
    @api.onchange('partner_id', 'payment_method_code')
    def onchange_partner_check(self):
        commercial_partner = self.partner_id.commercial_partner_id
        if self.payment_method_code == 'received_third_check':
            self.check_bank_id = (
                commercial_partner.bank_ids and
                commercial_partner.bank_ids[0].bank_id or False)
            self.check_owner_name = commercial_partner.name
            vat_field = 'vat'
            # to avoid needed of another module, we add this check to see
            # if l10n_ar cuit field is available
            if 'cuit' in commercial_partner._fields:
                vat_field = 'cuit'
            self.check_owner_vat = commercial_partner[vat_field]
        elif self.payment_method_code == 'issue_check':
            self.check_bank_id = self.journal_id.bank_id
            self.check_owner_name = False
            self.check_owner_vat = False
        # no hace falta else porque no se usa en otros casos

    @api.onchange('payment_method_code')
    def _onchange_payment_method_code(self):
        if self.payment_method_code == 'issue_check':
            checkbook = self.env['account.checkbook'].search([
                ('state', '=', 'active'),
                ('journal_id', '=', self.journal_id.id)],
                limit=1)
            self.checkbook_id = checkbook
        elif self.checkbook_id:
            # TODO ver si interesa implementar volver atras numeracion
            self.checkbook_id = False

    @api.onchange('checkbook_id')
    def onchange_checkbook(self):
        if self.checkbook_id:
            self.check_number = self.checkbook_id.next_number

# post methods
    @api.multi
    def cancel(self):
        res = super(AccountPayment, self).cancel()
        for rec in self:
            rec.do_checks_operations(cancel=True)
        return res

    @api.multi
    def create_check(self, check_type, operation, bank):
        self.ensure_one()

        check_vals = {
            'bank_id': bank.id,
            'owner_name': self.check_owner_name,
            'owner_vat': self.check_owner_vat,
            'number': self.check_number,
            'name': self.check_name,
            'checkbook_id': self.checkbook_id.id,
            'issue_date': self.check_issue_date,
            'type': self.check_type,
            'journal_id': self.journal_id.id,
            'amount': self.amount,
            'payment_date': self.check_payment_date,
            # TODO arreglar que monto va de amount y cual de amount currency
            # 'amount_currency': self.amount,
            'currency_id': self.currency_id.id,
        }
        check = self.env['account.check'].create(check_vals)
        self.check_ids = [(4, check.id, False)]
        check._add_operation(
            operation, self, self.partner_id, date=self.payment_date)
        return check

    @api.multi
    def get_third_check_account(self):
        """
        For third checks, if we use a journal only for third checks, we use
        accounts on journal, if not we use company account
        """
        self.ensure_one()
        if self.payment_type in ('outbound', 'transfer'):
            account = self.journal_id.default_debit_account_id
            methods_field = 'outbound_payment_method_ids'
        else:
            account = self.journal_id.default_credit_account_id
            methods_field = 'inbound_payment_method_ids'
        if len(self.journal_id[methods_field]) > 1 or not account:
            account = self.company_id._get_check_account('holding')
        return account

    @api.multi
    def do_checks_operations(self, vals=None, cancel=False):
        """
        Check attached .ods file on this module to understand checks workflows
        This method is called from:
        * cancellation of payment to execute delete the right operation and
            unlink check if needed
        * from _get_liquidity_move_line_vals to add check operation and, if
            needded, change payment vals and/or create check and
        TODO si queremos todos los del operation podriamos moverlos afuera y
        simplificarlo ya que es el mismo en casi todos
        Tambien podemos simplficiar las distintas opciones y como se recorren
        los if
        """
        self.ensure_one()
        rec = self
        if not rec.check_type:
            # continue
            return vals
        if (
                rec.payment_method_code == 'received_third_check' and
                rec.payment_type == 'inbound'
                # el chequeo de partner type no seria necesario
                # un proveedor nos podria devolver plata con un cheque
                # and rec.partner_type == 'customer'
        ):
            operation = 'holding'
            if cancel:
                _logger.info('Cancel Receive Check')
                rec.check_ids._del_operation(self)
                rec.check_ids.unlink()
                return None

            _logger.info('Receive Check')
            self.create_check('third_check', operation, self.check_bank_id)
            vals['date_maturity'] = self.check_payment_date
            vals['account_id'] = self.get_third_check_account().id
        elif (
                rec.payment_method_code == 'delivered_third_check' and
                rec.payment_type == 'transfer'):
            # si el cheque es entregado en una transferencia tenemos tres
            # opciones
            # TODO we should make this method selectable for transfers
            inbound_method = (
                rec.destination_journal_id.inbound_payment_method_ids)
            # si un solo inbound method y es received third check
            # entonces consideramos que se esta moviendo el cheque de un diario
            # al otro
            if len(inbound_method) == 1 and (
                    inbound_method.code == 'received_third_check'):
                if cancel:
                    _logger.info('Cancel Transfer Check')
                    for check in rec.check_ids:
                        check._del_operation(self)
                        check._del_operation(self)
                        receive_op = check._get_operation('holding')
                        if receive_op.origin._name == 'account.payment':
                            check.journal_id = receive_op.origin.journal_id.id
                    return None

                _logger.info('Transfer Check')
                rec.check_ids._add_operation(
                    'transfered', rec, False, date=rec.payment_date)
                rec.check_ids._add_operation(
                    'holding', rec, False, date=rec.payment_date)
                rec.check_ids.write({
                    'journal_id': rec.destination_journal_id.id})
                vals['account_id'] = self.get_third_check_account().id
            elif rec.destination_journal_id.type == 'cash':
                if cancel:
                    _logger.info('Cancel Sell Check')
                    rec.check_ids._del_operation(self)
                    return None

                _logger.info('Sell Check')
                rec.check_ids._add_operation(
                    'selled', rec, False, date=rec.payment_date)
                vals['account_id'] = self.get_third_check_account().id
            # bank
            else:
                if cancel:
                    _logger.info('Cancel Deposit Check')
                    rec.check_ids._del_operation(self)
                    return None

                _logger.info('Deposit Check')
                rec.check_ids._add_operation(
                    'deposited', rec, False, date=rec.payment_date)
                vals['account_id'] = self.get_third_check_account().id
        elif (
                rec.payment_method_code == 'delivered_third_check' and
                rec.payment_type == 'outbound'
                # el chequeo del partner type no es necesario
                # podriamos entregarlo a un cliente
                # and rec.partner_type == 'supplier'
        ):
            if cancel:
                _logger.info('Cancel Deliver Check')
                rec.check_ids._del_operation(self)
                return None

            _logger.info('Deliver Check')
            rec.check_ids._add_operation(
                'delivered', rec, rec.partner_id, date=rec.payment_date)
            vals['account_id'] = self.get_third_check_account().id
        elif (
                rec.payment_method_code == 'issue_check' and
                rec.payment_type == 'outbound'
                # el chequeo del partner type no es necesario
                # podriamos entregarlo a un cliente
                # and rec.partner_type == 'supplier'
        ):
            if cancel:
                _logger.info('Cancel Hand Check')
                rec.check_ids._del_operation(self)
                rec.check_ids.unlink()
                return None

            _logger.info('Hand Check')
            self.create_check('issue_check', 'handed', self.check_bank_id)
            vals['date_maturity'] = self.check_payment_date
            # if check is deferred, change account
            if self.check_subtype == 'deferred':
                vals['account_id'] = self.company_id._get_check_account(
                    'deferred').id
        elif (
                rec.payment_method_code == 'issue_check' and
                rec.payment_type == 'transfer' and
                rec.destination_journal_id.type == 'cash'):
            if cancel:
                _logger.info('Cancel Withdrawal Check')
                rec.check_ids._del_operation(self)
                rec.check_ids.unlink()
                return None

            _logger.info('Hand Check')
            self.create_check('issue_check', 'withdrawed', self.check_bank_id)
            vals['date_maturity'] = self.check_payment_date
            # if check is deferred, change account
            # si retiramos por caja directamente lo sacamos de banco
            # if self.check_subtype == 'deferred':
            #     vals['account_id'] = self.company_id._get_check_account(
            #         'deferred').id
        else:
            raise UserError(_(
                'This operatios is not implemented for checks:\n'
                '* Payment type: %s\n'
                '* Partner type: %s\n'
                '* Payment method: %s\n'
                '* Destination journal: %s\n' % (
                    rec.payment_type,
                    rec.partner_type,
                    rec.payment_method_code,
                    rec.destination_journal_id.type)))
        return vals

    def _get_liquidity_move_line_vals(self, amount):
        vals = super(AccountPayment, self)._get_liquidity_move_line_vals(
            amount)
        vals = self.do_checks_operations(vals=vals)
        return vals
<|endoftext|>


<commit_before>import os
import logging
import shutil
from zipfile import ZipFile
from gosa.backend.plugins.upload.main import IUploadFileHandler
from gosa.common import Environment
from gosa.plugin.gui import frontend_path

class WidgetUploadHandler(IUploadFileHandler):

    def __init__(self):
        self.env = Environment.getInstance()
        self.log = logging.getLogger(__name__)
        self.log.info("initializing dashboard widget upload handler")

    def handle_upload(self, file, request):
        filename = request.headers.get('X-File-Name')
        self.log.debug("uploaded widget package received %s" % filename)
        self.extract(file.f_out.name, filename)
        file.release()

    def extract(self, fn, real_name):
        try:
            shutil.copyfile(fn, os.path.join(frontend_path, "gosa", "uploads", "widgets", real_name))

            with ZipFile(fn, 'r') as widget_zip:

                if widget_zip.testzip():
                    self.log.error("bad widget zip uploaded")
                    return
                # extract filename from zip
                widget_zip.extractall(os.path.join(frontend_path, "gosa", "uploads", "widgets"))

        except Exception as e:
            print(e)
            raise e
<commit_msg>remove debugging copy<commit_after>import os
import logging
import shutil
from zipfile import ZipFile
from gosa.backend.plugins.upload.main import IUploadFileHandler
from gosa.common import Environment
from gosa.plugin.gui import frontend_path

class WidgetUploadHandler(IUploadFileHandler):

    def __init__(self):
        self.env = Environment.getInstance()
        self.log = logging.getLogger(__name__)
        self.log.info("initializing dashboard widget upload handler")

    def handle_upload(self, file, request):
        filename = request.headers.get('X-File-Name')
        self.log.debug("uploaded widget package received %s" % filename)
        self.extract(file.f_out.name, filename)
        file.release()

    def extract(self, fn, real_name):
        try:

            with ZipFile(fn, 'r') as widget_zip:

                if widget_zip.testzip():
                    self.log.error("bad widget zip uploaded")
                    return
                # extract filename from zip
                widget_zip.extractall(os.path.join(frontend_path, "gosa", "uploads", "widgets"))

        except Exception as e:
            print(e)
            raise e
<|endoftext|>


<commit_before>#!/usr/bin/python

#  This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

"""This file contains various locale lists consumed by other tools"""

# Sorted list of locales that ship in release builds of Focus/Klar.
#
# Other builds might include more locales.
#
# Note that there are differences in the locale codes used by Pontoon
# and by Android (e.g. Hebrew: he (Pontoon) vs. iw (Android)).
# This list uses the Android notation. A valid entry can be a
# language code (de) or a language plus country (de-DE). Do not use
# the name of the Androidresource folder (de-rDE) here.
#
# Releases should contain all locales that are at 100% or have been
# shipping in previous releases. Ping :delphine in case you want
# to add or remove locales from releases.
RELEASE_LOCALES = [
	"am",
	"an",
	"anp",
	"ar",
	"ast",
	"az",
	"bg",
	"bn-BD",
	"bn-IN",
	"bs",
	"ca",
	"cak",
	"cs",
	"cy",
	"da",
	"de",
	"dsb",
	"el",
	"eo",
	"es-AR",
	"es-CL",
	"es-ES",
	"es-MX",
	"eu",
	"fa",
	"fi",
	"fr",
	"fy-NL",
	"ga-IE",
	"gu-IN",
	"hi-IN",
	"hr",
	"hsb",
	"hu",
	"hy-AM",
	"ia",
	"in",
	"it",
	"iw",
	"ja",
	"ka",
	"kab",
	"kk",
	"ko",
	"kw",
	"lo",
	"meh",
	"mix",
	"ms",
	"my",
	"nb-NO",
	"ne-NP",
	"nl",
	"nn-NO",
	"oc",
	"pl",
	"pt-BR",
	"ro",
	"ru",
	"sk",
	"sl",
	"sq",
	"sr",
	"sv-SE",
	"ta",
	"te",
	"th",
	"tr",
	"trs",
	"tsz",
	"tt",
	"uk",
	"ur",
	"vi",
	"wo",
	"zam",
	"zh-CN",
	"zh-TW"
]

# This is the list of locales that we want to take automated screenshots of
# in addition to the list of release locales. We want to take screenshots
# of other locales so that translators of not yet completed locales can
# verify their work in progress.
ADDITIONAL_SCREENSHOT_LOCALES = [
	"ixl",
	"lt",
	"en-CA",
	"af",
	"pai",
	"quy",
	"ay",
	"quc"
]

# Those are locales that we take automated screenshots of.
SCREENSHOT_LOCALES = sorted(RELEASE_LOCALES + ADDITIONAL_SCREENSHOT_LOCALES)
<commit_msg>For #2737 - Adds new release locales for 6.0<commit_after>#!/usr/bin/python

#  This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

"""This file contains various locale lists consumed by other tools"""

# Sorted list of locales that ship in release builds of Focus/Klar.
#
# Other builds might include more locales.
#
# Note that there are differences in the locale codes used by Pontoon
# and by Android (e.g. Hebrew: he (Pontoon) vs. iw (Android)).
# This list uses the Android notation. A valid entry can be a
# language code (de) or a language plus country (de-DE). Do not use
# the name of the Androidresource folder (de-rDE) here.
#
# Releases should contain all locales that are at 100% or have been
# shipping in previous releases. Ping :delphine in case you want
# to add or remove locales from releases.
RELEASE_LOCALES = [
	"af",
	"am",
	"an",
	"anp",
	"ar",
	"ast",
	"az",
	"bg",
	"bn-BD",
	"bn-IN",
	"bs",
	"ca",
	"cak",
	"cs",
	"cy",
	"da",
	"de",
	"dsb",
	"el",
	"en-CA",
	"eo",
	"es-AR",
	"es-CL",
	"es-ES",
	"es-MX",
	"eu",
	"fa",
	"fi",
	"fr",
	"fy-NL",
	"ga-IE",
	"gu-IN",
	"hi-IN",
	"hr",
	"hsb",
	"hu",
	"hy-AM",
	"ia",
	"in",
	"it",
	"ixl",
	"iw",
	"ja",
	"ka",
	"kab",
	"kk",
	"ko",
	"kw",
	"lo",
	"lt",
	"meh",
	"mix",
	"ms",
	"my",
	"nb-NO",
	"ne-NP",
	"nl",
	"nn-NO",
	"oc",
	"pai",
	"pl",
	"pt-BR",
	"quy",
	"ro",
	"ru",
	"sk",
	"sl",
	"sq",
	"sr",
	"sv-SE",
	"ta",
	"te",
	"th",
	"tr",
	"trs",
	"tsz",
	"tt",
	"uk",
	"ur",
	"vi",
	"wo",
	"zam",
	"zh-CN",
	"zh-TW"
]

# This is the list of locales that we want to take automated screenshots of
# in addition to the list of release locales. We want to take screenshots
# of other locales so that translators of not yet completed locales can
# verify their work in progress.
ADDITIONAL_SCREENSHOT_LOCALES = [
	"ay",
	"quc",
	"pa-IN"
]

# Those are locales that we take automated screenshots of.
SCREENSHOT_LOCALES = sorted(RELEASE_LOCALES + ADDITIONAL_SCREENSHOT_LOCALES)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
##############################################################################
#
#    Copyright (C) 2015  ADHOC SA  (http://www.adhoc.com.ar)
#    All Rights Reserved.
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{
    "name": "Account Contract Project",
    "version": "9.0.0.0.0",
    'author': 'ADHOC SA',
    'website': 'www.adhoc.com.ar',
    'license': 'AGPL-3',
    "category": "Accounting",
    "description": """
Account Contract Project
========================
    """,
    'depends': [
        'project'
    ],
    'data': [
        'account_analytic_account_view.xml',
    ],
    'demo': [
    ],
    'test': [
    ],
    'installable': False,
    'auto_install': False,
    'application': False,
}
<commit_msg>ADD installable = True<commit_after># -*- coding: utf-8 -*-
##############################################################################
#
#    Copyright (C) 2015  ADHOC SA  (http://www.adhoc.com.ar)
#    All Rights Reserved.
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{
    "name": "Account Contract Project",
    "version": "9.0.0.0.0",
    'author': 'ADHOC SA',
    'website': 'www.adhoc.com.ar',
    'license': 'AGPL-3',
    "category": "Accounting",
    "description": """
Account Contract Project
========================
    """,
    'depends': [
        'project'
    ],
    'data': [
        'account_analytic_account_view.xml',
    ],
    'demo': [
    ],
    'test': [
    ],
    'installable': True,
    'auto_install': False,
    'application': False,
}
<|endoftext|>


<commit_before>import asyncio
import discord
from   discord.ext import commands

# This is the Face module. It sends faces.

class Face:

	# Init with the bot reference, and a reference to the settings var
	def __init__(self, bot):
		self.bot = bot

	@commands.command(pass_context=True)
	async def lenny(self, ctx):
		"""Give me some Lenny."""
		await self.bot.send_message(ctx.message.channel, "( ͡° ͜ʖ ͡°)")

	@commands.command(pass_context=True)
	async def shrug(self, ctx):
		"""Shrug it off."""
		await self.bot.send_message(ctx.message.channel, "¯\_(ツ)_/¯")

	<commit_msg>$shrug $lenny orig message delete<commit_after>import asyncio
import discord
from   discord.ext import commands

# This is the Face module. It sends faces.

class Face:

	# Init with the bot reference, and a reference to the settings var
	def __init__(self, bot):
		self.bot = bot

	@commands.command(pass_context=True)
	async def lenny(self, ctx):
		"""Give me some Lenny."""
		# Remove original message
		await self.bot.delete_message(ctx.message)
		await self.bot.send_message(ctx.message.channel, "( ͡° ͜ʖ ͡°)")

	@commands.command(pass_context=True)
	async def shrug(self, ctx):
		"""Shrug it off."""
		# Remove original message
		await self.bot.delete_message(ctx.message)
		await self.bot.send_message(ctx.message.channel, "¯\_(ツ)_/¯")

	<|endoftext|>


<commit_before>from collections import Iterable

from arpeggio import Optional, ZeroOrMore, OneOrMore, EOF, ParserPython, NoMatch, RegExMatch
from logger import log
import generate

import os

# STATUSES
ACCEPT = 'accept'
REJECT = 'reject'
INCOMPLETE = 'incomplete'

def parse_sentence(sentence, root_rule):
    parser = ParserPython(root_rule)
    res = {
        'rule': None,
        'status': None,
        'properties': {},
        'suggestions': [],
        'rejectindex': -1,
    }

    try:
        root_node = parser.parse(sentence)
        grammar_node = root_node[0]
        res['rule'] = grammar_node.rule_name
        res['status'] = ACCEPT
        all_properties = dict(parse_properties(grammar_node))
        res['primary_properties'] = dict((k,v) for k, v in all_properties.items() if k in generate.primary_keys)
        res['properties'] = dict((k,v) for k, v in all_properties.items() if k not in generate.primary_keys)
    except NoMatch as e:
        if e.col == len(sentence) + 1:
            # the sentence failed to match at the very end
            # so the status of it is incomplete match
            res['status'] = INCOMPLETE
        else:
            res['status'] = REJECT

        res['suggestions'] = list(parse_autocomplete(e.rules))
        res['rejectindex'] = e.col

    return res

def parse_autocomplete(nomatch_rules):
    for rule in nomatch_rules:
        if isinstance(rule, RegExMatch):
            yield {
                'type': 'property',
                'suggest': rule.rule_name,
            }
        else:
            yield {
                'type': 'value',
                'suggest': str(rule),
            }

def parse_properties(grammar_node):
    # grammar node is the top level node
    # all its children rules are denormalized to 1 level deep
    for rule in grammar_node:
        if rule.rule_name != '':
            if isinstance(rule, Iterable):
                # TODO: this happens in the case that a rule is
                # an xor of potential values. Thus, we would get
                # a list containing solely the value.
                # E.g. disease -> [hiv]

                values = []
                for subrule in rule:
                    value = str(subrule)
                    if value != ',':
                        values.append(value)
                yield (rule.rule_name, values)
            else:
                yield (rule.rule_name, str(rule))

def get_keywords(root_rule):
    log.info('Initializing keywords...')
    keywords = set()
    for base_rule in root_rule():
        grammar = base_rule()
        for rule in grammar:
            if isinstance(rule, str):
                # If a top-level rule is a string, then it must
                # be a keyword.
                keywords.add(rule)

    log.info('Keywords: ', keywords)
    return list(keywords)
<commit_msg>F U N C T I O N A L<commit_after>from collections import Iterable

from arpeggio import Optional, ZeroOrMore, OneOrMore, EOF, ParserPython, NoMatch, RegExMatch
from logger import log
import generate

import os

# STATUSES
ACCEPT = 'accept'
REJECT = 'reject'
INCOMPLETE = 'incomplete'

def split_dict(d, cond):
    d1 = {}
    d2 = {}
    for k, v in d.items():
        if cond(k):
            d1[k] = v
        else:
            d2[k] = v
    return d1, d2

def parse_sentence(sentence, root_rule):
    parser = ParserPython(root_rule)
    res = {
        'rule': None,
        'status': None,
        'properties': {},
        'suggestions': [],
        'rejectindex': -1,
    }

    try:
        root_node = parser.parse(sentence)
        grammar_node = root_node[0]
        res['rule'] = grammar_node.rule_name
        res['status'] = ACCEPT
        all_properties = dict(parse_properties(grammar_node))
        res['primary_properties'], res['properties'] = split_dict(all_properties, lambda k: k in generate.primary_keys)
    except NoMatch as e:
        if e.col == len(sentence) + 1:
            # the sentence failed to match at the very end
            # so the status of it is incomplete match
            res['status'] = INCOMPLETE
        else:
            res['status'] = REJECT

        res['suggestions'] = list(parse_autocomplete(e.rules))
        res['rejectindex'] = e.col

    return res

def parse_autocomplete(nomatch_rules):
    for rule in nomatch_rules:
        if isinstance(rule, RegExMatch):
            yield {
                'type': 'property',
                'suggest': rule.rule_name,
            }
        else:
            yield {
                'type': 'value',
                'suggest': str(rule),
            }

def parse_properties(grammar_node):
    # grammar node is the top level node
    # all its children rules are denormalized to 1 level deep
    for rule in grammar_node:
        if rule.rule_name != '':
            if isinstance(rule, Iterable):
                # TODO: this happens in the case that a rule is
                # an xor of potential values. Thus, we would get
                # a list containing solely the value.
                # E.g. disease -> [hiv]

                values = []
                for subrule in rule:
                    value = str(subrule)
                    if value != ',':
                        values.append(value)
                yield (rule.rule_name, values)
            else:
                yield (rule.rule_name, str(rule))

def get_keywords(root_rule):
    log.info('Initializing keywords...')
    keywords = set()
    for base_rule in root_rule():
        grammar = base_rule()
        for rule in grammar:
            if isinstance(rule, str):
                # If a top-level rule is a string, then it must
                # be a keyword.
                keywords.add(rule)

    log.info('Keywords: ', keywords)
    return list(keywords)
<|endoftext|>


<commit_before># Copyright 2019 Tecnativa S.L. - David Vidal
# Copyright 2020 Tecnativa - Pedro M. Baeza
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
{
    "name": "Account Global Discount",
    "version": "13.0.1.0.1",
    "category": "Accounting",
    "author": "Tecnativa, Odoo Community Association (OCA)",
    "website": "https://github.com/OCA/server-backend",
    "license": "AGPL-3",
    "depends": ["account", "base_global_discount"],
    "data": [
        "security/ir.model.access.csv",
        "security/security.xml",
        "views/account_invoice_views.xml",
        "views/global_discount_views.xml",
        "views/report_account_invoice.xml",
    ],
    "application": False,
    "installable": True,
}
<commit_msg>account_global_discount 13.0.1.0.2<commit_after># Copyright 2019 Tecnativa S.L. - David Vidal
# Copyright 2020 Tecnativa - Pedro M. Baeza
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
{
    "name": "Account Global Discount",
    "version": "13.0.1.0.2",
    "category": "Accounting",
    "author": "Tecnativa, Odoo Community Association (OCA)",
    "website": "https://github.com/OCA/server-backend",
    "license": "AGPL-3",
    "depends": ["account", "base_global_discount"],
    "data": [
        "security/ir.model.access.csv",
        "security/security.xml",
        "views/account_invoice_views.xml",
        "views/global_discount_views.xml",
        "views/report_account_invoice.xml",
    ],
    "application": False,
    "installable": True,
}
<|endoftext|>


<commit_before>#!/usr/bin/env python3

import logging
import os
from os import path

import geojson
import overpass
from geojson import Feature, Polygon

DATA_PATH = path.normpath(path.join(path.dirname(__file__), '..', 'data'))
STATS_PATH = path.join(DATA_PATH, 'stats')
BORDER_PATH = path.join(DATA_PATH, 'borders')
os.makedirs(STATS_PATH, exist_ok=True)
os.makedirs(BORDER_PATH, exist_ok=True)

def pseudo_distance(p1, p2):
    return (p1[0] - p2[0])**2 + (p1[1] - p2[1])**2

def lines_to_polygon(ways):
    if not ways:
        return []

    border = ways.pop(0)
    while ways:
        dist = -1
        closest = 0
        reverse = False
        for i in range(len(ways)):
            d = pseudo_distance(border[-1], ways[i][0])
            if dist > d or i == 0:
                dist = d
                closest = i
                reverse = False
            d = pseudo_distance(border[-1], ways[i][-1])
            if dist > d:
                dist = d
                closest = i
                reverse = True
        n = ways.pop(closest)
        if reverse:
            n.reverse()
        if dist == 0:
            n.pop(0)
        border += n

    return border

def build_municipality_list(department):
    """Build municipality list
    """
    api = overpass.API()
    response = api.Get('''[out:json];
        relation
            [boundary="administrative"]
            [admin_level=8]
            ["ref:INSEE"~"{}..."];
        out geom qt;'''.format(department),
        responseformat="json",
        build=False,
    )

    txt_content = ''
    for relation in response.get('elements'):
        outer_ways = []
        for member in relation.get('members'):
            if member.get('role') == 'outer':
                way = []
                for point in member.get('geometry'):
                    way.append((point.get('lon'), point.get('lat')))
                outer_ways.append(way)

        tags = relation.get('tags')
        insee = tags.get('ref:INSEE')
        name = tags.get('name')
        postcode = tags.get('addr:postcode')

        municipality_border = Feature(
            properties={
                'insee': insee,
                'name': name,
                'postcode': postcode,
                '_storage_options': {
                    'weight': '1',
                    'fillOpacity': '0.5',
                },
            },
        )
        border = lines_to_polygon(outer_ways)
        if not border:
            logging.warning('{} does not have borders'.format(name))
        else:
            municipality_border.geometry = Polygon([border])

        txt_content += '{},{},{}\n'.format(insee, name, postcode)

        # write geojson
        geojson_path = path.join(BORDER_PATH, '{}.geojson'.format(insee))
        with open(geojson_path, 'w') as fd:
            fd.write(geojson.dumps(municipality_border))

    # write txt
    txt_path = path.join(STATS_PATH, '{}-municipality.txt'.format(department))
    with open(txt_path, 'w') as fd:
        fd.write(txt_content)

if __name__ == '__main__':
    build_municipality_list(38)
<commit_msg>osm-cadastre.py: add color support<commit_after>#!/usr/bin/env python3

import sys
import logging
import os
from os import path
import datetime

from colour import Color

import geojson
import overpass
from geojson import Feature, Polygon

DATA_PATH = path.normpath(path.join(path.dirname(__file__), '..', 'data'))
STATS_PATH = path.join(DATA_PATH, 'stats')
BORDER_PATH = path.join(DATA_PATH, 'borders')
os.makedirs(STATS_PATH, exist_ok=True)
os.makedirs(BORDER_PATH, exist_ok=True)

def pseudo_distance(p1, p2):
    return (p1[0] - p2[0])**2 + (p1[1] - p2[1])**2

def lines_to_polygon(ways):
    if not ways:
        return []

    border = ways.pop(0)
    while ways:
        dist = -1
        closest = 0
        reverse = False
        for i in range(len(ways)):
            d = pseudo_distance(border[-1], ways[i][0])
            if dist > d or i == 0:
                dist = d
                closest = i
                reverse = False
            d = pseudo_distance(border[-1], ways[i][-1])
            if dist > d:
                dist = d
                closest = i
                reverse = True
        n = ways.pop(closest)
        if reverse:
            n.reverse()
        if dist == 0:
            n.pop(0)
        border += n

    return border

def color_for_insee(department, insee):
    colors = {
        "RASTER": "Black",
        None: "Gray",
    }

    stats_path = path.join(STATS_PATH, '{}-statistics.csv'.format(department))
    if not os.path.isfile(stats_path):
        logging.warning("{} does not exist, cannot find color for {}".format(stats_path, insee))
        return colors[None]

    with open(stats_path, 'r') as file:
        for line in file:
            fields = [x.strip() for x in line.split("\t")]
            if insee == fields[0]:
                date = fields[5]

                # Retrieve the last cadastre import for the given insee municipality.
                # 2009 and below should be red,
                # current year should be green
                # previous year should be orange
                # below 2009 and previous year, use a color gradient
                this_year = datetime.datetime.now().year
                gradient_colors = list(Color("red").range_to(Color("orange"), this_year - 2009))
                for year in range(2009, this_year):
                    colors[str(year)] = gradient_colors[year - 2009].hex
                colors[str(this_year)] = "Green"

                if date in colors:
                    return colors[date]
                else:
                    logging.warning("Unknown date '{}'! Using gray.".format(date));
                    return "Gray"

    return colors[None]

def build_municipality_list(department):
    """Build municipality list
    """
    api = overpass.API()
    response = api.Get('''[out:json];
        relation
            [boundary="administrative"]
            [admin_level=8]
            ["ref:INSEE"~"{}..."];
        out geom qt;'''.format(department),
        responseformat="json",
        build=False,
    )

    txt_content = ''
    for relation in response.get('elements'):
        outer_ways = []
        for member in relation.get('members'):
            if member.get('role') == 'outer':
                way = []
                for point in member.get('geometry'):
                    way.append((point.get('lon'), point.get('lat')))
                outer_ways.append(way)

        tags = relation.get('tags')
        insee = tags.get('ref:INSEE')
        name = tags.get('name')
        postcode = tags.get('addr:postcode')

        municipality_border = Feature(
            properties={
                'insee': insee,
                'name': name,
                'postcode': postcode,
                '_storage_options': {
                    'color': color_for_insee(department, insee),
                    'weight': '1',
                    'fillOpacity': '0.5',
                },
            },
        )
        border = lines_to_polygon(outer_ways)
        if not border:
            logging.warning('{} does not have borders'.format(name))
        else:
            municipality_border.geometry = Polygon([border])

        txt_content += '{},{},{}\n'.format(insee, name, postcode)

        # write geojson
        geojson_path = path.join(BORDER_PATH, '{}.geojson'.format(insee))
        with open(geojson_path, 'w') as fd:
            fd.write(geojson.dumps(municipality_border))

    # write txt
    txt_path = path.join(STATS_PATH, '{}-municipality.txt'.format(department))
    with open(txt_path, 'w') as fd:
        fd.write(txt_content)

if __name__ == '__main__':
    logging.basicConfig(level=logging.INFO)
    if len(sys.argv) != 2:
        logging.error("Please provide ONE argument: department to treat. Example: {} 26".format(sys.argv[0]))
    else:
        build_municipality_list(sys.argv[1])

<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
#
# This file is part of Invenio.
# Copyright (C) 2015 CERN.
#
# Invenio 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 2 of the
# License, or (at your option) any later version.
#
# Invenio is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Invenio; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307, USA.
#
# In applying this license, CERN does not
# waive the privileges and immunities granted to it by virtue of its status
# as an Intergovernmental Organization or submit itself to any jurisdiction.

"""Record API."""

from flask import current_app
from invenio_db import db
from jsonpatch import apply_patch
from sqlalchemy.orm.exc import NoResultFound
from werkzeug.local import LocalProxy

from .errors import MissingModelError
from .models import RecordMetadata
from .signals import after_record_delete, after_record_insert, \
    after_record_revert, after_record_update, before_record_delete, \
    before_record_insert, before_record_revert, before_record_update

_records_state = LocalProxy(lambda: current_app.extensions['invenio-records'])

class RecordBase(dict):
    """Base class for Record and RecordBase."""

    @property
    def __key_aliases__(self):
        """Return key aliases."""
        return current_app.config.get('RECORDS_KEY_ALIASES', {})

    def __getitem__(self, key):
        """Try to get aliased item on ``KeyError``."""
        try:
            return super(RecordBase, self).__getitem__(key)
        except KeyError:
            if key in self.__key_aliases__:
                if callable(self.__key_aliases__[key]):
                    return self.__key_aliases__[key](self, key)
                else:
                    return super(RecordBase, self).__getitem__(
                        self.__key_aliases__[key]
                    )
            raise

    def __setitem__(self, key, value):
        """Try to set first the aliased item if exists."""
        if key in self.__key_aliases__:
            if callable(self.__key_aliases__[key]):
                raise TypeError('Complex aliases can not be set')
            return super(RecordBase, self).__setitem__(
                self.__key_aliases__[key], value
            )
        return super(RecordBase, self).__setitem__(key, value)

    def __init__(self, data, model=None):
        """Initialize instance with dictionary data and SQLAlchemy model.

        :param data: dict with record metadata
        :param model: :class:`~invenio_records.models.RecordMetadata` instance
        """
        self.model = model
        super(RecordBase, self).__init__(data or {})

    @property
    def id(self):
        """Get model identifier."""
        return self.model.id if self.model else None

    @property
    def revision_id(self):
        """Get revision identifier."""
        return self.model.version_id-1 if self.model else None

    @property
    def created(self):
        """Get creation timestamp."""
        return self.model.created if self.model else None

    @property
    def updated(self):
        """Get last updated timestamp."""
        return self.model.updated if self.model else None

    def validate(self):
        """Validate record according to schema defined in ``$schema`` key."""
        if '$schema' in self:
            return _records_state.validate(self, self['$schema'])
        return True

    def replace_refs(self):
        """Replace the ``$ref`` keys within the JSON."""
        return _records_state.replace_refs(self)

    def dumps(self, **kwargs):
        """Return pure Python dictionary with record metadata."""
        return dict(self)

class Record(RecordBase):
    """Define API for metadata creation and manipulation."""

    @classmethod
    def create(cls, data, id_=None):
        """Create a record instance and store it in database."""
        with db.session.begin_nested():
            record = cls(data)

            before_record_insert.send(record)

            record.validate()

            record.model = RecordMetadata(id=id_, json=record)

            db.session.add(record.model)

        after_record_insert.send(record)
        return record

    @classmethod
    def get_record(cls, id, with_deleted=False):
        """Get record instance.

        Raises database exception if record does not exists.
        """
        with db.session.no_autoflush:
            obj = RecordMetadata.query.filter_by(id=id).one()
            # PostgreSQL JSON type stores None as a JSON value "null", while
            # MySQL and SQLite stores None as a database null value.
            if not with_deleted and obj.json is None:
                raise NoResultFound()
            return cls(obj.json, model=obj)

    def patch(self, patch):
        """Patch record metadata."""
        data = apply_patch(dict(self), patch)
        return self.__class__(data, model=self.model)

    def commit(self):
        """Store changes on current instance in database."""
        if self.model is None or self.model.json is None:
            raise MissingModelError()

        with db.session.begin_nested():
            before_record_update.send(self)

            self.validate()

            self.model.json = dict(self)

            db.session.merge(self.model)

        after_record_update.send(self)
        return self

    def delete(self, force=False):
        """Delete a record.

        If `force` is ``False``, the record is soft-deleted, i.e. the record
        stays in the database. This ensures e.g. that the same record
        identifier cannot be used twice, and that you can still retrieve the
        history of an object. If `force` is True, the record is completely
        removed from the database.

        :param force: Completely remove record from database.
        """
        if self.model is None:
            raise MissingModelError()

        with db.session.begin_nested():
            before_record_delete.send(self)

            if force:
                db.session.delete(self.model)
            else:
                self.model.json = None
                db.session.merge(self.model)

        after_record_delete.send(self)
        return self

    def revert(self, revision_id):
        """Revert to a specific revision."""
        if self.model is None:
            raise MissingModelError()

        revision = self.revisions[revision_id]

        with db.session.begin_nested():
            before_record_revert.send(self)

            self.model.json = dict(revision)

            db.session.merge(self.model)

        after_record_revert.send(self)
        return self.__class__(self.model.json, model=self.model)

    @property
    def revisions(self):
        """Get revision iterator."""
        if self.model is None:
            raise MissingModelError()

        return RevisionsIterator(self.model)

class RecordRevision(RecordBase):
    """API for record revisions."""

    def __init__(self, model):
        """Initialize revision."""
        super(RecordRevision, self).__init__(model.json, model=model)

class RevisionsIterator(object):
    """Iterator for record revisions."""

    def __init__(self, model):
        """Initialize iterator."""
        self._it = None
        self.model = model

    def __len__(self):
        """Get number of revisions."""
        return self.model.versions.count()

    def __iter__(self):
        """Get iterator."""
        self._it = iter(self.model.versions)
        return self

    def next(self):
        """Python 2.7 compatibility."""
        return self.__next__()  # pragma: no cover

    def __next__(self):
        """Get next revision item."""
        return RecordRevision(next(self._it))

    def __getitem__(self, revision_id):
        """Get a specific revision."""
        return RecordRevision(self.model.versions[revision_id])

    def __contains__(self, revision_id):
        """Test if revision exists."""
        try:
            self[revision_id]
            return True
        except IndexError:
            return False
<commit_msg>api: fix global import of models<commit_after># -*- coding: utf-8 -*-
#
# This file is part of Invenio.
# Copyright (C) 2015, 2016 CERN.
#
# Invenio 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 2 of the
# License, or (at your option) any later version.
#
# Invenio is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Invenio; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307, USA.
#
# In applying this license, CERN does not
# waive the privileges and immunities granted to it by virtue of its status
# as an Intergovernmental Organization or submit itself to any jurisdiction.

"""Record API."""

from flask import current_app
from invenio_db import db
from jsonpatch import apply_patch
from sqlalchemy.orm.exc import NoResultFound
from werkzeug.local import LocalProxy

from .errors import MissingModelError
from .signals import after_record_delete, after_record_insert, \
    after_record_revert, after_record_update, before_record_delete, \
    before_record_insert, before_record_revert, before_record_update

_records_state = LocalProxy(lambda: current_app.extensions['invenio-records'])

class RecordBase(dict):
    """Base class for Record and RecordBase."""

    @property
    def __key_aliases__(self):
        """Return key aliases."""
        return current_app.config.get('RECORDS_KEY_ALIASES', {})

    def __getitem__(self, key):
        """Try to get aliased item on ``KeyError``."""
        try:
            return super(RecordBase, self).__getitem__(key)
        except KeyError:
            if key in self.__key_aliases__:
                if callable(self.__key_aliases__[key]):
                    return self.__key_aliases__[key](self, key)
                else:
                    return super(RecordBase, self).__getitem__(
                        self.__key_aliases__[key]
                    )
            raise

    def __setitem__(self, key, value):
        """Try to set first the aliased item if exists."""
        if key in self.__key_aliases__:
            if callable(self.__key_aliases__[key]):
                raise TypeError('Complex aliases can not be set')
            return super(RecordBase, self).__setitem__(
                self.__key_aliases__[key], value
            )
        return super(RecordBase, self).__setitem__(key, value)

    def __init__(self, data, model=None):
        """Initialize instance with dictionary data and SQLAlchemy model.

        :param data: dict with record metadata
        :param model: :class:`~invenio_records.models.RecordMetadata` instance
        """
        self.model = model
        super(RecordBase, self).__init__(data or {})

    @property
    def id(self):
        """Get model identifier."""
        return self.model.id if self.model else None

    @property
    def revision_id(self):
        """Get revision identifier."""
        return self.model.version_id-1 if self.model else None

    @property
    def created(self):
        """Get creation timestamp."""
        return self.model.created if self.model else None

    @property
    def updated(self):
        """Get last updated timestamp."""
        return self.model.updated if self.model else None

    def validate(self):
        """Validate record according to schema defined in ``$schema`` key."""
        if '$schema' in self:
            return _records_state.validate(self, self['$schema'])
        return True

    def replace_refs(self):
        """Replace the ``$ref`` keys within the JSON."""
        return _records_state.replace_refs(self)

    def dumps(self, **kwargs):
        """Return pure Python dictionary with record metadata."""
        return dict(self)

class Record(RecordBase):
    """Define API for metadata creation and manipulation."""

    @classmethod
    def create(cls, data, id_=None):
        """Create a record instance and store it in database."""
        from .models import RecordMetadata
        with db.session.begin_nested():
            record = cls(data)

            before_record_insert.send(record)

            record.validate()

            record.model = RecordMetadata(id=id_, json=record)

            db.session.add(record.model)

        after_record_insert.send(record)
        return record

    @classmethod
    def get_record(cls, id, with_deleted=False):
        """Get record instance.

        Raises database exception if record does not exists.
        """
        from .models import RecordMetadata
        with db.session.no_autoflush:
            obj = RecordMetadata.query.filter_by(id=id).one()
            # PostgreSQL JSON type stores None as a JSON value "null", while
            # MySQL and SQLite stores None as a database null value.
            if not with_deleted and obj.json is None:
                raise NoResultFound()
            return cls(obj.json, model=obj)

    def patch(self, patch):
        """Patch record metadata."""
        data = apply_patch(dict(self), patch)
        return self.__class__(data, model=self.model)

    def commit(self):
        """Store changes on current instance in database."""
        if self.model is None or self.model.json is None:
            raise MissingModelError()

        with db.session.begin_nested():
            before_record_update.send(self)

            self.validate()

            self.model.json = dict(self)

            db.session.merge(self.model)

        after_record_update.send(self)
        return self

    def delete(self, force=False):
        """Delete a record.

        If `force` is ``False``, the record is soft-deleted, i.e. the record
        stays in the database. This ensures e.g. that the same record
        identifier cannot be used twice, and that you can still retrieve the
        history of an object. If `force` is True, the record is completely
        removed from the database.

        :param force: Completely remove record from database.
        """
        if self.model is None:
            raise MissingModelError()

        with db.session.begin_nested():
            before_record_delete.send(self)

            if force:
                db.session.delete(self.model)
            else:
                self.model.json = None
                db.session.merge(self.model)

        after_record_delete.send(self)
        return self

    def revert(self, revision_id):
        """Revert to a specific revision."""
        if self.model is None:
            raise MissingModelError()

        revision = self.revisions[revision_id]

        with db.session.begin_nested():
            before_record_revert.send(self)

            self.model.json = dict(revision)

            db.session.merge(self.model)

        after_record_revert.send(self)
        return self.__class__(self.model.json, model=self.model)

    @property
    def revisions(self):
        """Get revision iterator."""
        if self.model is None:
            raise MissingModelError()

        return RevisionsIterator(self.model)

class RecordRevision(RecordBase):
    """API for record revisions."""

    def __init__(self, model):
        """Initialize revision."""
        super(RecordRevision, self).__init__(model.json, model=model)

class RevisionsIterator(object):
    """Iterator for record revisions."""

    def __init__(self, model):
        """Initialize iterator."""
        self._it = None
        self.model = model

    def __len__(self):
        """Get number of revisions."""
        return self.model.versions.count()

    def __iter__(self):
        """Get iterator."""
        self._it = iter(self.model.versions)
        return self

    def next(self):
        """Python 2.7 compatibility."""
        return self.__next__()  # pragma: no cover

    def __next__(self):
        """Get next revision item."""
        return RecordRevision(next(self._it))

    def __getitem__(self, revision_id):
        """Get a specific revision."""
        return RecordRevision(self.model.versions[revision_id])

    def __contains__(self, revision_id):
        """Test if revision exists."""
        try:
            self[revision_id]
            return True
        except IndexError:
            return False
<|endoftext|>


<commit_before># Copyright (C) 2016, A10 Networks Inc. All rights reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.
from __future__ import absolute_import
from __future__ import unicode_literals

try:
    import unittest
    from unittest import mock
except ImportError:
    import mock
    import unittest2 as unittest

from acos_client.v30 import vlan

class TestVlan(unittest.TestCase):
    def setUp(self):
        self.client = mock.MagicMock()
        self.target = vlan.Vlan(self.client)
        self.url_prefix = "/axapi/v3/network/vlan"
        self.vlan_id = 1
        self.expected_payload = {"vlan": {"vlan-num": self.vlan_id}}

    def test_interface_get_list(self):
        self.target.get_list()
        self.client.http.request.assert_called_with("GET", self.url_prefix, {}, mock.ANY)

    def test_interface_get(self):
        self.target.get(self.vlan_id)
        self.client.http.request.assert_called_with("GET", '{0}/{1}'.format(self.url_prefix,
            self.vlan_id), {}, mock.ANY)

    def test_vlan_create_shared(self):
        self.target.create(self.vlan_id, shared_vlan=True, untagged_eths=[], untagged_trunks=[],
                           tagged_eths=[], tagged_trunks=[], veth=False, lif=None)

        ep = self.expected_payload
        ep['vlan']['shared-vlan'] = True
        self.client.http.request.assert_called_with("POST", self.url_prefix,
                                                    ep, mock.ANY)

    def test_vlan_create_untagged_eths(self):
        untagged_eths = [{'untagged-ethernet-start': 2, 'untagged-ethernet-end': 2}]
        vlan._build_range_list = mock.Mock(return_value={'untagged-eth-list': untagged_eths})
        self.target.create(self.vlan_id, shared_vlan=False, untagged_eths=[2], untagged_trunks=[],
                           tagged_eths=[], tagged_trunks=[], veth=False, lif=None)

        ep = self.expected_payload
        ep['vlan']['untagged-eth-list'] = untagged_eths
        self.client.http.request.assert_called_with("POST", self.url_prefix,
                                                    ep, mock.ANY)

    def test_vlan_create_untagged_trunks(self):
        untagged_trunks = [{'untagged-trunk-start': 2, 'untagged-trunk-end': 2}]
        vlan._build_range_list = mock.Mock(return_value={'untagged-trunk-list': untagged_trunks})
        self.target.create(self.vlan_id, shared_vlan=False, untagged_eths=[],
                           untagged_trunks=[2], tagged_eths=[],
                           tagged_trunks=[], veth=None, lif=None)

        ep = self.expected_payload
        ep['vlan']['untagged-trunk-list'] = untagged_trunks
        self.client.http.request.assert_called_with("POST", self.url_prefix,
                                                    ep, mock.ANY)

    def test_vlan_create_tagged_eths(self):
        tagged_eths = [{'tagged-ethernet-start': 2, 'tagged-ethernet-end': 2}]
        vlan._build_range_list = mock.Mock(return_value={'tagged-eth-list': tagged_eths})
        self.target.create(self.vlan_id, shared_vlan=False, untagged_eths=[], untagged_trunks=[],
                           tagged_eths=[2], tagged_trunks=[], veth=False, lif=None)

        ep = self.expected_payload
        ep['vlan']['tagged-eth-list'] = tagged_eths
        self.client.http.request.assert_called_with("POST", self.url_prefix,
                                                    ep, mock.ANY)

    def test_vlan_create_tagged_trunks(self):
        tagged_trunks = [{'tagged-trunk-start': 2, 'tagged-trunk-end': 2}]
        vlan._build_range_list = mock.Mock(return_value=tagged_trunks)
        self.target.create(self.vlan_id, shared_vlan=False, untagged_eths=[], untagged_trunks=[],
                           tagged_eths=[], tagged_trunks=[2], veth=False, lif=None)

        ep = self.expected_payload
        ep['vlan']['tagged-trunk-list'] = tagged_trunks
        self.client.http.request.assert_called_with("POST", self.url_prefix,
                                                    ep, mock.ANY)

    def test_vlan_create_ve(self):
        self.target.create(self.vlan_id, shared_vlan=False, untagged_eths=[], untagged_trunks=[],
                           tagged_eths=[], tagged_trunks=[], veth=True, lif=None)

        ep = self.expected_payload
        ep['vlan']['ve'] = 1
        self.client.http.request.assert_called_with("POST", self.url_prefix,
                                                    ep, mock.ANY)

    def test_vlan_create_lif(self):
        self.target.create(self.vlan_id, shared_vlan=False, untagged_eths=[], untagged_trunks=[],
                           tagged_eths=[], tagged_trunks=[], veth=False, lif=6)

        ep = self.expected_payload
        ep['vlan']['untagged-lif'] = 6
        self.client.http.request.assert_called_with("POST", self.url_prefix,
                                                    ep, mock.ANY)

    def test_vlan_delete(self):
        self.target.delete(self.vlan_id)
        self.client.http.request.assert_called_with("DELETE", '{0}/{1}'.format(self.url_prefix,self.vlan_id),
                                                    mock.ANY, mock.ANY)

<commit_msg>Quick formatting fix<commit_after># Copyright (C) 2016, A10 Networks Inc. All rights reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.
from __future__ import absolute_import
from __future__ import unicode_literals

try:
    import unittest
    from unittest import mock
except ImportError:
    import mock
    import unittest2 as unittest

from acos_client.v30 import vlan

class TestVlan(unittest.TestCase):
    def setUp(self):
        self.client = mock.MagicMock()
        self.target = vlan.Vlan(self.client)
        self.url_prefix = "/axapi/v3/network/vlan"
        self.vlan_id = 1
        self.expected_payload = {"vlan": {"vlan-num": self.vlan_id}}

    def test_interface_get_list(self):
        self.target.get_list()
        self.client.http.request.assert_called_with("GET", self.url_prefix, {}, mock.ANY)

    def test_interface_get(self):
        self.target.get(self.vlan_id)
        self.client.http.request.assert_called_with("GET", '{0}/{1}'.format(self.url_prefix,
            self.vlan_id), {}, mock.ANY)

    def test_vlan_create_shared(self):
        self.target.create(self.vlan_id, shared_vlan=True, untagged_eths=[], untagged_trunks=[],
                           tagged_eths=[], tagged_trunks=[], veth=False, lif=None)

        ep = self.expected_payload
        ep['vlan']['shared-vlan'] = True
        self.client.http.request.assert_called_with("POST", self.url_prefix,
                                                    ep, mock.ANY)

    def test_vlan_create_untagged_eths(self):
        untagged_eths = [{'untagged-ethernet-start': 2, 'untagged-ethernet-end': 2}]
        vlan._build_range_list = mock.Mock(return_value={'untagged-eth-list': untagged_eths})
        self.target.create(self.vlan_id, shared_vlan=False, untagged_eths=[2], untagged_trunks=[],
                           tagged_eths=[], tagged_trunks=[], veth=False, lif=None)

        ep = self.expected_payload
        ep['vlan']['untagged-eth-list'] = untagged_eths
        self.client.http.request.assert_called_with("POST", self.url_prefix,
                                                    ep, mock.ANY)

    def test_vlan_create_untagged_trunks(self):
        untagged_trunks = [{'untagged-trunk-start': 2, 'untagged-trunk-end': 2}]
        vlan._build_range_list = mock.Mock(return_value={'untagged-trunk-list': untagged_trunks})
        self.target.create(self.vlan_id, shared_vlan=False, untagged_eths=[],
                           untagged_trunks=[2], tagged_eths=[],
                           tagged_trunks=[], veth=None, lif=None)

        ep = self.expected_payload
        ep['vlan']['untagged-trunk-list'] = untagged_trunks
        self.client.http.request.assert_called_with("POST", self.url_prefix,
                                                    ep, mock.ANY)

    def test_vlan_create_tagged_eths(self):
        tagged_eths = [{'tagged-ethernet-start': 2, 'tagged-ethernet-end': 2}]
        vlan._build_range_list = mock.Mock(return_value={'tagged-eth-list': tagged_eths})
        self.target.create(self.vlan_id, shared_vlan=False, untagged_eths=[], untagged_trunks=[],
                           tagged_eths=[2], tagged_trunks=[], veth=False, lif=None)

        ep = self.expected_payload
        ep['vlan']['tagged-eth-list'] = tagged_eths
        self.client.http.request.assert_called_with("POST", self.url_prefix,
                                                    ep, mock.ANY)

    def test_vlan_create_tagged_trunks(self):
        tagged_trunks = [{'tagged-trunk-start': 2, 'tagged-trunk-end': 2}]
        vlan._build_range_list = mock.Mock(return_value=tagged_trunks)
        self.target.create(self.vlan_id, shared_vlan=False, untagged_eths=[], untagged_trunks=[],
                           tagged_eths=[], tagged_trunks=[2], veth=False, lif=None)

        ep = self.expected_payload
        ep['vlan']['tagged-trunk-list'] = tagged_trunks
        self.client.http.request.assert_called_with("POST", self.url_prefix,
                                                    ep, mock.ANY)

    def test_vlan_create_ve(self):
        self.target.create(self.vlan_id, shared_vlan=False, untagged_eths=[], untagged_trunks=[],
                           tagged_eths=[], tagged_trunks=[], veth=True, lif=None)

        ep = self.expected_payload
        ep['vlan']['ve'] = 1
        self.client.http.request.assert_called_with("POST", self.url_prefix,
                                                    ep, mock.ANY)

    def test_vlan_create_lif(self):
        self.target.create(self.vlan_id, shared_vlan=False, untagged_eths=[], untagged_trunks=[],
                           tagged_eths=[], tagged_trunks=[], veth=False, lif=6)

        ep = self.expected_payload
        ep['vlan']['untagged-lif'] = 6
        self.client.http.request.assert_called_with("POST", self.url_prefix,
                                                    ep, mock.ANY)

    def test_vlan_delete(self):
        self.target.delete(self.vlan_id)
        self.client.http.request.assert_called_with("DELETE",
            '{0}/{1}'.format(self.url_prefix,self.vlan_id), mock.ANY, mock.ANY)

<|endoftext|>