Exemple #1
0
class SaleOrder(Model):
    _inherit = 'sale.order'

    def _amount_all(self, cursor, user, ids, field_name, arg, context=None):
        '''Calculate the markup rate based on sums'''

        if context is None:
            context = {}
        res = {}
        res = super(SaleOrder, self)._amount_all(cursor, user, ids, field_name,
                                                 arg, context)

        for sale_order in self.browse(cursor, user, ids):
            cost_sum = 0.0
            sale_sum = 0.0
            for line in sale_order.order_line:
                cost_sum += line.cost_price
                sale_sum += line.price_unit * (100 - line.discount) / 100.0
            res[sale_order.id]['markup_rate'] = sale_sum and (
                sale_sum - cost_sum) / sale_sum * 100 or 0.0
        return res

    def _get_order(self, cr, uid, ids, context=None):
        if context is None:
            context = {}
        result = set()
        for line in self.pool.get('sale.order.line').browse(cr,
                                                            uid,
                                                            ids,
                                                            context=context):
            result.add(line.order_id.id)
        return list(result)

    _store_sums = {
        'sale.order':
        (lambda self, cr, uid, ids, c={}: ids, ['order_line'], 10),
        'sale.order.line': (_get_order, [
            'price_unit', 'tax_id', 'discount', 'product_uom_qty',
            'product_id', 'commercial_margin', 'markup_rate'
        ], 10)
    }

    _columns = {
        'markup_rate':
        fields.function(_amount_all,
                        method=True,
                        string='Markup Rate',
                        digits_compute=dp.get_precision('Sale Price'),
                        store=_store_sums,
                        multi='sums')
    }
class product_product(Model):
    _inherit = "product.product"

    def _compute_configurable_level(self,
                                    cursor,
                                    uid,
                                    pids,
                                    field_name,
                                    args,
                                    context=None):
        """We compute a custom stock level"""
        # we do not override _product_available once agin to avoid MRO troubles
        conf_obj = self.pool.get('stock.level.configuration')
        prod_obj = self.pool.get('product.product')
        conf_list = []
        conf_ids = conf_obj.search(cursor, uid, [])
        for conf in conf_obj.browse(cursor, uid, conf_ids):
            conf_list.append(
                (conf.stock_location_id.id, conf.product_field.name))
        if not isinstance(pids, list):
            pids = [pids]
        res = dict.fromkeys(pids, 0.0)
        for conf in conf_list:
            local_context = context.copy()
            local_context['location'] = [conf[0]]
            interm = prod_obj._product_available(cursor,
                                                 uid,
                                                 pids,
                                                 field_names=[conf[1]],
                                                 arg=False,
                                                 context=local_context)
            for key, val in interm.items():
                res.setdefault(
                    key, 0.0)  # this should not be usefull but we never know
                res[key] += val.get(conf[1], 0.0)
        return res

    _columns = {
        'configurable_stock_level':
        fields.function(_compute_configurable_level,
                        type='float',
                        digits_compute=dp.get_precision('Product UoM'),
                        string='Custom level')
    }
