<?php 
/*!
 * Jetpack CRM
 * https://jetpackcrm.com
 * V3.0
 *
 * Copyright 2020 Automattic
 *
 * Date: 20/02/2019
 */

defined( 'ZEROBSCRM_PATH' ) || exit( 0 );





/* ======================================================
   Init Func
   ====================================================== */

   function zeroBSCRM_TransactionsMetaboxSetup(){

        // main detail
        $zeroBS__Metabox_Transaction = new zeroBS__Metabox_Transaction( __FILE__ );

        // save
        $zeroBS__Metabox_TransactionActions = new zeroBS__Metabox_TransactionActions( __FILE__ );

        // Tags
        $zeroBS__Metabox_TransactionTags = new zeroBS__Metabox_TransactionTags( __FILE__ );

        // external sources
        $zeroBS__Metabox_ExtSource = new zeroBS__Metabox_ExtSource( __FILE__, 'transaction','zbs-add-edit-transaction-edit');
   }

   add_action( 'admin_init','zeroBSCRM_TransactionsMetaboxSetup');

/* ======================================================
   / Init Func
   ====================================================== */


/* ======================================================
  Transaction Metabox
   ====================================================== */

    class zeroBS__Metabox_Transaction extends zeroBS__Metabox{ 
        
        // this is for catching 'new' transactions
        private $newRecordNeedsRedir = false;

        public function __construct( $plugin_file ) {

            // set these
            $this->objType = 'transaction';
            $this->metaboxID = 'zerobs-transaction-edit';
            $this->metaboxTitle = __('Transaction Information','zero-bs-crm'); // will be headless anyhow
            $this->headless = true;
            $this->metaboxScreen = 'zbs-add-edit-transaction-edit';
            $this->metaboxArea = 'normal';
            $this->metaboxLocation = 'high';
            $this->saveOrder = 1;
            $this->capabilities = array(

                'can_hide'          => false, // can be hidden
                'areas'             => array('normal'), // areas can be dragged to - normal side = only areas currently
                'can_accept_tabs'   => true,  // can/can't accept tabs onto it
                'can_become_tab'    => false, // can be added as tab
                'can_minimise'      => true, // can be minimised
                'can_move'          => true // can be moved

            );

            // call this 
            $this->initMetabox();

        }

        public function html( $transaction, $metabox ) {

                // localise ID
                $transactionID = -1; if (is_array($transaction) && isset($transaction['id'])) $transactionID = (int)$transaction['id'];

                // if new + $zbsObjDataPrefill passed, use that instead of loaded trans.
                if ($transactionID == -1){
                	global $zbsObjDataPrefill;
                	$transaction = $zbsObjDataPrefill;
                }

                global $zbs;


                #} Prefill ID and OBJ are added to the #zbs_invoice to aid in prefilling the data (when drawn with JS)
                $prefill_id = -1; $prefill_obj = -1; $prefill_email = '';
                if (isset($_GET['zbsprefillcust']) && !empty($_GET['zbsprefillcust'])){
                    $prefill_id = (int)$_GET['zbsprefillcust'];
                    $prefill_obj = ZBS_TYPE_CONTACT;
                    $prefill_email = zeroBS_customerEmail($prefill_id);  
                }   
                if (isset($_GET['zbsprefillco']) && !empty($_GET['zbsprefillco'])){
                    $prefill_id = (int)$_GET['zbsprefillco'];
                    $prefill_obj = ZBS_TYPE_COMPANY;
                    $prefill_email = zeroBS_companyEmail($prefill_id);  
                }    

		    	// DAL2 legacy, patched through			    
		    	$contactID = -1;  if (is_array($transaction) && isset($transaction['contact']) && is_array($transaction['contact']) && count($transaction['contact']) > 0) $contactID = $transaction['contact'][0]['id'];
		    	$companyID = -1;  if (is_array($transaction) && isset($transaction['company']) && is_array($transaction['company']) && count($transaction['company']) > 0) $companyID = $transaction['company'][0]['id'];                
		    	$contactName = ''; $companyName = '';
		    	if ($contactID > 0) $contactName = $zbs->DAL->contacts->getContactNameWithFallback( $contactID );
	            if (empty($contactName) || $contactName == -1) $contactName = '';
				if (!empty($companyID) && $companyID > 0){
					$companyName = $zbs->DAL->companies->getCompanyNameEtc($companyID);
					if (empty($companyName)) $companyName = jpcrm_label_company().' #'.$companyID;
				} 

				// prefill if not assigned:
				if ($contactID == -1 && $companyID == -1){

					switch ($prefill_obj){

						case ZBS_TYPE_CONTACT:

							if ($prefill_id > 0){
								
								// dump into contactID etc.
								$contactID = $prefill_id;
								$contactName = $zbs->DAL->contacts->getContactNameWithFallback( $contactID );

							}

							break;

						case ZBS_TYPE_COMPANY:

							if ($prefill_id > 0){
								
								// dump into contactID etc.
								$companyID = $prefill_id;
								$companyName = $zbs->DAL->companies->getCompanyNameEtc($companyID);
								if (empty($companyName)) $companyName = jpcrm_label_company().' #'.$companyID;

							}


							break;

					}

				}


				?>
                <script type="text/javascript">var zbscrmjs_secToken = '<?php echo esc_js( wp_create_nonce( 'zbscrmjs-ajax-nonce' ) ); ?>';</script>
	    		<?php

                    // New transaction?
                    if (gettype($transaction) != "array") echo '<input type="hidden" name="zbscrm_newtransaction" value="1" />';

                ?>
					<div>
						<div class="jpcrm-form-grid" id="wptbpMetaBoxMainItem">
					
						<div class="jpcrm-form-group jpcrm-form-group-span-2">
							<label class="jpcrm-form-label" for="ref"><?php echo esc_html( __( 'Transaction unique ID', 'zero-bs-crm' ) ); ?>:</label>
							<input type="text" id="ref" name="zbst_ref" class="form-control" value="<?php echo esc_attr( isset( $transaction['ref'] ) ? $transaction['ref'] : zeroBSCRM_uniqueID() ); ?>" autocomplete="<?php echo esc_attr( jpcrm_disable_browser_autocomplete() ); ?>" /></td>
						</div>

					<?php

					// Refunds show a notice

					if (
						// has Refund Type
						isset( $transaction['type'] ) && $transaction['type'] == __( 'Refund', 'zero-bs-crm' )
						&&
						// has parent ID based transaction
						isset( $transaction['parent'] ) && $zbs->DAL->transactions->transaction_exists( $transaction['parent'] )
					) {

						// get parent ref
						$parent_ref = $zbs->DAL->transactions->get_transaction_ref( $transaction['parent'] );

						?>
						<div class="jpcrm-form-group jpcrm-form-group-span-2">
								<p style="text-align: center;">
									<?php echo esc_html( sprintf( __( 'This transaction is a refund against transaction #%s', 'zero-bs-crm' ), $parent_ref ) ); ?>
									<a href="<?php echo jpcrm_esc_link( 'edit', $transaction['parent'], ZBS_TYPE_TRANSACTION ); ?>" class="ui compact teal button" style="margin-left:10px"><?php echo esc_html( __( 'View Original Transaction', 'zero-bs-crm' ) ); ?></a>
								</p>
						</div>
						<?php

					}

				// get transaction statuses
				$available_statuses = zeroBSCRM_getTransactionsStatuses( true );

				// if current status is not a valid one, add it to statuses array
				if ( empty( $transaction['status'] ) ) {
					$transaction['status'] = $available_statuses[0];
				} elseif ( ! $zbs->DAL->is_valid_obj_status( ZBS_TYPE_TRANSACTION, $transaction['status'] ) ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
					$available_statuses[] = $transaction['status'];
				}

				?>
					<div class="jpcrm-form-group jpcrm-form-group-span-2">
						<label class="jpcrm-form-label" for="zbst_status"><?php echo esc_html( __( 'Transaction Status:', 'zero-bs-crm' ) ); ?></label>
						<select class="form-control" id="zbst_status" name="zbst_status">
							<?php
						foreach ( $available_statuses as $status ) {
							$sel = $status === $transaction['status'] ? ' selected' : '';
							echo '<option value="' .
							esc_attr( $status ) .
							'"' .
							esc_attr( $sel ) .
							'>' .
							esc_html( $status ) .
							'</option>';
						}
						?>
						</select>
					</div>

					<div class="jpcrm-form-group jpcrm-form-group-span-2">
						<label class="jpcrm-form-label" for="title"><?php echo esc_html( __( 'Transaction Name:', 'zero-bs-crm' ) ); ?>
							<span class="zbs-infobox zbs-infobox-transaction"><?php echo esc_html( __( 'If possible, keep these the same if you routinely use common products here (they are used in the transaction index)', 'zero-bs-crm' ) ); ?></span>
						</label>
						<td><input id="title" type="text" name="zbst_title" value="<?php echo esc_attr( isset( $transaction['title'] ) ? $transaction['title'] : '' ); ?>" class="form-control widetext" autocomplete="<?php echo esc_attr( jpcrm_disable_browser_autocomplete() ); ?>" /></td>
					</div>

					<div class="jpcrm-form-group jpcrm-form-group-span-2">
						<label class="jpcrm-form-label" for="total"><?php echo esc_html( __( 'Transaction Value', 'zero-bs-crm' ) ); ?><?php echo ' (' . esc_html( zeroBSCRM_getCurrencyChr() ) . "):"; // phpcs:ignore Squiz.Strings.DoubleQuoteUsage.NotRequired ?></label></th>
						<input class="form-control" type="text" id="total" name="zbst_total" value="<?php echo esc_attr( isset( $transaction['total'] ) ? $transaction['total'] : '0.00' ); ?>" class="form-control numbersOnly" autocomplete="<?php echo esc_attr( jpcrm_disable_browser_autocomplete() ); ?>" />
					</div>

					<div class="jpcrm-form-group">
						<label class="jpcrm-form-label">
							<?php echo esc_html( __( 'Transaction Date', 'zero-bs-crm' ) ); ?>:
							<span class="zbs-infobox zbs-infobox-transaction"><?php echo esc_html( __( 'The transaction date will default to the initial save date if left blank.', 'zero-bs-crm' ) ); ?></span>
						</label>
						<input class="form-control" type="date" name="zbst_date_datepart" id="transactionDate" value="<?php echo isset( $transaction['date'] ) ? esc_attr( jpcrm_uts_to_date_str( $transaction['date'], 'Y-m-d' ) ) : ''; ?>" autocomplete="<?php echo esc_attr( jpcrm_disable_browser_autocomplete() ); ?>" >
					</div>
					<div class="jpcrm-form-group">
						<label class="jpcrm-form-label">&nbsp;</label>
						<input class="form-control" type="time" name="zbst_date_timepart" value="<?php echo isset( $transaction['date'] ) ? esc_attr( jpcrm_uts_to_time_str( $transaction['date'], 'H:i' ) ) : ''; ?>" autocomplete="<?php echo esc_attr( jpcrm_disable_browser_autocomplete() ); ?>" >
					</div>

					<?php
					// Custom Fields

					global $zbsTransactionFields;

					// had to add this, because other fields are put out separately here
					// TODO resolve zbsTransactionFields global for new DAL
					$skipList = array( 'ref', 'customer', 'status', 'total', 'customer_name', 'date', 'currency', 'title', 'tax_rate', 'taxes', 'date_paid', 'date_completed' );

					if ( zeroBSCRM_getSetting( 'transaction_fee' ) !== 1 ) {
						$skipList[] = 'fee';
					}

					if ( zeroBSCRM_getSetting( 'transaction_net' ) !== 1 ) {
						$skipList[] = 'net';
					}

					if ( zeroBSCRM_getSetting( 'transaction_discount' ) !== 1 ) {
						$skipList[] = 'discount';
					}

					if ( zeroBSCRM_getSetting( 'transaction_tax' ) !== 1 ) {
						$skipList[] = 'tax';
					}

					// shipping?
					$useShipping = zeroBSCRM_getSetting('shippingfortransactions');
					if ($useShipping != 1){
						$skipList[] = 'shipping';
						$skipList[] = 'shipping_taxes';
					} 

					// output additional fields
					zeroBSCRM_html_editFields( $transaction, $zbsTransactionFields,'zbst_', $skipList );

					// use paid/completed dates?
					$usePaidDates = zeroBSCRM_getSetting('paiddatestransaction');
					if ( $usePaidDates === 1 ) {
						?>
						<div class="jpcrm-form-group jpcrm-form-group-span-2">
							<label class="jpcrm-form-label">
								<?php echo esc_html( __( 'Date Paid', 'zero-bs-crm' ) ); ?>:
								<span class="zbs-infobox zbs-infobox-transaction"><?php echo esc_html( __( 'This will default to the transaction date if left blank.', 'zero-bs-crm' ) ); ?></span>
							</label>
							<div class="jpcrm-form-input-group">
								<input type="date" name="zbst_date_paid_datepart" value="<?php echo isset( $transaction['date_paid'] ) ? esc_attr( jpcrm_uts_to_date_str( $transaction['date_paid'], 'Y-m-d' ) ) : ''; ?>" autocomplete="<?php echo esc_attr( jpcrm_disable_browser_autocomplete() ); ?>" >
								@
								<input type="time" name="zbst_date_paid_timepart" value="<?php echo isset( $transaction['date_paid'] ) ? esc_attr( jpcrm_uts_to_time_str( $transaction['date_paid'], 'H:i' ) ) : ''; ?>" autocomplete="<?php echo esc_attr( jpcrm_disable_browser_autocomplete() ); ?>" >
							</div>
						</div>

						<div class="jpcrm-form-group jpcrm-form-group-span-2">
							<label class="jpcrm-form-label">
								<?php echo esc_html( __( 'Date Completed', 'zero-bs-crm' ) ); ?>:
								<span class="zbs-infobox zbs-infobox-transaction"><?php echo esc_html( __( 'This will default to the transaction date if left blank.', 'zero-bs-crm' ) ); ?></span>
							</label>
							<div class="jpcrm-form-input-group">
								<input type="date" name="zbst_date_completed_datepart" value="<?php echo isset( $transaction['date_completed'] ) ? esc_attr( jpcrm_uts_to_date_str( $transaction['date_completed'], 'Y-m-d' ) ) : ''; ?>" autocomplete="<?php echo esc_attr( jpcrm_disable_browser_autocomplete() ); ?>" >
								@
								<input type="time" name="zbst_date_completed_timepart" value="<?php echo isset( $transaction['date_completed'] ) ? esc_attr( jpcrm_uts_to_time_str( $transaction['date_completed'], 'H:i' ) ) : ''; ?>" autocomplete="<?php echo esc_attr( jpcrm_disable_browser_autocomplete() ); ?>" >
							</div>
						</div>
						<?php
					}

					?>

					</div>
				</div>

				<table class="form-table wh-metatab wptbp">

					<tr><td><hr /></td></tr>

					<tr>
						<td>
							<h2 style="font-size: 20px"><i class="linkify icon"></i> <?php echo esc_html( __( 'Assign Transaction to', 'zero-bs-crm' ) ); ?></h2>
						</td>
					</tr>

					<tr class="wh-large" id="zbs-transaction-assignment-wrap">
						<td>
							<?php // hidden inputs dictating any assignment typeaheads ?>
			        		<input id="customer" name="customer" value="<?php echo esc_attr( $contactID ); ?>" class="form-control widetext" type="hidden">
			             	<input id="customer_name" name="customer_name" value="<?php echo esc_attr( $contactName ); ?>" class="form-control widetext" type="hidden">
			             	<input type="hidden" name="zbsct_company" id="zbsct_company" value="<?php echo esc_attr( $companyID ); ?>" />
		                    <?php 
		                    	if (zeroBSCRM_getSetting('companylevelcustomers') != "1"){ 

							// Just contact
							?>
									<div id="zbs-customer-title"><label><?php echo esc_html( __( 'Contact', 'zero-bs-crm' ) ); ?></label></div>
									<?php
		                    		echo zeroBSCRM_CustomerTypeList('zbscrmjs_transaction_setCustomer', $contactName,false,'zbscrmjs_transaction_unsetCustomer');

							// mikes inv selector
							?>
									<div class="assignInvToCust" style="display:none;max-width:658px;" id="invoiceSelectionTitle"><label><?php echo esc_html( __( 'Contact invoice:', 'zero-bs-crm' ) ); ?></label><span class="zbs-infobox zbs-infobox-transaction" style="margin-top:3px"><?php echo esc_html( __( 'Is this transaction a payment for an invoice? If so, enter the Invoice ID. Otherwise leave blank.', 'zero-bs-crm' ) ); ?></span></div>
									<div id="invoiceFieldWrap" style="position:relative;display:none;max-width:658px" class="assignInvToCust"><input style="max-width:200px" id="invoice_id" name="invoice_id" value="<?php echo esc_attr( isset( $transaction['invoice_id'] ) ? $transaction['invoice_id'] : '' ); ?>" class="form-control" autocomplete="<?php echo esc_attr( jpcrm_disable_browser_autocomplete() ); ?>" /></div>
									<?php

		                    	} else {

							// contact or co
							?>
									<div class="ui grid"><div class="seven wide column">
										<div id="zbs-customer-title"><label>
											<?php
											echo esc_html( __( 'Contact', 'zero-bs-crm' ) );
									?>
										</label></div>
										<?php

										// contact
										echo zeroBSCRM_CustomerTypeList( 'zbscrmjs_transaction_setCustomer', $contactName, false, 'zbscrmjs_transaction_unsetCustomer' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped,WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase

								// mikes inv selector
								?>
										<div class="assignInvToCust" style="display:none;max-width:658px;margin-top:21px;margin-bottom:10px;" id="invoiceSelectionTitle"><label><?php echo esc_html( __( 'Contact invoice:', 'zero-bs-crm' ) ); ?>&nbsp;</label><span class="zbs-infobox" style="margin-top:3px"><?php echo esc_html( __( 'Is this transaction a payment for an invoice? If so, enter the Invoice ID. Otherwise leave blank.', 'zero-bs-crm' ) ); ?></span></div>
										<div id="invoiceFieldWrap" style="position:relative;display:none;max-width:658px" class="assignInvToCust"><input style="max-width:200px" id="invoice_id" name="invoice_id" value="<?php echo esc_attr( isset( $transaction['invoice_id'] ) ? $transaction['invoice_id'] : '' ); ?>" class="form-control" autocomplete="<?php echo esc_attr( jpcrm_disable_browser_autocomplete() ); ?>" /></div>

												</div><div class="two wide column centered" style="text-align:center;"><?php echo esc_html( __( 'Or', 'zero-bs-crm' ) ); ?></div><div class="seven wide column"><div id="zbs-company-title"><label><?php echo esc_html( jpcrm_label_company() ); ?></label></div>
											<?php

			                    		// company
				                       	echo zeroBSCRM_CompanyTypeList('zbscrmjs_transaction_setCompany',$companyName,true,'zbscrmjs_transaction_unsetCompany'); 
				                          
				                        ?></div>
				                    </div><?php 
				                } 

				            ?>

			        	</td>
			        </tr>

			    </table>

	  
		<script type="text/javascript">

			// v3.0 Moved into it's own JS for optimal perf.
			// js/ZeroBSCRM.admin.transactioneditor.js
			var zeroBSCRMJS_transactionedit_lang = {

                    'noinvoices': '<?php echo esc_html( zeroBSCRM_slashOut(__('No Invoices Found!',"zero-bs-crm")) ); ?>',
                    'none': '<?php echo esc_html( zeroBSCRM_slashOut(__('None',"zero-bs-crm") )); ?>',
                    'view': '<?php echo esc_html( zeroBSCRM_slashOut(__('View',"zero-bs-crm")) ); ?>',
                    'contact': '<?php echo esc_html( zeroBSCRM_slashOut(__('Contact',"zero-bs-crm")) ); ?>',
                    'company': '<?php echo esc_html( zeroBSCRM_slashOut(jpcrm_label_company()) ); ?>',
                    'selectinv': '<?php echo esc_html( zeroBSCRM_slashOut(__('Select Invoice',"zero-bs-crm")) ); ?>',
			}
			var zeroBSCRMJS_transactionedit_links = {

				'editinvprefix': '<?php echo jpcrm_esc_link( 'edit', -1, 'zerobs_invoice', true ); ?>',
				'editcontactprefix': '<?php echo jpcrm_esc_link( 'edit', -1, 'zerobs_customer', true ); ?>',
				'editcompanyprefix': '<?php echo jpcrm_esc_link( 'edit', -1, 'zerobs_company', true ); ?>',
			}

		</script>
		<?php

              
        }

        public function save_data( $transactionID, $transaction ) {

            if (!defined('ZBS_T_SAVED')){

                define('ZBS_T_SAVED',1);

                // DAL3.0+
                global $zbs;

                // check this
                if (empty($transactionID) || $transactionID < 1)  $transactionID = -1;

	                // ====== DAL 3 way
                    $autoGenAutonumbers = true; // generate if not set
					$transaction = zeroBS_buildObjArr($_POST,array(),'zbst_','',false,ZBS_TYPE_TRANSACTION,$autoGenAutonumbers);

	                // Use the tag-class function to retrieve any tags so we can add inline.
	                // Save tags against objid
					$transaction['tags'] = zeroBSCRM_tags_retrieveFromPostBag(true,ZBS_TYPE_TRANSACTION); 

					$date = jpcrm_datetime_post_keys_to_uts( 'zbst_date' );
					$transaction['date'] = empty( $date ) ? time() : $date;

					$date_paid = jpcrm_datetime_post_keys_to_uts( 'zbst_date_paid' );
					$transaction['date_paid'] = empty( $date_paid ) ? $transaction['date'] : $date_paid;

					$date_completed = jpcrm_datetime_post_keys_to_uts( 'zbst_date_completed' );
					$transaction['date_completed'] = empty( $date_completed ) ? $transaction['date'] : $date_completed;

					// currency wasn't set when storing manually too
					$transaction['currency'] = zeroBSCRM_getCurrencyStr();


			            // assignments
			            $zbsTransactionContact = (int)sanitize_text_field($_POST['customer']);
			            $transaction['contacts'] = ($zbsTransactionContact > 0) ? array($zbsTransactionContact) : array();
			            $zbsTransactionCompany = (int)sanitize_text_field($_POST['zbsct_company']);
			            $transaction['companies'] = ($zbsTransactionCompany > 0) ? array($zbsTransactionCompany) : array();
						

					  	#} Invoice allocation:
						$transaction['invoice_id'] = ''; 	if(isset($_POST['invoice_id'])) 	$transaction['invoice_id'] = (int)sanitize_text_field($_POST["invoice_id"]);


		                // add/update
		                $addUpdateReturn = $zbs->DAL->transactions->addUpdateTransaction(array(

		                            'id'    => $transactionID,
		                            'data'  => $transaction,
		                            'limitedFields' => -1,

		                    ));

		                // Note: For NEW objs, we make sure a global is set here, that other update funcs can catch 
		                // ... so it's essential this one runs first!
		                // this is managed in the metabox Class :)
		                if ($transactionID == -1 && !empty($addUpdateReturn) && $addUpdateReturn != -1) {
		                    
		                    $transactionID = $addUpdateReturn;
		                    global $zbsJustInsertedMetaboxID; $zbsJustInsertedMetaboxID = $transactionID;

		                    // set this so it redirs
		                    $this->newRecordNeedsRedir = true;
		                }

		                // success?
		                if ($addUpdateReturn != -1 && $addUpdateReturn > 0){

			                // Update Msg
			                // this adds an update message which'll go out ahead of any content
			                // 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');
			                // This adds to edit page
			                $this->updateMessage();

			                // catch any non-critical messages
			            	$nonCriticalMessages = $zbs->DAL->getErrors(ZBS_TYPE_TRANSACTION);
			            	if (is_array($nonCriticalMessages) && count($nonCriticalMessages) > 0) $this->dalNoticeMessage($nonCriticalMessages);


			            } else {

			            	// fail somehow
			            	$failMessages = $zbs->DAL->getErrors(ZBS_TYPE_TRANSACTION);

			            	// show msg (retrieved from DAL err stack)
			            	if (is_array($failMessages) && count($failMessages) > 0)
			            		$this->dalErrorMessage($failMessages);
			            	else
			            		$this->dalErrorMessage(array(__('Insert/Update Failed with general error','zero-bs-crm')));

			            	// pass the pre-fill:
			            	global $zbsObjDataPrefill; $zbsObjDataPrefill = $transaction;

	            
			            }

	            

            }

            return $transaction;
        }

        // This catches 'new' contacts + redirs to right url
        public function post_save_data($objID,$obj){

            if ($this->newRecordNeedsRedir){

                global $zbsJustInsertedMetaboxID;
                if (!empty($zbsJustInsertedMetaboxID) && $zbsJustInsertedMetaboxID > 0){

                    // redir
                    wp_redirect( jpcrm_esc_link('edit',$zbsJustInsertedMetaboxID,$this->objType) );
				exit( 0 );

                }

            }

        }

        public function updateMessage(){

            global $zbs;

            // zbs-not-urgent means it'll auto hide after 1.5s
            // genericified from DAL3.0
            $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');

            $zbs->pageMessages[] = $msg;

        }
    }


/* ======================================================
  / Transaction Metabox
   ====================================================== */


/* ======================================================
  Create Tags Box
   ====================================================== */

// phpcs:ignore
class zeroBS__Metabox_TransactionTags extends zeroBS__Metabox_Tags {

	public function __construct( $plugin_file ) { // phpcs:ignore
		// phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
		$this->objTypeID       = ZBS_TYPE_TRANSACTION;
		$this->objType         = 'transaction';
		$this->metaboxID       = 'zerobs-transaction-tags';
		$this->metaboxTitle    = __( 'Transaction Tags', 'zero-bs-crm' );
		$this->metaboxScreen   = 'zbs-add-edit-transaction-edit'; // we can use anything here as is now using our func
		$this->metaboxArea     = 'side';
		$this->metaboxLocation = 'high';
		$this->showSuggestions = true;
		// phpcs:enable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
		$this->capabilities = array(
			'can_hide'        => true, // can be hidden
			'areas'           => array( 'side' ), // areas can be dragged to - normal side = only areas currently
			'can_accept_tabs' => false,  // can/can't accept tabs onto it
			'can_become_tab'  => false, // can be added as tab
			'can_minimise'    => true, // can be minimised
		);

		// call this
		$this->initMetabox();
	}
	// html + save dealt with by parent class :)
}

/* ======================================================
  / Create Tags Box
   ====================================================== */


/* ======================================================
    Transaction Actions Metabox
   ====================================================== */

// phpcs:ignore
class zeroBS__Metabox_TransactionActions extends zeroBS__Metabox {
	public function __construct( $plugin_file ) { // phpcs:ignore
		// phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
		$this->objType         = 'transaction';
		$this->metaboxID       = 'zerobs-transaction-actions';
		$this->metaboxTitle    = __( 'Transaction', 'zero-bs-crm' ) . ' ' . __( 'Actions', 'zero-bs-crm' ); // will be headless anyhow
		$this->headless        = true;
		$this->metaboxScreen   = 'zbs-add-edit-transaction-edit';
		$this->metaboxArea     = 'side';
		$this->metaboxLocation = 'high';
		$this->saveOrder       = 1;
		// phpcs:enable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
		$this->capabilities = array(
			'can_hide'        => false, // can be hidden
			'areas'           => array( 'side' ), // areas can be dragged to - normal side = only areas currently
			'can_accept_tabs' => true,  // can/can't accept tabs onto it
			'can_become_tab'  => false, // can be added as tab
			'can_minimise'    => true, // can be minimised
			'can_move'        => true, // can be moved
		);

		// call this
		$this->initMetabox();
	}

	public function html( $transaction, $metabox ) { // phpcs:ignore Squiz.Commenting.FunctionComment.Missing,VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
		?>
		<div class="zbs-generic-save-wrap">
			<div class="ui medium dividing header"><i class="save icon"></i> <?php echo esc_html( __( 'Transaction Actions', 'zero-bs-crm' ) ); ?></div>
			<?php

			// localise ID & content
			$transaction_id = -1;
			if ( is_array( $transaction ) && isset( $transaction['id'] ) ) {
				$transaction_id = (int) $transaction['id'];
			}

			// if a saved post...
			if ( $transaction_id > 0 ) {
				?>
				<div class="zbs-transaction-actions-bottom zbs-objedit-actions-bottom">
					<button class="ui button black" type="button" id="zbs-edit-save"><?php echo esc_html( __( 'Update Transaction', 'zero-bs-crm' ) ); ?></button>
					<?php
					// for now just check if can modify, later better, granular perms.
					if ( zeroBSCRM_permsTransactions() ) {
						?>
						<div id="zbs-transaction-actions-delete" class="zbs-objedit-actions-delete">
							<a class="submitdelete deletion" href="<?php echo jpcrm_esc_link( 'delete', $transaction_id, 'transaction' ); ?>"><?php echo esc_html( __( 'Delete Permanently', 'zero-bs-crm' ) ); ?></a>
						</div>
						<?php
					}
					?>
					<div class='clear'></div>
				</div>
				<?php
			} else {
				// NEW transaction
				?>
				<div class="zbs-transaction-actions-bottom zbs-objedit-actions-bottom">
					<button class="ui button black" type="button" id="zbs-edit-save"><?php echo esc_html( __( 'Save Transaction', 'zero-bs-crm' ) ); ?></button>
				</div>
				<?php
			}
			?>
		</div>
		<?php
	} // html

	// saved via main metabox
}

/**
 * End of Transaction Action Metabox
 */