@@ -25,255 +25,8 @@ function codeable_estimate_callback() {
25
25
if ( isset ( $ _GET ['rate ' ] ) && is_numeric ( $ _GET ['rate ' ] ) ) {
26
26
$ rate = (float ) $ _GET ['rate ' ];
27
27
}
28
- ?>
29
- <div class="wrap">
30
- <h1>PERT Estimator</h1>
31
- <form id="estimator" class="metabox-holder">
32
- <div class="estimate-row">
33
- <div id="estimates" class="postbox">
34
- <h2 class="hndle">
35
- <span>Time required to complete task</span>
36
- </h2>
37
- <div class="inside">
38
- <div class="field">
39
- <span class="label">Optimistic estimate: </span><input id="optimistic_estimate" type="number" step="0.25" min="0.25" value="1" /> hours
40
- <small><em>(the lucky case, no scope changes, ...)</em></small>
41
- </div>
42
- <div class="field">
43
- <span class="label">Most likely estimate: </span><input id="likely_estimate" type="number" step="0.25" min="0.25" value="1" /> hours
44
- <small><em>(your experience)</em></small>
45
- </div>
46
- <div class="field">
47
- <span class="label">Pessimistic estimate: </span><input id="pessimistic_estimate" type="number" step="0.25" min="0.25" value="1" /> hours
48
- <small><em>(scope changes, bad communication, technical issues, ...)</em></small>
49
- </div>
50
- </div>
51
- </div>
52
-
53
- <div id="fees" class="postbox">
54
- <h2 class="hndle">
55
- <span>
56
- Rate and Fees
57
- <a href="<?php echo esc_url ( admin_url ( 'admin.php?page=codeable_settings ' ) ); ?> "><?php esc_html_e ( 'Change ' , 'wpcable ' ); ?> </a>
58
- </span>
59
- </h2>
60
- <div class="inside">
61
- <div class="field">
62
- <span class="label">Your hourly rate: </span><input id="hourly_rate" type="number" class="calc-input" value="<?php echo esc_attr ( $ rate ); ?> " min="35" max="1000" /> $
63
- </div>
64
- <div>
65
- <p class="description">
66
- <strong>Fees:
67
- <?php
68
- if ( 'full ' === $ fee_type ) {
69
- _e ( 'My rate is what I want to get paid, without any fees ' , 'wpcable ' );
70
- } elseif ( 'client ' === $ fee_type ) {
71
- _e ( 'My rate includes my fee (10%) but not the client fee ' , 'wpcable ' );
72
- } elseif ( 'none ' === $ fee_type ) {
73
- _e ( 'My rate includes all fees ' , 'wpcable ' );
74
- }
75
- ?> .</strong><br />
76
- <small>Following values are used to calculate the total estimate and your earnings.</small>
77
- </p>
78
- </div>
79
- <div class="field">
80
- <span class="label">Contractor fee: </span><input id="contractor_fee" type="number" class="calc-input" step="0.01" value="<?php echo esc_attr ( $ fee_contractor ); ?> " max="100" min="0" /> % (your fee)
81
- </div>
82
- <div class="field">
83
- <span class="label">Client fee: </span><input id="client_fee" type="number" class="calc-input" step="0.01" value="<?php echo esc_attr ( $ fee_client ); ?> " max="100" min="0" /> % (depends on the client)
84
- </div>
85
- </div>
86
- </div>
87
- </div>
88
-
89
- <div class="estimate-row">
90
- <div id="totals" class="postbox">
91
- <h2 class="hndle">
92
- <span>Totals</span>
93
- </h2>
94
- <div class="inside">
95
- <p class="description">
96
- Take these metrics as consideration if you put more weight on the realistic value. (Proper documentation, clear scope etc.)</p>
97
- <div class="field">
98
- <span class="label">Standard Estimate: </span><input id="estimate_hours_standard" type="text" value="" readonly="readonly"/> hours
99
- </div>
100
- <div class="field">
101
- <span class="label">Paid by the client: <br/><small>(including fees)</small></span><input id="payment" type="text" value="" readonly="readonly"/> $
102
- </div>
103
- <div class="field">
104
- <span class="label"><strong>Estimate</strong>: <br/><small>(what you enter in Codeable)</small></span><input id="estimate" type="text" value="" readonly="readonly"/> $
105
- </div>
106
- <div class="field">
107
- <span class="label">Your earnings</span><input id="earnings" type="text" value="" readonly="readonly"/> $
108
- </div>
109
- </div>
110
- </div>
111
-
112
- <div id="totals_pessimistic" class="postbox">
113
- <h2 class="hndle">
114
- <span>Totals, with extra buffer</span>
115
- </h2>
116
- <div class="inside">
117
- <p class="description">
118
- Take these metrics as consideration if you put more weight on the pessimistic value. (Not proper documentation, not so clear scope etc.)</p>
119
- <div class="field">
120
- <span class="label">Cautious Estimate: </span><input id="estimate_hours_pessimistic" type="text" value="" readonly="readonly"/> hours
121
- </div>
122
- <div class="field">
123
- <span class="label">Paid by the client: <br/><small>(including fees)</small></span><input id="payment_pessimistic" type="text" value="" readonly="readonly"/> $
124
- </div>
125
- <div class="field">
126
- <span class="label"><strong>Estimate</strong>: <br/><small>(what you enter in Codeable)</small></span><input id="estimate_pessimistic" type="text" value="" readonly="readonly"/> $
127
- </div>
128
- <div class="field">
129
- <span class="label">Your earnings</span><input id="earnings_pessimistic" type="text" value="" readonly="readonly"/> $
130
- </div>
131
- </div>
132
- </div>
133
- </div>
134
- </form>
135
- </div>
136
-
137
- <?php codeable_last_fetch_info (); ?>
138
-
139
- <script type="text/javascript">
140
- jQuery(document).ready(function($) {
141
- function round(value, step) {
142
- step || (step = 1.0);
143
- var inv = 1.0 / step;
144
-
145
- return (Math.round(value * inv) / inv)
146
- .toLocaleString(false, {minimumFractionDigits: 2, maximumFractionDigits: 2});
147
- }
148
-
149
- function applyAllFees( value ) {
150
- var feeContractor = 1 / (1 - parseFloat( $('#contractor_fee').val() ) / 100);
151
- var feeClient = 1 + parseFloat( $('#client_fee').val() ) / 100;
152
-
153
- <?php if ( 'full ' === $ fee_type ) : ?>
154
- var factor = feeContractor * feeClient;
155
- <?php elseif ( 'client ' === $ fee_type ) : ?>
156
- var factor = feeClient;
157
- <?php elseif ( 'none ' === $ fee_type ) : ?>
158
- var factor = 1;
159
- <?php endif ; ?>
160
-
161
- return round(value * factor, 0.01);
162
- }
163
-
164
- function applyMyFees( value ) {
165
- var feeContractor = 1 / (1 - parseFloat( $('#contractor_fee').val() ) / 100);
166
- var feeClient = 1 + parseFloat( $('#client_fee').val() ) / 100;
167
-
168
- <?php if ( 'full ' === $ fee_type ) : ?>
169
- var factor = feeContractor;
170
- <?php elseif ( 'client ' === $ fee_type ) : ?>
171
- var factor = 1;
172
- <?php elseif ( 'none ' === $ fee_type ) : ?>
173
- var factor = 1 / feeClient;
174
- <?php endif ; ?>
175
-
176
- return round(value * factor, 0.01);
177
- }
178
-
179
- function withoutFees( value ) {
180
- var feeContractor = 1 / (1 - parseFloat( $('#contractor_fee').val() ) / 100);
181
- var feeClient = 1 + parseFloat( $('#client_fee').val() ) / 100;
182
-
183
- <?php if ( 'full ' === $ fee_type ) : ?>
184
- var factor = 1;
185
- <?php elseif ( 'client ' === $ fee_type ) : ?>
186
- var factor = feeContractor;
187
- <?php elseif ( 'none ' === $ fee_type ) : ?>
188
- var factor = feeContractor * feeClient;
189
- <?php endif ; ?>
190
-
191
- return round(value / factor, 0.01);
192
- }
193
-
194
- function showTime( time ) {
195
- var hours = Math.floor( time );
196
- var minutes = parseInt((time - hours) * 60);
197
-
198
- return hours + ':' + ('00' + minutes).substr( -2 );
199
- }
200
-
201
- function calculate() {
202
- var optimistic = parseFloat($('#optimistic_estimate').val());
203
- var likely = parseFloat($('#likely_estimate').val());
204
- var pessimistic = parseFloat($('#pessimistic_estimate').val());
205
- var rate = parseFloat($('#hourly_rate').val());
206
-
207
- var estimate_hours_standard = (optimistic + 4 * likely + pessimistic) / 6;
208
- var estimate_hours_pessimistic = (optimistic + 2 * likely + 3 * pessimistic) / 6;
209
-
210
- var estimate_standard = estimate_hours_standard * rate;
211
- var estimate_pessimistic = estimate_hours_pessimistic * rate;
212
-
213
- $('#estimate_hours_standard').val(showTime( estimate_hours_standard ));
214
- $('#estimate_hours_pessimistic').val(showTime( estimate_hours_pessimistic ));
215
-
216
- $('#payment').val(applyAllFees( estimate_standard ));
217
- $('#payment_pessimistic').val(applyAllFees( estimate_pessimistic ));
218
-
219
- $('#estimate').val(applyMyFees( estimate_standard ));
220
- $('#estimate_pessimistic').val(applyMyFees( estimate_pessimistic ));
221
-
222
- $('#earnings').val(withoutFees( estimate_standard ));
223
- $('#earnings_pessimistic').val(withoutFees( estimate_pessimistic ));
224
- }
225
-
226
- function validateO() {
227
- var valO = parseFloat($('#optimistic_estimate').val());
228
- var valM = parseFloat($('#likely_estimate').val());
229
- var valP = parseFloat($('#pessimistic_estimate').val());
230
-
231
- if (valO > valM) {
232
- $('#likely_estimate').val(valO);
233
- }
234
- if (valO > valP) {
235
- $('#pessimistic_estimate').val(valO);
236
- }
237
-
238
- calculate();
239
- }
240
-
241
- function validateM() {
242
- var valO = parseFloat($('#optimistic_estimate').val());
243
- var valM = parseFloat($('#likely_estimate').val());
244
- var valP = parseFloat($('#pessimistic_estimate').val());
245
-
246
- if (valO > valM) {
247
- $('#optimistic_estimate').val(valM);
248
- }
249
- if (valM > valP) {
250
- $('#pessimistic_estimate').val(valM);
251
- }
252
-
253
- calculate();
254
- }
255
-
256
- function validateP() {
257
- var valO = parseFloat($('#optimistic_estimate').val());
258
- var valM = parseFloat($('#likely_estimate').val());
259
- var valP = parseFloat($('#pessimistic_estimate').val());
260
-
261
- if (valO > valP) {
262
- $('#optimistic_estimate').val(valP);
263
- }
264
- if (valM > valP) {
265
- $('#likely_estimate').val(valP);
266
- }
267
-
268
- calculate();
269
- }
270
-
271
- $('.calc-input').on('change', calculate);
272
- $('#optimistic_estimate').on('change', validateO)
273
- $('#likely_estimate').on('change', validateM)
274
- $('#pessimistic_estimate').on('change', validateP)
275
- calculate();
276
- });
277
- </script>
278
- <?php
28
+ $ admin_estimate_template = apply_filters ('wpcable_admin_estimate_template ' , WPCABLE_TEMPLATE_DIR .'/admin-estimate.php ' ) ;
29
+ ob_start ();
30
+ require_once $ admin_estimate_template ;
31
+ echo ob_get_clean ();
279
32
}
0 commit comments