Пример #1
0
    def write(self, vals):
        for journal in self:
            if ('company_id' in vals and journal.company_id.id != vals['company_id']):
                if self.env['account.move'].search([('journal_id', 'in', self.ids)], limit=1):
                    raise UserError(_('This journal already contains items, therefore you cannot modify its company.'))
            if ('code' in vals and journal.code != vals['code']):
                if self.env['account.move'].search([('journal_id', 'in', self.ids)], limit=1):
                    raise UserError(_('This journal already contains items, therefore you cannot modify its short name.'))
                new_prefix = self._get_sequence_prefix(vals['code'], refund=False)
                journal.sequence_id.write({'prefix': new_prefix})
                if journal.refund_sequence_id:
                    new_prefix = self._get_sequence_prefix(vals['code'], refund=True)
                    journal.refund_sequence_id.write({'prefix': new_prefix})
            if 'currency_id' in vals:
                if not 'default_debit_account_id' in vals and self.default_debit_account_id:
                    self.default_debit_account_id.currency_id = vals['currency_id']
                if not 'default_credit_account_id' in vals and self.default_credit_account_id:
                    self.default_credit_account_id.currency_id = vals['currency_id']
        result = super(AccountJournal, self).write(vals)

        # Create the bank_account_id if necessary
        if 'bank_acc_number' in vals:
            for journal in self.filtered(lambda r: r.type == 'bank' and not r.bank_account_id):
                journal.set_bank_account(vals.get('bank_acc_number'), vals.get('bank_id'))

        return result
Пример #2
0
    def write(self, vals):
        if 'content' in vals:
            vals['content'] = self._update_content(vals['content'], self.forum_id.id)
        if 'state' in vals:
            if vals['state'] in ['active', 'close'] and any(not post.can_close for post in self):
                raise KarmaError('Not enough karma to close or reopen a post.')
        if 'active' in vals:
            if any(not post.can_unlink for post in self):
                raise KarmaError('Not enough karma to delete or reactivate a post')
        if 'is_correct' in vals:
            if any(not post.can_accept for post in self):
                raise KarmaError('Not enough karma to accept or refuse an answer')
            # update karma except for self-acceptance
            mult = 1 if vals['is_correct'] else -1
            for post in self:
                if vals['is_correct'] != post.is_correct and post.create_uid.id != self._uid:
                    post.create_uid.sudo().add_karma(post.forum_id.karma_gen_answer_accepted * mult)
                    self.env.user.sudo().add_karma(post.forum_id.karma_gen_answer_accept * mult)
        if any(key not in ['state', 'active', 'is_correct', 'closed_uid', 'closed_date', 'closed_reason_id'] for key in vals.keys()) and any(not post.can_edit for post in self):
            raise KarmaError('Not enough karma to edit a post.')

        res = super(Post, self).write(vals)
        # if post content modify, notify followers
        if 'content' in vals or 'name' in vals:
            for post in self:
                if post.parent_id:
                    body, subtype = _('Answer Edited'), 'website_forum.mt_answer_edit'
                    obj_id = post.parent_id
                else:
                    body, subtype = _('Question Edited'), 'website_forum.mt_question_edit'
                    obj_id = post
                obj_id.message_post(body=body, subtype=subtype)
        return res
Пример #3
0
    def print_checks(self):
        """ Check that the recordset is valid, set the payments state to sent and call print_checks() """
        # Since this method can be called via a client_action_multi, we need to make sure the received records are what we expect
        self = self.filtered(lambda r: r.payment_method_id.code == 'check_printing' and r.state != 'reconciled')

        if len(self) == 0:
            raise UserError(_("Payments to print as a checks must have 'Check' selected as payment method and "
                              "not have already been reconciled"))
        if any(payment.journal_id != self[0].journal_id for payment in self):
            raise UserError(_("In order to print multiple checks at once, they must belong to the same bank journal."))

        self.filtered(lambda r: r.state == 'draft').post()
        self.write({'state': 'sent'})

        if not self[0].journal_id.check_manual_sequencing:
            # The wizard asks for the number printed on the first pre-printed check
            # so payments are attributed the number of the check the'll be printed on.
            last_printed_check = self.search([
                ('journal_id', '=', self[0].journal_id.id),
                ('check_number', '!=', 0)], order="check_number desc", limit=1)
            next_check_number = last_printed_check and last_printed_check.check_number + 1 or 1
            return {
                'name': _('Print Pre-numbered Checks'),
                'type': 'ir.actions.act_window',
                'res_model': 'print.prenumbered.checks',
                'view_type': 'form',
                'view_mode': 'form',
                'target': 'new',
                'context': {
                    'payment_ids': self.ids,
                    'default_next_check_number': next_check_number,
                }
            }
        else:
            return self.do_print_checks()
Пример #4
0
 def launch_action(self, cr, uid, ids, context=None):
     res = {}
     for rec in self.browse(cr, uid, ids, context):
         if rec.action:
             if rec.action._name == 'ir.actions.act_window':
                 ids_to_launch = self.pool.get(rec.action.res_model).search(cr, uid, [])
                 res = {
                 'domain': "[('id','in', ["+','.join(map(str,ids_to_launch))+"])]",
                 'name': rec.name,
                 'view_type': 'form',
                 'view_mode': 'tree,form',
                 'res_model': rec.action.res_model,
                 'view_id': False,
                 'type': 'ir.actions.act_window'
                 }
             else:
                 raise except_orm(
                     _('Error!'),
                     _('Este Menu no contiene una Accion de Ventana.')
                     )
         else:
             raise except_orm(
                 _('Error!'),
                 _('Este Menu no contiene una Accion de Ventana.')
                 )
     return res
Пример #5
0
 def _get_counterpart_move_line_vals(self, invoice=False):
     if self.payment_type == 'transfer':
         name = self.name
     else:
         name = ''
         if self.partner_type == 'customer':
             if self.payment_type == 'inbound':
                 name += _("Customer Payment")
             elif self.payment_type == 'outbound':
                 name += _("Customer Refund")
         elif self.partner_type == 'supplier':
             if self.payment_type == 'inbound':
                 name += _("Vendor Refund")
             elif self.payment_type == 'outbound':
                 name += _("Vendor Payment")
         if invoice:
             name += ': '
             for inv in invoice:
                 name += inv.number + ', '
             name = name[:len(name) - 2]
     return {
         'name':
         name,
         'account_id':
         self.destination_account_id.id,
         'journal_id':
         self.journal_id.id,
         'currency_id':
         self.currency_id != self.company_id.currency_id
         and self.currency_id.id or False,
         'payment_id':
         self.id,
     }
