Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
0.00% |
0 / 535 |
|
0.00% |
0 / 18 |
CRAP | |
0.00% |
0 / 7 |
| zeroBSCRM_QuotesMetaboxSetup | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
2 | |||
| zeroBS__Metabox_Quote | |
0.00% |
0 / 239 |
|
0.00% |
0 / 5 |
5550 | |
0.00% |
0 / 1 |
| __construct | |
0.00% |
0 / 17 |
|
0.00% |
0 / 1 |
2 | |||
| html | |
0.00% |
0 / 140 |
|
0.00% |
0 / 1 |
1406 | |||
| save_data | |
0.00% |
0 / 74 |
|
0.00% |
0 / 1 |
992 | |||
| post_save_data | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
20 | |||
| updateMessage | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
| zeroBS__Metabox_QuoteContent | |
0.00% |
0 / 33 |
|
0.00% |
0 / 2 |
42 | |
0.00% |
0 / 1 |
| __construct | |
0.00% |
0 / 17 |
|
0.00% |
0 / 1 |
2 | |||
| html | |
0.00% |
0 / 16 |
|
0.00% |
0 / 1 |
30 | |||
| zeroBS__Metabox_QuoteNextStep | |
0.00% |
0 / 89 |
|
0.00% |
0 / 2 |
930 | |
0.00% |
0 / 1 |
| __construct | |
0.00% |
0 / 17 |
|
0.00% |
0 / 1 |
2 | |||
| html | |
0.00% |
0 / 72 |
|
0.00% |
0 / 1 |
870 | |||
| zeroBS__Metabox_QuoteFiles | |
0.00% |
0 / 69 |
|
0.00% |
0 / 3 |
462 | |
0.00% |
0 / 1 |
| __construct | |
0.00% |
0 / 14 |
|
0.00% |
0 / 1 |
2 | |||
| html | |
0.00% |
0 / 31 |
|
0.00% |
0 / 1 |
56 | |||
| save_data | |
0.00% |
0 / 24 |
|
0.00% |
0 / 1 |
182 | |||
| zeroBS__Metabox_QuoteAcceptedDetails | |
0.00% |
0 / 46 |
|
0.00% |
0 / 2 |
380 | |
0.00% |
0 / 1 |
| __construct | |
0.00% |
0 / 19 |
|
0.00% |
0 / 1 |
6 | |||
| html | |
0.00% |
0 / 27 |
|
0.00% |
0 / 1 |
306 | |||
| zeroBS__Metabox_QuoteTags | |
0.00% |
0 / 16 |
|
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
| __construct | |
0.00% |
0 / 16 |
|
0.00% |
0 / 1 |
2 | |||
| zeroBS__Metabox_QuoteActions | |
0.00% |
0 / 34 |
|
0.00% |
0 / 2 |
42 | |
0.00% |
0 / 1 |
| __construct | |
0.00% |
0 / 17 |
|
0.00% |
0 / 1 |
2 | |||
| html | |
0.00% |
0 / 17 |
|
0.00% |
0 / 1 |
30 | |||
| 1 | <?php |
| 2 | /* |
| 3 | * Jetpack CRM |
| 4 | * https://jetpackcrm.com |
| 5 | * V3.0 |
| 6 | * |
| 7 | * Copyright 2020 Automattic |
| 8 | * |
| 9 | * Date: 20/02/2019 |
| 10 | */ |
| 11 | |
| 12 | defined( 'ZEROBSCRM_PATH' ) || exit( 0 ); |
| 13 | |
| 14 | /* |
| 15 | ====================================================== |
| 16 | Init Func |
| 17 | ====================================================== */ |
| 18 | |
| 19 | function zeroBSCRM_QuotesMetaboxSetup() { |
| 20 | |
| 21 | // main detail |
| 22 | $zeroBS__Metabox_Quote = new zeroBS__Metabox_Quote( __FILE__ ); |
| 23 | |
| 24 | // quote content box |
| 25 | $zeroBS__Metabox_QuoteContent = new zeroBS__Metabox_QuoteContent( __FILE__ ); |
| 26 | |
| 27 | // quote next step box (publish etc.) |
| 28 | $zeroBS__Metabox_QuoteNextStep = new zeroBS__Metabox_QuoteNextStep( __FILE__ ); |
| 29 | |
| 30 | // quote actions box |
| 31 | $zeroBS__Metabox_QuoteActions = new zeroBS__Metabox_QuoteActions( __FILE__ ); |
| 32 | |
| 33 | // quote tags box |
| 34 | $zeroBS__Metabox_QuoteTags = new zeroBS__Metabox_QuoteTags( __FILE__ ); |
| 35 | |
| 36 | // quote accepted details |
| 37 | $zeroBS__Metabox_QuoteAcceptedDetails = new zeroBS__Metabox_QuoteAcceptedDetails( __FILE__ ); |
| 38 | |
| 39 | // files |
| 40 | $zeroBS__Metabox_QuoteFiles = new zeroBS__Metabox_QuoteFiles( __FILE__ ); |
| 41 | } |
| 42 | |
| 43 | add_action( 'admin_init', 'zeroBSCRM_QuotesMetaboxSetup' ); |
| 44 | |
| 45 | /* |
| 46 | $zeroBS__MetaboxQuote = new zeroBS__MetaboxQuote( __FILE__ ); |
| 47 | $zeroBS__QuoteContentMetabox = new zeroBS__QuoteContentMetabox( __FILE__ ); |
| 48 | $zeroBS__QuoteActionsMetabox = new zeroBS__QuoteActionsMetabox( __FILE__ ); |
| 49 | $zeroBS__QuoteStatusMetabox = new zeroBS__QuoteStatusMetabox( __FILE__ ); |
| 50 | */ |
| 51 | |
| 52 | /* |
| 53 | ====================================================== |
| 54 | / Init Func |
| 55 | ====================================================== */ |
| 56 | |
| 57 | /* |
| 58 | ====================================================== |
| 59 | Quote Metabox |
| 60 | ====================================================== */ |
| 61 | |
| 62 | class zeroBS__Metabox_Quote extends zeroBS__Metabox { |
| 63 | |
| 64 | // this is for catching 'new' quotes |
| 65 | private $newRecordNeedsRedir = false; |
| 66 | |
| 67 | public function __construct( $plugin_file ) { |
| 68 | |
| 69 | // set these |
| 70 | $this->objType = 'quote'; |
| 71 | $this->metaboxID = 'zerobs-quote-edit'; |
| 72 | $this->metaboxTitle = __( 'Step 1: Quote Details', 'zero-bs-crm' ); // will be headless anyhow |
| 73 | $this->headless = true; |
| 74 | $this->metaboxScreen = 'zbs-add-edit-quote-edit'; |
| 75 | $this->metaboxArea = 'normal'; |
| 76 | $this->metaboxLocation = 'high'; |
| 77 | $this->saveOrder = 1; |
| 78 | $this->capabilities = array( |
| 79 | |
| 80 | 'can_hide' => false, // can be hidden |
| 81 | 'areas' => array( 'normal' ), // areas can be dragged to - normal side = only areas currently |
| 82 | 'can_accept_tabs' => true, // can/can't accept tabs onto it |
| 83 | 'can_become_tab' => false, // can be added as tab |
| 84 | 'can_minimise' => true, // can be minimised |
| 85 | 'can_move' => true, // can be moved |
| 86 | |
| 87 | ); |
| 88 | |
| 89 | // call this |
| 90 | $this->initMetabox(); |
| 91 | } |
| 92 | |
| 93 | public function html( $quote, $metabox ) { |
| 94 | |
| 95 | // localise ID |
| 96 | $quoteID = -1; |
| 97 | if ( is_array( $quote ) && isset( $quote['id'] ) ) { |
| 98 | $quoteID = (int) $quote['id']; |
| 99 | } |
| 100 | |
| 101 | // if new + $zbsObjDataPrefill passed, use that instead of loaded trans. |
| 102 | if ( $quoteID == -1 ) { |
| 103 | global $zbsObjDataPrefill; |
| 104 | $quote = $zbsObjDataPrefill; |
| 105 | } |
| 106 | |
| 107 | global $zbs; |
| 108 | |
| 109 | // Define Quote statuses. |
| 110 | $acceptable_quote_statuses = jpcrm_get_quote_statuses(); |
| 111 | |
| 112 | // status |
| 113 | $status = $acceptable_quote_statuses['draft']; |
| 114 | if ( is_array( $quote ) && isset( $quote['status'] ) ) { |
| 115 | if ( $quote['status'] === -2 ) { |
| 116 | $status = $acceptable_quote_statuses['published']; |
| 117 | } |
| 118 | if ( $quote['status'] === 1 ) { |
| 119 | $status = $acceptable_quote_statuses['accepted']; |
| 120 | } |
| 121 | } |
| 122 | // Debug echo 'Quote:<pre>'.print_r($quote,1).'</pre>'; |
| 123 | |
| 124 | ?> |
| 125 | <script type="text/javascript">var zbscrmjs_secToken = '<?php echo esc_js( wp_create_nonce( 'zbscrmjs-ajax-nonce' ) ); ?>';</script> |
| 126 | <?php |
| 127 | |
| 128 | #} retrieve |
| 129 | // some legacy bits from CPT days: |
| 130 | $quoteContactID = -1; |
| 131 | if ( is_array( $quote ) && isset( $quote['contact'] ) && is_array( $quote['contact'] ) && count( $quote['contact'] ) > 0 ) { |
| 132 | $quoteContactID = $quote['contact'][0]['id']; // get_post_meta($post->ID, 'zbs_customer_quote_customer', true); |
| 133 | } |
| 134 | $templateUsed = -1; |
| 135 | if ( is_array( $quote ) && isset( $quote['template'] ) ) { |
| 136 | $templateUsed = $quote['template']; // get_post_meta($post->ID, 'zbs_quote_template_id', true); |
| 137 | } |
| 138 | |
| 139 | #} this is a temp weird one, just passing onto meta for now (long day): |
| 140 | // ? Not used DAL3? |
| 141 | // $zbsTemplated = get_post_meta($post->ID, 'templated', true); |
| 142 | // if (!empty($zbsTemplated)) $quote['templated'] = true; |
| 143 | // quick WH predictive hack, not sure if viable - to test DAL3 |
| 144 | $quote['templated'] = false; |
| 145 | if ( $templateUsed !== -1 && ! empty( $templateUsed ) ) { |
| 146 | $quote['templated'] = true; |
| 147 | } |
| 148 | |
| 149 | #} if customer id is empty, but prefill isn't, use prefill |
| 150 | if ( $quoteContactID == -1 && isset( $_GET['zbsprefillcust'] ) ) { |
| 151 | $quoteContactID = (int) $_GET['zbsprefillcust']; |
| 152 | } |
| 153 | |
| 154 | #} pass to other metaboxes (cache?) |
| 155 | global $zbsCurrentEditQuote; |
| 156 | $zbsCurrentEditQuote = $quote; |
| 157 | |
| 158 | #} Retrieve fields from global |
| 159 | global $zbsCustomerQuoteFields; |
| 160 | $fields = $zbsCustomerQuoteFields; |
| 161 | // Debug echo 'Fields:<pre>'.print_r($fields,1).'</pre>'; |
| 162 | |
| 163 | #} Using "Quote Builder" or not? |
| 164 | $useQuoteBuilder = zeroBSCRM_getSetting( 'usequotebuilder' ); |
| 165 | |
| 166 | // Inputs out: |
| 167 | |
| 168 | #} New quote? |
| 169 | if ( ! isset( $quote['id'] ) ) { |
| 170 | echo '<input type="hidden" name="zbscrm_newquote" value="1" />'; |
| 171 | } |
| 172 | |
| 173 | #} pass this if already templated: |
| 174 | if ( $useQuoteBuilder == 1 && isset( $quote['template'] ) ) { |
| 175 | echo '<input type="hidden" name="zbscrm_templated" id="zbscrm_templated" value="1" />'; |
| 176 | } |
| 177 | |
| 178 | #} Nonce used for loading quote template, left in for now, could be centralised to normal sec nonce |
| 179 | echo '<input type="hidden" name="quo-ajax-nonce" id="quo-ajax-nonce" value="' . esc_attr( wp_create_nonce( 'quo-ajax-nonce' ) ) . '" />'; |
| 180 | |
| 181 | // we pass the hash along the chain here too :) |
| 182 | echo '<input type="hidden" name="zbscq_hash" id="zbscq_hash" value="' . ( isset( $quote['hash'] ) ? esc_attr( $quote['hash'] ) : '' ) . '" />'; |
| 183 | ?> |
| 184 | <div> |
| 185 | <div class="jpcrm-form-grid" id="wptbpMetaBoxMainItem"> |
| 186 | <?php |
| 187 | |
| 188 | // DAL3 only show after saved, easier |
| 189 | if ( ! empty( $quoteID ) && $quoteID > 0 ) { |
| 190 | ?> |
| 191 | <div class="jpcrm-form-group jpcrm-form-group-span-2"> |
| 192 | <label class="jpcrm-form-label"><?php esc_html_e( 'Quote (ID)', 'zero-bs-crm' ); ?>:</label> |
| 193 | <?php |
| 194 | echo '<b>' . esc_html( $quoteID ) . '</b>'; //phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase |
| 195 | ?> |
| 196 | <input type="hidden" name="zbsquoteid" value="<?php echo esc_attr( $quoteID ); //phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase ?>" /> |
| 197 | </div> |
| 198 | <?php |
| 199 | |
| 200 | } |
| 201 | // Quote status. |
| 202 | if ( $quoteID > 0 ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase |
| 203 | ?> |
| 204 | |
| 205 | <div class="jpcrm-form-group jpcrm-form-group-span-2"> |
| 206 | <label class="jpcrm-form-label" for="quote_status"><?php esc_html_e( 'Status', 'zero-bs-crm' ); ?>:</label> |
| 207 | <select class="form-control" id="quote_status" name="quote_status"> |
| 208 | <?php |
| 209 | foreach ( $acceptable_quote_statuses as $status_opt => $status_str ) { |
| 210 | $sel = ''; |
| 211 | if ( $status_str === $status ) { |
| 212 | $sel = ' selected="selected"'; |
| 213 | } |
| 214 | /* Translators: %s is the Quote status. */ |
| 215 | echo '<option value="' . esc_attr( $status_opt ) . '"' . esc_attr( $sel ) . '>' . esc_html( sprintf( __( '%s', 'zero-bs-crm' ), $status_str ) ) . '</option>'; // phpcs:ignore WordPress.WP.I18n.NoEmptyStrings |
| 216 | } |
| 217 | ?> |
| 218 | </select> |
| 219 | </div> |
| 220 | <?php |
| 221 | } // end if |
| 222 | |
| 223 | ?> |
| 224 | <div class="jpcrm-form-group jpcrm-form-group-span-2 jpcrm-override-typeahead-padding"> |
| 225 | <label class="jpcrm-form-label"><?php esc_html_e( 'Contact', 'zero-bs-crm' ); ?>:</label> |
| 226 | <?php |
| 227 | |
| 228 | #} 27/09/16 - switched select for typeahead |
| 229 | |
| 230 | #} Any customer? |
| 231 | $prefillStr = ''; if ( isset( $quoteContactID ) && ! empty( $quoteContactID ) ) { |
| 232 | |
| 233 | $prefillStr = $zbs->DAL->contacts->getContactNameWithFallback( $quoteContactID ); |
| 234 | |
| 235 | } |
| 236 | |
| 237 | #} Output select box |
| 238 | echo zeroBSCRM_CustomerTypeList( 'zbscrmjs_quoteCustomerSelect', $prefillStr, true, 'zbscrmjs_quote_unsetCustomer' ); |
| 239 | |
| 240 | #} Output input which will pass the value via post |
| 241 | ?> |
| 242 | <input type="hidden" name="zbscq_customer" id="zbscq_customer" value="<?php echo esc_attr( $quoteContactID ); ?>" /> |
| 243 | <?php |
| 244 | |
| 245 | #} Output function which will copy over value - maybe later move to js |
| 246 | ?> |
| 247 | <script type="text/javascript"> |
| 248 | |
| 249 | jQuery(function(){ |
| 250 | |
| 251 | // bind |
| 252 | setTimeout(function(){ |
| 253 | zeroBSCRMJS_showContactLinkIf(jQuery("#zbscq_customer").val()); |
| 254 | },0); |
| 255 | |
| 256 | }); |
| 257 | |
| 258 | function zbscrmjs_quoteCustomerSelect(cust){ |
| 259 | |
| 260 | // pass id to hidden input |
| 261 | jQuery('#zbscq_customer').val(cust.id); |
| 262 | |
| 263 | // enable/disable button if present (here is def present) |
| 264 | jQuery('#zbsQuoteBuilderStep2').prop( 'disabled', false ); |
| 265 | jQuery('#zbsQuoteBuilderStep2info').hide(); |
| 266 | |
| 267 | |
| 268 | setTimeout(function(){ |
| 269 | |
| 270 | var lID = cust.id; |
| 271 | |
| 272 | // when inv select drop down changed, show/hide quick nav |
| 273 | zeroBSCRMJS_showContactLinkIf(lID); |
| 274 | |
| 275 | },0); |
| 276 | |
| 277 | } |
| 278 | |
| 279 | function zbscrmjs_quote_unsetCustomer(o){ |
| 280 | |
| 281 | if (typeof o == "undefined" || o == ''){ |
| 282 | |
| 283 | jQuery("#zbscq_customer").val(''); |
| 284 | //jQuery("#bill").val(''); |
| 285 | //jQuery("#cusbill").val(''); |
| 286 | |
| 287 | setTimeout(function(){ |
| 288 | |
| 289 | // when inv select drop down changed, show/hide quick nav |
| 290 | zeroBSCRMJS_showContactLinkIf(''); |
| 291 | |
| 292 | },0); |
| 293 | |
| 294 | } |
| 295 | } |
| 296 | |
| 297 | // if an contact is selected (against a trans) can 'quick nav' to contact |
| 298 | function zeroBSCRMJS_showContactLinkIf(contactID){ |
| 299 | |
| 300 | // remove old |
| 301 | //jQuery('#zbs-customer-title .zbs-view-contact').remove(); |
| 302 | jQuery('#zbs-quote-learn-nav .zbs-quote-quicknav-contact').remove(); |
| 303 | |
| 304 | if (typeof contactID != "undefined" && contactID !== null && contactID !== ''){ |
| 305 | |
| 306 | contactID = parseInt(contactID); |
| 307 | if (contactID > 0){ |
| 308 | |
| 309 | // seems like a legit inv, add |
| 310 | |
| 311 | /* this was from trans meta, here just add to top |
| 312 | var html = '<div class="ui right floated mini animated button zbs-view-contact">'; |
| 313 | html += '<div class="visible content"><?php zeroBSCRM_slashOut( __( 'View', 'zero-bs-crm' ) ); ?></div>'; |
| 314 | html += '<div class="hidden content">'; |
| 315 | html += '<i class="user icon"></i>'; |
| 316 | html += '</div>'; |
| 317 | html += '</div>'; |
| 318 | |
| 319 | jQuery('#zbs-customer-title').prepend(html); */ |
| 320 | |
| 321 | // ALSO show in header bar, if so |
| 322 | var navButton = '<a target="_blank" style="margin-left:6px;" class="zbs-quote-quicknav-contact ui icon button black mini labeled" href="<?php echo jpcrm_esc_link( 'edit', -1, 'zerobs_customer', true ); ?>' + contactID + '"><i class="user icon"></i> <?php zeroBSCRM_slashOut( __( 'Contact', 'zero-bs-crm' ) ); ?></a>'; |
| 323 | jQuery('#zbs-quote-learn-nav').append(navButton); |
| 324 | |
| 325 | // bind |
| 326 | //zeroBSCRMJS_bindContactLinkIf(); |
| 327 | } |
| 328 | } |
| 329 | |
| 330 | } |
| 331 | |
| 332 | </script> |
| 333 | </div> |
| 334 | <?php |
| 335 | |
| 336 | // wh centralised 20/7/18 - 2.91+ skipFields |
| 337 | zeroBSCRM_html_editFields( $quote, $fields, 'zbscq_' ); |
| 338 | |
| 339 | #} if enabled, and new quote, or one which hasn't had the 'templated' meta key added. |
| 340 | if ( $useQuoteBuilder == 1 && ! isset( $quote['template'] ) ) { |
| 341 | ?> |
| 342 | <div class="jpcrm-form-group jpcrm-form-group-span-2"> |
| 343 | <div class="zbs-move-on-wrap"> |
| 344 | |
| 345 | <!-- infoz --> |
| 346 | <h3><?php esc_html_e( 'Publish this Quote', 'zero-bs-crm' ); ?></h3> |
| 347 | <p><?php esc_html_e( 'Do you want to use the Quote Builder to publish this quote? (This lets you email it to a client directly, for approval)', 'zero-bs-crm' ); ?></p> |
| 348 | |
| 349 | <input type="hidden" name="zbs_quote_template_id_used" id="zbs_quote_template_id_used" value="<?php echo ! empty( $templateUsed ) ? esc_attr( $templateUsed ) : ''; ?>" /> |
| 350 | <select class="form-control" name="zbs_quote_template_id" id="zbs_quote_template_id"> |
| 351 | <option value="" disabled="disabled"><?php esc_html_e( 'Select a template', 'zero-bs-crm' ); ?>:</option> |
| 352 | <?php |
| 353 | |
| 354 | $templates = zeroBS_getQuoteTemplates( true, 100, 0 ); |
| 355 | |
| 356 | #} If this quote has already selected a template it'll be stored in the meta under 'templateid' |
| 357 | #} But if it's not the first, we never need to show this anyway... |
| 358 | |
| 359 | if ( count( $templates ) > 0 ) { |
| 360 | foreach ( $templates as $template ) { |
| 361 | |
| 362 | $templateName = __( 'Template', 'zero-bs-crm' ) . ' ' . $template['id']; |
| 363 | if ( isset( $template['title'] ) && ! empty( $template['title'] ) ) { |
| 364 | $templateName = $template['title'] . ' (' . $template['id'] . ')'; |
| 365 | } |
| 366 | |
| 367 | echo '<option value="' . esc_attr( $template['id'] ) . '"'; |
| 368 | #if (isset()) |
| 369 | echo '>' . esc_html( $templateName ) . '</option>'; |
| 370 | |
| 371 | } |
| 372 | } |
| 373 | |
| 374 | ?> |
| 375 | <option value=""><?php esc_html_e( 'Blank Template', 'zero-bs-crm' ); ?></option> |
| 376 | </select> |
| 377 | <br /> |
| 378 | <p> |
| 379 | <?php esc_html_e( 'Create additional quote templates', 'zero-bs-crm' ); ?> |
| 380 | <a href="<?php echo jpcrm_esc_link( $zbs->slugs['quote-templates'] ); ?>"> |
| 381 | <?php esc_html_e( 'here', 'zero-bs-crm' ); ?> |
| 382 | </a> |
| 383 | </p> |
| 384 | <button type="button" id="zbsQuoteBuilderStep2" class="ui button button-primary black button-large xl" |
| 385 | <?php disabled( $quoteContactID <= 0 ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase ?>><?php esc_html_e( 'Use Quote Builder', 'zero-bs-crm' ); ?> |
| 386 | </button> |
| 387 | <?php if ( $quoteContactID <= 0 ) { /* phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase, Squiz.ControlStructures.ControlSignature.NewlineAfterOpenBrace */ ?> |
| 388 | <p id="zbsQuoteBuilderStep2info">(<?php esc_html_e( "You'll need to assign this Quote to a contact to use this", 'zero-bs-crm' ); ?>);</p> |
| 389 | <?php } ?> |
| 390 | |
| 391 | </div> |
| 392 | </div> |
| 393 | <?php } ?> |
| 394 | |
| 395 | </div> |
| 396 | </div> |
| 397 | <?php |
| 398 | } |
| 399 | |
| 400 | public function save_data( $quoteID, $quote ) { |
| 401 | |
| 402 | if ( ! defined( 'ZBS_OBJ_SAVED' ) ) { |
| 403 | |
| 404 | define( 'ZBS_OBJ_SAVED', 1 ); |
| 405 | |
| 406 | // DAL3.0+ |
| 407 | global $zbs; |
| 408 | |
| 409 | // check this |
| 410 | if ( empty( $quoteID ) || $quoteID < 1 ) { |
| 411 | $quoteID = -1; |
| 412 | } |
| 413 | |
| 414 | // defaults, pulled from DAL obj 25/2/19 |
| 415 | /* |
| 416 | $quote = array( |
| 417 | 'title' => '', |
| 418 | 'currency' => '', |
| 419 | 'value' => '', |
| 420 | 'date' => '', |
| 421 | 'template' => '', |
| 422 | 'content' => '', |
| 423 | 'notes' => '', |
| 424 | 'send_attachments' => -1, (removed 4.0.9) |
| 425 | 'hash' => '', |
| 426 | 'lastviewed' => '', |
| 427 | 'viewed_count' => '', |
| 428 | 'accepted' => '', |
| 429 | //'created' => '', |
| 430 | //'lastupdated' => '', |
| 431 | ); |
| 432 | */ |
| 433 | $extraMeta = array(); // can pass any additional meta here |
| 434 | |
| 435 | // retrieve _POST into arr |
| 436 | // global $zbsCustomerQuoteFields; |
| 437 | // $zbsCustomerQuoteMeta = zeroBSCRM_save_fields($zbsCustomerQuoteFields,'zbscq_'); |
| 438 | $autoGenAutonumbers = true; // generate if not set :) |
| 439 | $removeEmpties = false; // req for autoGenAutonumbers |
| 440 | $quote = zeroBS_buildObjArr( $_POST, array(), 'zbscq_', '', $removeEmpties, ZBS_TYPE_QUOTE, $autoGenAutonumbers ); |
| 441 | |
| 442 | // Use the tag-class function to retrieve any tags so we can add inline. |
| 443 | // Save tags against objid |
| 444 | $quote['tags'] = zeroBSCRM_tags_retrieveFromPostBag( true, ZBS_TYPE_QUOTE ); |
| 445 | |
| 446 | // we always get this, because it's used below, but not part of buildObjArr (currently at 3.0) |
| 447 | if ( $quoteID > 0 ) { |
| 448 | $quote['template'] = (int) $zbs->DAL->quotes->getQuoteTemplateID( $quoteID ); |
| 449 | } |
| 450 | |
| 451 | // content (from other metabox actually) |
| 452 | if ( isset( $_POST['zbs_quote_content'] ) ) { |
| 453 | |
| 454 | #} Save content |
| 455 | // $data=htmlspecialchars($_POST['zbs_quote_content'], ENT_COMPAT); |
| 456 | $quote['content'] = wp_kses( $_POST['zbs_quote_content'], $zbs->acceptable_html ); // phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.MissingUnslash -- to follow up with. |
| 457 | #} update templated vars |
| 458 | if ( isset( $_POST['zbs_quote_template_id'] ) ) { |
| 459 | $quote['template'] = (int) sanitize_text_field( $_POST['zbs_quote_template_id'] ); |
| 460 | } |
| 461 | } |
| 462 | |
| 463 | #} First up, save quote id! #TRANSITIONTOMETANO |
| 464 | // DAL 3 will probs move away from this, for now leaving for refactoring round 2 |
| 465 | // for now store as meta (though perhaps needs a new field zbsid) |
| 466 | $quoteOffset = zeroBSCRM_getQuoteOffset(); |
| 467 | $quoteZBSID = (int) $quoteID + $quoteOffset; |
| 468 | if ( isset( $_POST['zbsquoteid'] ) && ! empty( $_POST['zbsquoteid'] ) ) { |
| 469 | $quoteZBSID = (int) $_POST['zbsquoteid']; |
| 470 | } |
| 471 | // update_post_meta($post_id,"zbsid",$quoteID); |
| 472 | $extraMeta['zbsid'] = $quoteZBSID; |
| 473 | #} and increment this |
| 474 | if ( ! empty( $quoteZBSID ) ) { |
| 475 | zeroBSCRM_setMaxQuoteID( $quoteZBSID ); |
| 476 | } |
| 477 | |
| 478 | // assignments |
| 479 | $zbsQuoteContact = -1; |
| 480 | if ( isset( $_POST['zbscq_customer'] ) ) { |
| 481 | $zbsQuoteContact = (int) sanitize_text_field( $_POST['zbscq_customer'] ); |
| 482 | } |
| 483 | $quote['contacts'] = ( $zbsQuoteContact > 0 ) ? array( $zbsQuoteContact ) : array(); |
| 484 | $zbsQuoteCompany = -1; |
| 485 | if ( isset( $_POST['zbscq_company'] ) ) { |
| 486 | $zbsQuoteCompany = (int) sanitize_text_field( $_POST['zbscq_company'] ); |
| 487 | } |
| 488 | $quote['companies'] = ( $zbsQuoteCompany > 0 ) ? array( $zbsQuoteCompany ) : array(); |
| 489 | |
| 490 | /* |
| 491 | line item (temp here from Inv metabox, not yet implemented in ui) |
| 492 | //new way.. now not limited to 30 lines as now they are stored in [] type array in JS draw |
| 493 | $zbsInvoiceLines = array(); |
| 494 | foreach($_POST['zbsli_itemname'] as $k => $v){ |
| 495 | |
| 496 | $ks = sanitize_text_field( $k ); // at least this |
| 497 | |
| 498 | $zbsInvoiceLines[$ks]['title'] = sanitize_text_field($_POST['zbsli_itemname'][$k]); |
| 499 | $zbsInvoiceLines[$ks]['desc'] = sanitize_text_field($_POST['zbsli_itemdes'][$k]); |
| 500 | $zbsInvoiceLines[$ks]['quantity'] = sanitize_text_field($_POST['zbsli_quan'][$k]); |
| 501 | $zbsInvoiceLines[$ks]['price'] = sanitize_text_field($_POST['zbsli_price'][$k]); |
| 502 | $zbsInvoiceLines[$ks]['tax'] = sanitize_text_field($_POST['zbsli_tax'][$k]); |
| 503 | |
| 504 | } |
| 505 | if (count($zbsInvoiceLines) > 0) $invoice['lineitems'] = $zbsInvoiceLines; |
| 506 | */ |
| 507 | |
| 508 | // Status Overwrites (manual changes, only after initial save) |
| 509 | if ( $quoteID > 0 && isset( $_POST['quote_status'] ) ) { |
| 510 | |
| 511 | switch ( $_POST['quote_status'] ) { |
| 512 | |
| 513 | case 'draft': |
| 514 | // if changing to draft, remove any accepted date + template ID |
| 515 | $quote['accepted'] = 0; |
| 516 | $quote['template'] = -1; |
| 517 | |
| 518 | break; |
| 519 | case 'published': |
| 520 | // if changing to published, just needs accepted unsetting, and if no template, populate |
| 521 | $quote['accepted'] = 0; |
| 522 | |
| 523 | // got template? |
| 524 | |
| 525 | // if not already set, set, otherwise leave existing set time in. |
| 526 | if ( ! isset( $quote['template'] ) || $quote['template'] <= 0 ) { |
| 527 | |
| 528 | // hacky setting of it to unlikely cieling |
| 529 | $quote['template'] = 99999; |
| 530 | |
| 531 | } |
| 532 | |
| 533 | break; |
| 534 | case 'accepted': |
| 535 | // if not already accepted, mark accepted. |
| 536 | |
| 537 | // existing |
| 538 | $accepted = (int) $zbs->DAL->quotes->getQuoteAcceptedTime( $quoteID ); |
| 539 | |
| 540 | // if not already set, set, otherwise leave existing set time in. |
| 541 | if ( $accepted <= 0 ) { |
| 542 | |
| 543 | // set it (first time, manual) |
| 544 | $quote['accepted'] = time(); |
| 545 | $quote['acceptedsigned'] = 'manual'; |
| 546 | $quote['acceptedip'] = ''; |
| 547 | |
| 548 | } |
| 549 | |
| 550 | break; |
| 551 | |
| 552 | } |
| 553 | } |
| 554 | |
| 555 | // add/update |
| 556 | $addUpdateReturn = $zbs->DAL->quotes->addUpdateQuote( |
| 557 | array( |
| 558 | |
| 559 | 'id' => $quoteID, |
| 560 | 'data' => $quote, |
| 561 | 'extraMeta' => $extraMeta, |
| 562 | 'limitedFields' => -1, |
| 563 | |
| 564 | ) |
| 565 | ); |
| 566 | |
| 567 | // Note: For NEW objs, we make sure a global is set here, that other update funcs can catch |
| 568 | // ... so it's essential this one runs first! |
| 569 | // this is managed in the metabox Class :) |
| 570 | if ( $quoteID == -1 && ! empty( $addUpdateReturn ) && $addUpdateReturn != -1 ) { |
| 571 | |
| 572 | $quoteID = $addUpdateReturn; |
| 573 | global $zbsJustInsertedMetaboxID; |
| 574 | $zbsJustInsertedMetaboxID = $quoteID; |
| 575 | |
| 576 | // set this so it redirs |
| 577 | $this->newRecordNeedsRedir = true; |
| 578 | } |
| 579 | |
| 580 | // success? |
| 581 | if ( $addUpdateReturn != -1 && $addUpdateReturn > 0 ) { |
| 582 | |
| 583 | // Update Msg |
| 584 | // this adds an update message which'll go out ahead of any content |
| 585 | // This adds to metabox: $this->updateMessages['update'] = zeroBSCRM_UI2_messageHTML('info olive mini zbs-not-urgent',__('Contact Updated',"zero-bs-crm"),'','address book outline','contactUpdated'); |
| 586 | // This adds to edit page |
| 587 | $this->updateMessage(); |
| 588 | |
| 589 | // catch any non-critical messages |
| 590 | $nonCriticalMessages = $zbs->DAL->getErrors( ZBS_TYPE_QUOTE ); |
| 591 | if ( is_array( $nonCriticalMessages ) && count( $nonCriticalMessages ) > 0 ) { |
| 592 | $this->dalNoticeMessage( $nonCriticalMessages ); |
| 593 | } |
| 594 | } else { |
| 595 | |
| 596 | // fail somehow |
| 597 | $failMessages = $zbs->DAL->getErrors( ZBS_TYPE_QUOTE ); |
| 598 | |
| 599 | // show msg (retrieved from DAL err stack) |
| 600 | if ( is_array( $failMessages ) && count( $failMessages ) > 0 ) { |
| 601 | $this->dalErrorMessage( $failMessages ); |
| 602 | } else { |
| 603 | $this->dalErrorMessage( array( __( 'Insert/Update Failed with general error', 'zero-bs-crm' ) ) ); |
| 604 | } |
| 605 | |
| 606 | // pass the pre-fill: |
| 607 | global $zbsObjDataPrefill; |
| 608 | $zbsObjDataPrefill = $quote; |
| 609 | |
| 610 | } |
| 611 | } |
| 612 | |
| 613 | return $quote; |
| 614 | } |
| 615 | |
| 616 | // This catches 'new' contacts + redirs to right url |
| 617 | public function post_save_data( $objID, $obj ) { |
| 618 | |
| 619 | if ( $this->newRecordNeedsRedir ) { |
| 620 | |
| 621 | global $zbsJustInsertedMetaboxID; |
| 622 | if ( ! empty( $zbsJustInsertedMetaboxID ) && $zbsJustInsertedMetaboxID > 0 ) { |
| 623 | |
| 624 | // redir |
| 625 | wp_redirect( jpcrm_esc_link( 'edit', $zbsJustInsertedMetaboxID, $this->objType ) ); |
| 626 | exit( 0 ); |
| 627 | |
| 628 | } |
| 629 | } |
| 630 | } |
| 631 | |
| 632 | public function updateMessage() { |
| 633 | |
| 634 | global $zbs; |
| 635 | |
| 636 | // zbs-not-urgent means it'll auto hide after 1.5s |
| 637 | // genericified from DAL3.0 |
| 638 | $msg = zeroBSCRM_UI2_messageHTML( 'info olive mini zbs-not-urgent', $zbs->DAL->typeStr( $zbs->DAL->objTypeKey( $this->objType ) ) . ' ' . __( 'Updated', 'zero-bs-crm' ), '', 'address book outline', 'contactUpdated' ); |
| 639 | |
| 640 | $zbs->pageMessages[] = $msg; |
| 641 | } |
| 642 | } |
| 643 | |
| 644 | /* |
| 645 | ====================================================== |
| 646 | / Quote Metabox |
| 647 | ====================================================== */ |
| 648 | |
| 649 | /* |
| 650 | ====================================================== |
| 651 | Quote Content Metabox |
| 652 | ====================================================== */ |
| 653 | |
| 654 | class zeroBS__Metabox_QuoteContent extends zeroBS__Metabox { |
| 655 | |
| 656 | public function __construct( $plugin_file ) { |
| 657 | |
| 658 | // set these |
| 659 | $this->objType = 'quote'; |
| 660 | $this->metaboxID = 'zerobs-quote-content-edit'; |
| 661 | $this->metaboxTitle = __( 'Step 2: Quote Content', 'zero-bs-crm' ); // will be headless anyhow |
| 662 | $this->headless = true; |
| 663 | $this->metaboxScreen = 'zbs-add-edit-quote-edit'; |
| 664 | $this->metaboxArea = 'normal'; |
| 665 | $this->metaboxLocation = 'low'; |
| 666 | $this->saveOrder = 1; |
| 667 | $this->capabilities = array( |
| 668 | |
| 669 | 'can_hide' => false, // can be hidden |
| 670 | 'areas' => array( 'normal' ), // areas can be dragged to - normal side = only areas currently |
| 671 | 'can_accept_tabs' => true, // can/can't accept tabs onto it |
| 672 | 'can_become_tab' => false, // can be added as tab |
| 673 | 'can_minimise' => true, // can be minimised |
| 674 | 'can_move' => true, // can be moved |
| 675 | |
| 676 | ); |
| 677 | |
| 678 | // call this |
| 679 | $this->initMetabox(); |
| 680 | } |
| 681 | |
| 682 | public function html( $quote, $metabox ) { |
| 683 | |
| 684 | global $zbs; |
| 685 | |
| 686 | // localise ID & content |
| 687 | $quoteID = -1; |
| 688 | if ( is_array( $quote ) && isset( $quote['id'] ) ) { |
| 689 | $quoteID = (int) $quote['id']; |
| 690 | } |
| 691 | $quote_content = ''; |
| 692 | if ( is_array( $quote ) && isset( $quote['content'] ) ) { |
| 693 | $quote_content = wp_kses( $quote['content'], $zbs->acceptable_html ); |
| 694 | } |
| 695 | |
| 696 | // remove "Add contact form" button from Jetpack |
| 697 | remove_action( 'media_buttons', 'grunion_media_button', 999 ); |
| 698 | wp_editor( |
| 699 | $quote_content, |
| 700 | 'zbs_quote_content', |
| 701 | array( |
| 702 | 'editor_height' => 580, |
| 703 | 'wpautop' => false, |
| 704 | ) |
| 705 | ); |
| 706 | } |
| 707 | |
| 708 | // saved via main metabox |
| 709 | } |
| 710 | |
| 711 | /* |
| 712 | ====================================================== |
| 713 | / Quote Content Metabox |
| 714 | ====================================================== */ |
| 715 | |
| 716 | /* |
| 717 | ====================================================== |
| 718 | Quote Next Step Metabox |
| 719 | ====================================================== */ |
| 720 | |
| 721 | class zeroBS__Metabox_QuoteNextStep extends zeroBS__Metabox { |
| 722 | |
| 723 | public function __construct( $plugin_file ) { |
| 724 | |
| 725 | // set these |
| 726 | $this->objType = 'quote'; |
| 727 | $this->metaboxID = 'zerobs-quote-nextstep'; |
| 728 | $this->metaboxTitle = __( 'Step 3: Publish and Send', 'zero-bs-crm' ); // will be headless anyhow |
| 729 | $this->headless = true; |
| 730 | $this->metaboxScreen = 'zbs-add-edit-quote-edit'; |
| 731 | $this->metaboxArea = 'normal'; |
| 732 | $this->metaboxLocation = 'low'; |
| 733 | $this->saveOrder = 1; |
| 734 | $this->capabilities = array( |
| 735 | |
| 736 | 'can_hide' => false, // can be hidden |
| 737 | 'areas' => array( 'normal' ), // areas can be dragged to - normal side = only areas currently |
| 738 | 'can_accept_tabs' => true, // can/can't accept tabs onto it |
| 739 | 'can_become_tab' => false, // can be added as tab |
| 740 | 'can_minimise' => true, // can be minimised |
| 741 | 'can_move' => true, // can be moved |
| 742 | |
| 743 | ); |
| 744 | |
| 745 | // call this |
| 746 | $this->initMetabox(); |
| 747 | } |
| 748 | |
| 749 | public function html( $quote, $metabox ) { |
| 750 | |
| 751 | if ( $quote === false ) { |
| 752 | $quote = array(); |
| 753 | } |
| 754 | global $zbs; |
| 755 | |
| 756 | // localise ID & content |
| 757 | $quoteID = -1; |
| 758 | if ( is_array( $quote ) && isset( $quote['id'] ) ) { |
| 759 | $quoteID = (int) $quote['id']; |
| 760 | } |
| 761 | |
| 762 | #} retrieve |
| 763 | // some legacy bits from CPT days: |
| 764 | $quoteContactID = -1; |
| 765 | if ( is_array( $quote ) && isset( $quote['contact'] ) && is_array( $quote['contact'] ) && count( $quote['contact'] ) > 0 ) { |
| 766 | $quoteContactID = $quote['contact'][0]['id']; // get_post_meta($post->ID, 'zbs_customer_quote_customer', true); |
| 767 | } |
| 768 | $templateUsed = -1; |
| 769 | if ( is_array( $quote ) && isset( $quote['template'] ) ) { |
| 770 | $templateUsed = $quote['template']; // get_post_meta($post->ID, 'zbs_quote_template_id', true); |
| 771 | } |
| 772 | |
| 773 | #} Using "Quote Builder" or not? |
| 774 | $useQuoteBuilder = zeroBSCRM_getSetting( 'usequotebuilder' ); |
| 775 | $useHash = zeroBSCRM_getSetting( 'easyaccesslinks' ); |
| 776 | |
| 777 | #} if enabled, and new quote, or one which hasn't had the 'templated' meta key added. |
| 778 | if ( $useQuoteBuilder == '1' ) { |
| 779 | |
| 780 | // retrieve email $contactEmail = ''; |
| 781 | $contactEmail = $zbs->DAL->contacts->getContactEmail( $quoteContactID );// zeroBS_contactEmail($quoteContactID); |
| 782 | |
| 783 | // quick WH predictive hack, not sure if viable - to test DAL3 |
| 784 | $quote['templated'] = false; |
| 785 | if ( $templateUsed !== -1 && ! empty( $templateUsed ) ) { |
| 786 | $quote['templated'] = true; |
| 787 | } |
| 788 | |
| 789 | #} first load? |
| 790 | if ( gettype( $quote ) != 'array' || ! isset( $quote['templated'] ) ) { |
| 791 | |
| 792 | ?> |
| 793 | <div class="zbs-move-on-wrap" style="padding-top:30px;"> |
| 794 | |
| 795 | <!-- infoz --> |
| 796 | <h3><?php esc_html_e( 'Publish this Quote', 'zero-bs-crm' ); ?></h3> |
| 797 | <p><?php esc_html_e( "When you've finished writing your Quote, save it here before sending on to your contact", 'zero-bs-crm' ); ?>:</p> |
| 798 | |
| 799 | <button type="button" id="zbsQuoteBuilderStep3" class="button button-primary button-large xl"><?php esc_html_e( 'Save Quote', 'zero-bs-crm' ); ?></button> |
| 800 | |
| 801 | </div> |
| 802 | |
| 803 | <?php |
| 804 | |
| 805 | } else { |
| 806 | |
| 807 | # already has a saved quote |
| 808 | #} If Portal is uninstalled it will break Quotes. So show a message warning them that this should be on |
| 809 | if ( ! zeroBSCRM_isExtensionInstalled( 'portal' ) ) { |
| 810 | ?> |
| 811 | <div class="ui message red" style="font-size:18px;"> |
| 812 | <b><i class="ui icon warning"></i><?php esc_html_e( 'Client Portal Deactivated', 'zero-bs-crm' ); ?></b> |
| 813 | <p><?php esc_html_e( 'You have uninstalled the Client Portal. The only way you will be able to send your Quote to your contact is by downloading a PDF (needs PDF invoicing installed) and then emailing it to them manually.', 'zero-bs-crm' ); ?></p> |
| 814 | <a class="ui button blue" href="<?php echo esc_url( admin_url( 'admin.php?page=zerobscrm-extensions' ) ); ?>"><?php esc_html_e( 'Enable Client Portal', 'zero-bs-crm' ); ?></a> |
| 815 | </div> |
| 816 | <?php |
| 817 | } else { |
| 818 | |
| 819 | // v3.0+ we use hash urls, so check exists |
| 820 | $dal3HashCheck = true; |
| 821 | if ( ( ! isset( $quote['hash'] ) || empty( $quote['hash'] ) ) ) { |
| 822 | $dal3HashCheck = false; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase |
| 823 | } |
| 824 | |
| 825 | if ( isset( $contactEmail ) && ! empty( $contactEmail ) && zeroBSCRM_validateEmail( $contactEmail ) && ( ! $useHash || ( $useHash && $dal3HashCheck ) ) ) { |
| 826 | |
| 827 | // has email, and portal, all good |
| 828 | |
| 829 | ?> |
| 830 | |
| 831 | <div class="zbs-move-on-wrap" style="padding-top:30px;"> |
| 832 | <?php |
| 833 | #} Add nonce |
| 834 | echo '<script type="text/javascript">var zbscrmjs_secToken = \'' . esc_js( wp_create_nonce( 'zbscrmjs-ajax-nonce' ) ) . '\';</script>'; |
| 835 | ?> |
| 836 | |
| 837 | <!-- infoz --> |
| 838 | <h3><?php esc_html_e( 'Email or Share', 'zero-bs-crm' ); ?></h3> |
| 839 | <p><?php esc_html_e( 'Great! Your Quote has been published. You can now email it to your contact, or share the link directly', 'zero-bs-crm' ); ?>:</p> |
| 840 | |
| 841 | <?php do_action( 'zbs_quote_actions' ); ?> |
| 842 | |
| 843 | <div class="zbsEmailOrShare"> |
| 844 | <h4><?php esc_html_e( 'Email to Contact', 'zero-bs-crm' ); ?>:</h4> |
| 845 | <!-- todo --> |
| 846 | <p><input type="text" class="form-control" id="zbsQuoteBuilderEmailTo" value="<?php echo esc_attr( $contactEmail ); ?>" placeholder="<?php esc_attr_e( 'e.g. customer@yahoo.com', 'zero-bs-crm' ); ?>" data-quoteid="<?php echo esc_attr( $quoteID ); ?>" /></p> |
| 847 | <p><button type="button" id="zbsQuoteBuilderSendNotification" class="ui button black"><?php esc_html_e( 'Send Quote', 'zero-bs-crm' ); ?></button></p> |
| 848 | <p class="small" id="zbsQuoteBuilderEmailToErr" style="display:none"><?php esc_html_e( 'An Email Address to send to is required', 'zero-bs-crm' ); ?>!</p> |
| 849 | </div> |
| 850 | <?php |
| 851 | if ( property_exists( $zbs->modules, 'portal' ) ) : |
| 852 | $quote_id_or_hash = $useHash ? $quote['hash'] : $quoteID; |
| 853 | $single_quote_slug = $zbs->modules->portal->get_endpoint( ZBS_TYPE_QUOTE ); |
| 854 | $preview_url = zeroBS_portal_link( $single_quote_slug, $quote_id_or_hash ); |
| 855 | |
| 856 | ?> |
| 857 | <div class="zbsEmailOrShare"> |
| 858 | <h4><?php esc_html_e( 'Share the Link or', 'zero-bs-crm' ); ?> <a href="<?php echo esc_url( $preview_url ); ?>" target="_blank"><?php esc_html_e( 'preview', 'zero-bs-crm' ); ?></a>:</h4> |
| 859 | <p><input type="text" class="form-control" id="zbsQuoteBuilderURL" value="<?php echo esc_url( $preview_url ); ?>" /></p> |
| 860 | </div> |
| 861 | <?php |
| 862 | endif; |
| 863 | ?> |
| 864 | |
| 865 | <?php |
| 866 | #} WH second change, only showed if dompdf extension installed |
| 867 | if ( zeroBSCRM_isExtensionInstalled( 'pdfinv' ) ) { |
| 868 | |
| 869 | #} PDF Invoicing is installed |
| 870 | ?> |
| 871 | <div class="zbsEmailOrShare"> |
| 872 | <h4><?php esc_html_e( 'Download PDF', 'zero-bs-crm' ); ?></h4> |
| 873 | <p><i class="file pdf outline icon red" style="font-size:30px;margin-top:10px;"></i></p> |
| 874 | <input type="button" name="jpcrm_quote_download_pdf" id="jpcrm_quote_download_pdf" class="ui button black" value="<?php esc_attr_e( 'Download PDF', 'zero-bs-crm' ); ?>" /> |
| 875 | |
| 876 | </div> |
| 877 | <script type="text/javascript"> |
| 878 | jQuery(function(){ |
| 879 | |
| 880 | // add your form to the end of body (outside <form>) |
| 881 | var formHTML = '<form target="_blank" method="post" id="jpcrm_quote_download_pdf_form" action="">'; |
| 882 | formHTML += '<input type="hidden" name="jpcrm_quote_download_pdf" value="1" />'; |
| 883 | formHTML += '<input type="hidden" name="jpcrm_quote_id" value="<?php echo esc_attr( $quoteID ); ?>" />'; |
| 884 | formHTML += '<input type="hidden" name="jpcrm_quote_pdf_gen_nonce" value="<?php echo esc_attr( wp_create_nonce( 'jpcrm-quote-pdf-gen' ) ); ?>" />'; |
| 885 | formHTML += '</form>'; |
| 886 | jQuery('#wpbody').append(formHTML); |
| 887 | |
| 888 | // on click |
| 889 | jQuery('#jpcrm_quote_download_pdf').on( 'click', function(){ |
| 890 | |
| 891 | // submit form |
| 892 | jQuery('#jpcrm_quote_download_pdf_form').submit(); |
| 893 | |
| 894 | }); |
| 895 | |
| 896 | }); |
| 897 | </script> |
| 898 | <?php |
| 899 | |
| 900 | } |
| 901 | ?> |
| 902 | |
| 903 | </div> |
| 904 | |
| 905 | <?php |
| 906 | |
| 907 | } elseif ( isset( $quoteContactID ) && $quoteContactID > 0 ) { |
| 908 | |
| 909 | // Contact, but they don't have an email addr on file: |
| 910 | ?> |
| 911 | |
| 912 | <div class="zbs-move-on-wrap" style="padding-top:30px;"> |
| 913 | |
| 914 | <h3><?php esc_html_e( 'Email or Share', 'zero-bs-crm' ); ?></h3> |
| 915 | <div class="zbsEmailOrShare"> |
| 916 | <h4><?php esc_html_e( "Add Contact's Email", 'zero-bs-crm' ); ?>:</h4> |
| 917 | <p><?php esc_html_e( 'To proceed, edit the contact and add their email address, that way we can then send them this quote online.', 'zero-bs-crm' ); ?></p> |
| 918 | <p><a href="<?php echo jpcrm_esc_link( 'edit', $quoteContactID, 'zerobs_customer', true ); ?>" class="button button-primary button-large"><?php esc_html_e( 'Edit Contact', 'zero-bs-crm' ); ?></a></p> |
| 919 | </div> |
| 920 | |
| 921 | </div> |
| 922 | |
| 923 | <?php |
| 924 | } else { |
| 925 | |
| 926 | // not yet assigned to anyone. |
| 927 | ?> |
| 928 | |
| 929 | <div class="zbs-move-on-wrap" style="padding-top:30px;"> |
| 930 | |
| 931 | <h3><?php esc_html_e( 'Email or Share', 'zero-bs-crm' ); ?></h3> |
| 932 | <div class="zbsEmailOrShare"> |
| 933 | <h4><?php esc_html_e( 'Assign to Contact', 'zero-bs-crm' ); ?>:</h4> |
| 934 | <p><?php esc_html_e( 'To proceed, assign this quote to a contact and save it.', 'zero-bs-crm' ); ?></p> |
| 935 | </div> |
| 936 | |
| 937 | </div> |
| 938 | |
| 939 | <?php |
| 940 | |
| 941 | } |
| 942 | } |
| 943 | } |
| 944 | } # if quotebuilder |
| 945 | } |
| 946 | |
| 947 | // nothing to save. |
| 948 | } |
| 949 | |
| 950 | /* |
| 951 | ====================================================== |
| 952 | / Quote Actions Metabox |
| 953 | ====================================================== */ |
| 954 | |
| 955 | /* |
| 956 | ====================================================== |
| 957 | Quote files Metabox |
| 958 | ====================================================== */ |
| 959 | |
| 960 | class zeroBS__Metabox_QuoteFiles extends zeroBS__Metabox { |
| 961 | |
| 962 | public function __construct( $plugin_file ) { |
| 963 | |
| 964 | // DAL3 switched for objType $this->postType = 'zerobs_customer'; |
| 965 | $this->objType = 'quote'; |
| 966 | $this->metaboxID = 'zerobs-quote-files'; |
| 967 | $this->metaboxTitle = __( 'Associated Files', 'zero-bs-crm' ); |
| 968 | $this->metaboxScreen = 'zbs-add-edit-quote-edit'; // 'zerobs_edit_contact'; // we can use anything here as is now using our func |
| 969 | $this->metaboxArea = 'normal'; |
| 970 | $this->metaboxLocation = 'low'; |
| 971 | $this->capabilities = array( |
| 972 | |
| 973 | 'can_hide' => true, // can be hidden |
| 974 | 'areas' => array( 'normal' ), // areas can be dragged to - normal side = only areas currently |
| 975 | 'can_accept_tabs' => true, // can/can't accept tabs onto it |
| 976 | 'can_become_tab' => true, // can be added as tab |
| 977 | 'can_minimise' => true, // can be minimised |
| 978 | |
| 979 | ); |
| 980 | |
| 981 | // call this |
| 982 | $this->initMetabox(); |
| 983 | } |
| 984 | |
| 985 | public function html( $quote, $metabox ) { |
| 986 | |
| 987 | global $zbs; |
| 988 | |
| 989 | $html = ''; |
| 990 | |
| 991 | // localise ID |
| 992 | $quoteID = -1; |
| 993 | if ( is_array( $quote ) && isset( $quote['id'] ) ) { |
| 994 | $quoteID = (int) $quote['id']; |
| 995 | } |
| 996 | |
| 997 | #} retrieve |
| 998 | $zbsFiles = array(); |
| 999 | if ( $quoteID > 0 ) { |
| 1000 | $zbsFiles = zeroBSCRM_files_getFiles( 'quote', $quoteID ); |
| 1001 | } |
| 1002 | |
| 1003 | ?> |
| 1004 | <table class="form-table wh-metatab wptbp" id="wptbpMetaBoxMainItemFiles"> |
| 1005 | |
| 1006 | <?php |
| 1007 | |
| 1008 | // WH only slightly updated this for DAL3 - could do with a cleanup run (contact file edit has more functionality) |
| 1009 | |
| 1010 | #} Any existing |
| 1011 | if ( is_array( $zbsFiles ) && count( $zbsFiles ) > 0 ) { |
| 1012 | ?> |
| 1013 | <tr class="wh-large"><th><label><?php printf( esc_html( _n( '%s associated file', '%s associated files', count( $zbsFiles ), 'text-domain' ) ), esc_html( number_format_i18n( count( $zbsFiles ) ) ) ); ?></label></th> |
| 1014 | <td id="zbsFileWrapInvoices"> |
| 1015 | <?php |
| 1016 | $fileLineIndx = 1; foreach ( $zbsFiles as $zbsFile ) { |
| 1017 | |
| 1018 | $file = zeroBSCRM_files_baseName( $zbsFile['file'], isset( $zbsFile['priv'] ) ); |
| 1019 | |
| 1020 | echo '<div class="zbsFileLine" id="zbsFileLineQuote' . esc_attr( $fileLineIndx ) . '"><a href="' . esc_url( $zbsFile['url'] ) . '" target="_blank">' . esc_html( $file ) . '</a> (<span class="zbsDelFile" data-delurl="' . esc_attr( $zbsFile['url'] ) . '"><i class="fa fa-trash"></i></span>)</div>'; |
| 1021 | ++$fileLineIndx; |
| 1022 | |
| 1023 | } |
| 1024 | ?> |
| 1025 | </td></tr> |
| 1026 | <?php |
| 1027 | |
| 1028 | } |
| 1029 | ?> |
| 1030 | |
| 1031 | <?php |
| 1032 | #adapted from http://code.tutsplus.com/articles/attaching-files-to-your-posts-using-wordpress-custom-meta-boxes-part-1--wp-22291 |
| 1033 | |
| 1034 | $html .= '<input type="file" id="zbsobj_file_attachment" name="zbsobj_file_attachment" size="25" class="zbs-dc">'; |
| 1035 | |
| 1036 | ?> |
| 1037 | <tr class="wh-large"><th><label><?php esc_html_e( 'Add File', 'zero-bs-crm' ); ?>:</label><br />(<?php esc_html_e( 'Optional', 'zero-bs-crm' ); ?>)<br /><?php esc_html_e( 'Accepted File Types', 'zero-bs-crm' ); ?>:<br /><?php echo esc_html( zeroBS_acceptableFileTypeListStr() ); ?></th> |
| 1038 | <td> |
| 1039 | <?php |
| 1040 | wp_nonce_field( plugin_basename( __FILE__ ), 'zbsobj_file_attachment_nonce' ); |
| 1041 | echo $html; |
| 1042 | ?> |
| 1043 | </td></tr> |
| 1044 | |
| 1045 | </table> |
| 1046 | <script type="text/javascript"> |
| 1047 | |
| 1048 | var zbsQuotesCurrentlyDeleting = false; |
| 1049 | var zbsMetaboxFilesLang = { |
| 1050 | 'err': '<?php echo esc_html( zeroBSCRM_slashOut( __( 'Error', 'zero-bs-crm' ) ) ); ?>', |
| 1051 | 'unabletodel' : '<?php echo esc_html( zeroBSCRM_slashOut( __( 'Unable to delete this file', 'zero-bs-crm' ) ) ); ?>', |
| 1052 | |
| 1053 | } |
| 1054 | |
| 1055 | jQuery(function(){ |
| 1056 | |
| 1057 | jQuery('.zbsDelFile').on( 'click', function(){ |
| 1058 | |
| 1059 | if (!window.zbsQuotesCurrentlyDeleting){ |
| 1060 | |
| 1061 | // blocking |
| 1062 | window.zbsQuotesCurrentlyDeleting = true; |
| 1063 | |
| 1064 | var delUrl = jQuery(this).attr('data-delurl'); |
| 1065 | var lineIDtoRemove = jQuery(this).closest('.zbsFileLine').attr('id'); |
| 1066 | |
| 1067 | if (typeof delUrl != "undefined" && delUrl != ''){ |
| 1068 | |
| 1069 | |
| 1070 | |
| 1071 | // postbag! |
| 1072 | var data = { |
| 1073 | 'action': 'delFile', |
| 1074 | 'zbsfType': 'quotes', |
| 1075 | 'zbsDel': delUrl, // could be csv, never used though |
| 1076 | 'zbsCID': <?php echo esc_html( $quoteID ); ?>, |
| 1077 | 'sec': window.zbscrmjs_secToken |
| 1078 | }; |
| 1079 | |
| 1080 | // Send it Pat :D |
| 1081 | jQuery.ajax({ |
| 1082 | type: "POST", |
| 1083 | url: ajaxurl, // admin side is just ajaxurl not wptbpAJAX.ajaxurl, |
| 1084 | "data": data, |
| 1085 | dataType: 'json', |
| 1086 | timeout: 20000, |
| 1087 | success: function(response) { |
| 1088 | |
| 1089 | // visually remove |
| 1090 | jQuery('#' + lineIDtoRemove).remove(); |
| 1091 | |
| 1092 | // file deletion errors, show msg: |
| 1093 | if (typeof response.errors != "undefined" && response.errors.length > 0){ |
| 1094 | |
| 1095 | jQuery.each(response.errors,function(ind,ele){ |
| 1096 | |
| 1097 | jQuery('#zerobs-quotes-files-box').append('<div class="ui warning message" style="margin-top:10px;">' + ele + '</div>'); |
| 1098 | |
| 1099 | }); |
| 1100 | |
| 1101 | } |
| 1102 | |
| 1103 | |
| 1104 | }, |
| 1105 | error: function(response){ |
| 1106 | |
| 1107 | jQuery('#zerobs-quotes-files-box').append('<div class="ui warning message" style="margin-top:10px;"><strong>' + window.zbsMetaboxFilesLang.err + ':</strong> ' + window.zbsMetaboxFilesLang.unabletodel + '</div>'); |
| 1108 | |
| 1109 | } |
| 1110 | |
| 1111 | }); |
| 1112 | |
| 1113 | } |
| 1114 | |
| 1115 | window.zbsQuotesCurrentlyDeleting = false; |
| 1116 | |
| 1117 | } // / blocking |
| 1118 | |
| 1119 | }); |
| 1120 | |
| 1121 | }); |
| 1122 | |
| 1123 | |
| 1124 | </script> |
| 1125 | <?php |
| 1126 | } |
| 1127 | |
| 1128 | public function save_data( $quoteID, $quote ) { |
| 1129 | |
| 1130 | global $zbsobj_justUploadedObjFile; |
| 1131 | $id = $quoteID; |
| 1132 | |
| 1133 | if ( ! empty( $_FILES['zbsobj_file_attachment']['name'] ) && |
| 1134 | ( ! isset( $zbsobj_justUploadedObjFile ) || |
| 1135 | ( isset( $zbsobj_justUploadedObjFile ) && $zbsobj_justUploadedObjFile != $_FILES['zbsobj_file_attachment']['name'] ) |
| 1136 | ) |
| 1137 | ) { |
| 1138 | |
| 1139 | /* --- security verification --- */ |
| 1140 | if ( ! wp_verify_nonce( $_POST['zbsobj_file_attachment_nonce'], plugin_basename( __FILE__ ) ) ) { |
| 1141 | return $id; |
| 1142 | } // end if |
| 1143 | |
| 1144 | if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) { |
| 1145 | return $id; |
| 1146 | } // end if |
| 1147 | |
| 1148 | if ( ! zeroBSCRM_permsQuotes() ) { |
| 1149 | return $id; |
| 1150 | } |
| 1151 | /* - end security verification - */ |
| 1152 | |
| 1153 | // Blocking repeat-upload bug |
| 1154 | $zbsobj_justUploadedObjFile = $_FILES['zbsobj_file_attachment']['name']; |
| 1155 | |
| 1156 | // verify file extension and mime type |
| 1157 | if ( jpcrm_file_check_mime_extension( $_FILES['zbsobj_file_attachment'] ) ) { |
| 1158 | |
| 1159 | $quote_dir_info = jpcrm_storage_dir_info_for_quotes( $quoteID ); |
| 1160 | $upload = jpcrm_save_admin_upload_to_folder( 'zbsobj_file_attachment', $quote_dir_info['files'] ); |
| 1161 | |
| 1162 | if ( isset( $upload['error'] ) && $upload['error'] != 0 ) { |
| 1163 | wp_die( 'There was an error uploading your file. The error is: ' . esc_html( $upload['error'] ) ); |
| 1164 | } else { |
| 1165 | // w mod - adds to array :) |
| 1166 | $zbsFiles = zeroBSCRM_files_getFiles( 'quote', $quoteID ); |
| 1167 | |
| 1168 | if ( is_array( $zbsFiles ) ) { |
| 1169 | |
| 1170 | // add it |
| 1171 | $zbsFiles[] = $upload; |
| 1172 | |
| 1173 | } else { |
| 1174 | |
| 1175 | // first |
| 1176 | $zbsFiles = array( $upload ); |
| 1177 | |
| 1178 | } |
| 1179 | |
| 1180 | // update |
| 1181 | zeroBSCRM_files_updateFiles( 'quote', $quoteID, $zbsFiles ); |
| 1182 | |
| 1183 | // Fire any 'post-upload-processing' (e.g. CPP makes thumbnails of pdf, jpg, etc.) |
| 1184 | // not req invoicing: do_action('zbs_post_upload_contact',$upload); |
| 1185 | } |
| 1186 | } else { |
| 1187 | wp_die( "The file type that you've uploaded is not an accepted file format." ); |
| 1188 | } |
| 1189 | } |
| 1190 | |
| 1191 | return $quote; |
| 1192 | } |
| 1193 | } |
| 1194 | |
| 1195 | /* |
| 1196 | ====================================================== |
| 1197 | / Attach files to quote metabox |
| 1198 | ====================================================== */ |
| 1199 | |
| 1200 | /* |
| 1201 | ====================================================== |
| 1202 | Quote Accepted Details Metabox |
| 1203 | ====================================================== */ |
| 1204 | |
| 1205 | class zeroBS__Metabox_QuoteAcceptedDetails extends zeroBS__Metabox { |
| 1206 | |
| 1207 | // this is for catching 'new' contacts |
| 1208 | private $newRecordNeedsRedir = false; |
| 1209 | |
| 1210 | public function __construct( $plugin_file ) { |
| 1211 | |
| 1212 | // set these |
| 1213 | $this->objType = 'quote'; |
| 1214 | $this->metaboxID = 'zerobs-quote-status-edit'; |
| 1215 | $this->metaboxTitle = __( 'Quote Public Status', 'zero-bs-crm' ); // will be headless anyhow |
| 1216 | $this->headless = true; |
| 1217 | $this->metaboxScreen = 'zbs-add-edit-quote-edit'; |
| 1218 | $this->metaboxArea = 'side'; |
| 1219 | $this->metaboxLocation = 'low'; |
| 1220 | $this->saveOrder = 1; |
| 1221 | $this->capabilities = array( |
| 1222 | |
| 1223 | 'can_hide' => false, // can be hidden |
| 1224 | 'areas' => array( 'side' ), // areas can be dragged to - normal side = only areas currently |
| 1225 | 'can_accept_tabs' => true, // can/can't accept tabs onto it |
| 1226 | 'can_become_tab' => false, // can be added as tab |
| 1227 | 'can_minimise' => true, // can be minimised |
| 1228 | 'can_move' => true, // can be moved |
| 1229 | |
| 1230 | ); |
| 1231 | |
| 1232 | global $useQuoteBuilder; |
| 1233 | |
| 1234 | // call this |
| 1235 | if ( $useQuoteBuilder == '1' ) { |
| 1236 | $this->initMetabox(); |
| 1237 | } |
| 1238 | } |
| 1239 | |
| 1240 | public function html( $quote, $metabox ) { |
| 1241 | |
| 1242 | // localise ID & template |
| 1243 | $quoteID = -1; |
| 1244 | if ( is_array( $quote ) && isset( $quote['id'] ) ) { |
| 1245 | $quoteID = (int) $quote['id']; |
| 1246 | } |
| 1247 | $templateUsed = -1; |
| 1248 | if ( is_array( $quote ) && isset( $quote['template'] ) ) { |
| 1249 | $templateUsed = $quote['template']; |
| 1250 | } |
| 1251 | |
| 1252 | // quick WH predictive hack, not sure if viable - to test DAL3 |
| 1253 | $quote['templated'] = false; |
| 1254 | if ( $templateUsed !== -1 && ! empty( $templateUsed ) ) { |
| 1255 | $quote['templated'] = true; |
| 1256 | } |
| 1257 | |
| 1258 | global $useQuoteBuilder; |
| 1259 | |
| 1260 | #} if enabled, and new quote, or one which hasn't had the 'templated' meta key added. |
| 1261 | #} ... also hide unless it's been "published" |
| 1262 | if ( $useQuoteBuilder == '1' && ( is_array( $quote ) && isset( $quote['templated'] ) && $quote['templated'] ) ) { |
| 1263 | |
| 1264 | if ( isset( $quote ) && is_array( $quote ) && isset( $quote['accepted'] ) && $quote['accepted'] > 0 ) { |
| 1265 | |
| 1266 | #} Deets |
| 1267 | $acceptedDate = date( zeroBSCRM_getTimeFormat() . ' ' . zeroBSCRM_getDateFormat(), $quote['accepted'] ); |
| 1268 | $acceptedBy = $quote['acceptedsigned']; |
| 1269 | $acceptedIP = $quote['acceptedip']; |
| 1270 | |
| 1271 | ?> |
| 1272 | |
| 1273 | <table class="wh-metatab-side wptbp" id="wptbpMetaBoxQuoteStatus"> |
| 1274 | <tr><td style="text-align:center;color:green"><strong><?php esc_html_e( 'Accepted', 'zero-bs-crm' ); ?> <?php echo esc_html( $acceptedDate ); ?></strong></td></tr> |
| 1275 | <?php |
| 1276 | if ( ! empty( $acceptedBy ) ) { |
| 1277 | ?> |
| 1278 | <tr><td style="text-align:center"><?php esc_html_e( 'By: ', 'zero-bs-crm' ); ?> <a href="mailto:<?php echo esc_attr( $acceptedBy ); ?>" target="_blank" |
| 1279 | <?php |
| 1280 | if ( ! empty( $acceptedIP ) ) { |
| 1281 | echo ' title="IP address:' . esc_attr( $acceptedIP ) . '"'; } |
| 1282 | ?> |
| 1283 | ><?php echo esc_html( $acceptedBy ); ?></a></td></tr><?php } ?> |
| 1284 | </table> |
| 1285 | |
| 1286 | <?php |
| 1287 | |
| 1288 | } else { |
| 1289 | |
| 1290 | ?> |
| 1291 | |
| 1292 | <table class="wh-metatab-side wptbp" id="wptbpMetaBoxQuoteStatus"> |
| 1293 | <tr> |
| 1294 | <td style="text-align:center"><strong><?php esc_html_e( 'Not Yet Accepted', 'zero-bs-crm' ); ?></td></tr> |
| 1295 | </table> |
| 1296 | |
| 1297 | <?php |
| 1298 | |
| 1299 | } |
| 1300 | } else { // / only load if post type |
| 1301 | |
| 1302 | #} Gross hide :/ |
| 1303 | ?> |
| 1304 | <style type="text/css">#wpzbscquote_status {display:none;}</style> |
| 1305 | <?php |
| 1306 | |
| 1307 | } |
| 1308 | } |
| 1309 | |
| 1310 | // nothing to save |
| 1311 | } |
| 1312 | |
| 1313 | /* |
| 1314 | ====================================================== |
| 1315 | / Quote Accepted Details Metabox |
| 1316 | ====================================================== */ |
| 1317 | |
| 1318 | /* |
| 1319 | ====================================================== |
| 1320 | Create Tags Box |
| 1321 | ====================================================== */ |
| 1322 | |
| 1323 | class zeroBS__Metabox_QuoteTags extends zeroBS__Metabox_Tags { |
| 1324 | |
| 1325 | public function __construct( $plugin_file ) { |
| 1326 | |
| 1327 | $this->objTypeID = ZBS_TYPE_QUOTE; |
| 1328 | // DAL3 switched for objType $this->postType = 'zerobs_customer'; |
| 1329 | $this->objType = 'quote'; |
| 1330 | $this->metaboxID = 'zerobs-quote-tags'; |
| 1331 | $this->metaboxTitle = __( 'Quote Tags', 'zero-bs-crm' ); |
| 1332 | $this->metaboxScreen = 'zbs-add-edit-quote-edit'; // 'zerobs_edit_contact'; // we can use anything here as is now using our func |
| 1333 | $this->metaboxArea = 'side'; |
| 1334 | $this->metaboxLocation = 'high'; |
| 1335 | $this->showSuggestions = true; |
| 1336 | $this->capabilities = array( |
| 1337 | |
| 1338 | 'can_hide' => true, // can be hidden |
| 1339 | 'areas' => array( 'side' ), // areas can be dragged to - normal side = only areas currently |
| 1340 | 'can_accept_tabs' => false, // can/can't accept tabs onto it |
| 1341 | 'can_become_tab' => false, // can be added as tab |
| 1342 | 'can_minimise' => true, // can be minimised |
| 1343 | |
| 1344 | ); |
| 1345 | |
| 1346 | // call this |
| 1347 | $this->initMetabox(); |
| 1348 | } |
| 1349 | |
| 1350 | // html + save dealt with by parent class :) |
| 1351 | } |
| 1352 | |
| 1353 | /* |
| 1354 | ====================================================== |
| 1355 | / Create Tags Box |
| 1356 | ====================================================== */ |
| 1357 | |
| 1358 | /* |
| 1359 | ====================================================== |
| 1360 | Quote Actions Metabox |
| 1361 | ====================================================== */ |
| 1362 | |
| 1363 | class zeroBS__Metabox_QuoteActions extends zeroBS__Metabox { |
| 1364 | |
| 1365 | public function __construct( $plugin_file ) { |
| 1366 | |
| 1367 | // set these |
| 1368 | $this->objType = 'quote'; |
| 1369 | $this->metaboxID = 'zerobs-quote-actions'; |
| 1370 | $this->metaboxTitle = __( 'Quote Actions', 'zero-bs-crm' ); // will be headless anyhow |
| 1371 | $this->headless = true; |
| 1372 | $this->metaboxScreen = 'zbs-add-edit-quote-edit'; |
| 1373 | $this->metaboxArea = 'side'; |
| 1374 | $this->metaboxLocation = 'high'; |
| 1375 | $this->saveOrder = 1; |
| 1376 | $this->capabilities = array( |
| 1377 | |
| 1378 | 'can_hide' => false, // can be hidden |
| 1379 | 'areas' => array( 'high' ), // areas can be dragged to - normal side = only areas currently |
| 1380 | 'can_accept_tabs' => true, // can/can't accept tabs onto it |
| 1381 | 'can_become_tab' => false, // can be added as tab |
| 1382 | 'can_minimise' => true, // can be minimised |
| 1383 | 'can_move' => true, // can be moved |
| 1384 | |
| 1385 | ); |
| 1386 | |
| 1387 | // call this |
| 1388 | $this->initMetabox(); |
| 1389 | } |
| 1390 | |
| 1391 | public function html( $quote, $metabox ) { |
| 1392 | |
| 1393 | ?> |
| 1394 | <div class="zbs-generic-save-wrap"> |
| 1395 | |
| 1396 | <div class="ui medium dividing header"><i class="save icon"></i> <?php esc_html_e( 'Quote Actions', 'zero-bs-crm' ); ?></div> |
| 1397 | |
| 1398 | <?php |
| 1399 | |
| 1400 | // localise ID & content |
| 1401 | $quoteID = -1; |
| 1402 | if ( is_array( $quote ) && isset( $quote['id'] ) ) { |
| 1403 | $quoteID = (int) $quote['id']; |
| 1404 | } |
| 1405 | |
| 1406 | #} if a saved post... |
| 1407 | // if (isset($post->post_status) && $post->post_status != "auto-draft"){ |
| 1408 | if ( $quoteID > 0 ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase |
| 1409 | ?> |
| 1410 | <div class="zbs-quote-actions-bottom zbs-objedit-actions-bottom"> |
| 1411 | |
| 1412 | <button class="ui button black" type="button" id="zbs-edit-save"><?php esc_html_e( 'Update', 'zero-bs-crm' ); ?> <?php esc_html_e( 'Quote', 'zero-bs-crm' ); ?></button> |
| 1413 | |
| 1414 | <?php |
| 1415 | |
| 1416 | // delete? |
| 1417 | |
| 1418 | // for now just check if can modify, later better, granular perms. |
| 1419 | if ( zeroBSCRM_permsQuotes() ) { |
| 1420 | ?> |
| 1421 | <div id="zbs-quote-actions-delete" class="zbs-objedit-actions-delete"> |
| 1422 | <a class="submitdelete deletion" href="<?php echo jpcrm_esc_link( 'delete', $quoteID, 'quote' ); ?>"><?php esc_html_e( 'Delete Permanently', 'zero-bs-crm' ); ?></a> |
| 1423 | </div> |
| 1424 | <?php } // can delete ?> |
| 1425 | |
| 1426 | <div class='clear'></div> |
| 1427 | |
| 1428 | </div> |
| 1429 | <?php |
| 1430 | |
| 1431 | } else { |
| 1432 | |
| 1433 | // NEW quote |
| 1434 | ?> |
| 1435 | |
| 1436 | <button class="ui button black" type="button" id="zbs-edit-save"><?php esc_html_e( 'Save', 'zero-bs-crm' ); ?> <?php esc_html_e( 'Quote', 'zero-bs-crm' ); ?></button> |
| 1437 | |
| 1438 | <?php |
| 1439 | |
| 1440 | } |
| 1441 | |
| 1442 | ?> |
| 1443 | </div> |
| 1444 | <?php |
| 1445 | // / .zbs-generic-save-wrap |
| 1446 | } // html |
| 1447 | |
| 1448 | // saved via main metabox |
| 1449 | } |
| 1450 | |
| 1451 | /* |
| 1452 | ====================================================== |
| 1453 | / Quotes Actions Metabox |
| 1454 | ====================================================== */ |