mirror of
https://github.com/InvoiceShelf/InvoiceShelf.git
synced 2026-04-15 09:14:08 +00:00
Remove app/Space folder and extract model business logic into services
Relocate all 14 files from the catch-all app/Space namespace into proper locations: data providers to Support/Formatters, installation utilities to Services/Installation, PDF utils to Services/Pdf, module/update classes to Services/Module and Services/Update, SiteApi trait to Traits, and helpers to Support. Extract ~1,400 lines of business logic from 8 fat models (Invoice, Payment, Estimate, RecurringInvoice, Company, Customer, Expense, User) into 9 new service classes with constructor injection. Controllers now depend on services instead of calling static model methods. Shared item/tax creation logic consolidated into DocumentItemService.
This commit is contained in:
@@ -2,9 +2,6 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Facades\Hashids;
|
||||
use App\Http\Requests\RecurringInvoiceRequest;
|
||||
use App\Services\SerialNumberFormatter;
|
||||
use App\Traits\HasCustomFieldsTrait;
|
||||
use Carbon\Carbon;
|
||||
use Cron;
|
||||
@@ -193,204 +190,6 @@ class RecurringInvoice extends Model
|
||||
}
|
||||
}
|
||||
|
||||
public static function createFromRequest(RecurringInvoiceRequest $request)
|
||||
{
|
||||
$recurringInvoice = self::create($request->getRecurringInvoicePayload());
|
||||
|
||||
$company_currency = CompanySetting::getSetting('currency', $request->header('company'));
|
||||
|
||||
if ((string) $recurringInvoice['currency_id'] !== $company_currency) {
|
||||
ExchangeRateLog::addExchangeRateLog($recurringInvoice);
|
||||
}
|
||||
|
||||
self::createItems($recurringInvoice, $request->items);
|
||||
|
||||
if ($request->has('taxes') && (! empty($request->taxes))) {
|
||||
self::createTaxes($recurringInvoice, $request->taxes);
|
||||
}
|
||||
|
||||
if ($request->customFields) {
|
||||
$recurringInvoice->addCustomFields($request->customFields);
|
||||
}
|
||||
|
||||
return $recurringInvoice;
|
||||
}
|
||||
|
||||
public function updateFromRequest(RecurringInvoiceRequest $request)
|
||||
{
|
||||
$data = $request->getRecurringInvoicePayload();
|
||||
|
||||
$this->update($data);
|
||||
|
||||
$company_currency = CompanySetting::getSetting('currency', $request->header('company'));
|
||||
|
||||
if ((string) $data['currency_id'] !== $company_currency) {
|
||||
ExchangeRateLog::addExchangeRateLog($this);
|
||||
}
|
||||
|
||||
$this->items()->delete();
|
||||
self::createItems($this, $request->items);
|
||||
|
||||
$this->taxes()->delete();
|
||||
if ($request->has('taxes') && (! empty($request->taxes))) {
|
||||
self::createTaxes($this, $request->taxes);
|
||||
}
|
||||
|
||||
if ($request->customFields) {
|
||||
$this->updateCustomFields($request->customFields);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public static function createItems($recurringInvoice, $invoiceItems)
|
||||
{
|
||||
foreach ($invoiceItems as $invoiceItem) {
|
||||
$invoiceItem['company_id'] = $recurringInvoice->company_id;
|
||||
$item = $recurringInvoice->items()->create($invoiceItem);
|
||||
if (array_key_exists('taxes', $invoiceItem) && $invoiceItem['taxes']) {
|
||||
foreach ($invoiceItem['taxes'] as $tax) {
|
||||
$tax['company_id'] = $recurringInvoice->company_id;
|
||||
if (gettype($tax['amount']) !== 'NULL') {
|
||||
$item->taxes()->create($tax);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function createTaxes($recurringInvoice, $taxes)
|
||||
{
|
||||
foreach ($taxes as $tax) {
|
||||
$tax['company_id'] = $recurringInvoice->company_id;
|
||||
|
||||
if (gettype($tax['amount']) !== 'NULL') {
|
||||
$recurringInvoice->taxes()->create($tax);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function generateInvoice()
|
||||
{
|
||||
if (Carbon::now()->lessThan($this->starts_at)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->limit_by == 'DATE') {
|
||||
$startDate = Carbon::today()->format('Y-m-d');
|
||||
|
||||
$endDate = $this->limit_date;
|
||||
|
||||
if ($endDate >= $startDate) {
|
||||
$this->createInvoice();
|
||||
|
||||
$this->updateNextInvoiceDate();
|
||||
} else {
|
||||
$this->markStatusAsCompleted();
|
||||
}
|
||||
} elseif ($this->limit_by == 'COUNT') {
|
||||
$invoiceCount = Invoice::where('recurring_invoice_id', $this->id)->count();
|
||||
|
||||
if ($invoiceCount < $this->limit_count) {
|
||||
$this->createInvoice();
|
||||
|
||||
$this->updateNextInvoiceDate();
|
||||
} else {
|
||||
$this->markStatusAsCompleted();
|
||||
}
|
||||
} else {
|
||||
$this->createInvoice();
|
||||
|
||||
$this->updateNextInvoiceDate();
|
||||
}
|
||||
}
|
||||
|
||||
public function createInvoice()
|
||||
{
|
||||
// get invoice_number
|
||||
$serial = (new SerialNumberFormatter)
|
||||
->setModel(new Invoice)
|
||||
->setCompany($this->company_id)
|
||||
->setCustomer($this->customer_id)
|
||||
->setNextNumbers();
|
||||
|
||||
$days = intval(CompanySetting::getSetting('invoice_due_date_days', $this->company_id));
|
||||
|
||||
if (! $days || $days == 'null') {
|
||||
$days = 7;
|
||||
}
|
||||
|
||||
$newInvoice['creator_id'] = $this->creator_id;
|
||||
$newInvoice['invoice_date'] = Carbon::today()->format('Y-m-d');
|
||||
$newInvoice['due_date'] = Carbon::today()->addDays($days)->format('Y-m-d');
|
||||
$newInvoice['status'] = Invoice::STATUS_DRAFT;
|
||||
$newInvoice['company_id'] = $this->company_id;
|
||||
$newInvoice['paid_status'] = Invoice::STATUS_UNPAID;
|
||||
$newInvoice['sub_total'] = $this->sub_total;
|
||||
$newInvoice['tax_per_item'] = $this->tax_per_item;
|
||||
$newInvoice['discount_per_item'] = $this->discount_per_item;
|
||||
$newInvoice['tax'] = $this->tax;
|
||||
$newInvoice['total'] = $this->total;
|
||||
$newInvoice['customer_id'] = $this->customer_id;
|
||||
$newInvoice['currency_id'] = Customer::find($this->customer_id)->currency_id;
|
||||
$newInvoice['template_name'] = $this->template_name;
|
||||
$newInvoice['due_amount'] = $this->total;
|
||||
$newInvoice['recurring_invoice_id'] = $this->id;
|
||||
$newInvoice['discount_val'] = $this->discount_val;
|
||||
$newInvoice['discount'] = $this->discount;
|
||||
$newInvoice['discount_type'] = $this->discount_type;
|
||||
$newInvoice['notes'] = $this->notes;
|
||||
$newInvoice['exchange_rate'] = $this->exchange_rate;
|
||||
$newInvoice['sales_tax_type'] = $this->sales_tax_type;
|
||||
$newInvoice['sales_tax_address_type'] = $this->sales_tax_address_type;
|
||||
$newInvoice['invoice_number'] = $serial->getNextNumber();
|
||||
$newInvoice['sequence_number'] = $serial->nextSequenceNumber;
|
||||
$newInvoice['customer_sequence_number'] = $serial->nextCustomerSequenceNumber;
|
||||
$newInvoice['base_due_amount'] = $this->exchange_rate * $this->due_amount;
|
||||
$newInvoice['base_discount_val'] = $this->exchange_rate * $this->discount_val;
|
||||
$newInvoice['base_sub_total'] = $this->exchange_rate * $this->sub_total;
|
||||
$newInvoice['base_tax'] = $this->exchange_rate * $this->tax;
|
||||
$newInvoice['base_total'] = $this->exchange_rate * $this->total;
|
||||
$invoice = Invoice::create($newInvoice);
|
||||
$invoice->unique_hash = Hashids::connection(Invoice::class)->encode($invoice->id);
|
||||
$invoice->save();
|
||||
|
||||
$this->load('items.taxes');
|
||||
Invoice::createItems($invoice, $this->items->toArray());
|
||||
|
||||
if ($this->taxes()->exists()) {
|
||||
Invoice::createTaxes($invoice, $this->taxes->toArray());
|
||||
}
|
||||
|
||||
if ($this->fields()->exists()) {
|
||||
$customField = [];
|
||||
|
||||
foreach ($this->fields as $data) {
|
||||
$customField[] = [
|
||||
'id' => $data->custom_field_id,
|
||||
'value' => $data->defaultAnswer,
|
||||
];
|
||||
}
|
||||
|
||||
$invoice->addCustomFields($customField);
|
||||
}
|
||||
|
||||
// send automatically
|
||||
if ($this->send_automatically == true) {
|
||||
$data = [
|
||||
'body' => CompanySetting::getSetting('invoice_mail_body', $this->company_id),
|
||||
'from' => config('mail.from.address'),
|
||||
'to' => $this->customer->email,
|
||||
'subject' => trans('invoices')['new_invoice'],
|
||||
'invoice' => $invoice->toArray(),
|
||||
'customer' => $invoice->customer->toArray(),
|
||||
'company' => Company::find($invoice->company_id),
|
||||
];
|
||||
|
||||
$invoice->send($data);
|
||||
}
|
||||
}
|
||||
|
||||
public function markStatusAsCompleted()
|
||||
{
|
||||
if ($this->status == $this->status) {
|
||||
@@ -413,27 +212,4 @@ class RecurringInvoice extends Model
|
||||
$this->next_invoice_at = $nextInvoiceAt;
|
||||
$this->save();
|
||||
}
|
||||
|
||||
public static function deleteRecurringInvoice($ids)
|
||||
{
|
||||
foreach ($ids as $id) {
|
||||
$recurringInvoice = self::find($id);
|
||||
|
||||
if ($recurringInvoice->invoices()->exists()) {
|
||||
$recurringInvoice->invoices()->update(['recurring_invoice_id' => null]);
|
||||
}
|
||||
|
||||
if ($recurringInvoice->items()->exists()) {
|
||||
$recurringInvoice->items()->delete();
|
||||
}
|
||||
|
||||
if ($recurringInvoice->taxes()->exists()) {
|
||||
$recurringInvoice->taxes()->delete();
|
||||
}
|
||||
|
||||
$recurringInvoice->delete();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user