Пример #6
0
    def delivery_set(self):

        # Remove delivery products from the sale order
        self._delivery_unset()

        for order in self:
            carrier = order.carrier_id
            if carrier:
                if order.state not in ('draft', 'sent'):
                    raise UserError(_('The order state have to be draft to add delivery lines.'))

                if carrier.delivery_type not in ['fixed', 'base_on_rule']:
                    # Shipping providers are used when delivery_type is other than 'fixed' or 'base_on_rule'
                    price_unit = order.carrier_id.get_shipping_price_from_so(order)[0]
                else:
                    # Classic grid-based carriers
                    carrier = order.carrier_id.verify_carrier(order.partner_shipping_id)
                    if not carrier:
                        raise UserError(_('No carrier matching.'))
                    price_unit = carrier.get_price_available(order)
                    if order.company_id.currency_id.id != order.pricelist_id.currency_id.id:
                        price_unit = order.company_id.currency_id.with_context(date=order.date_order).compute(price_unit, order.pricelist_id.currency_id)

                order._create_delivery_line(carrier, price_unit)

            else:
                raise UserError(_('No carrier set for this order.'))
Пример #7
0
    def delivery_set(self):

        # Remove delivery products from the sale order
        self._delivery_unset()

        for order in self:
            carrier = order.carrier_id
            if carrier:
                if order.state not in ('draft', 'sent'):
                    raise UserError(
                        _('The order state have to be draft to add delivery lines.'
                          ))

                if carrier.delivery_type not in ['fixed', 'base_on_rule']:
                    # Shipping providers are used when delivery_type is other than 'fixed' or 'base_on_rule'
                    price_unit = order.carrier_id.get_shipping_price_from_so(
                        order)[0]
                else:
                    # Classic grid-based carriers
                    carrier = order.carrier_id.verify_carrier(
                        order.partner_shipping_id)
                    if not carrier:
                        raise UserError(_('No carrier matching.'))
                    price_unit = carrier.get_price_available(order)
                    if order.company_id.currency_id.id != order.pricelist_id.currency_id.id:
                        price_unit = order.company_id.currency_id.with_context(
                            date=order.date_order).compute(
                                price_unit, order.pricelist_id.currency_id)

                order._create_delivery_line(carrier, price_unit)

            else:
                raise UserError(_('No carrier set for this order.'))
Пример #8
0
 def open_map(self):
     self.ensure_one()
     map_website = self.env.user.context_map_website_id
     if not map_website:
         raise UserError(
             _('Missing map provider: '
               'you should set it in your preferences.'))
     if (map_website.lat_lon_url and hasattr(self, 'partner_latitude')
             and self.partner_latitude and self.partner_longitude):
         url = self._prepare_url(
             map_website.lat_lon_url, {
                 '{LATITUDE}': self.partner_latitude,
                 '{LONGITUDE}': self.partner_longitude
             })
     else:
         if not map_website.address_url:
             raise UserError(
                 _("Missing parameter 'URL that uses the address' "
                   "for map website '%s'.") % map_website.name)
         url = self._prepare_url(map_website.address_url,
                                 {'{ADDRESS}': self._address_as_string()})
     return {
         'type': 'ir.actions.act_url',
         'url': url,
         'target': 'new',
     }
Пример #9
0
 def _get_counterpart_move_line_vals(self, invoice=False):
     if self.payment_type == 'transfer':
         name = self.name
     else:
         name = ''
         if self.partner_type == 'customer':
             if self.payment_type == 'inbound':
                 name += _("Customer Payment")
             elif self.payment_type == 'outbound':
                 name += _("Customer Refund")
         elif self.partner_type == 'supplier':
             if self.payment_type == 'inbound':
                 name += _("Vendor Refund")
             elif self.payment_type == 'outbound':
                 name += _("Vendor Payment")
         if invoice:
             name += ': '
             for inv in invoice:
                 name += inv.number+', '
             name = name[:len(name)-2] 
     return {
         'name': name,
         'account_id': self.destination_account_id.id,
         'journal_id': self.journal_id.id,
         'currency_id': self.currency_id != self.company_id.currency_id and self.currency_id.id or False,
         'payment_id': self.id,
     }
Пример #10
0
 def post_notification(self):
     base_url = self.env['ir.config_parameter'].get_param('web.base.url')
     for post in self:
         if post.state == 'active' and post.parent_id:
             body = _(
                 '<p>A new answer for <i>%s</i> has been posted. <a href="%s/forum/%s/question/%s">Click here to access the post.</a></p>' %
                 (post.parent_id.name, base_url, slug(post.parent_id.forum_id), slug(post.parent_id))
             )
             post.parent_id.message_post(subject=_('Re: %s') % post.parent_id.name, body=body, subtype='website_forum.mt_answer_new')
         elif post.state == 'active' and not post.parent_id:
             body = _(
                 '<p>A new question <i>%s</i> has been asked on %s. <a href="%s/forum/%s/question/%s">Click here to access the question.</a></p>' %
                 (post.name, post.forum_id.name, base_url, slug(post.forum_id), slug(post))
             )
             post.message_post(subject=post.name, body=body, subtype='website_forum.mt_question_new')
         elif post.state == 'pending' and not post.parent_id:
             # TDE FIXME: in master, you should probably use a subtype;
             # however here we remove subtype but set partner_ids
             partners = post.sudo().message_partner_ids.filtered(lambda partner: partner.user_ids and partner.user_ids.karma >= post.forum_id.karma_moderate)
             note_subtype = self.sudo().env.ref('mail.mt_note')
             body = _(
                 '<p>A new question <i>%s</i> has been asked on %s and require your validation. <a href="%s/forum/%s/question/%s">Click here to access the question.</a></p>' %
                 (post.name, post.forum_id.name, base_url, slug(post.forum_id), slug(post))
             )
             post.message_post(subject=post.name, body=body, subtype_id=note_subtype.id, partner_ids=partners.ids)
     return True
    def _print_report(self, data):
        res = {}
        data = self.pre_print_report(data)
        data['form'].update(self.read(['period_length'])[0])
        period_length = data['form']['period_length']
        if period_length <= 0:
            raise UserError(_('You must set a period length greater than 0.'))
        if not data['form']['date_from']:
            raise UserError(_('You must set a start date.'))

        start = datetime.strptime(data['form']['date_from'], "%Y-%m-%d")

        for i in range(5)[::-1]:
            stop = start - relativedelta(days=period_length)
            res[str(i)] = {
                'name': (i != 0 and (str(
                    (5 - (i + 1)) * period_length) + '-' + str(
                        (5 - i) * period_length))
                         or ('+' + str(4 * period_length))),
                'stop':
                start.strftime('%Y-%m-%d'),
                'start': (i != 0 and stop.strftime('%Y-%m-%d') or False),
            }
            start = stop - relativedelta(days=1)
        data['form'].update(res)
        return self.env['report'].with_context(landscape=True).get_action(
            self, 'account.report_agedpartnerbalance', data=data)
