App\Ninja\Repositories\InvoiceRepository::save PHP Метод

save() публичный Метод

public save ( array $data, Invoice $invoice = null ) : Invoice | mixed
$data array
$invoice app\models\Invoice
Результат app\models\Invoice | mixed
    public function save(array $data, Invoice $invoice = null)
    {
        /** @var Account $account */
        $account = \Auth::user()->account;
        $publicId = isset($data['public_id']) ? $data['public_id'] : false;
        $isNew = !$publicId || $publicId == '-1';
        if ($invoice) {
            // do nothing
            $entityType = $invoice->getEntityType();
        } elseif ($isNew) {
            $entityType = ENTITY_INVOICE;
            if (isset($data['is_recurring']) && filter_var($data['is_recurring'], FILTER_VALIDATE_BOOLEAN)) {
                $entityType = ENTITY_RECURRING_INVOICE;
            } elseif (isset($data['is_quote']) && filter_var($data['is_quote'], FILTER_VALIDATE_BOOLEAN)) {
                $entityType = ENTITY_QUOTE;
            }
            $invoice = $account->createInvoice($entityType, $data['client_id']);
            $invoice->invoice_date = date_create()->format('Y-m-d');
            if (isset($data['has_tasks']) && filter_var($data['has_tasks'], FILTER_VALIDATE_BOOLEAN)) {
                $invoice->has_tasks = true;
            }
            if (isset($data['has_expenses']) && filter_var($data['has_expenses'], FILTER_VALIDATE_BOOLEAN)) {
                $invoice->has_expenses = true;
            }
        } else {
            $invoice = Invoice::scope($publicId)->firstOrFail();
            if (Utils::isNinjaDev()) {
                \Log::warning('Entity not set in invoice repo save');
            }
        }
        if ($invoice->is_deleted) {
            return $invoice;
        }
        $invoice->fill($data);
        if (isset($data['set_default_terms']) && $data['set_default_terms'] || isset($data['set_default_footer']) && $data['set_default_footer']) {
            if (isset($data['set_default_terms']) && $data['set_default_terms']) {
                $account->{"{$invoice->getEntityType()}_terms"} = trim($data['terms']);
            }
            if (isset($data['set_default_footer']) && $data['set_default_footer']) {
                $account->invoice_footer = trim($data['invoice_footer']);
            }
            $account->save();
        }
        if (isset($data['invoice_number']) && !$invoice->is_recurring) {
            $invoice->invoice_number = trim($data['invoice_number']);
        }
        if (isset($data['discount'])) {
            $invoice->discount = round(Utils::parseFloat($data['discount']), 2);
        }
        if (isset($data['is_amount_discount'])) {
            $invoice->is_amount_discount = $data['is_amount_discount'] ? true : false;
        }
        if (isset($data['invoice_date_sql'])) {
            $invoice->invoice_date = $data['invoice_date_sql'];
        } elseif (isset($data['invoice_date'])) {
            $invoice->invoice_date = Utils::toSqlDate($data['invoice_date']);
        }
        if (isset($data['invoice_status_id'])) {
            if ($data['invoice_status_id'] == 0) {
                $data['invoice_status_id'] = INVOICE_STATUS_DRAFT;
            }
            $invoice->invoice_status_id = $data['invoice_status_id'];
        }
        if ($invoice->is_recurring) {
            if ($invoice->start_date && $invoice->start_date != Utils::toSqlDate($data['start_date'])) {
                $invoice->last_sent_date = null;
            }
            $invoice->frequency_id = $data['frequency_id'] ? $data['frequency_id'] : 0;
            $invoice->start_date = Utils::toSqlDate($data['start_date']);
            $invoice->end_date = Utils::toSqlDate($data['end_date']);
            $invoice->client_enable_auto_bill = isset($data['client_enable_auto_bill']) && $data['client_enable_auto_bill'] ? true : false;
            $invoice->auto_bill = isset($data['auto_bill']) ? intval($data['auto_bill']) : AUTO_BILL_OFF;
            if ($invoice->auto_bill < AUTO_BILL_OFF || $invoice->auto_bill > AUTO_BILL_ALWAYS) {
                $invoice->auto_bill = AUTO_BILL_OFF;
            }
            if (isset($data['recurring_due_date'])) {
                $invoice->due_date = $data['recurring_due_date'];
            } elseif (isset($data['due_date'])) {
                $invoice->due_date = $data['due_date'];
            }
        } else {
            if (isset($data['due_date']) || isset($data['due_date_sql'])) {
                $invoice->due_date = isset($data['due_date_sql']) ? $data['due_date_sql'] : Utils::toSqlDate($data['due_date']);
            }
            $invoice->frequency_id = 0;
            $invoice->start_date = null;
            $invoice->end_date = null;
        }
        if (isset($data['terms']) && trim($data['terms'])) {
            $invoice->terms = trim($data['terms']);
        } elseif ($isNew && $account->{"{$entityType}_terms"}) {
            $invoice->terms = $account->{"{$entityType}_terms"};
        } else {
            $invoice->terms = '';
        }
        $invoice->invoice_footer = isset($data['invoice_footer']) && trim($data['invoice_footer']) ? trim($data['invoice_footer']) : (!$publicId && $account->invoice_footer ? $account->invoice_footer : '');
        $invoice->public_notes = isset($data['public_notes']) ? trim($data['public_notes']) : null;
        // process date variables if not recurring
        if (!$invoice->is_recurring) {
            $invoice->terms = Utils::processVariables($invoice->terms);
            $invoice->invoice_footer = Utils::processVariables($invoice->invoice_footer);
            $invoice->public_notes = Utils::processVariables($invoice->public_notes);
        }
        if (isset($data['po_number'])) {
            $invoice->po_number = trim($data['po_number']);
        }
        $invoice->invoice_design_id = isset($data['invoice_design_id']) ? $data['invoice_design_id'] : $account->invoice_design_id;
        // provide backwards compatability
        if (isset($data['tax_name']) && isset($data['tax_rate'])) {
            $data['tax_name1'] = $data['tax_name'];
            $data['tax_rate1'] = $data['tax_rate'];
        }
        $total = 0;
        $itemTax = 0;
        foreach ($data['invoice_items'] as $item) {
            $item = (array) $item;
            if (!$item['cost'] && !$item['product_key'] && !$item['notes']) {
                continue;
            }
            $invoiceItemCost = round(Utils::parseFloat($item['cost']), 2);
            $invoiceItemQty = round(Utils::parseFloat($item['qty']), 2);
            $lineTotal = $invoiceItemCost * $invoiceItemQty;
            $total += round($lineTotal, 2);
        }
        foreach ($data['invoice_items'] as $item) {
            $item = (array) $item;
            $invoiceItemCost = round(Utils::parseFloat($item['cost']), 2);
            $invoiceItemQty = round(Utils::parseFloat($item['qty']), 2);
            $lineTotal = $invoiceItemCost * $invoiceItemQty;
            if ($invoice->discount > 0) {
                if ($invoice->is_amount_discount) {
                    $lineTotal -= round($lineTotal / $total * $invoice->discount, 2);
                } else {
                    $lineTotal -= round($lineTotal * ($invoice->discount / 100), 2);
                }
            }
            if (isset($item['tax_rate1']) && Utils::parseFloat($item['tax_rate1']) > 0) {
                $invoiceItemTaxRate = Utils::parseFloat($item['tax_rate1']);
                $itemTax += round($lineTotal * $invoiceItemTaxRate / 100, 2);
            }
            if (isset($item['tax_rate2']) && Utils::parseFloat($item['tax_rate2']) > 0) {
                $invoiceItemTaxRate = Utils::parseFloat($item['tax_rate2']);
                $itemTax += round($lineTotal * $invoiceItemTaxRate / 100, 2);
            }
        }
        if ($invoice->discount > 0) {
            if ($invoice->is_amount_discount) {
                $total -= $invoice->discount;
            } else {
                $total *= (100 - $invoice->discount) / 100;
                $total = round($total, 2);
            }
        }
        if (isset($data['custom_value1'])) {
            $invoice->custom_value1 = round($data['custom_value1'], 2);
            if ($isNew) {
                $invoice->custom_taxes1 = $account->custom_invoice_taxes1 ?: false;
            }
        }
        if (isset($data['custom_value2'])) {
            $invoice->custom_value2 = round($data['custom_value2'], 2);
            if ($isNew) {
                $invoice->custom_taxes2 = $account->custom_invoice_taxes2 ?: false;
            }
        }
        if (isset($data['custom_text_value1'])) {
            $invoice->custom_text_value1 = trim($data['custom_text_value1']);
        }
        if (isset($data['custom_text_value2'])) {
            $invoice->custom_text_value2 = trim($data['custom_text_value2']);
        }
        // custom fields charged taxes
        if ($invoice->custom_value1 && $invoice->custom_taxes1) {
            $total += $invoice->custom_value1;
        }
        if ($invoice->custom_value2 && $invoice->custom_taxes2) {
            $total += $invoice->custom_value2;
        }
        $taxAmount1 = round($total * $invoice->tax_rate1 / 100, 2);
        $taxAmount2 = round($total * $invoice->tax_rate2 / 100, 2);
        $total = round($total + $taxAmount1 + $taxAmount2, 2);
        $total += $itemTax;
        // custom fields not charged taxes
        if ($invoice->custom_value1 && !$invoice->custom_taxes1) {
            $total += $invoice->custom_value1;
        }
        if ($invoice->custom_value2 && !$invoice->custom_taxes2) {
            $total += $invoice->custom_value2;
        }
        if ($publicId) {
            $invoice->balance = $total - ($invoice->amount - $invoice->balance);
        } else {
            $invoice->balance = $total;
        }
        if (isset($data['partial'])) {
            $invoice->partial = max(0, min(round(Utils::parseFloat($data['partial']), 2), $invoice->balance));
        }
        $invoice->amount = $total;
        $invoice->save();
        if ($publicId) {
            $invoice->invoice_items()->forceDelete();
        }
        if (!empty($data['document_ids'])) {
            $document_ids = array_map('intval', $data['document_ids']);
            foreach ($document_ids as $document_id) {
                $document = Document::scope($document_id)->first();
                if ($document && Auth::user()->can('edit', $document)) {
                    if ($document->invoice_id && $document->invoice_id != $invoice->id) {
                        // From a clone
                        $document = $document->cloneDocument();
                        $document_ids[] = $document->public_id;
                        // Don't remove this document
                    }
                    $document->invoice_id = $invoice->id;
                    $document->expense_id = null;
                    $document->save();
                }
            }
            if (!$invoice->wasRecentlyCreated) {
                foreach ($invoice->documents as $document) {
                    if (!in_array($document->public_id, $document_ids)) {
                        // Removed
                        // Not checking permissions; deleting a document is just editing the invoice
                        if ($document->invoice_id == $invoice->id) {
                            // Make sure the document isn't on a clone
                            $document->delete();
                        }
                    }
                }
            }
        }
        foreach ($data['invoice_items'] as $item) {
            $item = (array) $item;
            if (empty($item['cost']) && empty($item['product_key']) && empty($item['notes']) && empty($item['custom_value1']) && empty($item['custom_value2'])) {
                continue;
            }
            $task = false;
            if (isset($item['task_public_id']) && $item['task_public_id']) {
                $task = Task::scope($item['task_public_id'])->where('invoice_id', '=', null)->firstOrFail();
                if (Auth::user()->can('edit', $task)) {
                    $task->invoice_id = $invoice->id;
                    $task->client_id = $invoice->client_id;
                    $task->save();
                }
            }
            $expense = false;
            if (isset($item['expense_public_id']) && $item['expense_public_id']) {
                $expense = Expense::scope($item['expense_public_id'])->where('invoice_id', '=', null)->firstOrFail();
                if (Auth::user()->can('edit', $expense)) {
                    $expense->invoice_id = $invoice->id;
                    $expense->client_id = $invoice->client_id;
                    $expense->save();
                }
            }
            if ($productKey = trim($item['product_key'])) {
                if (\Auth::user()->account->update_products && !$invoice->has_tasks && !$invoice->has_expenses) {
                    $product = Product::findProductByKey($productKey);
                    if (!$product) {
                        if (Auth::user()->can('create', ENTITY_PRODUCT)) {
                            $product = Product::createNew();
                            $product->product_key = trim($item['product_key']);
                        } else {
                            $product = null;
                        }
                    }
                    if ($product && Auth::user()->can('edit', $product)) {
                        $product->notes = $task || $expense ? '' : $item['notes'];
                        $product->cost = $expense ? 0 : $item['cost'];
                        $product->save();
                    }
                }
            }
            $invoiceItem = InvoiceItem::createNew();
            $invoiceItem->product_id = isset($product) ? $product->id : null;
            $invoiceItem->product_key = isset($item['product_key']) ? trim($invoice->is_recurring ? $item['product_key'] : Utils::processVariables($item['product_key'])) : '';
            $invoiceItem->notes = trim($invoice->is_recurring ? $item['notes'] : Utils::processVariables($item['notes']));
            $invoiceItem->cost = Utils::parseFloat($item['cost']);
            $invoiceItem->qty = Utils::parseFloat($item['qty']);
            if (isset($item['custom_value1'])) {
                $invoiceItem->custom_value1 = $item['custom_value1'];
            }
            if (isset($item['custom_value2'])) {
                $invoiceItem->custom_value2 = $item['custom_value2'];
            }
            // provide backwards compatability
            if (isset($item['tax_name']) && isset($item['tax_rate'])) {
                $item['tax_name1'] = $item['tax_name'];
                $item['tax_rate1'] = $item['tax_rate'];
            }
            $invoiceItem->fill($item);
            $invoice->invoice_items()->save($invoiceItem);
        }
        return $invoice;
    }

