费用
从费用创建费用报告
方法: action_submit_expense
def action_submit_expenses(self):
context_vals = self._get_default_expense_sheet_values()
if len(context_vals) > 1:
sheets = self.env['hr.expense.sheet'].create(context_vals)
return {
'name': _('New Expense Reports'),
'type': 'ir.actions.act_window',
'views': [[False, "list"], [False, "form"]],
'res_model': 'hr.expense.sheet',
'domain': [('id', 'in', sheets.ids)],
'context': self.env.context,
}
else:
context_vals_def = {}
for key in context_vals[0]:
context_vals_def['default_' + key] = context_vals[0][key]
return {
'name': _('New Expense Report'),
'type': 'ir.actions.act_window',
'views': [[False, "form"]],
'res_model': 'hr.expense.sheet',
'target': 'current',
'context': context_vals_def,
}
内部使用 _get_default_expense_sheet_values方法获取默认值
从费用报告创建账单
方法: action_sheet_move_create
def action_sheet_move_create(self):
samples = self.mapped('expense_line_ids.sample')
if samples.count(True):
if samples.count(False):
raise UserError(_("You can't mix sample expenses and regular ones"))
self.write({'state': 'post'})
return
if any(sheet.state != 'approve' for sheet in self):
raise UserError(_("You can only generate accounting entry for approved expense(s)."))
if any(not sheet.journal_id for sheet in self):
raise UserError(_("Specify expense journal to generate accounting entries."))
if not self.employee_id.sudo().address_home_id:
raise UserError(_("The private address of the employee is required to post the expense report. Please add it on the employee form."))
expense_line_ids = self.mapped('expense_line_ids')\
.filtered(lambda r: not float_is_zero(r.total_amount, precision_rounding=(r.currency_id or self.env.company.currency_id).rounding))
res = expense_line_ids.with_context(clean_context(self.env.context)).action_move_create()
paid_expenses_company = self.filtered(lambda m: m.payment_mode == 'company_account')
paid_expenses_company.write({'state': 'done', 'amount_residual': 0.0, 'payment_state': 'paid'})
paid_expenses_employee = self - paid_expenses_company
paid_expenses_employee.write({'state': 'post'})
self.activity_update()
return res
sheet中准备bill数据的方法:_prepare_bill_vals
def _prepare_bill_vals(self):
self.ensure_one()
return {
**self._prepare_move_vals(),
# force the name to the default value, to avoid an eventual 'default_name' in the context
# to set it to '' which cause no number to be given to the account.move when posted.
'journal_id': self.journal_id.id,
'move_type': 'in_invoice',
'partner_id': self.employee_id.sudo().address_home_id.commercial_partner_id.id,
'currency_id': self.currency_id.id,
'line_ids':[Command.create(expense._prepare_move_line_vals()) for expense in self.expense_line_ids],
}
准备move的方法是_prepare_move_vals
费用中准备账单明细行数据的方法: _prepare_move_line_vals
def _prepare_move_line_vals(self):
self.ensure_one()
account = self.account_id
if not account:
# We need to do this as the installation process may delete the original account and it doesn't recompute properly after.
# This forces the default values if none is found
if self.product_id:
account = self.product_id.product_tmpl_id._get_product_accounts()['expense']
else:
account = self.env['ir.property']._get('property_account_expense_categ_id', 'product.category')
return {
'name': self.employee_id.name + ': ' + self.name.split('\n')[0][:64],
'account_id': account.id,
'quantity': self.quantity or 1,
'price_unit': self.unit_amount,
'product_id': self.product_id.id,
'product_uom_id': self.product_uom_id.id,
'analytic_distribution': self.analytic_distribution,
'expense_id': self.id,
'partner_id': False if self.payment_mode == 'company_account' else self.employee_id.sudo().address_home_id.commercial_partner_id.id,
'tax_ids': [Command.set(self.tax_ids.ids)],
}
- 从费用报告创建账单的时候,使用的是员工的联系人地址(私人地址)关联的商业实体(通常为上级公司)。