Пример #12
0
 def unlink(self):
     for asset in self:
         if asset.state in ['open', 'close']:
             raise UserError(_('You cannot delete a document is in %s state.') % (asset.state,))
         if asset.account_move_ids:
             raise UserError(_('You cannot delete a document that contains posted entries.'))
     return super(AccountAssetAsset, self).unlink()
Пример #13
0
 def launch_action(self, cr, uid, ids, context=None):
     res = {}
     for rec in self.browse(cr, uid, ids, context):
         if rec.action:
             if rec.action._name == 'ir.actions.act_window':
                 ids_to_launch = self.pool.get(rec.action.res_model).search(
                     cr, uid, [])
                 res = {
                     'domain':
                     "[('id','in', [" + ','.join(map(str, ids_to_launch)) +
                     "])]",
                     'name':
                     rec.name,
                     'view_type':
                     'form',
                     'view_mode':
                     'tree,form',
                     'res_model':
                     rec.action.res_model,
                     'view_id':
                     False,
                     'type':
                     'ir.actions.act_window'
                 }
             else:
                 raise except_orm(
                     _('Error!'),
                     _('Este Menu no contiene una Accion de Ventana.'))
         else:
             raise except_orm(
                 _('Error!'),
                 _('Este Menu no contiene una Accion de Ventana.'))
     return res
    def _balance_check(self):
        for stmt in self:
            if not stmt.currency_id.is_zero(stmt.difference):
                if stmt.journal_type == 'cash':
                    if stmt.difference < 0.0:
                        account = stmt.journal_id.loss_account_id
                        name = _('Loss')
                    else:
                        # statement.difference > 0.0
                        account = stmt.journal_id.profit_account_id
                        name = _('Profit')
                    if not account:
                        raise UserError(_('There is no account defined on the journal %s for %s involved in a cash difference.') % (stmt.journal_id.name, name))

                    values = {
                        'statement_id': stmt.id,
                        'account_id': account.id,
                        'amount': stmt.difference,
                        'name': _("Cash difference observed during the counting (%s)") % name,
                    }
                    self.env['account.bank.statement.line'].create(values)
                else:
                    balance_end_real = formatLang(self.env, stmt.balance_end_real, currency_obj=stmt.currency_id)
                    balance_end = formatLang(self.env, stmt.balance_end, currency_obj=stmt.currency_id)
                    raise UserError(_('The ending balance is incorrect !\nThe expected balance (%s) is different from the computed one. (%s)')
                        % (balance_end_real, balance_end))
        return True
    def reconciliation_widget_preprocess(self):
        """ Get statement lines of the specified statements or all unreconciled statement lines and try to automatically reconcile them / find them a partner.
            Return ids of statement lines left to reconcile and other data for the reconciliation widget.
        """
        statements = self
        bsl_obj = self.env['account.bank.statement.line']

        # NB : The field account_id can be used at the statement line creation/import to avoid the reconciliation process on it later on,
        # this is why we filter out statements lines where account_id is set
        st_lines_filter = [('journal_entry_ids', '=', False), ('account_id', '=', False)]
        if statements:
            st_lines_filter += [('statement_id', 'in', statements.ids)]

        # Try to automatically reconcile statement lines
        automatic_reconciliation_entries = []
        st_lines_left = self.env['account.bank.statement.line']
        for st_line in bsl_obj.search(st_lines_filter):
            res = st_line.auto_reconcile()
            if not res:
                st_lines_left = (st_lines_left | st_line)
            else:
                automatic_reconciliation_entries.append(res.ids)

        # Try to set statement line's partner
        for st_line in st_lines_left:
            if st_line.name and not st_line.partner_id:
                additional_domain = [('ref', '=', st_line.name)]
                match_recs = st_line.get_move_lines_for_reconciliation(limit=1, additional_domain=additional_domain, overlook_partner=True)
                if match_recs and match_recs[0].partner_id:
                    st_line.write({'partner_id': match_recs[0].partner_id.id})

        # Collect various informations for the reconciliation widget
        notifications = []
        num_auto_reconciled = len(automatic_reconciliation_entries)
        if num_auto_reconciled > 0:
            auto_reconciled_message = num_auto_reconciled > 1 \
                and _("%d transactions were automatically reconciled.") % num_auto_reconciled \
                or _("1 transaction was automatically reconciled.")
            notifications += [{
                'type': 'info',
                'message': auto_reconciled_message,
                'details': {
                    'name': _("Automatically reconciled items"),
                    'model': 'account.move',
                    'ids': automatic_reconciliation_entries
                }
            }]

        lines = []
        for el in statements:
            lines.extend(el.line_ids.ids)
        lines = list(set(lines))

        return {
            'st_lines_ids': st_lines_left.ids,
            'notifications': notifications,
            'statement_name': len(statements) == 1 and statements[0].name or False,
            'num_already_reconciled_lines': statements and bsl_obj.search_count([('journal_entry_ids', '!=', False), ('id', 'in', lines)]) or 0,
        }
Пример #16
0
 def _check_bank_account(self):
     if self.type == 'bank' and self.bank_account_id:
         if self.bank_account_id.company_id != self.company_id:
             raise ValidationError(_('The bank account of a bank journal must belong to the same company (%s).') % self.company_id.name)
         # A bank account can belong to a customer/supplier, in which case their partner_id is the customer/supplier.
         # Or they are part of a bank journal and their partner_id must be the company's partner_id.
         if self.bank_account_id.partner_id != self.company_id.partner_id:
             raise ValidationError(_('The holder of a journal\'s bank account must be the company (%s).') % self.company_id.name)
