1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import base64
from odoo import api, fields, models, _
from odoo.modules.module import get_module_resource
from odoo.modules.module import get_resource_path
class ResCompany(models.Model):
_inherit = "res.company"
portal_confirmation_sign = fields.Boolean(string='Online Signature', default=True)
portal_confirmation_pay = fields.Boolean(string='Online Payment')
quotation_validity_days = fields.Integer(default=30, string="Default Quotation Validity (Days)")
# sale quotation onboarding
sale_quotation_onboarding_state = fields.Selection([('not_done', "Not done"), ('just_done', "Just done"), ('done', "Done"), ('closed', "Closed")], string="State of the sale onboarding panel", default='not_done')
sale_onboarding_order_confirmation_state = fields.Selection([('not_done', "Not done"), ('just_done', "Just done"), ('done', "Done")], string="State of the onboarding confirmation order step", default='not_done')
sale_onboarding_sample_quotation_state = fields.Selection([('not_done', "Not done"), ('just_done', "Just done"), ('done', "Done")], string="State of the onboarding sample quotation step", default='not_done')
sale_onboarding_payment_method = fields.Selection([
('digital_signature', 'Sign online'),
('paypal', 'PayPal'),
('stripe', 'Stripe'),
('other', 'Pay with another payment acquirer'),
('manual', 'Manual Payment'),
], string="Sale onboarding selected payment method")
@api.model
def action_close_sale_quotation_onboarding(self):
""" Mark the onboarding panel as closed. """
self.env.company.sale_quotation_onboarding_state = 'closed'
@api.model
def action_open_sale_onboarding_payment_acquirer(self):
""" Called by onboarding panel above the quotation list."""
self.env.company.get_chart_of_accounts_or_fail()
action = self.env["ir.actions.actions"]._for_xml_id("sale.action_open_sale_onboarding_payment_acquirer_wizard")
return action
def _get_sample_sales_order(self):
""" Get a sample quotation or create one if it does not exist. """
# use current user as partner
partner = self.env.user.partner_id
company_id = self.env.company.id
# is there already one?
sample_sales_order = self.env['sale.order'].search(
[('company_id', '=', company_id), ('partner_id', '=', partner.id),
('state', '=', 'draft')], limit=1)
if len(sample_sales_order) == 0:
sample_sales_order = self.env['sale.order'].create({
'partner_id': partner.id
})
# take any existing product or create one
product = self.env['product.product'].search([], limit=1)
if len(product) == 0:
default_image_path = get_module_resource('product', 'static/img', 'product_product_13-image.png')
product = self.env['product.product'].create({
'name': _('Sample Product'),
'active': False,
'image_1920': base64.b64encode(open(default_image_path, 'rb').read())
})
product.product_tmpl_id.write({'active': False})
self.env['sale.order.line'].create({
'name': _('Sample Order Line'),
'product_id': product.id,
'product_uom_qty': 10,
'price_unit': 123,
'order_id': sample_sales_order.id,
'company_id': sample_sales_order.company_id.id,
})
return sample_sales_order
@api.model
def action_open_sale_onboarding_sample_quotation(self):
""" Onboarding step for sending a sample quotation. Open a window to compose an email,
with the edi_invoice_template message loaded by default. """
sample_sales_order = self._get_sample_sales_order()
template = self.env.ref('sale.email_template_edi_sale', False)
message_composer = self.env['mail.compose.message'].with_context(
default_use_template=bool(template),
mark_so_as_sent=True,
custom_layout='mail.mail_notification_paynow',
proforma=self.env.context.get('proforma', False),
force_email=True, mail_notify_author=True
).create({
'res_id': sample_sales_order.id,
'template_id': template and template.id or False,
'model': 'sale.order',
'composition_mode': 'comment'})
# Simulate the onchange (like trigger in form the view)
update_values = message_composer.onchange_template_id(template.id, 'comment', 'sale.order', sample_sales_order.id)['value']
message_composer.write(update_values)
message_composer.send_mail()
self.set_onboarding_step_done('sale_onboarding_sample_quotation_state')
self.action_close_sale_quotation_onboarding()
action = self.env["ir.actions.actions"]._for_xml_id("sale.action_orders")
action.update({
'views': [[self.env.ref('sale.view_order_form').id, 'form']],
'view_mode': 'form',
'target': 'main',
})
return action
def get_and_update_sale_quotation_onboarding_state(self):
""" This method is called on the controller rendering method and ensures that the animations
are displayed only one time. """
steps = [
'base_onboarding_company_state',
'account_onboarding_invoice_layout_state',
'sale_onboarding_order_confirmation_state',
'sale_onboarding_sample_quotation_state',
]
return self.get_and_update_onbarding_state('sale_quotation_onboarding_state', steps)
_sql_constraints = [('check_quotation_validity_days', 'CHECK(quotation_validity_days > 0)', 'Quotation Validity is required and must be greater than 0.')]
|