Usage Example

Пример #1
0
 /**
  * @param array $data
  * @param Invoice|null $invoice
  * @return \App\Models\Invoice|Invoice|mixed
  */
 public function save(array $data, Invoice $invoice = null)
 {
     if (isset($data['client'])) {
         $canSaveClient = false;
         $canViewClient = false;
         $clientPublicId = array_get($data, 'client.public_id') ?: array_get($data, 'client.id');
         if (empty($clientPublicId) || $clientPublicId == '-1') {
             $canSaveClient = Auth::user()->can('create', ENTITY_CLIENT);
         } else {
             $client = Client::scope($clientPublicId)->first();
             $canSaveClient = Auth::user()->can('edit', $client);
             $canViewClient = Auth::user()->can('view', $client);
         }
         if ($canSaveClient) {
             $client = $this->clientRepo->save($data['client']);
         }
         if ($canSaveClient || $canViewClient) {
             $data['client_id'] = $client->id;
         }
     }
     $invoice = $this->invoiceRepo->save($data, $invoice);
     $client = $invoice->client;
     $client->load('contacts');
     $sendInvoiceIds = [];
     foreach ($client->contacts as $contact) {
         if ($contact->send_invoice) {
             $sendInvoiceIds[] = $contact->id;
         }
     }
     // if no contacts are selected auto-select the first to enusre there's an invitation
     if (!count($sendInvoiceIds)) {
         $sendInvoiceIds[] = $client->contacts[0]->id;
     }
     foreach ($client->contacts as $contact) {
         $invitation = Invitation::scope()->whereContactId($contact->id)->whereInvoiceId($invoice->id)->first();
         if (in_array($contact->id, $sendInvoiceIds) && !$invitation) {
             $invitation = Invitation::createNew();
             $invitation->invoice_id = $invoice->id;
             $invitation->contact_id = $contact->id;
             $invitation->invitation_key = str_random(RANDOM_KEY_LENGTH);
             $invitation->save();
         } elseif (!in_array($contact->id, $sendInvoiceIds) && $invitation) {
             $invitation->delete();
         }
     }
     return $invoice;
 }
All Usage Examples Of App\Ninja\Repositories\InvoiceRepository::save