Пример #17
0
 def _run(self, records):
     for box in self:
         for record in records:
             if not record.journal_id:
                 raise UserError(_("Please check that the field 'Journal' is set on the Bank Statement"))
             if not record.journal_id.company_id.transfer_account_id:
                 raise UserError(_("Please check that the field 'Transfer Account' is set on the company."))
             box._create_bank_statement_line(record)
     return {}
    def get_journal_dashboard_datas(self):
        number_to_reconcile = last_balance = account_sum = 0
        ac_bnk_stmt = []
        title = ''
        number_draft = number_waiting = number_late = sum_draft = sum_waiting = sum_late = 0
        if self.type in ['bank', 'cash']:
            last_bank_stmt = self.env['account.bank.statement'].search([('journal_id', 'in', self.ids)], order="date desc, id desc", limit=1)
            last_balance = last_bank_stmt and last_bank_stmt[0].balance_end or 0
            ac_bnk_stmt = self.env['account.bank.statement'].search([('journal_id', 'in', self.ids),('state', '=', 'open')])
            for ac_bnk in ac_bnk_stmt:
                for line in ac_bnk.line_ids:
                    if not line.journal_entry_ids:
                        number_to_reconcile += 1
            # optimization to read sum of balance from account_move_line
            account_ids = tuple(filter(None, [self.default_debit_account_id.id, self.default_credit_account_id.id]))
            if account_ids:
                query = """SELECT sum(balance) FROM account_move_line WHERE account_id in %s;"""
                self.env.cr.execute(query, (account_ids,))
                query_results = self.env.cr.dictfetchall()
                if query_results and query_results[0].get('sum') != None:
                    account_sum = query_results[0].get('sum')
        #TODO need to check if all invoices are in the same currency than the journal!!!!
        elif self.type in ['sale', 'purchase']:
            title = _('Bills to pay') if self.type == 'purchase' else _('Invoices owed to you')
            # optimization to find total and sum of invoice that are in draft, open state
            query = """SELECT state, count(id) AS count, sum(amount_total) AS total FROM account_invoice WHERE journal_id = %s AND state NOT IN ('paid', 'cancel') GROUP BY state;"""
            self.env.cr.execute(query, (self.id,))
            query_results = self.env.cr.dictfetchall()
            today = datetime.today()
            query = """SELECT count(id) AS count_late, sum(amount_total) AS total FROM account_invoice WHERE journal_id = %s AND date < %s AND state = 'open';"""
            self.env.cr.execute(query, (self.id, today))
            late_query_results = self.env.cr.dictfetchall()
            for result in query_results:
                if result.get('state') in ['draft', 'proforma', 'proforma2']:
                    number_draft = result.get('count')
                    sum_draft = result.get('total')
                elif result.get('state') == 'open':
                    number_waiting = result.get('count')
                    sum_waiting = result.get('total')
            if late_query_results and late_query_results[0].get('count_late') != None:
                number_late = late_query_results[0].get('count_late')
                sum_late = late_query_results[0].get('total')

        return {
            'number_to_reconcile': number_to_reconcile,
            'account_balance': formatLang(self.env, account_sum, currency_obj=self.currency_id or self.company_id.currency_id),
            'last_balance': formatLang(self.env, last_balance, currency_obj=self.currency_id or self.company_id.currency_id),
            'number_draft': number_draft,
            'number_waiting': number_waiting,
            'number_late': number_late,
            'sum_draft': formatLang(self.env, sum_draft or 0.0, currency_obj=self.currency_id or self.company_id.currency_id),
            'sum_waiting': formatLang(self.env, sum_waiting or 0.0, currency_obj=self.currency_id or self.company_id.currency_id),
            'sum_late': formatLang(self.env, sum_late or 0.0, currency_obj=self.currency_id or self.company_id.currency_id),
            'currency_id': self.currency_id and self.currency_id.id or self.company_id.currency_id.id,
            'bank_statements_source': self.bank_statements_source,
            'title': title, 
        }
Пример #19
0
class MgmtSystemSystem(models.Model):

    _name = 'mgmtsystem.system'
    _description = _('System')

    name = fields.Char(string=_('System'), required=True)
    company_id = fields.Many2one('res.company',
                                 string=_('Company'),
                                 default=own_company)
Пример #20
0
 def unlink(self):
     if self.env['account.move.line'].search([('account_id', 'in', self.ids)], limit=1):
         raise UserError(_('You cannot do that on an account that contains journal items.'))
     #Checking whether the account is set as a property to any Partner or not
     values = ['account.account,%s' % (account_id,) for account_id in self.ids]
     partner_prop_acc = self.env['ir.property'].search([('value_reference', 'in', values)], limit=1)
     if partner_prop_acc:
         raise UserError(_('You cannot remove/deactivate an account which is set on a customer or vendor.'))
     return super(AccountAccount, self).unlink()
Пример #21
0
 def create(self, vals):
     res = super(event_registration, self).create(vals)
     if res.origin or res.sale_order_id:
         message = _("The registration has been created for event %(event_name)s%(ticket)s from sale order %(order)s") % ({
             'event_name': '<i>%s</i>' % res.event_id.name,
             'ticket': res.event_ticket_id and _(' with ticket %s') % (('<i>%s</i>') % res.event_ticket_id.name) or '',
             'order': res.origin or res.sale_order_id.name})
         res.message_post(body=message)
     return res
Пример #22
0
 def unlink(self):
     for record in self:
         if record.move_check:
             if record.asset_id.category_id.type == 'purchase':
                 msg = _("You cannot delete posted depreciation lines.")
             else:
                 msg = _("You cannot delete posted installment lines.")
             raise UserError(msg)
     return super(AccountAssetDepreciationLine, self).unlink()
Пример #23
0
 def _check_currency(self):
     if self.currency_id:
         if self.default_credit_account_id and not self.default_credit_account_id.currency_id.id == self.currency_id.id:
             raise UserError(
                 _('Configuration error!\nThe currency of the journal should be the same than the default credit account.'
                   ))
         if self.default_debit_account_id and not self.default_debit_account_id.currency_id.id == self.currency_id.id:
             raise UserError(
                 _('Configuration error!\nThe currency of the journal should be the same than the default debit account.'
                   ))
