PluginProbe
Easy Invoice – Invoice Generator, PDF Quotes & Payments / 2.1.0
Easy Invoice – Invoice Generator, PDF Quotes & Payments v2.1.0
2.4.3 2.4.4 2.4.2 2.4.0 2.4.1 2.3.8 2.3.7 2.3.6 2.3.5 2.3.4 2.3.3 2.3.2 2.3.1 2.2.0 2.1.21 2.1.20 2.1.19 2.1.18 2.1.0 2.1.1 2.1.10 2.1.11 2.1.12 2.1.13 2.1.14 All 60 releases
easy-invoice / templates / invoices / builder.php

builder.php in Easy Invoice – Invoice Generator, PDF Quotes & Payments 2.1.0, at templates/invoices/builder.php

339 lines 14.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 // Exit if accessed directly
3 if (!defined('ABSPATH')) {
4 exit;
5 }
6
7 // Enqueue CSS and JS files for the builder page
8 wp_enqueue_style('easy-invoice-form', plugin_dir_url(__FILE__) . '../../assets/css/invoice-form.css', array(), '1.0.0');
9 wp_enqueue_script('easy-invoice-form', plugin_dir_url(__FILE__) . '../../assets/js/invoice-form.js', array('jquery'), '1.0.0', true);
10 wp_enqueue_script('easy-client-manager', plugin_dir_url(__FILE__) . '../../assets/js/client-manager.js', array('jquery'), '1.0.0', true);
11
12 use EasyInvoice\Providers\ClientServiceProvider;
13 use EasyInvoice\Providers\InvoiceServiceProvider;
14
15
16 // Get invoice ID if present in URL
17 $invoice_id = isset($_GET['invoice_id']) ? intval($_GET['invoice_id']) : 0;
18 $invoice = null;
19
20 // Check if this is a new invoice (no ID)
21 $is_new_invoice = ($invoice_id === 0);
22
23 // Default values for new invoice
24 $invoice_number_service = easy_invoice_get_invoice_number_service();
25 $invoice_data = array(
26 'number' => $invoice_number_service->getNextNumber(),
27 'date' => date('Y-m-d'),
28 'due_date' => date('Y-m-d', strtotime('+30 days')),
29 'client_id' => '',
30 'client_name' => '',
31 'client_email' => '',
32 'client_phone' => '',
33 'client_address' => '',
34 'items' => array(),
35 'notes' => '',
36 'internal_notes' => '',
37 'discount' => 0,
38 'discount_type' => 'percentage',
39 'calculation_method' => 'before_tax',
40 'tax_rate' => 10,
41 'prices_include_tax' => 'no',
42 'payment_method' => 'bank_transfer',
43 'payment_status' => 'unpaid',
44 'currency' => 'USD',
45 'currency_symbol' => '$',
46 'title' => '',
47 'description' => '',
48 'terms' => '',
49 'is_recurring' => 'no',
50 'recurring_frequency' => '',
51 );
52
53 // Load clients for the dropdown
54 $client_repository = ClientServiceProvider::getClientRepository();
55 $clients = $client_repository->all();
56
57 // If editing an existing invoice, load its data
58 if ($invoice_id > 0) {
59 // Get the invoice from repository
60 $invoice_repository = InvoiceServiceProvider::getInvoiceRepository();
61 $invoice = $invoice_repository->find($invoice_id);
62 } else {
63 // Create a temporary WP_Post object for new invoice
64 $empty_post = new WP_Post((object) array(
65 'ID' => 0,
66 'post_author' => get_current_user_id(),
67 'post_date' => current_time('mysql'),
68 'post_date_gmt' => current_time('mysql', 1),
69 'post_title' => $invoice_data['number'],
70 'post_status' => 'auto-draft',
71 'comment_status' => 'closed',
72 'ping_status' => 'closed',
73 'post_name' => '',
74 'post_modified' => current_time('mysql'),
75 'post_modified_gmt' => current_time('mysql', 1),
76 'post_parent' => 0,
77 'guid' => '',
78 'menu_order' => 0,
79 'post_type' => \EasyInvoice\Constants\PostTypes::EASY_INVOICE_POST_TYPE,
80 'post_mime_type' => '',
81 'comment_count' => 0,
82 'filter' => 'raw',
83 ));
84
85 $invoice = new \EasyInvoice\Models\Invoice($empty_post);
86
87 // Set default values on the invoice object
88 foreach ($invoice_data as $key => $value) {
89 $setter = 'set' . easy_invoice_str_replace('_', '', ucwords($key, '_'));
90 if (method_exists($invoice, $setter)) {
91 // Handle client_id specially to avoid type errors
92 if ($key === 'client_id' && empty($value)) {
93 $invoice->setClientId(0);
94 } else {
95 $invoice->$setter($value);
96 }
97 }
98 }
99
100 // Initialize empty items array
101 $invoice->setItems([]);
102 }
103
104 // Only load custom meta that's not handled by Invoice object
105 if ($invoice) {
106 // These are still accessed from meta as they don't have model methods yet
107 $invoice_data['terms'] = $invoice_id > 0 ? get_post_meta($invoice_id, '_easy_invoice_terms', true) : $invoice_data['terms'];
108 $invoice_data['internal_notes'] = $invoice_id > 0 ? get_post_meta($invoice_id, '_easy_invoice_internal_notes', true) : $invoice_data['internal_notes'];
109 $invoice_data['payment_method'] = $invoice_id > 0 ? get_post_meta($invoice_id, '_easy_invoice_payment_method', true) : $invoice_data['payment_method'];
110 $invoice_data['payment_status'] = $invoice_id > 0 ? get_post_meta($invoice_id, '_easy_invoice_payment_status', true) : $invoice_data['payment_status'];
111 $invoice_data['currency'] = $invoice_id > 0 ? get_post_meta($invoice_id, '_easy_invoice_currency_code', true) : $invoice_data['currency'];
112 $invoice_data['currency_symbol'] = $invoice_id > 0 ? get_post_meta($invoice_id, '_easy_invoice_currency_position', true) : $invoice_data['currency_symbol'];
113 $invoice_data['calculation_method'] = $invoice_id > 0 ? get_post_meta($invoice_id, '_easy_invoice_calculation_method', true) : $invoice_data['calculation_method'];
114 }
115
116 // Prepare invoice items JSON for JavaScript
117 $invoice_items_json = json_encode($invoice ? $invoice->getItems() : []);
118
119 // Create nonce for AJAX calls
120 $admin_nonce = wp_create_nonce('easy_invoice_admin_nonce');
121
122 // Prepare client data for JavaScript
123 $client_data_json = json_encode($client_data ?? null);
124
125 // Start output buffering to capture content
126 ?>
127
128 <div id="easy-invoice-content" class="h-screen flex flex-col">
129 <!-- Header -->
130 <div class="bg-white shadow-sm w-full z-10">
131 <div class="max-w-full mx-auto px-5">
132 <div class="py-3 flex items-center justify-between">
133 <div class="flex items-center">
134 <a href="<?php echo admin_url('admin.php?page=easy-invoice-all'); ?>"
135 class="inline-flex items-center text-gray-600 hover:text-gray-900">
136 <i class="fas fa-arrow-left mr-2"></i>
137 <span>Back to Invoices</span>
138 </a>
139 </div>
140 <h1 class="text-lg font-semibold text-gray-800">
141 <?php
142 if ($invoice_id && $invoice) {
143 $title = $invoice->title ?: $invoice->number ?: 'Untitled Invoice';
144 echo esc_html($title);
145 } else {
146 echo esc_html__('Create New Invoice', 'easy-invoice');
147 }
148 ?>
149 </h1>
150 <div class="flex items-center space-x-4">
151 <?php if ($invoice && $invoice_id > 0): ?>
152 <div class="flex items-center space-x-2">
153 <?php do_action('easy_invoice_builder_before_invoice_actions', $invoice); // Deposit info button appears here ?>
154 </div>
155 <?php endif; ?>
156 <button type="button" id="save-invoice-btn" class="inline-flex items-center px-4 py-2 border border-gray-300 shadow-sm text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
157 <i class="fas fa-save mr-2"></i>
158 <span><?php echo (isset($_GET['invoice_id']) ? __('Update Invoice', 'easy-invoice') : __('Save Invoice', 'easy-invoice')); ?></span>
159 </button>
160 <button type="button" id="send-invoice-btn" class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
161 <i class="fas fa-paper-plane mr-2"></i>
162 <span>Send Invoice</span>
163 </button>
164 </div>
165 </div>
166 </div>
167 </div>
168
169 <!-- Main Content -->
170 <div class="flex-grow overflow-y-auto">
171 <div class="max-w-full mx-auto px-5 py-5">
172 <div id="ei-invoice-builder-grid" class="grid grid-cols-1 lg:grid-cols-2 gap-8">
173 <!-- Left Panel - Editable Fields -->
174
175 <?php
176 include_once EASY_INVOICE_PLUGIN_DIR . 'templates/invoices/form.php';
177
178 include_once EASY_INVOICE_PLUGIN_DIR . 'templates/invoices/live-preview.php';
179 ?>
180 </div>
181
182 <!-- Add Client Modal -->
183 <div id="add_client_modal" class="hidden fixed inset-0 bg-gray-600 bg-opacity-75 overflow-y-auto h-full w-full z-50">
184 <div class="relative top-20 mx-auto p-5 border w-11/12 md:w-2/3 lg:w-1/2 shadow-lg rounded-md bg-white">
185 <div class="flex justify-between items-center mb-4">
186 <h3 class="text-lg font-medium text-gray-900">Add New Client</h3>
187 <button type="button" class="close-modal text-gray-400 hover:text-gray-500">
188 <span class="sr-only">Close</span>
189 <i class="fas fa-times"></i>
190 </button>
191 </div>
192
193 <?php
194 // Unset the $client variable from the foreach loop to ensure clean add form
195 unset($client);
196 include_once EASY_INVOICE_PLUGIN_DIR . 'templates/client-form.php';
197 ?>
198 </div>
199 </div>
200
201 <input type="hidden" name="invoice_template" id="invoice_template" value="<?php echo esc_attr($invoice ? $invoice->getTemplate() : 'standard'); ?>" />
202 </div>
203 </div>
204 </div>
205
206 <script type="text/javascript">
207 jQuery(document).ready(function($) {
208 // Initialize easyInvoice object for client manager
209 window.easyInvoice = {
210 ajaxUrl: '<?php echo admin_url('admin-ajax.php'); ?>',
211 nonce: '<?php echo wp_create_nonce('easy_invoice_nonce'); ?>',
212 clientData: <?php echo $client_data_json; ?>,
213 isPro: <?php echo easy_invoice_has_pro() ? 'true' : 'false'; ?>
214 };
215
216 // Handle Send Invoice button
217 $('#send-invoice-btn').on('click', function(e) {
218 e.preventDefault();
219
220 // First save the invoice if it's not saved yet
221 if ($('#invoice-id').val() == '0') {
222 // Invoice not saved yet, save it first
223 $('#save-invoice-btn').click();
224
225 // Wait for save to complete, then send
226 setTimeout(function() {
227 if ($('#invoice-id').val() != '0') {
228 sendInvoiceEmail();
229 } else {
230 if (typeof EasyInvoiceToast !== 'undefined') {
231 EasyInvoiceToast.warning('Please save the invoice first before sending.');
232 } else {
233 console.log('Please save the invoice first before sending.');
234 }
235 }
236 }, 2000);
237 } else {
238 // Invoice already saved, send directly
239 sendInvoiceEmail();
240 }
241 });
242
243 function sendInvoiceEmail() {
244 const invoiceId = $('#invoice-id').val();
245
246 if (invoiceId == '0') {
247 if (typeof EasyInvoiceToast !== 'undefined') {
248 EasyInvoiceToast.warning('Please save the invoice first before sending.');
249 } else {
250 console.log('Please save the invoice first before sending.');
251 }
252 return;
253 }
254
255 // Use the confirmation system instead of alert
256 if (typeof EasyInvoiceConfirmation !== 'undefined') {
257 EasyInvoiceConfirmation.confirmAction('send email', 'this invoice', function() {
258 // Show loading state
259 const $btn = $('#send-invoice-btn');
260 const originalText = $btn.html();
261 $btn.prop('disabled', true).html('<i class="fas fa-spinner fa-spin mr-2"></i>Sending...');
262
263 // Send AJAX request
264 $.ajax({
265 url: window.easyInvoice.ajaxUrl,
266 type: 'POST',
267 data: {
268 action: 'easy_invoice_send_invoice_email',
269 invoice_id: invoiceId,
270 nonce: '<?php echo wp_create_nonce('easy_invoice_send_invoice_email'); ?>'
271 },
272 success: function(response) {
273 if (response.success) {
274 if (typeof EasyInvoiceToast !== 'undefined') {
275 EasyInvoiceToast.success('Invoice email sent successfully!');
276 } else {
277 console.log('Invoice email sent successfully!');
278 }
279 } else {
280 if (typeof EasyInvoiceToast !== 'undefined') {
281 EasyInvoiceToast.error(response.data.message || 'Error sending email');
282 } else {
283 console.log('Error sending email: ' + (response.data.message || 'Unknown error'));
284 }
285 }
286 },
287 error: function() {
288 if (typeof EasyInvoiceToast !== 'undefined') {
289 EasyInvoiceToast.error('Error connecting to server');
290 } else {
291 console.log('Error connecting to server');
292 }
293 },
294 complete: function() {
295 // Reset button
296 $btn.prop('disabled', false).html(originalText);
297 }
298 });
299 });
300 } else {
301 // Fallback to browser confirm if confirmation system not available
302 if (confirm('Send this invoice via email?')) {
303 // Show loading state
304 const $btn = $('#send-invoice-btn');
305 const originalText = $btn.html();
306 $btn.prop('disabled', true).html('<i class="fas fa-spinner fa-spin mr-2"></i>Sending...');
307
308 // Send AJAX request
309 $.ajax({
310 url: window.easyInvoice.ajaxUrl,
311 type: 'POST',
312 data: {
313 action: 'easy_invoice_send_invoice_email',
314 invoice_id: invoiceId,
315 nonce: '<?php echo wp_create_nonce('easy_invoice_send_invoice_email'); ?>'
316 },
317 success: function(response) {
318 if (response.success) {
319 alert('Invoice email sent successfully!');
320 } else {
321 alert(response.data.message || 'Error sending email');
322 }
323 },
324 error: function() {
325 alert('Error connecting to server');
326 },
327 complete: function() {
328 // Reset button
329 $btn.prop('disabled', false).html(originalText);
330 }
331 });
332 }
333 }
334 }
335 });
336 </script>
337
338
339