PluginProbe
Easy Invoice – Invoice Generator, PDF Quotes & Payments / 2.1.2
Easy Invoice – Invoice Generator, PDF Quotes & Payments v2.1.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 2.1.15 2.1.16 2.1.2 All 57 releases
easy-invoice / includes / Models / QuoteItem.php

QuoteItem.php in Easy Invoice – Invoice Generator, PDF Quotes & Payments 2.1.2, at includes/Models/QuoteItem.php

280 lines 7.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Quote Item Model
4 *
5 * @package EasyInvoice
6 * @author Your Name
7 * @copyright Copyright (c) 2023, Your Company
8 * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
9 * @since 1.0.0
10 */
11
12 namespace EasyInvoice\Models;
13
14 /**
15 * Quote Item Model
16 *
17 * Represents an item in a quote with dynamic field support.
18 *
19 * @since 1.0.0
20 */
21 class QuoteItem {
22 /**
23 * Item ID
24 *
25 * @var int
26 */
27 private $id;
28
29 /**
30 * Dynamic data storage for all fields
31 *
32 * @var array
33 */
34 private $data = [];
35
36 /**
37 * Modified flag
38 *
39 * @var bool
40 */
41 private $is_modified = false;
42
43 /**
44 * Is post flag
45 *
46 * @var bool
47 */
48 private $is_post = false;
49
50 /**
51 * Magic method to get dynamic properties
52 *
53 * @since 1.0.0
54 * @param string $name Property name
55 * @return mixed Property value
56 */
57 public function __get($name) {
58 // Handle special properties
59 if ($name === 'id') {
60 return $this->id;
61 }
62
63 // Handle name/title compatibility
64 if ($name === 'name' && empty($this->data[$name]) && !empty($this->data['title'])) {
65 return $this->data['title'];
66 }
67 if ($name === 'title' && empty($this->data[$name]) && !empty($this->data['name'])) {
68 return $this->data['name'];
69 }
70
71 // Return from dynamic data array
72 return $this->data[$name] ?? null;
73 }
74
75 /**
76 * Magic method to set dynamic properties
77 *
78 * @since 1.0.0
79 * @param string $name Property name
80 * @param mixed $value Property value
81 */
82 public function __set($name, $value) {
83 // Handle special properties
84 if ($name === 'id') {
85 $this->id = $value;
86 return;
87 }
88
89 // Store in dynamic data array
90 $this->data[$name] = $value;
91 $this->is_modified = true;
92 }
93
94 /**
95 * Magic method to check if property exists
96 *
97 * @since 1.0.0
98 * @param string $name Property name
99 * @return bool
100 */
101 public function __isset($name) {
102 if ($name === 'id') {
103 return isset($this->id);
104 }
105
106 return isset($this->data[$name]);
107 }
108
109 /**
110 * Constructor
111 *
112 * @since 1.0.0
113 * @param array $data Item data
114 */
115 public function __construct($data) {
116 $this->data = $data;
117
118 if ($data instanceof \WP_Post) {
119 $this->is_post = true;
120 $this->id = $data->ID;
121 } elseif (is_array($data)) {
122 $this->is_post = false;
123 $this->id = isset($data['id']) ? intval($data['id']) : 0;
124 }
125 }
126
127 /**
128 * Convert to array
129 *
130 * @since 1.0.0
131 * @return array
132 */
133 public function toArray(): array {
134 $data = $this->data;
135 $data['id'] = $this->id;
136
137 // Ensure taxable field is properly set as a boolean
138 $data['taxable'] = $this->isTaxable();
139
140 // Allow plugins to modify the array data
141 return apply_filters('easy_invoice_quote_item_to_array', $data, $this);
142 }
143
144 /**
145 * Get data for form compatibility
146 *
147 * @since 1.0.0
148 * @return array
149 */
150 public function getData(): array {
151 return $this->toArray();
152 }
153
154 /**
155 * Check if the model has been modified
156 *
157 * @since 1.0.0
158 * @return bool
159 */
160 public function isModified(): bool {
161 return $this->is_modified;
162 }
163
164 /**
165 * Determine if the model data has been changed
166 *
167 * @return bool True if the model data has been changed, false otherwise
168 */
169 public function isDirty(): bool {
170 return $this->is_modified;
171 }
172
173 /**
174 * Reset the dirty flag
175 *
176 * @return $this For method chaining
177 */
178 public function resetDirty() {
179 $this->is_modified = false;
180 return $this;
181 }
182
183 /**
184 * Get the calculated amount for this item
185 *
186 * @since 1.0.0
187 * @return float The calculated amount
188 */
189 public function getAmount(): float {
190 $quantity = floatval($this->data['quantity'] ?? 1);
191 $price = floatval($this->data['price'] ?? 0);
192 $adjust_percentage = floatval($this->data['adjust_percentage'] ?? 0);
193
194 // Calculate base total
195 $base_total = $quantity * $price;
196
197 // Apply adjustment percentage if any
198 if ($adjust_percentage != 0) {
199 $base_total = $base_total * (1 + $adjust_percentage / 100);
200 }
201
202 return $base_total;
203 }
204
205 /**
206 * Check if the item is taxable
207 *
208 * @since 1.0.0
209 * @return bool
210 */
211 public function isTaxable(): bool {
212 // Convert various values to boolean
213 $value = $this->data['taxable'] ?? true;
214 if (is_string($value)) {
215 $value = strtolower($value);
216 return $value === '1' || $value === 'true' || $value === 'yes' || $value === 'on';
217 }
218 return (bool) $value;
219 }
220
221 /**
222 * Dynamic getter method
223 *
224 * @since 1.0.0
225 * @param string $name Method name
226 * @param array $arguments Method arguments
227 * @return mixed
228 */
229 public function __call($name, $arguments) {
230 // Handle getter methods (getFieldName)
231 if (strpos($name, 'get') === 0) {
232 $field_name = $this->camelCaseToSnakeCase(substr($name, 3)); // Remove 'get' prefix
233
234 // Special handling for getName() to check both 'name' and 'title' fields
235 if ($field_name === 'name') {
236 if (!empty($this->data['name'])) {
237 return $this->data['name'];
238 } elseif (!empty($this->data['title'])) {
239 return $this->data['title'];
240 }
241 return null;
242 }
243
244 return $this->__get($field_name);
245 }
246
247 // Handle setter methods (setFieldName)
248 if (strpos($name, 'set') === 0) {
249 $field_name = $this->camelCaseToSnakeCase(substr($name, 3)); // Remove 'set' prefix
250 $value = $arguments[0] ?? null;
251 $this->__set($field_name, $value);
252 return null;
253 }
254
255 // Handle isset methods (isFieldName)
256 if (strpos($name, 'is') === 0) {
257 $field_name = $this->camelCaseToSnakeCase(substr($name, 2)); // Remove 'is' prefix
258 return (bool) $this->__get($field_name);
259 }
260
261 // Handle has methods (hasFieldName)
262 if (strpos($name, 'has') === 0) {
263 $field_name = $this->camelCaseToSnakeCase(substr($name, 3)); // Remove 'has' prefix
264 return !empty($this->__get($field_name));
265 }
266
267 throw new \BadMethodCallException("Method $name does not exist");
268 }
269
270 /**
271 * Convert camelCase to snake_case
272 *
273 * @since 1.0.0
274 * @param string $camelCase
275 * @return string
276 */
277 private function camelCaseToSnakeCase($camelCase) {
278 return strtolower(preg_replace('/(?<!^)[A-Z]/', '_$0', $camelCase));
279 }
280 }