[IMP] sale: docstrings improvements/fixes
closes odoo/odoo#104115 X-original-commit: 7018ea22fedf75c16926c19e85b84dd82c23ab1b Signed-off-by: Victor Feyens (vfe) <vfe@odoo.com>
This commit is contained in:
@@ -712,12 +712,12 @@ class SaleOrder(models.Model):
|
||||
lang = mail_template._render_lang(self.ids)[self.id]
|
||||
ctx = {
|
||||
'default_model': 'sale.order',
|
||||
'default_res_id': self.ids[0],
|
||||
'default_res_id': self.id,
|
||||
'default_use_template': bool(mail_template),
|
||||
'default_template_id': mail_template.id if mail_template else None,
|
||||
'default_composition_mode': 'comment',
|
||||
'mark_so_as_sent': True,
|
||||
'default_email_layout_xmlid': "mail.mail_notification_layout_with_responsible_signature",
|
||||
'default_email_layout_xmlid': 'mail.mail_notification_layout_with_responsible_signature',
|
||||
'proforma': self.env.context.get('proforma', False),
|
||||
'force_email': True,
|
||||
'model_description': self.with_context(lang=lang).type_name,
|
||||
@@ -748,9 +748,17 @@ class SaleOrder(models.Model):
|
||||
return self._get_confirmation_template()
|
||||
|
||||
def _get_confirmation_template(self):
|
||||
""" Get the mail template sent on SO confirmation (or for confirmed SO's).
|
||||
|
||||
:return: `mail.template` record or None if default template wasn't found
|
||||
"""
|
||||
return self.env.ref('sale.mail_template_sale_confirmation', raise_if_not_found=False)
|
||||
|
||||
def action_quotation_sent(self):
|
||||
""" Mark the given draft quotation(s) as sent.
|
||||
|
||||
:raise: UserError if any given SO is not in draft state.
|
||||
"""
|
||||
if self.filtered(lambda so: so.state != 'draft'):
|
||||
raise UserError(_("Only draft orders can be marked as sent directly."))
|
||||
|
||||
@@ -760,6 +768,14 @@ class SaleOrder(models.Model):
|
||||
self.write({'state': 'sent'})
|
||||
|
||||
def action_confirm(self):
|
||||
""" Confirm the given quotation(s) and set their confirmation date.
|
||||
|
||||
If the corresponding setting is enabled, also locks the Sale Order.
|
||||
|
||||
:return: True
|
||||
:rtype: bool
|
||||
:raise: UserError if trying to confirm locked or cancelled SO's
|
||||
"""
|
||||
if self._get_forbidden_state_confirm() & set(self.mapped('state')):
|
||||
raise UserError(_(
|
||||
"It is not allowed to confirm an order in the following states: %s",
|
||||
@@ -788,6 +804,13 @@ class SaleOrder(models.Model):
|
||||
return {'done', 'cancel'}
|
||||
|
||||
def _prepare_confirmation_values(self):
|
||||
""" Prepare the sales order confirmation values.
|
||||
|
||||
Note: self can contain multiple records.
|
||||
|
||||
:return: Sales Order confirmation values
|
||||
:rtype: dict
|
||||
"""
|
||||
return {
|
||||
'state': 'sale',
|
||||
'date_order': fields.Datetime.now()
|
||||
@@ -834,9 +857,9 @@ class SaleOrder(models.Model):
|
||||
self.write({'state': 'sale'})
|
||||
|
||||
def action_cancel(self):
|
||||
""" Cancel SO after showing the cancel wizard when needed. (cfr `_show_cancel_wizard`)
|
||||
""" Cancel SO after showing the cancel wizard when needed. (cfr :meth:`_show_cancel_wizard`)
|
||||
|
||||
For post-cancel operations, please only override `_action_cancel`.
|
||||
For post-cancel operations, please only override :meth:`_action_cancel`.
|
||||
|
||||
note: self.ensure_one() if the wizard is shown.
|
||||
"""
|
||||
@@ -876,6 +899,11 @@ class SaleOrder(models.Model):
|
||||
return self.write({'state': 'cancel'})
|
||||
|
||||
def _show_cancel_wizard(self):
|
||||
""" Decide whether the sale.order.cancel wizard should be shown to cancel specified orders.
|
||||
|
||||
:return: True if there are draft order(s) in the given orders
|
||||
:rtype: bool
|
||||
"""
|
||||
if self.env.context.get('disable_cancel_warning'):
|
||||
return False
|
||||
return any(so.state != 'draft' for so in self)
|
||||
@@ -1026,12 +1054,15 @@ class SaleOrder(models.Model):
|
||||
return self.env['sale.order.line'].browse(invoiceable_line_ids + down_payment_line_ids)
|
||||
|
||||
def _create_invoices(self, grouped=False, final=False, date=None):
|
||||
"""
|
||||
Create the invoice associated to the SO.
|
||||
:param grouped: if True, invoices are grouped by SO id. If False, invoices are grouped by
|
||||
(partner_invoice_id, currency)
|
||||
:param final: if True, refunds will be generated if necessary
|
||||
:returns: list of created invoices
|
||||
""" Create invoice(s) for the given Sales Order(s).
|
||||
|
||||
:param bool grouped: if True, invoices are grouped by SO id.
|
||||
If False, invoices are grouped by keys returned by :meth:`_get_invoice_grouping_keys`
|
||||
:param bool final: if True, refunds will be generated if necessary
|
||||
:param date: unused parameter
|
||||
:returns: created invoices
|
||||
:rtype: `account.move` recordset
|
||||
:raises: UserError if one of the orders has no invoiceable lines.
|
||||
"""
|
||||
if not self.env['account.move'].check_access_rights('create', False):
|
||||
try:
|
||||
@@ -1361,56 +1392,64 @@ class SaleOrder(models.Model):
|
||||
note=_("Upsell %(order)s for customer %(customer)s", order=order_ref, customer=customer_ref))
|
||||
|
||||
def _prepare_analytic_account_data(self, prefix=None):
|
||||
"""
|
||||
Prepare method for analytic account data
|
||||
""" Prepare SO analytic account creation values.
|
||||
|
||||
:param prefix: The prefix of the to-be-created analytic account name
|
||||
:type prefix: string
|
||||
:return: dictionary of value for new analytic account creation
|
||||
:param str prefix: The prefix of the to-be-created analytic account name
|
||||
:return: `account.analytic.account` creation values
|
||||
:rtype: dict
|
||||
"""
|
||||
self.ensure_one()
|
||||
name = self.name
|
||||
if prefix:
|
||||
name = prefix + ": " + self.name
|
||||
plan = self.env['account.analytic.plan'].search(['|', ('company_id', '=', self.company_id.id), ('company_id', '=', False)], limit=1)
|
||||
plan = self.env['account.analytic.plan'].search([
|
||||
'|', ('company_id', '=', self.company_id.id), ('company_id', '=', False)
|
||||
], limit=1)
|
||||
if not plan:
|
||||
plan = self.env['account.analytic.plan'].create({
|
||||
'name': 'Default',
|
||||
'company_id': self.company_id.id
|
||||
'company_id': self.company_id.id,
|
||||
})
|
||||
return {
|
||||
'name': name,
|
||||
'code': self.client_order_ref,
|
||||
'company_id': self.company_id.id,
|
||||
'plan_id': plan.id,
|
||||
'partner_id': self.partner_id.id
|
||||
'partner_id': self.partner_id.id,
|
||||
}
|
||||
|
||||
def _create_analytic_account(self, prefix=None):
|
||||
""" Create a new analytic account for the given orders.
|
||||
|
||||
:param str prefix: if specified, the account name will be '<prefix>: <so_reference>'.
|
||||
If not, the account name will be the Sales Order reference.
|
||||
:return: None
|
||||
"""
|
||||
for order in self:
|
||||
analytic = self.env['account.analytic.account'].create(order._prepare_analytic_account_data(prefix))
|
||||
order.analytic_account_id = analytic
|
||||
|
||||
@api.model
|
||||
def _prepare_down_payment_section_line(self, **optional_values):
|
||||
"""
|
||||
Prepare the dict of values to create a new down payment section for a sales order line.
|
||||
""" Prepare the values to create a new down payment section.
|
||||
|
||||
:param optional_values: any parameter that should be added to the returned down payment section
|
||||
:param dict optional_values: any parameter that should be added to the returned down payment section
|
||||
:return: `account.move.line` creation values
|
||||
:rtype: dict
|
||||
"""
|
||||
self.ensure_one()
|
||||
context = {'lang': self.partner_id.lang}
|
||||
down_payments_section_line = {
|
||||
'display_type': 'line_section',
|
||||
'name': _('Down Payments'),
|
||||
'name': _("Down Payments"),
|
||||
'product_id': False,
|
||||
'product_uom_id': False,
|
||||
'quantity': 0,
|
||||
'discount': 0,
|
||||
'price_unit': 0,
|
||||
'account_id': False
|
||||
'account_id': False,
|
||||
**optional_values
|
||||
}
|
||||
del context
|
||||
if optional_values:
|
||||
down_payments_section_line.update(optional_values)
|
||||
return down_payments_section_line
|
||||
|
||||
#=== HOOKS ===#
|
||||
|
||||
@@ -986,6 +986,11 @@ class SaleOrderLine(models.Model):
|
||||
return super().write(values)
|
||||
|
||||
def _get_protected_fields(self):
|
||||
""" Give the fields that should not be modified on a locked SO.
|
||||
|
||||
:returns: list of field names
|
||||
:rtype: list
|
||||
"""
|
||||
return [
|
||||
'product_id', 'name', 'price_unit', 'product_uom', 'product_uom_qty',
|
||||
'tax_id', 'analytic_distribution'
|
||||
@@ -1010,21 +1015,26 @@ class SaleOrderLine(models.Model):
|
||||
order.message_post(body=msg)
|
||||
|
||||
def _check_line_unlink(self):
|
||||
"""
|
||||
Check whether a line can be deleted or not.
|
||||
""" Check whether given lines can be deleted or not.
|
||||
|
||||
Lines cannot be deleted if the order is confirmed; downpayment
|
||||
lines who have not yet been invoiced bypass that exception.
|
||||
Also, allow deleting UX lines (notes/sections).
|
||||
:rtype: recordset sale.order.line
|
||||
:returns: set of lines that cannot be deleted
|
||||
* Lines cannot be deleted if the order is confirmed.
|
||||
* Down payment lines who have not yet been invoiced bypass that exception.
|
||||
* Sections and Notes can always be deleted.
|
||||
|
||||
:returns: Sales Order Lines that cannot be deleted
|
||||
:rtype: `sale.order.line` recordset
|
||||
"""
|
||||
return self.filtered(lambda line: line.state in ('sale', 'done') and (line.invoice_lines or not line.is_downpayment) and not line.display_type)
|
||||
return self.filtered(
|
||||
lambda line:
|
||||
line.state in ('sale', 'done')
|
||||
and (line.invoice_lines or not line.is_downpayment)
|
||||
and not line.display_type
|
||||
)
|
||||
|
||||
@api.ondelete(at_uninstall=False)
|
||||
def _unlink_except_confirmed(self):
|
||||
if self._check_line_unlink():
|
||||
raise UserError(_('You can not remove an order line once the sales order is confirmed.\nYou should rather set the quantity to 0.'))
|
||||
raise UserError(_("You can not remove an order line once the sales order is confirmed.\nYou should rather set the quantity to 0."))
|
||||
|
||||
#=== BUSINESS METHODS ===#
|
||||
|
||||
|
||||
Reference in New Issue
Block a user