Exemple #3
0
class AccountInvoice(Model):
    """Inherit account.invoice in order to add bvr
    printing functionnalites. BVR is a Swiss payment vector"""
    _inherit = "account.invoice"

    _compile_get_ref = re.compile('[^0-9]')

    def _get_reference_type(self, cursor, user, context=None):
        """Function use by the function field reference_type in order to initalise available
        BVR Reference Types"""
        res = super(AccountInvoice, self)._get_reference_type(cursor,
                                                              user,
                                                              context=context)
        res.append(('bvr', 'BVR'))
        return res

    def _compute_full_bvr_name(self,
                               cursor,
                               uid,
                               ids,
                               field_names,
                               arg,
                               context=None):
        res = {}
        move_line_obj = self.pool.get('account.move.line')
        account_obj = self.pool.get('account.account')
        tier_account_id = account_obj.search(
            cursor, uid, [('type', 'in', ['receivable', 'payable'])])
        for inv in self.browse(cursor, uid, ids, context=context):
            move_lines = move_line_obj.search(
                cursor, uid, [('move_id', '=', inv.move_id.id),
                              ('account_id', 'in', tier_account_id)])
            if move_lines:
                if len(move_lines) == 1:
                    res[inv.id] = self._space(inv.get_bvr_ref())
                else:
                    refs = []
                    for move_line in move_line_obj.browse(cursor,
                                                          uid,
                                                          move_lines,
                                                          context=context):
                        refs.append(self._space(move_line.get_bvr_ref()))
                    res[inv.id] = ' ; '.join(refs)
        return res

    _columns = {
        ### BVR reference type BVR or FREE
        'reference_type':
        fields.selection(_get_reference_type, 'Reference Type', required=True),
        ### Partner bank link between bank and partner id
        'partner_bank_id':
        fields.many2one(
            'res.partner.bank',
            'Bank Account',
            help=
            'The partner bank account to pay\nKeep empty to use the default'),
        'bvr_reference':
        fields.function(_compute_full_bvr_name,
                        type="char",
                        size=512,
                        string="BVR REF.",
                        store=True,
                        readonly=True)
    }

    def get_bvr_ref(self, cursor, uid, inv_id, context=None):
        """Retrieve ESR/BVR reference form invoice in order to print it"""
        res = ''
        if isinstance(inv_id, list):
            inv_id = inv_id[0]
        inv = self.browse(cursor, uid, inv_id, context=context)
        ## We check if the type is bvr, if not we return false
        if inv.partner_bank_id.state != 'bvr':
            return ''
        ##
        if inv.partner_bank_id.bvr_adherent_num:
            res = inv.partner_bank_id.bvr_adherent_num
        invoice_number = ''
        if inv.number:
            invoice_number = self._compile_get_ref.sub('', inv.number)
        return mod10r(res + invoice_number.rjust(26 - len(res), '0'))

    def _space(self, nbr, nbrspc=5):
        """Spaces * 5.

        Example:
            self._space('123456789012345')
            '12 34567 89012 345'
        """
        return ''.join([' '[(i - 2) % nbrspc:] + c for i, c in enumerate(nbr)])

    def _update_ref_on_account_analytic_line(self,
                                             cr,
                                             uid,
                                             ref,
                                             move_id,
                                             context=None):
        cr.execute(
            'UPDATE account_analytic_line SET ref=%s'
            '   FROM account_move_line '
            ' WHERE account_move_line.move_id = %s '
            '   AND account_analytic_line.move_id = account_move_line.id',
            (ref, move_id))
        return True

    def action_number(self, cr, uid, ids, context=None):
        res = super(AccountInvoice, self).action_number(cr,
                                                        uid,
                                                        ids,
                                                        context=context)
        move_line_obj = self.pool.get('account.move.line')
        account_obj = self.pool.get('account.account')
        tier_account_id = account_obj.search(
            cr, uid, [('type', 'in', ['receivable', 'payable'])])

        for inv in self.browse(cr, uid, ids, context=context):
            if inv.type != 'out_invoice' and inv.partner_bank_id.state != 'bvr':
                continue
            move_lines = move_line_obj.search(
                cr, uid, [('move_id', '=', inv.move_id.id),
                          ('account_id', 'in', tier_account_id)])
            # We keep this branch for compatibility with single BVR report.
            # This should be cleaned when porting to V8
            if move_lines:
                if len(move_lines) == 1:
                    ref = inv.get_bvr_ref()
                    move_id = inv.move_id
                    if move_id:
                        cr.execute(
                            'UPDATE account_move_line SET transaction_ref=%s'
                            '  WHERE move_id=%s', (ref, move_id.id))
                        self._update_ref_on_account_analytic_line(
                            cr, uid, ref, move_id.id)
                else:
                    for move_line in move_line_obj.browse(cr,
                                                          uid,
                                                          move_lines,
                                                          context=context):
                        ref = move_line.get_bvr_ref()
                        if ref:
                            cr.execute(
                                'UPDATE account_move_line SET transaction_ref=%s'
                                '  WHERE id=%s', (ref, move_line.id))
                            self._update_ref_on_account_analytic_line(
                                cr, uid, ref, move_line.move_id.id)
        return res

    def copy(self, cursor, uid, inv_id, default=None, context=None):
        default = default or {}
        default.update({'reference': False})
        return super(AccountInvoice, self).copy(cursor, uid, inv_id, default,
                                                context)
