Diff -- /var/www/vhosts/3dshawn.com/affiliate.3dshawn.com/promotion_action.cgi
Diff

/var/www/vhosts/3dshawn.com/affiliate.3dshawn.com/promotion_action.cgi

added on local at 2026-07-01 13:47:41

Added
+206
lines
Removed
-0
lines
Context
0
unchanged
Blobs
from
to 702e97655185
Restore this content →
Unified diff
Naive LCS-based line diff. Additions in emerald, deletions in rose. Both sides decompressed live from BLOB_STORE.
1#!/usr/bin/perl
2#======================================================================
3# WebSTLs - Seller Promotion Actions
4#
5# Handles create/update/delete/activate/pause for promotions owned by
6# the logged-in seller. Every action checks ownership via Promotions
7# helper before mutating.
8#======================================================================
9use strict;
10use warnings;
11
12use lib '/var/www/vhosts/3dshawn.com/affiliate.3dshawn.com';
13use CGI;
14use MODS::DBConnect;
15use MODS::Login;
16use MODS::AffSoft::Config;
17use MODS::AffSoft::Promotions;
18
19my $q = CGI->new;
20my $form = $q->Vars;
21my $auth = MODS::Login->new;
22my $db = MODS::DBConnect->new;
23my $cfg = MODS::AffSoft::Config->new;
24my $promo = MODS::AffSoft::Promotions->new;
25my $DB = $cfg->settings('database_name');
26
27$|=1;
28my $userinfo = $auth->login_verify();
29if (!$userinfo) {
30 print "Status: 302 Found\nLocation: /login.cgi\n\n";
31 exit;
32}
33require MODS::AffSoft::Permissions;
34MODS::AffSoft::Permissions->new->require_feature($userinfo, 'edit_promotions');
35my $uid = $userinfo->{user_id};
36$uid =~ s/[^0-9]//g;
37
38my $act = defined $form->{act} ? $form->{act} : '';
39
40my $dbh = $db->db_connect();
41unless ($promo->schema_ready($db, $dbh, $DB)) {
42 $db->db_disconnect($dbh);
43 _redirect('/promotions.cgi?err=schema');
44 exit;
45}
46
47# Find the seller's primary storefront -- new rows are attached to it.
48my $sf = $db->db_readwrite($dbh,
49 qq~SELECT id FROM `${DB}`.storefronts WHERE user_id='$uid' ORDER BY id LIMIT 1~,
50 $ENV{SCRIPT_NAME}, __LINE__);
51my $store_id = ($sf && $sf->{id}) ? $sf->{id} : 0;
52
53if ($act eq 'create') {
54 unless ($store_id) {
55 $db->db_disconnect($dbh);
56 _redirect('/promotions.cgi?err=no_storefront');
57 exit;
58 }
59 my $new_id = $promo->create($db, $dbh, $DB,
60 scope => 'storefront',
61 storefront_id => $store_id,
62 kind => $form->{kind},
63 name => $form->{name},
64 description => $form->{description},
65 discount_type => $form->{discount_type},
66 discount_value_bp => _percent_to_bp($form->{discount_value_pct}),
67 discount_value_cents => _dollars_to_cents($form->{discount_value_amt}),
68 minimum_order_cents => _dollars_to_cents($form->{minimum_order}),
69 code => $form->{code},
70 public_slug => $form->{public_slug},
71 starts_at => $form->{starts_at_local},
72 ends_at => $form->{ends_at_local},
73 max_redemptions => $form->{max_redemptions},
74 max_per_user => $form->{max_per_user},
75 new_customers_only => $form->{new_customers_only},
76 status => $form->{publish_now} ? 'active' : 'draft',
77 created_by_user_id => $uid,
78 );
79 unless ($new_id) {
80 $db->db_disconnect($dbh);
81 _redirect('/promotions.cgi?err=bad_input');
82 exit;
83 }
84 _attach_models($promo, $db, $dbh, $DB, $new_id, $form);
85 $db->db_disconnect($dbh);
86 _redirect('/promotions.cgi?ok=created');
87 exit;
88}
89
90if ($act eq 'update') {
91 my $id = $form->{id}; $id =~ s/[^0-9]//g;
92 my $row = $id ? $promo->get_for_seller($db, $dbh, $DB, $id, $uid) : {};
93 unless ($row && $row->{id}) {
94 $db->db_disconnect($dbh);
95 _redirect('/promotions.cgi?err=denied');
96 exit;
97 }
98 my $ok = $promo->update($db, $dbh, $DB, $id,
99 scope => 'storefront',
100 storefront_id => $store_id,
101 kind => $form->{kind},
102 name => $form->{name},
103 description => $form->{description},
104 discount_type => $form->{discount_type},
105 discount_value_bp => _percent_to_bp($form->{discount_value_pct}),
106 discount_value_cents => _dollars_to_cents($form->{discount_value_amt}),
107 minimum_order_cents => _dollars_to_cents($form->{minimum_order}),
108 code => $form->{code},
109 public_slug => $form->{public_slug},
110 starts_at => $form->{starts_at_local},
111 ends_at => $form->{ends_at_local},
112 max_redemptions => $form->{max_redemptions},
113 max_per_user => $form->{max_per_user},
114 new_customers_only => $form->{new_customers_only},
115 );
116 unless ($ok) {
117 $db->db_disconnect($dbh);
118 _redirect('/promotions.cgi?err=bad_input');
119 exit;
120 }
121 # Refresh model attachments.
122 $promo->clear_models($db, $dbh, $DB, $id);
123 _attach_models($promo, $db, $dbh, $DB, $id, $form);
124
125 $db->db_disconnect($dbh);
126 _redirect('/promotions.cgi?ok=updated');
127 exit;
128}
129
130if ($act eq 'activate' || $act eq 'pause' || $act eq 'archive') {
131 my $id = $form->{id}; $id =~ s/[^0-9]//g;
132 my $row = $id ? $promo->get_for_seller($db, $dbh, $DB, $id, $uid) : {};
133 unless ($row && $row->{id}) {
134 $db->db_disconnect($dbh);
135 _redirect('/promotions.cgi?err=denied');
136 exit;
137 }
138 my $new_status =
139 $act eq 'activate' ? 'active' :
140 $act eq 'pause' ? 'paused' :
141 'archived';
142 $promo->set_status($db, $dbh, $DB, $id, $new_status);
143 $db->db_disconnect($dbh);
144 _redirect('/promotions.cgi?ok=' . ($act eq 'activate' ? 'activated' : $act eq 'pause' ? 'paused' : 'updated'));
145 exit;
146}
147
148if ($act eq 'delete') {
149 my $id = $form->{id}; $id =~ s/[^0-9]//g;
150 my $row = $id ? $promo->get_for_seller($db, $dbh, $DB, $id, $uid) : {};
151 unless ($row && $row->{id}) {
152 $db->db_disconnect($dbh);
153 _redirect('/promotions.cgi?err=denied');
154 exit;
155 }
156 $promo->delete_promo($db, $dbh, $DB, $id);
157 $db->db_disconnect($dbh);
158 _redirect('/promotions.cgi?ok=deleted');
159 exit;
160}
161
162$db->db_disconnect($dbh);
163_redirect('/promotions.cgi?err=unknown_act');
164
165# ------------------------------------------------------------- helpers
166sub _redirect {
167 my $url = shift;
168 print "Status: 302 Found\nLocation: $url\n\n";
169}
170
171sub _percent_to_bp {
172 my $v = shift;
173 return 0 unless defined $v && $v ne '';
174 $v =~ s/[^0-9.]//g;
175 return 0 unless length $v;
176 my $bp = int($v * 100);
177 $bp = 0 if $bp < 0;
178 $bp = 10000 if $bp > 10000;
179 return $bp;
180}
181
182sub _dollars_to_cents {
183 my $v = shift;
184 return 0 unless defined $v && $v ne '';
185 $v =~ s/[^0-9.]//g;
186 return 0 unless length $v;
187 return int($v * 100 + 0.5);
188}
189
190# Pull the selected model ids out of the form (checkbox names like
191# model_id[]). Attach each at the requested role.
192sub _attach_models {
193 my ($promo, $db, $dbh, $DB, $promo_id, $form) = @_;
194 # CGI may store multi-valued fields as "\0"-joined strings.
195 my @ids;
196 my $raw = $form->{'model_ids'};
197 if (defined $raw && $raw ne '') {
198 @ids = split(/\0/, $raw);
199 }
200 foreach my $mid (@ids) {
201 $mid =~ s/[^0-9]//g;
202 next unless $mid;
203 my $role = $form->{"role_$mid"} || 'target';
204 $promo->add_model($db, $dbh, $DB, $promo_id, $mid, $role);
205 }
206}
Keyboard: j next diff k previous diff g top G bottom r restore c compile-check ? help