Пример #24
0
    def execute(self):
        '''
        This function is called at the confirmation of the wizard to generate the COA from the templates. It will read
        all the provided information to create the accounts, the banks, the journals, the taxes, the
        accounting properties... accordingly for the chosen company.
        '''
        if len(self.env['account.account'].search([('company_id', '=', self.company_id.id)])) > 0:
            # We are in a case where we already have some accounts existing, meaning that user has probably
            # created its own accounts and does not need a coa, so skip installation of coa.
            _logger.info('Could not install chart of account since some accounts already exists for the company (%s)', (self.company_id.id,))
            return {}
        if not self.env.user._is_admin():
            raise AccessError(_("Only administrators can change the settings"))
        ir_values_obj = self.env['ir.values']
        company = self.company_id
        self.company_id.write({'currency_id': self.currency_id.id,
                               'accounts_code_digits': self.code_digits,
                               'anglo_saxon_accounting': self.use_anglo_saxon,
                               'bank_account_code_prefix': self.bank_account_code_prefix,
                               'cash_account_code_prefix': self.cash_account_code_prefix,
                               'chart_template_id': self.chart_template_id.id})

        #set the coa currency to active
        self.currency_id.write({'active': True})

        # When we install the CoA of first company, set the currency to price types and pricelists
        if company.id == 1:
            for reference in ['product.list_price', 'product.standard_price', 'product.list0']:
                try:
                    tmp2 = self.env.ref(reference).write({'currency_id': self.currency_id.id})
                except ValueError:
                    pass

        # If the floats for sale/purchase rates have been filled, create templates from them
        self._create_tax_templates_from_rates(company.id)

        # Install all the templates objects and generate the real objects
        acc_template_ref, taxes_ref = self.chart_template_id._install_template(company, code_digits=self.code_digits, transfer_account_id=self.transfer_account_id)

        # write values of default taxes for product as super user
        if self.sale_tax_id and taxes_ref:
            ir_values_obj.sudo().set_default('product.template', "taxes_id", [taxes_ref[self.sale_tax_id.id]], for_all_users=True, company_id=company.id)
        if self.purchase_tax_id and taxes_ref:
            ir_values_obj.sudo().set_default('product.template', "supplier_taxes_id", [taxes_ref[self.purchase_tax_id.id]], for_all_users=True, company_id=company.id)

        # Create Bank journals
        self._create_bank_journals_from_o2m(company, acc_template_ref)

        # Create the current year earning account (outside of the CoA)
        self.env['account.account'].create({
            'code': '9999',
            'name': _('Undistributed Profits/Losses'),
            'user_type_id': self.env.ref("account.data_unaffected_earnings").id,
            'company_id': company.id,})
        return {}
Пример #25
0
    def post(self):
        """ Create the journal items for the payment and update the payment's state to 'posted'.
            A journal entry is created containing an item in the source liquidity account (selected journal's default_debit or default_credit)
            and another in the destination reconciliable account (see _compute_destination_account_id).
            If invoice_ids is not empty, there will be one reconciliable move line per invoice to reconcile with.
            If the payment is a transfer, a second journal entry is created in the destination journal to receive money from the transfer account.
        """
        for rec in self:

            if rec.state != 'draft':
                raise UserError(
                    _("Only a draft payment can be posted. Trying to post a payment in state %s."
                      ) % rec.state)

            if any(inv.state != 'open' for inv in rec.invoice_ids):
                raise ValidationError(
                    _("The payment cannot be processed because the invoice is not open!"
                      ))

            # Use the right sequence to set the name
            if rec.payment_type == 'transfer':
                sequence = rec.env.ref('account.sequence_payment_transfer')
            else:
                if rec.partner_type == 'customer':
                    if rec.payment_type == 'inbound':
                        sequence = rec.env.ref(
                            'account.sequence_payment_customer_invoice')
                    if rec.payment_type == 'outbound':
                        sequence = rec.env.ref(
                            'account.sequence_payment_customer_refund')
                if rec.partner_type == 'supplier':
                    if rec.payment_type == 'inbound':
                        sequence = rec.env.ref(
                            'account.sequence_payment_supplier_refund')
                    if rec.payment_type == 'outbound':
                        sequence = rec.env.ref(
                            'account.sequence_payment_supplier_invoice')
            rec.name = sequence.with_context(
                ir_sequence_date=rec.payment_date).next_by_id()

            # Create the journal entry
            amount = rec.amount * (rec.payment_type in ('outbound', 'transfer')
                                   and 1 or -1)
            move = rec._create_payment_entry(amount)

            # In case of a transfer, the first journal entry created debited the source liquidity account and credited
            # the transfer account. Now we debit the transfer account and credit the destination liquidity account.
            if rec.payment_type == 'transfer':
                transfer_credit_aml = move.line_ids.filtered(
                    lambda r: r.account_id == rec.company_id.
                    transfer_account_id)
                transfer_debit_aml = rec._create_transfer_entry(amount)
                (transfer_credit_aml + transfer_debit_aml).reconcile()

            rec.state = 'posted'
Пример #26
0
 def on_change_url(self):
     self.ensure_one()
     if self.url:
         res = self._parse_document_url(self.url)
         if res.get('error'):
             raise Warning(_('Could not fetch data from url. Document or access right not available:\n%s') % res['error'])
         values = res['values']
         if not values.get('document_id'):
             raise Warning(_('Please enter valid Youtube or Google Doc URL'))
         for key, value in values.iteritems():
             setattr(self, key, value)
Пример #27
0
 def _str_to_date(self, model, field, value):
     try:
         time.strptime(value, DEFAULT_SERVER_DATE_FORMAT)
         return value, []
     except ValueError:
         raise self._format_import_error(
             ValueError,
             _(u"'%s' does not seem to be a valid date for field '%%(field)s'"),
             value,
             {'moreinfo': _(u"Use the format '%s'") % u"2012-12-31"}
         )
Пример #28
0
    def _check_parsed_data(self, stmts_vals):
        """ Basic and structural verifications """
        if len(stmts_vals) == 0:
            raise UserError(_('This file doesn\'t contain any statement.'))

        no_st_line = True
        for vals in stmts_vals:
            if vals['transactions'] and len(vals['transactions']) > 0:
                no_st_line = False
                break
        if no_st_line:
            raise UserError(_('This file doesn\'t contain any transaction.'))
Пример #29
0
 def _check_bank_account(self):
     if self.type == 'bank' and self.bank_account_id:
         if self.bank_account_id.company_id != self.company_id:
             raise ValidationError(
                 _('The bank account of a bank journal must belong to the same company (%s).'
                   ) % self.company_id.name)
         # A bank account can belong to a customer/supplier, in which case their partner_id is the customer/supplier.
         # Or they are part of a bank journal and their partner_id must be the company's partner_id.
         if self.bank_account_id.partner_id != self.company_id.partner_id:
             raise ValidationError(
                 _('The holder of a journal\'s bank account must be the company (%s).'
                   ) % self.company_id.name)