Exemple #4
0
class AccountInvoice(Model):
    """Inherit account.invoice in order to add bvr
    printing functionnalites. BVR is a Swiss payment vector"""
    _inherit = "account.invoice"

    _compile_get_ref = re.compile('[^0-9]')

    def _get_reference_type(self, cr, user, context=None):
        """Function used by the function field 'reference_type'
        in order to initalise available BVR Reference Types
        """
        res = super(AccountInvoice, self)._get_reference_type(cr,
                                                              user,
                                                              context=context)
        res.append(('bvr', 'BVR'))
        return res

    def _compute_full_bvr_name(self,
                               cr,
                               uid,
                               ids,
                               field_names,
                               arg,
                               context=None):
        res = {}
        move_line_obj = self.pool.get('account.move.line')
        account_obj = self.pool.get('account.account')
        tier_account_id = account_obj.search(
            cr,
            uid, [('type', 'in', ['receivable', 'payable'])],
            context=context)
        for inv in self.browse(cr, uid, ids, context=context):
            move_lines = move_line_obj.search(
                cr,
                uid, [('move_id', '=', inv.move_id.id),
                      ('account_id', 'in', tier_account_id)],
                context=context)
            if move_lines:
                refs = []
                for move_line in move_line_obj.browse(cr,
                                                      uid,
                                                      move_lines,
                                                      context=context):
                    refs.append(AccountInvoice._space(move_line.get_bvr_ref()))
                res[inv.id] = ' ; '.join(refs)
        return res

    _columns = {
        # BVR reference type BVR or FREE
        'reference_type':
        fields.selection(_get_reference_type, 'Reference Type', required=True),

        # Partner bank link between bank and partner id
        'partner_bank_id':
        fields.many2one('res.partner.bank',
                        'Bank Account',
                        help='The partner bank account to pay\n'
                        'Keep empty to use the default'),
        'bvr_reference':
        fields.function(_compute_full_bvr_name,
                        type="char",
                        size=512,
                        string="BVR REF.",
                        store=True,
                        readonly=True)
    }

    @staticmethod
    def _space(nbr, nbrspc=5):
        """Spaces * 5.

        Example:
            AccountInvoice._space('123456789012345')
            '12 34567 89012 345'
        """
        return ''.join([' '[(i - 2) % nbrspc:] + c for i, c in enumerate(nbr)])

    def _update_ref_on_account_analytic_line(self,
                                             cr,
                                             uid,
                                             ref,
                                             move_id,
                                             context=None):
        """Propagate reference on analytic line"""
        cr.execute(
            'UPDATE account_analytic_line SET ref=%s'
            '   FROM account_move_line '
            ' WHERE account_move_line.move_id = %s '
            '   AND account_analytic_line.move_id = account_move_line.id',
            (ref, move_id))
        return True

    def _action_bvr_number_move_line(self,
                                     cr,
                                     uid,
                                     invoice,
                                     move_line,
                                     ref,
                                     context=None):
        """Propagate reference on move lines and analytic lines"""
        if not ref:
            return
        cr.execute(
            'UPDATE account_move_line SET transaction_ref=%s'
            '  WHERE id=%s', (ref, move_line.id))
        self._update_ref_on_account_analytic_line(cr, uid, ref,
                                                  move_line.move_id.id)

    def action_number(self, cr, uid, ids, context=None):
        """ Copy the BVR/ESR reference in the transaction_ref of move lines.

        For customers invoices: the BVR reference is computed using
        ``get_bvr_ref()`` on the invoice or move lines.

        For suppliers invoices: the BVR reference is stored in the reference
        field of the invoice.

        """
        res = super(AccountInvoice, self).action_number(cr,
                                                        uid,
                                                        ids,
                                                        context=context)
        move_line_obj = self.pool.get('account.move.line')

        for inv in self.browse(cr, uid, ids, context=context):
            move_line_ids = move_line_obj.search(
                cr,
                uid, [('move_id', '=', inv.move_id.id),
                      ('account_id', '=', inv.account_id.id)],
                context=context)
            if not move_line_ids:
                continue
            move_lines = move_line_obj.browse(cr,
                                              uid,
                                              move_line_ids,
                                              context=context)
            for move_line in move_lines:
                if inv.type in ('out_invoice', 'out_refund'):
                    ref = move_line.get_bvr_ref()
                elif inv.reference_type == 'bvr' and inv.reference:
                    ref = inv.reference
                else:
                    ref = False
                self._action_bvr_number_move_line(cr,
                                                  uid,
                                                  inv,
                                                  move_line,
                                                  ref,
                                                  context=context)
        return res

    def copy(self, cr, uid, inv_id, default=None, context=None):
        default = default or {}
        default.update({'reference': False})
        return super(AccountInvoice, self).copy(cr, uid, inv_id, default,
                                                context)
