PluginProbe
Easy Invoice – Invoice Generator, PDF Quotes & Payments / 2.4.0
Easy Invoice – Invoice Generator, PDF Quotes & Payments v2.4.0
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 2.1.15 2.1.16 2.1.2 All 57 releases
← All changes | includes/Repositories/InvoiceRepository.php +31 -5 2.3.22.4.0 View file →
@@ -103,16 +103,33 @@
103 103 // Set basic data
104 104 $invoice->setTitle($data['title'] ?? 'New Invoice');
105 105
106 106 // Auto-generate invoice number if not provided
107 - if ((!isset($data['number']) || empty($data['number'])) &&
108 - (!isset($data['invoice_number']) || empty($data['invoice_number']))) {
109 - $invoice_number_service = easy_invoice_get_invoice_number_service();
110 - $data['number'] = $invoice_number_service->generateUniqueNumber();
107 + // A number the form sent is kept only if nobody has it yet (two
108 + // builders opened at once are pre-filled with the same one); the
109 + // counter moves past it, or a fresh number is issued.
110 + $invoice_number_service = easy_invoice_get_invoice_number_service();
111 + $requested = (string) ($data['number'] ?? $data['invoice_number'] ?? '');
112 + $data['number'] = $invoice_number_service->claimOrGenerate($requested);
113 + unset($data['invoice_number']);
114 +
115 + // Discount timing defaults to "before tax", the first choice the builder
116 + // offers. Left empty, the model's arithmetic takes the after-tax branch,
117 + // which is what API- and import-created invoices used to get.
118 + if (empty($data['discount_calculation_method'])) {
119 + $data['discount_calculation_method'] = 'before_tax';
111 120 }
112 -
121 +
113 122 // Set invoice data
114 123 $this->setInvoiceData($invoice, $data, false);
124 +
125 + // A client was given but no customer details: take them from the
126 + // client record now, so the object handed back (and the meta saved)
127 + // already carries the name and email — callers that email straight
128 + // after creating would otherwise see "client email is missing".
129 + if (is_numeric($data['client_id'] ?? 0) && (int) ($data['client_id'] ?? 0) > 0 && (empty($data['customer_email']) || empty($data['customer_name'])) && method_exists($invoice, 'populateClientInfo')) {
130 + $invoice->populateClientInfo();
131 + }
115 132
116 133 // Allow plugins to modify the invoice before saving
117 134 do_action('easy_invoice_invoice_before_create', $invoice, $data);
118 135
@@ -185,10 +202,19 @@
185 202 * @param int $customer_id The customer ID
186 203 * @return array Array of Invoice models
187 204 */
188 205 public function findByCustomer($customer_id) {
206 + // Invoices record their client as _easy_invoice_client_id; the
207 + // _easy_invoice_customer_id key was never written, so this lookup
208 + // used to match nothing (the dashboard's "active clients" stayed 0).
189 209 $args = [
190 210 'meta_query' => [
211 + 'relation' => 'OR',
212 + [
213 + 'key' => '_easy_invoice_client_id',
214 + 'value' => (int) $customer_id,
215 + 'compare' => '=',
216 + ],
191 217 [
192 218 'key' => '_easy_invoice_customer_id',
193 219 'value' => $customer_id,
194 220 'compare' => '=',