Пример #30
0
    def execute_code(self, code_exec):
        def reconciled_inv():
            """
            returns the list of invoices that are set as reconciled = True
            """
            return self.env['account.invoice'].search([('reconciled', '=',
                                                        True)]).ids

        def order_columns(item, cols=None):
            """
            This function is used to display a dictionary as a string, with its columns in the order chosen.

            :param item: dict
            :param cols: list of field names
            :returns: a list of tuples (fieldname: value) in a similar way that would dict.items() do except that the
                returned values are following the order given by cols
            :rtype: [(key, value)]
            """
            if cols is None:
                cols = item.keys()
            return [(col, item.get(col)) for col in cols if col in item.keys()]

        localdict = {
            'cr': self.env.cr,
            'uid': self.env.uid,
            'reconciled_inv':
            reconciled_inv,  # specific function used in different tests
            'result': None,  # used to store the result of the test
            'column_order':
            None,  # used to choose the display order of columns (in case you are returning a list of dict)
        }
        eval(code_exec, localdict, mode="exec", nocopy=True)
        result = localdict['result']
        column_order = localdict.get('column_order', None)

        if not isinstance(result, (tuple, list, set)):
            result = [result]
        if not result:
            result = [_('The test was passed successfully')]
        else:

            def _format(item):
                if isinstance(item, dict):
                    return ', '.join([
                        "%s: %s" % (tup[0], tup[1])
                        for tup in order_columns(item, column_order)
                    ])
                else:
                    return item

            result = [_(_format(rec)) for rec in result]

        return result
Пример #31
0
    def create_invoices(self):
        sale_orders = self.env['sale.order'].browse(
            self._context.get('active_ids', []))

        if self.advance_payment_method == 'delivered':
            sale_orders.action_invoice_create()
        elif self.advance_payment_method == 'all':
            sale_orders.action_invoice_create(final=True)
        else:
            # Create deposit product if necessary
            if not self.product_id:
                vals = self._prepare_deposit_product()
                self.product_id = self.env['product.product'].create(vals)
                self.env['ir.values'].set_default(
                    'sale.config.settings', 'deposit_product_id_setting',
                    self.product_id.id)

            sale_line_obj = self.env['sale.order.line']
            for order in sale_orders:
                if self.advance_payment_method == 'percentage':
                    amount = order.amount_untaxed * self.amount / 100
                else:
                    amount = self.amount
                if self.product_id.invoice_policy != 'order':
                    raise UserError(
                        _('The product used to invoice a down payment should have an invoice policy set to "Ordered quantities". Please update your deposit product to be able to create a deposit invoice.'
                          ))
                if self.product_id.type != 'service':
                    raise UserError(
                        _("The product used to invoice a down payment should be of type 'Service'. Please use another product or update this product."
                          ))
                so_line = sale_line_obj.create({
                    'name':
                    _('Advance: %s') % (time.strftime('%m %Y'), ),
                    'price_unit':
                    amount,
                    'product_uom_qty':
                    0.0,
                    'order_id':
                    order.id,
                    'discount':
                    0.0,
                    'product_uom':
                    self.product_id.uom_id.id,
                    'product_id':
                    self.product_id.id,
                    'tax_id': [(6, 0, self.product_id.taxes_id.ids)],
                })
                self._create_invoice(order, so_line, amount)
        if self._context.get('open_invoices', False):
            return sale_orders.action_view_invoice()
        return {'type': 'ir.actions.act_window_close'}
    def _create_invoice(self, order, so_line, amount):
        inv_obj = self.env['account.invoice']
        ir_property_obj = self.env['ir.property']

        account_id = False
        if self.product_id.id:
            account_id = self.product_id.property_account_income_id.id
        if not account_id:
            prop = ir_property_obj.get('property_account_income_categ_id', 'product.category')
            prop_id = prop and prop.id or False
            account_id = order.fiscal_position_id.map_account(prop_id)
        if not account_id:
            raise UserError(
                _('There is no income account defined for this product: "%s". You may have to install a chart of account from Accounting app, settings menu.') % \
                    (self.product_id.name,))

        if self.amount <= 0.00:
            raise UserError(_('The value of the down payment amount must be positive.'))
        if self.advance_payment_method == 'percentage':
            amount = order.amount_untaxed * self.amount / 100
            name = _("Down payment of %s%%") % (self.amount,)
        else:
            amount = self.amount
            name = _('Down Payment')

        invoice = inv_obj.create({
            'name': order.client_order_ref or order.name,
            'origin': order.name,
            'type': 'out_invoice',
            'reference': False,
            'account_id': order.partner_id.property_account_receivable_id.id,
            'partner_id': order.partner_invoice_id.id,
            'invoice_line_ids': [(0, 0, {
                'name': name,
                'origin': order.name,
                'account_id': account_id,
                'price_unit': amount,
                'quantity': 1.0,
                'discount': 0.0,
                'uom_id': self.product_id.uom_id.id,
                'product_id': self.product_id.id,
                'sale_line_ids': [(6, 0, [so_line.id])],
                'invoice_line_tax_ids': [(6, 0, [x.id for x in self.product_id.taxes_id])],
                'account_analytic_id': order.project_id.id or False,
            })],
            'currency_id': order.pricelist_id.currency_id.id,
            'payment_term_id': order.payment_term_id.id,
            'fiscal_position_id': order.fiscal_position_id.id or order.partner_id.property_account_position_id.id,
            'team_id': order.team_id.id,
        })
        invoice.compute_taxes()
        return invoice
Пример #33
0
 def _onchange_product_uom_qty(self):
     if self.state == 'sale' and self.product_id.type in [
             'product', 'consu'
     ] and self.product_uom_qty < self._origin.product_uom_qty:
         warning_mess = {
             'title':
             _('Ordered quantity decreased!'),
             'message':
             _('You are decreasing the ordered quantity! Do not forget to manually update the delivery order if needed.'
               ),
         }
         return {'warning': warning_mess}
     return {}
Пример #34
0
 def _get_new_menu_pages(self):
     todo = [
         (_('Introduction'), 'website_event.template_intro'),
         (_('Location'), 'website_event.template_location')
     ]
     result = []
     for name, path in todo:
         complete_name = name + ' ' + self.name
         newpath = self.env['website'].new_page(complete_name, path, ispage=False)
         url = "/event/" + slug(self) + "/page/" + newpath
         result.append((name, url))
     result.append((_('Register'), '/event/%s/register' % slug(self)))
     return result
Пример #35
0
 def on_change_url(self):
     self.ensure_one()
     if self.url:
         res = self._parse_document_url(self.url)
         if res.get('error'):
             raise Warning(
                 _('Could not fetch data from url. Document or access right not available:\n%s'
                   ) % res['error'])
         values = res['values']
         if not values.get('document_id'):
             raise Warning(
                 _('Please enter valid Youtube or Google Doc URL'))
         for key, value in values.iteritems():
             setattr(self, key, value)