Exemple #5
0
class ResPartner(Model):
    """Adds lastname and firstname, name become a stored function field"""

    _inherit = 'res.partner'

    def init(self, cursor):
        cursor.execute(
            'SELECT id FROM res_partner WHERE lastname IS NOT NULL Limit 1')
        if not cursor.fetchone():
            cursor.execute(
                'UPDATE res_partner set lastname = name WHERE name IS NOT NULL'
            )
            # Create Sql constraint if table is not empty
            cursor.execute('SELECT id FROM res_partner Limit 1')
            if cursor.fetchone():
                cursor.execute(
                    'ALTER TABLE res_partner ALTER COLUMN lastname SET NOT NULL'
                )

    def _prepare_name_custom(self, cursor, uid, partner, context=None):
        """
        This function is designed to be inherited in a custom module
        """
        names = (partner.lastname, partner.firstname)
        fullname = " ".join([s for s in names if s])
        return fullname

    def _compute_name_custom(self, cursor, uid, ids, fname, arg, context=None):
        res = {}
        for partner in self.browse(cursor, uid, ids, context=context):
            res[partner.id] = self._prepare_name_custom(cursor,
                                                        uid,
                                                        partner,
                                                        context=context)
        return res

    def _write_name(self,
                    cursor,
                    uid,
                    partner_id,
                    field_name,
                    field_value,
                    arg,
                    context=None):
        """
        Try to reverse the effect of _compute_name_custom:
        * if the partner is not a company and the firstname does not change in the new name
          then firstname remains untouched and lastname is updated accordingly
        * otherwise lastname=new name and firstname=False
        In addition an heuristic avoids to keep a firstname without a non-blank lastname
        """
        field_value = field_value and not field_value.isspace(
        ) and field_value or False
        vals = {'lastname': field_value, 'firstname': False}
        if field_value:
            flds = self.read(cursor,
                             uid, [partner_id], ['firstname', 'is_company'],
                             context=context)[0]
            if not flds['is_company']:
                to_check = ' %s' % flds['firstname']
                if field_value.endswith(to_check):
                    ln = field_value[:-len(to_check)].strip()
                    if ln:
                        vals['lastname'] = ln
                        del (vals['firstname'])
                    else:
                        # If the lastname is deleted from the new name
                        # then the firstname becomes the lastname
                        vals['lastname'] = flds['firstname']

        return self.write(cursor, uid, partner_id, vals, context=context)

    def copy_data(self, cr, uid, _id, default=None, context=None):
        """
        Avoid to replicate the firstname into the name when duplicating a partner
        """
        default = default or {}
        if not default.get('lastname'):
            default = default.copy()
            default['lastname'] = _('%s (copy)') % self.read(
                cr, uid, [_id], ['lastname'], context=context)[0]['lastname']
            if default.get('name'):
                del (default['name'])
        return super(ResPartner, self).copy_data(cr,
                                                 uid,
                                                 _id,
                                                 default,
                                                 context=context)

    def create(self, cursor, uid, vals, context=None):
        """
        To support data backward compatibility we have to keep this overwrite even if we
        use fnct_inv: otherwise we can't create entry because lastname is mandatory and module
        will not install if there is demo data
        """
        to_use = vals
        if 'name' in vals:
            corr_vals = vals.copy()
            corr_vals['lastname'] = corr_vals['name']
            del (corr_vals['name'])
            to_use = corr_vals
        return super(ResPartner, self).create(cursor,
                                              uid,
                                              to_use,
                                              context=context)

    _columns = {
        'name':
        fields.function(_compute_name_custom,
                        string="Name",
                        type="char",
                        store=True,
                        select=True,
                        readonly=True,
                        fnct_inv=_write_name),
        'firstname':
        fields.char("Firstname"),
        'lastname':
        fields.char("Lastname", required=True)
    }