WebOrbiton
v1.0.0.1

StocketBase

88 lines · 3.4 KB
  1. <?php
  2. ​
  3. declare(strict_types=1);
  4. ​
  5. if (count(get_included_files()) === 1) {
  6. http_response_code(403);
  7. exit;
  8. }
  9. ​
  10. require_once __DIR__ . '/../includes/currency.php';
  11. ​
  12. if (!Auth::hasRoleAtLeast(Auth::ROLE_STORE_MANAGER)) {
  13. return ['You don\'t have access to discounts.', 'error', false];
  14. }
  15. ​
  16. $db = Database::site();
  17. ​
  18. $discountId = (int) ($_POST['discount_id'] ?? 0) ?: null;
  19. $code = strtoupper(trim((string) ($_POST['code'] ?? '')));
  20. $description = trim((string) ($_POST['description'] ?? ''));
  21. $discountType = ($_POST['discount_type'] ?? 'percentage') === 'fixed_amount' ? 'fixed_amount' : 'percentage';
  22. $currencyCode = Currency::normalize((string) ($_POST['currency'] ?? SiteFront::settings()['store_currency'] ?? 'USD'));
  23. $rawValue = (string) ($_POST['value'] ?? '0');
  24. ​
  25. if ($discountType === 'percentage') {
  26. $value = max(1, min(100, (int) round((float) $rawValue)));
  27. } else {
  28. $value = (int) round(((float) $rawValue) * (10 ** Currency::decimals($currencyCode)));
  29. }
  30. ​
  31. $minOrderRaw = trim((string) ($_POST['min_order'] ?? ''));
  32. $minOrderCents = $minOrderRaw !== '' ? (int) round(((float) $minOrderRaw) * (10 ** Currency::decimals($currencyCode))) : null;
  33. $maxRedemptions = (int) ($_POST['max_redemptions'] ?? 0) ?: null;
  34. $isActive = isset($_POST['is_active']) ? 1 : 0;
  35. ​
  36. if ($code === '') {
  37. return ['Please type a code for the discount.', 'error', false];
  38. }
  39. ​
  40. try {
  41. if ($discountId !== null) {
  42. $update = $db->prepare(
  43. 'UPDATE discounts SET code = :code, description = :description, discount_type = :type, value = :value,
  44. currency = :currency, min_order_cents = :min_order, max_redemptions = :max_redemptions, is_active = :is_active,
  45. updated_at = NOW() WHERE id = :id'
  46. );
  47. $update->execute([
  48. 'code' => $code,
  49. 'description' => $description !== '' ? $description : null,
  50. 'type' => $discountType,
  51. 'value' => $value,
  52. 'currency' => $discountType === 'fixed_amount' ? $currencyCode : null,
  53. 'min_order' => $minOrderCents,
  54. 'max_redemptions' => $maxRedemptions,
  55. 'is_active' => $isActive,
  56. 'id' => $discountId,
  57. ]);
  58. ​
  59. return ['Discount saved.', 'success', true];
  60. }
  61. ​
  62. $insert = $db->prepare(
  63. 'INSERT INTO discounts (code, description, discount_type, value, currency, min_order_cents, max_redemptions, is_active, created_by)
  64. VALUES (:code, :description, :type, :value, :currency, :min_order, :max_redemptions, :is_active, :created_by)'
  65. );
  66. $insert->execute([
  67. 'code' => $code,
  68. 'description' => $description !== '' ? $description : null,
  69. 'type' => $discountType,
  70. 'value' => $value,
  71. 'currency' => $discountType === 'fixed_amount' ? $currencyCode : null,
  72. 'min_order' => $minOrderCents,
  73. 'max_redemptions' => $maxRedemptions,
  74. 'is_active' => $isActive,
  75. 'created_by' => $currentUser['id'],
  76. ]);
  77. ​
  78. return ['Discount created. Customers can use it now.', 'success', true];
  79. } catch (PDOException $exception) {
  80. if ((int) $exception->getCode() === 23000 || str_contains($exception->getMessage(), 'uq_discount_code')) {
  81. return ['That code is taken. Try a different one.', 'error', false];
  82. }
  83. ​
  84. error_log('StocketBase: could not save discount: ' . $exception->getMessage());
  85. ​
  86. return ['Something went wrong while saving. Please try again.', 'error', false];
  87. }
  88. ​