Пример #36
0
    def create(self, values):
        if not values.get('login', False):
            action = self.env.ref('base.action_res_users')
            msg = _("You cannot create a new user from here.\n To create new user please go to configuration panel.")
            raise ecore.exceptions.RedirectWarning(msg, action.id, _('Go to the configuration panel'))

        user = super(Users, self.with_context(
            alias_model_name=self._name,
            alias_parent_model_name=self._name
        )).create(values)
        user.alias_id.sudo().write({"alias_force_thread_id": user.id, "alias_parent_thread_id": user.id})

        # create a welcome message
        user._create_welcome_message()
        return user
Пример #37
0
    def _str_to_datetime(self, model, field, value):
        try:
            parsed_value = fields.Datetime.from_string(value)
        except ValueError:
            raise self._format_import_error(
                ValueError,
                _(u"'%s' does not seem to be a valid datetime for field '%%(field)s'"),
                value,
                {'moreinfo': _(u"Use the format '%s'") % u"2012-12-31 23:59:59"}
            )

        input_tz = self._input_tz()# Apply input tz to the parsed naive datetime
        dt = input_tz.localize(parsed_value, is_dst=False)
        # And convert to UTC before reformatting for writing
        return dt.astimezone(pytz.UTC).strftime(DEFAULT_SERVER_DATETIME_FORMAT), []
Пример #38
0
 def default_get(self, fields):
     result = super(Invite, self).default_get(fields)
     user_name = self.env.user.name_get()[0][1]
     model = result.get('res_model')
     res_id = result.get('res_id')
     if self._context.get('mail_invite_follower_channel_only'):
         result['send_mail'] = False
     if 'message' in fields and model and res_id:
         model_name = self.env['ir.model'].search([('model', '=', self.pool[model]._name)]).name_get()[0][1]
         document_name = self.env[model].browse(res_id).name_get()[0][1]
         message = _('<div><p>Hello,</p><p>%s invited you to follow %s document: %s.</p></div>') % (user_name, model_name, document_name)
         result['message'] = message
     elif 'message' in fields:
         result['message'] = _('<div><p>Hello,</p><p>%s invited you to follow a new document.</p></div>') % user_name
     return result
Пример #39
0
    def get_record_data(self, values):
        """ Returns a defaults-like dict with initial values for the composition
        wizard when sending an email related a previous email (parent_id) or
        a document (model, res_id). This is based on previously computed default
        values. """
        result, subject = {}, False
        if values.get('parent_id'):
            parent = self.env['mail.message'].browse(values.get('parent_id'))
            result['record_name'] = parent.record_name,
            subject = tools.ustr(parent.subject or parent.record_name or '')
            if not values.get('model'):
                result['model'] = parent.model
            if not values.get('res_id'):
                result['res_id'] = parent.res_id
            partner_ids = values.get('partner_ids', list()) + [
                (4, id) for id in parent.partner_ids.ids
            ]
            if self._context.get(
                    'is_private'
            ) and parent.author_id:  # check message is private then add author also in partner list.
                partner_ids += [(4, parent.author_id.id)]
            result['partner_ids'] = partner_ids
        elif values.get('model') and values.get('res_id'):
            doc_name_get = self.env[values.get('model')].browse(
                values.get('res_id')).name_get()
            result['record_name'] = doc_name_get and doc_name_get[0][1] or ''
            subject = tools.ustr(result['record_name'])

        re_prefix = _('Re:')
        if subject and not (subject.startswith('Re:')
                            or subject.startswith(re_prefix)):
            subject = "%s %s" % (re_prefix, subject)
        result['subject'] = subject

        return result
Пример #40
0
 def _check_communication(self, payment_method_id, communication):
     super(account_payment, self)._check_communication(payment_method_id, communication)
     if payment_method_id == self.env.ref('account_check_printing.account_payment_method_check').id:
         if not communication:
             return
         if len(communication) > 60:
             raise ValidationError(_("A check memo cannot exceed 60 characters."))
Пример #41
0
 def _parse_document_url(self, url, only_preview_fields=False):
     document_source, document_id = self._find_document_data_from_url(url)
     if document_source and hasattr(self,
                                    '_parse_%s_document' % document_source):
         return getattr(self, '_parse_%s_document' % document_source)(
             document_id, only_preview_fields)
     return {'error': _('Unknown document')}
Пример #42
0
 def _get_move_vals(self, journal=None):
     """ Return dict to create the payment move
     """
     journal = journal or self.journal_id
     if not journal.sequence_id:
         raise UserError(_('Configuration Error !'), _('The journal %s does not have a sequence, please specify one.') % journal.name)
     if not journal.sequence_id.active:
         raise UserError(_('Configuration Error !'), _('The sequence of journal %s is deactivated.') % journal.name)
     name = journal.with_context(ir_sequence_date=self.payment_date).sequence_id.next_by_id()
     return {
         'name': name,
         'date': self.payment_date,
         'ref': self.communication or '',
         'company_id': self.company_id.id,
         'journal_id': journal.id,
     }
 def action_create_new(self):
     ctx = self._context.copy()
     model = 'account.invoice'
     if self.type == 'sale':
         ctx.update({'journal_type': self.type, 'default_type': 'out_invoice', 'type': 'out_invoice', 'default_journal_id': self.id})
         if ctx.get('refund'):
             ctx.update({'default_type':'out_refund', 'type':'out_refund'})
         view_id = self.env.ref('account.invoice_form').id
     elif self.type == 'purchase':
         ctx.update({'journal_type': self.type, 'default_type': 'in_invoice', 'type': 'in_invoice', 'default_journal_id': self.id})
         if ctx.get('refund'):
             ctx.update({'default_type': 'in_refund', 'type': 'in_refund'})
         view_id = self.env.ref('account.invoice_supplier_form').id
     else:
         ctx.update({'default_journal_id': self.id})
         view_id = self.env.ref('account.view_move_form').id
         model = 'account.move'
     return {
         'name': _('Create invoice/bill'),
         'type': 'ir.actions.act_window',
         'view_type': 'form',
         'view_mode': 'form',
         'res_model': model,
         'view_id': view_id,
         'context': ctx,
     }
