Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
 
 
 
 

158 righe
4.1 KiB

  1. import json
  2. import frappe
  3. from frappe.core.doctype.file import remove_file_by_url
  4. from frappe.rate_limiter import rate_limit
  5. from frappe.website.doctype.web_form.web_form import WebForm
  6. from payments.utils import get_payment_gateway_controller
  7. class PaymentWebForm(WebForm):
  8. def validate(self):
  9. super().validate()
  10. if getattr(self, "accept_payment", False):
  11. self.validate_payment_amount()
  12. def validate_payment_amount(self):
  13. if self.amount_based_on_field and not self.amount_field:
  14. frappe.throw(frappe._("Please select a Amount Field."))
  15. elif not self.amount_based_on_field and not self.amount > 0:
  16. frappe.throw(frappe._("Amount must be greater than 0."))
  17. def get_payment_gateway_url(self, doc):
  18. if getattr(self, "accept_payment", False):
  19. controller = get_payment_gateway_controller(self.payment_gateway)
  20. title = f"Payment for {doc.doctype} {doc.name}"
  21. amount = self.amount
  22. if self.amount_based_on_field:
  23. amount = doc.get(self.amount_field)
  24. from decimal import Decimal
  25. if amount is None or Decimal(amount) <= 0:
  26. return frappe.utils.get_url(self.success_url or self.route)
  27. payment_details = {
  28. "amount": amount,
  29. "title": title,
  30. "description": title,
  31. "reference_doctype": doc.doctype,
  32. "reference_docname": doc.name,
  33. "payer_email": frappe.session.user,
  34. "payer_name": frappe.utils.get_fullname(frappe.session.user),
  35. "order_id": doc.name,
  36. "currency": self.currency,
  37. "redirect_to": frappe.utils.get_url(self.success_url or self.route),
  38. }
  39. # Redirect the user to this url
  40. return controller.get_payment_url(**payment_details)
  41. @frappe.whitelist(allow_guest=True)
  42. @rate_limit(key="web_form", limit=5, seconds=60, methods=["POST"])
  43. def accept(web_form, data, docname=None, for_payment=False):
  44. """Save the web form"""
  45. data = frappe._dict(json.loads(data))
  46. for_payment = frappe.parse_json(for_payment)
  47. files = []
  48. files_to_delete = []
  49. web_form = frappe.get_doc("Web Form", web_form)
  50. if data.name and not web_form.allow_edit:
  51. frappe.throw(frappe._("You are not allowed to update this Web Form Document"))
  52. frappe.flags.in_web_form = True
  53. meta = frappe.get_meta(data.doctype)
  54. if docname:
  55. # update
  56. doc = frappe.get_doc(data.doctype, docname)
  57. else:
  58. # insert
  59. doc = frappe.new_doc(data.doctype)
  60. # set values
  61. for field in web_form.web_form_fields:
  62. fieldname = field.fieldname
  63. df = meta.get_field(fieldname)
  64. value = data.get(fieldname, None)
  65. if df and df.fieldtype in ("Attach", "Attach Image"):
  66. if value and "data:" and "base64" in value:
  67. files.append((fieldname, value))
  68. if not doc.name:
  69. doc.set(fieldname, "")
  70. continue
  71. elif not value and doc.get(fieldname):
  72. files_to_delete.append(doc.get(fieldname))
  73. doc.set(fieldname, value)
  74. if for_payment:
  75. web_form.validate_mandatory(doc)
  76. doc.run_method("validate_payment")
  77. if doc.name:
  78. if web_form.has_web_form_permission(doc.doctype, doc.name, "write"):
  79. doc.save(ignore_permissions=True)
  80. else:
  81. # only if permissions are present
  82. doc.save()
  83. else:
  84. # insert
  85. if web_form.login_required and frappe.session.user == "Guest":
  86. frappe.throw(frappe._("You must login to submit this form"))
  87. ignore_mandatory = True if files else False
  88. doc.insert(ignore_permissions=True, ignore_mandatory=ignore_mandatory)
  89. # add files
  90. if files:
  91. for f in files:
  92. fieldname, filedata = f
  93. # remove earlier attached file (if exists)
  94. if doc.get(fieldname):
  95. remove_file_by_url(doc.get(fieldname), doctype=doc.doctype, name=doc.name)
  96. # save new file
  97. filename, dataurl = filedata.split(",", 1)
  98. _file = frappe.get_doc(
  99. {
  100. "doctype": "File",
  101. "file_name": filename,
  102. "attached_to_doctype": doc.doctype,
  103. "attached_to_name": doc.name,
  104. "content": dataurl,
  105. "decode": True,
  106. }
  107. )
  108. _file.save()
  109. # update values
  110. doc.set(fieldname, _file.file_url)
  111. doc.save(ignore_permissions=True)
  112. if files_to_delete:
  113. for f in files_to_delete:
  114. if f:
  115. remove_file_by_url(f, doctype=doc.doctype, name=doc.name)
  116. frappe.flags.web_form_doc = doc
  117. if for_payment:
  118. # this is needed for Payments app
  119. return web_form.get_payment_gateway_url(doc)
  120. else:
  121. return doc