payment_onboarding_wizard.py 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. # Part of Odoo. See LICENSE file for full copyright and licensing details.
  2. from odoo import _, api, fields, models
  3. from odoo.exceptions import UserError
  4. class PaymentWizard(models.TransientModel):
  5. _name = 'payment.provider.onboarding.wizard'
  6. _description = 'Payment provider onboarding wizard'
  7. payment_method = fields.Selection([
  8. ('stripe', "Credit & Debit card (via Stripe)"),
  9. ('paypal', "PayPal"),
  10. ('manual', "Custom payment instructions"),
  11. ], string="Payment Method", default=lambda self: self._get_default_payment_provider_onboarding_value('payment_method'))
  12. paypal_user_type = fields.Selection([
  13. ('new_user', "I don't have a Paypal account"),
  14. ('existing_user', 'I have a Paypal account')], string="Paypal User Type", default='new_user')
  15. paypal_email_account = fields.Char("Email", default=lambda self: self._get_default_payment_provider_onboarding_value('paypal_email_account'))
  16. paypal_seller_account = fields.Char("Merchant Account ID")
  17. paypal_pdt_token = fields.Char("PDT Identity Token", default=lambda self: self._get_default_payment_provider_onboarding_value('paypal_pdt_token'))
  18. # Account-specific logic. It's kept here rather than moved in `account_payment` as it's not used by `account` module.
  19. manual_name = fields.Char("Method", default=lambda self: self._get_default_payment_provider_onboarding_value('manual_name'))
  20. journal_name = fields.Char("Bank Name", default=lambda self: self._get_default_payment_provider_onboarding_value('journal_name'))
  21. acc_number = fields.Char("Account Number", default=lambda self: self._get_default_payment_provider_onboarding_value('acc_number'))
  22. manual_post_msg = fields.Html("Payment Instructions")
  23. _data_fetched = fields.Boolean(store=False)
  24. @api.onchange('journal_name', 'acc_number')
  25. def _set_manual_post_msg_value(self):
  26. self.manual_post_msg = _(
  27. '<h3>Please make a payment to: </h3><ul><li>Bank: %s</li><li>Account Number: %s</li><li>Account Holder: %s</li></ul>',
  28. self.journal_name or _("Bank"),
  29. self.acc_number or _("Account"),
  30. self.env.company.name
  31. )
  32. _payment_provider_onboarding_cache = {}
  33. def _get_manual_payment_provider(self, env=None):
  34. if env is None:
  35. env = self.env
  36. module_id = env.ref('base.module_payment_custom').id
  37. return env['payment.provider'].search([('module_id', '=', module_id),
  38. ('company_id', '=', env.company.id)], limit=1)
  39. def _get_default_payment_provider_onboarding_value(self, key):
  40. if not self.env.is_admin():
  41. raise UserError(_("Only administrators can access this data."))
  42. if self._data_fetched:
  43. return self._payment_provider_onboarding_cache.get(key, '')
  44. self._data_fetched = True
  45. self._payment_provider_onboarding_cache['payment_method'] = self.env.company.payment_onboarding_payment_method
  46. installed_modules = self.env['ir.module.module'].sudo().search([
  47. ('name', 'in', ('payment_paypal', 'payment_stripe')),
  48. ('state', '=', 'installed'),
  49. ]).mapped('name')
  50. if 'payment_paypal' in installed_modules:
  51. provider = self.env['payment.provider'].search(
  52. [('company_id', '=', self.env.company.id), ('code', '=', 'paypal')], limit=1
  53. )
  54. self._payment_provider_onboarding_cache['paypal_email_account'] = provider['paypal_email_account'] or self.env.user.email or ''
  55. self._payment_provider_onboarding_cache['paypal_pdt_token'] = provider['paypal_pdt_token']
  56. manual_payment = self._get_manual_payment_provider()
  57. journal = manual_payment.journal_id
  58. self._payment_provider_onboarding_cache['manual_name'] = manual_payment['name']
  59. self._payment_provider_onboarding_cache['manual_post_msg'] = manual_payment['pending_msg']
  60. self._payment_provider_onboarding_cache['journal_name'] = journal.name if journal.name != "Bank" else ""
  61. self._payment_provider_onboarding_cache['acc_number'] = journal.bank_acc_number
  62. return self._payment_provider_onboarding_cache.get(key, '')
  63. def add_payment_methods(self):
  64. """ Install required payment providers, configure them and mark the
  65. onboarding step as done."""
  66. payment_method = self.payment_method
  67. if self.payment_method == 'paypal':
  68. self.env.company._install_modules(['payment_paypal', 'account_payment'])
  69. elif self.payment_method == 'manual':
  70. self.env.company._install_modules(['account_payment'])
  71. if self.payment_method in ('paypal', 'manual'):
  72. # create a new env including the freshly installed module(s)
  73. new_env = api.Environment(self.env.cr, self.env.uid, self.env.context)
  74. if self.payment_method == 'paypal':
  75. provider = new_env['payment.provider'].search(
  76. [('company_id', '=', self.env.company.id), ('code', '=', 'paypal')], limit=1
  77. )
  78. if not provider:
  79. base_provider = self.env.ref('payment.payment_provider_paypal')
  80. # Use sudo to access payment provider record that can be in different company.
  81. provider = base_provider.sudo().copy(default={'company_id':self.env.company.id})
  82. default_journal = new_env['account.journal'].search(
  83. [('type', '=', 'bank'), ('company_id', '=', new_env.company.id)], limit=1
  84. )
  85. provider.write({
  86. 'paypal_email_account': self.paypal_email_account,
  87. 'paypal_pdt_token': self.paypal_pdt_token,
  88. 'state': 'enabled',
  89. 'is_published': 'True',
  90. 'journal_id': provider.journal_id or default_journal
  91. })
  92. elif self.payment_method == 'manual':
  93. manual_provider = self._get_manual_payment_provider(new_env)
  94. if not manual_provider:
  95. raise UserError(_(
  96. 'No manual payment method could be found for this company. '
  97. 'Please create one from the Payment Provider menu.'
  98. ))
  99. manual_provider.name = self.manual_name
  100. manual_provider.pending_msg = self.manual_post_msg
  101. manual_provider.state = 'enabled'
  102. journal = manual_provider.journal_id
  103. if journal:
  104. journal.name = self.journal_name
  105. journal.bank_acc_number = self.acc_number
  106. if self.payment_method in ('paypal', 'manual', 'stripe'):
  107. self.env.company.payment_onboarding_payment_method = self.payment_method
  108. # delete wizard data immediately to get rid of residual credentials
  109. self.sudo().unlink()
  110. if payment_method == 'stripe':
  111. return self._start_stripe_onboarding()
  112. # the user clicked `apply` and not cancel so we can assume this step is done.
  113. self._set_payment_provider_onboarding_step_done()
  114. return {'type': 'ir.actions.act_window_close'}
  115. def _set_payment_provider_onboarding_step_done(self):
  116. self.env.company.sudo().set_onboarding_step_done('payment_provider_onboarding_state')
  117. def _start_stripe_onboarding(self):
  118. """ Start Stripe Connect onboarding. """
  119. menu = self.env.ref('account_payment.payment_provider_menu', False)
  120. menu_id = menu and menu.id # Only set if `account_payment` is installed.
  121. return self.env.company._run_payment_onboarding_step(menu_id)