Пример #44
0
    def write(self, values):
        if 'vote' in values:
            for vote in self:
                # own post check
                if vote.user_id.id == vote.post_id.create_uid.id:
                    raise UserError(_('Not allowed to vote for its own post'))
                # karma check
                if (values['vote'] == '1' or vote.vote == '-1' and
                        values['vote'] == '0') and not vote.post_id.can_upvote:
                    raise KarmaError('Not enough karma to upvote.')
                elif (values['vote'] == '-1' or vote.vote == '1' and
                      values['vote'] == '0') and not vote.post_id.can_downvote:
                    raise KarmaError('Not enough karma to downvote.')

                # karma update
                if vote.post_id.parent_id:
                    karma_value = self._get_karma_value(
                        vote.vote, values['vote'],
                        vote.forum_id.karma_gen_answer_upvote,
                        vote.forum_id.karma_gen_answer_downvote)
                else:
                    karma_value = self._get_karma_value(
                        vote.vote, values['vote'],
                        vote.forum_id.karma_gen_question_upvote,
                        vote.forum_id.karma_gen_question_downvote)
                vote.recipient_id.sudo().add_karma(karma_value)
        res = super(Vote, self).write(values)
        return res
Пример #45
0
    def _get_sale_order_line_vals(self):
        order = self.env['sale.order'].search(
            [('project_id', '=', self.account_id.id)], limit=1)
        if not order:
            return False
        if order.state != 'sale':
            raise UserError(
                _('The Sale Order %s linked to the Analytic Account must be validated before registering expenses.'
                  % order.name))

        last_so_line = self.env['sale.order.line'].search(
            [('order_id', '=', order.id)], order='sequence desc', limit=1)
        last_sequence = last_so_line.sequence + 1 if last_so_line else 100

        fpos = order.fiscal_position_id or order.partner_id.property_account_position_id
        taxes = fpos.map_tax(self.product_id.taxes_id)
        price = self._get_invoice_price(order)

        return {
            'order_id': order.id,
            'name': self.name,
            'sequence': last_sequence,
            'price_unit': price,
            'tax_id': [x.id for x in taxes],
            'discount': 0.0,
            'product_id': self.product_id.id,
            'product_uom': self.product_uom_id.id,
            'product_uom_qty': 0.0,
            'qty_delivered': self.unit_amount,
        }
Пример #46
0
 def _notification_get_recipient_groups(self,
                                        cr,
                                        uid,
                                        ids,
                                        message,
                                        recipients,
                                        context=None):
     res = super(note_note,
                 self)._notification_get_recipient_groups(cr,
                                                          uid,
                                                          ids,
                                                          message,
                                                          recipients,
                                                          context=context)
     new_action_id = self.pool['ir.model.data'].xmlid_to_res_id(
         cr, uid, 'note.action_note_note')
     new_action = self._notification_link_helper(cr,
                                                 uid,
                                                 ids,
                                                 'new',
                                                 context=context,
                                                 action_id=new_action_id)
     res['user'] = {
         'actions': [{
             'url': new_action,
             'title': _('New Note')
         }]
     }
     return res
Пример #47
0
 def _check_default_post_type(self):
     if (self.default_post_type == 'question' and not self.allow_question) \
             or (self.default_post_type == 'discussion' and not self.allow_discussion) \
             or (self.default_post_type == 'link' and not self.allow_link):
         raise UserError(
             _('You cannot choose %s as default post since the forum does not allow it.'
               % self.default_post_type))
Пример #48
0
    def create(self, vals):
        if 'content' in vals and vals.get('forum_id'):
            vals['content'] = self._update_content(vals['content'],
                                                   vals['forum_id'])

        post = super(Post,
                     self.with_context(mail_create_nolog=True)).create(vals)
        # deleted or closed questions
        if post.parent_id and (post.parent_id.state == 'close'
                               or post.parent_id.active is False):
            raise UserError(
                _('Posting answer on a [Deleted] or [Closed] question is not possible'
                  ))
        # karma-based access
        if not post.parent_id and not post.can_ask:
            raise KarmaError('Not enough karma to create a new question')
        elif post.parent_id and not post.can_answer:
            raise KarmaError('Not enough karma to answer to a question')
        if not post.parent_id and not post.can_post:
            post.state = 'pending'

        # add karma for posting new questions
        if not post.parent_id and post.state == 'active':
            self.env.user.sudo().add_karma(
                post.forum_id.karma_gen_question_new)

        post.post_notification()
        return post
Пример #49
0
 def view_header_get(self, view_id, view_type):
     context = (self._context or {})
     header = False
     if context.get('account_id', False):
         analytic_account = self.env['account.analytic.account'].search([('id', '=', context['account_id'])], limit=1)
         header = _('Entries: ') + (analytic_account.name or '')
     return header
Пример #50
0
 def create(self, vals):
     res = super(event_registration, self).create(vals)
     if res.origin or res.sale_order_id:
         message = _(
             "The registration has been created for event %(event_name)s%(ticket)s from sale order %(order)s"
         ) % ({
             'event_name':
             '<i>%s</i>' % res.event_id.name,
             'ticket':
             res.event_ticket_id and _(' with ticket %s') %
             (('<i>%s</i>') % res.event_ticket_id.name) or '',
             'order':
             res.origin or res.sale_order_id.name
         })
         res.message_post(body=message)
     return res
Пример #51
0
    def _create_transfer_entry(self, amount):
        """ Create the journal entry corresponding to the 'incoming money' part of an internal transfer, return the reconciliable move line
        """
        aml_obj = self.env['account.move.line'].with_context(check_move_validity=False)
        debit, credit, amount_currency = aml_obj.with_context(date=self.payment_date).compute_amount_fields(amount, self.currency_id, self.company_id.currency_id)
        amount_currency = self.destination_journal_id.currency_id and self.currency_id.with_context(date=self.payment_date).compute(amount, self.destination_journal_id.currency_id) or 0

        dst_move = self.env['account.move'].create(self._get_move_vals(self.destination_journal_id))

        dst_liquidity_aml_dict = self._get_shared_move_line_vals(debit, credit, amount_currency, dst_move.id)
        dst_liquidity_aml_dict.update({
            'name': _('Transfer from %s') % self.journal_id.name,
            'account_id': self.destination_journal_id.default_credit_account_id.id,
            'currency_id': self.destination_journal_id.currency_id.id,
            'payment_id': self.id,
            'journal_id': self.destination_journal_id.id})
        aml_obj.create(dst_liquidity_aml_dict)

        transfer_debit_aml_dict = self._get_shared_move_line_vals(credit, debit, 0, dst_move.id)
        transfer_debit_aml_dict.update({
            'name': self.name,
            'payment_id': self.id,
            'account_id': self.company_id.transfer_account_id.id,
            'journal_id': self.destination_journal_id.id})
        if self.currency_id != self.company_id.currency_id:
            transfer_debit_aml_dict.update({
                'currency_id': self.currency_id.id,
                'amount_currency': -self.amount,
            })
        transfer_debit_aml = aml_obj.create(transfer_debit_aml_dict)
        dst_move.post()
        return transfer_debit_aml