PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.6.4
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.6.4
1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.5.4 1.5.5 1.5.3 1.5.2 1.5.1 1.5.0 1.4.2 1.4.1 1.4.0 1.3.28 1.3.27 1.3.26 1.3.25 1.3.23 1.3.22 1.3.21 1.3.20 1.3.19 trunk 1.2.0 All 47 releases
fluent-cart / app / Services / Report / ReportService.php

ReportService.php in FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler 1.6.4, at app/Services/Report/ReportService.php

244 lines 6.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentCart\App\Services\Report;
4
5 use FluentCart\App\App;
6 use FluentCart\App\Helpers\Helper;
7 use FluentCart\Api\CurrencySettings;
8 use FluentCart\Framework\Database\Orm\Builder;
9 use FluentCart\Framework\Database\Query\Builder as Query;
10
11 abstract class ReportService
12 {
13 protected $data = null;
14
15 protected $selects = '*';
16
17 protected array $filters = [];
18
19 protected bool $loaded = false;
20
21 protected array $amountColumns = [];
22
23 public function __construct(array $filters = [])
24 {
25 $this->filters = $filters;
26 if (!isset($this->filters['currency']) || empty($this->filters['currency'])) {
27 $this->filters['currency'] = CurrencySettings::get()['currency'];
28 }
29 }
30
31 public function getModel(): string
32 {
33 return '';
34 }
35
36 protected function prepareReportData(): void
37 {
38
39 }
40
41 public function setAmountColumns(array $columns)
42 {
43 $this->amountColumns = $columns;
44 return $this;
45 }
46
47 public function mergeAmountColumns(array $columns)
48 {
49 $this->amountColumns = array_merge(
50 $this->amountColumns,
51 $columns
52 );
53 return $this;
54 }
55
56 public function getAmountColumns(): array
57 {
58 return $this->amountColumns;
59 }
60
61 public static function make(array $filters = [])
62 {
63 return new static($filters);
64 }
65
66 public function setSelects($selects)
67 {
68 $this->selects = $selects;
69 return $this;
70 }
71
72 protected function getFilters(): array
73 {
74 return $this->filters ?? [];
75 }
76
77 protected function buildQuery(): Builder
78 {
79 return $this->getModel()::search($this->getFilters())
80 ->select($this->selects);
81 }
82
83 protected function modifyQuery(Builder $query): Builder
84 {
85 return $query;
86 }
87
88 protected function transformAmountColumns()
89 {
90 if (!empty($this->amountColumns)) {
91 $this->data = $this->data->transform(function ($data) {
92 foreach ($this->amountColumns as $column) {
93 $columnName = is_array($column) ? $column['name'] : $column;
94 // $withCurrency = is_array($column) ? $column['with_currency'] : false;
95 // $currency = is_array($column) ? $column['currency_sign'] : null;
96 if (is_array($data)) {
97 $data[$columnName] = Helper::toDecimalWithoutComma($data[$columnName]);
98 } else {
99 $data->{$columnName} = Helper::toDecimalWithoutComma($data[$columnName]);
100 }
101 }
102 return $data;
103 });
104 }
105 }
106
107 public function getOriginalData()
108 {
109 return $this->data;
110 }
111
112
113 public function generate()
114 {
115
116
117 $this->data = $this->modifyQuery(
118 $this->buildQuery()
119 )->get();
120
121 $this->transformAmountColumns();
122 $this->prepareReportData();
123
124 $this->loaded = true;
125 return $this;
126 }
127
128
129 /**
130 * Begin a fluent query against a database table.
131 * @return \FluentCart\Framework\Database\Query\Builder
132 */
133 public function addFiltersToQuery($query, $filters, $table = null): Query
134 {
135 foreach ($filters as $key => $value) {
136 if ($table) {
137 $key = $table . '.' . $key;
138 }
139
140 if (is_array($value)) {
141 $query->whereIn($key, $value);
142 } else if (!empty($value) && $value !== 'all') {
143 $query->where($key, $value);
144 }
145 }
146
147 return $query;
148 }
149
150 public function applyFilters(Query $query, array $filters): Query
151 {
152 $defaults = [
153 'currency' => null,
154 'orderTypes' => null,
155 'orderStatus' => null,
156 'variationIds' => null,
157 'paymentStatus' => null,
158 ];
159
160 $filters = wp_parse_args($filters, $defaults);
161
162 $query->whereBetween("o.created_at", [
163 $filters['startDate'], $filters['endDate']
164 ])
165 ->when($filters['currency'], fn($q) =>
166 $q->where("o.currency", $filters['currency'])
167 )
168 ->when($filters['paymentStatus'], fn($q) =>
169 $q->whereIn("o.payment_status", $filters['paymentStatus'])
170 )
171 ->when($filters['orderStatus'], fn($q) =>
172 $q->whereNotIn("o.status", $filters['orderStatus'])
173 )
174 ->when($filters['orderTypes'], fn($q) =>
175 $q->whereIn("o.type", $filters['orderTypes'])
176 )
177 ->when($filters['variationIds'], fn($q) =>
178 $q->whereExists(fn($q) =>
179 $q->selectRaw('1')
180 ->from('fct_order_items as oi')
181 ->whereRaw("oi.order_id = o.id")
182 ->whereIn('oi.object_id', $filters['variationIds'])
183 )
184 )
185 // ->where('o.payment_method', '!=', 'manual_purchases')
186 ;
187
188 return $query;
189 }
190
191 protected function getPeriodRange($startDate, $endDate, $groupKey, $keys = [])
192 {
193 $interval = 'P1D';
194
195 if ($groupKey === 'monthly') {
196 $interval = 'P1M';
197 } else if ($groupKey === 'yearly') {
198 $interval = 'P1Y';
199 }
200
201 // force include the end date in the period to support php < 8.0
202 $endDate = $endDate->copy()->add(new \DateInterval('PT1S'));
203
204 $period = new \DatePeriod($startDate, new \DateInterval($interval), $endDate);
205
206 $range = [];
207
208 foreach ($period as $date) {
209 $year = $date->format('Y');
210
211 if ($groupKey === 'daily') {
212 $group = $date->format('Y-m-d');
213 } else if ($groupKey === 'monthly') {
214 $group = $date->format('Y-m');
215 } else {
216 $group = $date->format('Y');
217 }
218
219 $range[$group] = array_merge(
220 [
221 'year' => $year,
222 'group' => $group,
223 ],
224 array_fill_keys($keys, 0)
225 );
226 }
227
228 return $range;
229 }
230
231 public function getFutureInstallments($params = [])
232 {
233 $query = App::db()->table('fct_subscriptions as s')
234 ->selectRaw("SUM((s.bill_times - s.bill_count) * s.recurring_total) / 100 AS amount")
235 ->join('fct_orders as o', 'o.id', '=', 's.parent_order_id')
236 ->where('s.bill_times', '>', 0)
237 ->where('s.bill_count', '<', App::db()->raw('s.bill_times'));
238
239 $query = $this->applyFilters($query, $params);
240
241 return $query->first()->amount;
242 }
243 }
244