mirror of
https://github.com/VueFileManager/vuefilemanager.git
synced 2026-04-05 18:23:48 +00:00
Edit invoice
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
<?php
|
||||
namespace App\Http\Controllers\Oasis;
|
||||
|
||||
use App\Http\Resources\Oasis\OasisInvoiceResource;
|
||||
use Auth;
|
||||
use Illuminate\Http\Request;
|
||||
use Storage;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Str;
|
||||
@@ -20,7 +22,7 @@ use App\Notifications\Oasis\InvoiceDeliveryNotification;
|
||||
class InvoiceController extends Controller
|
||||
{
|
||||
/**
|
||||
* @return mixed
|
||||
* @return Application|ResponseFactory|Response
|
||||
*/
|
||||
public function get_all_regular_invoices()
|
||||
{
|
||||
@@ -31,7 +33,7 @@ class InvoiceController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
* @return Application|ResponseFactory|Response
|
||||
*/
|
||||
public function get_all_advance_invoices()
|
||||
{
|
||||
@@ -41,11 +43,23 @@ class InvoiceController extends Controller
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Invoice $invoice
|
||||
* @return Application|ResponseFactory|Response
|
||||
*/
|
||||
public function get_single_invoice(Invoice $invoice)
|
||||
{
|
||||
return response(
|
||||
new OasisInvoiceResource($invoice),
|
||||
200
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Invoice $invoice
|
||||
* @return \Symfony\Component\HttpFoundation\StreamedResponse
|
||||
*/
|
||||
public function get_invoice(Invoice $invoice)
|
||||
public function download_invoice(Invoice $invoice)
|
||||
{
|
||||
if (! Storage::exists(invoice_path($invoice))) {
|
||||
abort(404, 'Not Found');
|
||||
@@ -55,7 +69,7 @@ class InvoiceController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
* @return Application|ResponseFactory|Response
|
||||
*/
|
||||
public function search()
|
||||
{
|
||||
@@ -130,6 +144,51 @@ class InvoiceController extends Controller
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store and generate new invoice
|
||||
*
|
||||
* @param Request $request
|
||||
* @param Invoice $invoice
|
||||
* @return Application|ResponseFactory|Response
|
||||
*/
|
||||
public function update(StoreInvoiceRequest $request, Invoice $invoice)
|
||||
{
|
||||
$user = $request->user();
|
||||
|
||||
$invoice->update([
|
||||
'invoice_number' => $request->invoice_number,
|
||||
'variable_number' => $request->variable_number,
|
||||
'delivery_at' => $request->delivery_at,
|
||||
'discount_type' => $request->discount_type ?? null,
|
||||
'discount_rate' => $request->discount_rate ?? null,
|
||||
'items' => json_decode($request->items),
|
||||
]);
|
||||
|
||||
Storage::delete(invoice_path($invoice));
|
||||
|
||||
// Generate PDF
|
||||
\PDF::loadView('oasis.invoices.invoice', [
|
||||
'invoice' => Invoice::find($invoice->id),
|
||||
'user' => $user,
|
||||
])
|
||||
->setPaper('a4')
|
||||
->setOrientation('portrait')
|
||||
->save(
|
||||
storage_path("app/files/{$user->id}/invoice-{$invoice->id}.pdf")
|
||||
);
|
||||
|
||||
if ($request->send_invoice && $invoice->client['email']) {
|
||||
Notification::route('mail', $invoice->client['email'])->notify(
|
||||
new InvoiceDeliveryNotification($user, $invoice)
|
||||
);
|
||||
}
|
||||
|
||||
return response(
|
||||
'Done',
|
||||
204
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Invoice $invoice
|
||||
* @throws \Exception
|
||||
|
||||
@@ -23,10 +23,10 @@ class StoreInvoiceRequest extends FormRequest
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'invoice_type' => 'required|string',
|
||||
'invoice_type' => 'sometimes|string',
|
||||
'invoice_number' => 'required|string',
|
||||
'variable_number' => 'required|string',
|
||||
'client' => 'required',
|
||||
'client' => 'sometimes|required',
|
||||
'items' => 'required|string',
|
||||
'discount_type' => 'sometimes|string',
|
||||
'discount_rate' => 'sometimes|integer',
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources\Oasis;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
@@ -15,15 +16,22 @@ class OasisInvoiceResource extends JsonResource
|
||||
{
|
||||
return [
|
||||
'data' => [
|
||||
'id' => $this->id,
|
||||
'type' => 'invoice',
|
||||
'id' => $this->id,
|
||||
'type' => 'invoice',
|
||||
'attributes' => [
|
||||
'name' => $this->client['name'] . ' ' . format_to_currency($this->total_net, $this->currency),
|
||||
'invoiceNumber' => $this->invoice_number,
|
||||
'total' => format_to_currency($this->total_net, $this->currency),
|
||||
'file_url' => "/oasis/invoice/$this->id",
|
||||
'mimetype' => 'pdf',
|
||||
'created_at' => format_date($this->created_at, '%d. %B. %Y'),
|
||||
'name' => $this->client['name'] . ' ' . format_to_currency($this->total_net, $this->currency),
|
||||
'invoice_number' => $this->invoice_number,
|
||||
'variable_number' => $this->variable_number,
|
||||
'invoice_type' => $this->invoice_type,
|
||||
'delivery_at' => $this->delivery_at,
|
||||
'items' => $this->items,
|
||||
'discount_type' => $this->discount_type,
|
||||
'discount_rate' => $this->discount_rate,
|
||||
'client' => $this->client,
|
||||
'total' => format_to_currency($this->total_net, $this->currency),
|
||||
'file_url' => "/oasis/invoice/$this->id",
|
||||
'mimetype' => 'pdf',
|
||||
'created_at' => format_date($this->created_at, '%d. %B. %Y'),
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
@@ -17,10 +17,10 @@ class OasisViewInvoiceResource extends JsonResource
|
||||
'id' => $this->id,
|
||||
'client_id' => $this->client_id,
|
||||
'name' => $this->client['name'] . ' ' . format_to_currency($this->total_net, $this->currency),
|
||||
'invoiceNumber' => $this->invoice_number,
|
||||
'invoice_number' => $this->invoice_number,
|
||||
'total' => format_to_currency($this->total_net, $this->currency),
|
||||
'file_url' => "/oasis/invoice/$this->id",
|
||||
'clientName' => $this->client['name'],
|
||||
'client_name' => $this->client['name'],
|
||||
'mimetype' => 'pdf',
|
||||
'type' => 'invoice',
|
||||
'created_at' => format_date($this->created_at, '%d. %B. %Y'),
|
||||
|
||||
@@ -161,7 +161,7 @@ function invoice_total($invoice)
|
||||
foreach ($invoice['items'] as $item) {
|
||||
$total_without_tax = $item['amount'] * $item['price'];
|
||||
|
||||
if ($item['tax_rate']) {
|
||||
if ($invoice['user']['ic_dph'] && $item['tax_rate']) {
|
||||
$total_without_tax += $total_without_tax * ($item['tax_rate'] / 100);
|
||||
}
|
||||
|
||||
|
||||
@@ -60,15 +60,17 @@ class Invoice extends Model
|
||||
static::creating(function ($invoice) {
|
||||
$invoice->id = (string) Str::uuid();
|
||||
|
||||
$invoice->delivery_at = $invoice->created_at;
|
||||
$invoice->due_at = Carbon::parse($invoice->created_at)->addWeeks(2);
|
||||
|
||||
$invoice->total_net = invoice_total($invoice);
|
||||
$invoice->total_tax = invoice_total_tax($invoice);
|
||||
|
||||
$invoice->currency = 'CZK';
|
||||
});
|
||||
|
||||
static::updating(function ($invoice) {
|
||||
$invoice->total_net = invoice_total($invoice);
|
||||
$invoice->total_tax = invoice_total_tax($invoice);
|
||||
});
|
||||
|
||||
static::deleting(function ($invoice) {
|
||||
Storage::delete(invoice_path($invoice));
|
||||
});
|
||||
|
||||
@@ -91,6 +91,9 @@ return [
|
||||
'in_editor.page.create_regular_invoice' => 'Create Regular Invoice',
|
||||
'in_editor.page.create_advance_invoice' => 'Create Advance Invoice',
|
||||
|
||||
'in_editor.page.edit_regular_invoice' => 'Edit Regular Invoice',
|
||||
'in_editor.page.edit_advance_invoice' => 'Edit Advance Invoice',
|
||||
|
||||
'in_number' => 'Invoice Number',
|
||||
'in_variable' => 'Variable Number',
|
||||
'in_delivery_at' => 'Delivery At',
|
||||
|
||||
@@ -29,7 +29,7 @@ class CreateInvoicesTable extends Migration
|
||||
$table->longText('user');
|
||||
$table->longText('items');
|
||||
|
||||
$table->dateTime('delivery_at')->nullable();
|
||||
$table->date('delivery_at')->nullable();
|
||||
$table->dateTime('due_at')->nullable();
|
||||
|
||||
$table->enum('discount_type', [
|
||||
|
||||
@@ -3,22 +3,22 @@
|
||||
"/css/app.css": "/css/app.css",
|
||||
"/chunks/admin.js": "/chunks/admin.js?id=d29c8270ce8e3564d24d",
|
||||
"/chunks/admin-account.js": "/chunks/admin-account.js?id=a520b95b3a97831ee1ab",
|
||||
"/chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/app-index~chu~f7b5598c.js": "/chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/app-index~chu~f7b5598c.js?id=561bbeab3ee2be3482d1",
|
||||
"/chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/app-index~chu~e360f8a1.js": "/chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/app-index~chu~e360f8a1.js?id=9a997811677c9fcc0c6e",
|
||||
"/chunks/admin-account~chunks/app-setup~chunks/billings-detail~chunks/create-new-password~chunks/datab~062c965c.js": "/chunks/admin-account~chunks/app-setup~chunks/billings-detail~chunks/create-new-password~chunks/datab~062c965c.js?id=515118382f7ad5724a54",
|
||||
"/chunks/admin~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/~968e2d44.js": "/chunks/admin~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/~968e2d44.js?id=e84800d9aeaa44d365c5",
|
||||
"/chunks/admin~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/~56ae6336.js": "/chunks/admin~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/~56ae6336.js?id=3500df10c19053acd77b",
|
||||
"/chunks/admin~chunks/files~chunks/oasis/invoices~chunks/oasis/invoices/list~chunks/platform~chunks/sh~f205bd67.js": "/chunks/admin~chunks/files~chunks/oasis/invoices~chunks/oasis/invoices/list~chunks/platform~chunks/sh~f205bd67.js?id=94e67ef1eef94f3de4a7",
|
||||
"/chunks/admin~chunks/files~chunks/oasis/invoices~chunks/settings~chunks/shared-files~chunks/shared/fi~41abd910.js": "/chunks/admin~chunks/files~chunks/oasis/invoices~chunks/settings~chunks/shared-files~chunks/shared/fi~41abd910.js?id=c804f9bf9138c4da52e9",
|
||||
"/chunks/admin~chunks/oasis/invoices~chunks/platform.js": "/chunks/admin~chunks/oasis/invoices~chunks/platform.js?id=cb303b17a97eae5e5eb2",
|
||||
"/chunks/admin~chunks/oasis/invoices~chunks/platform~chunks/shared.js": "/chunks/admin~chunks/oasis/invoices~chunks/platform~chunks/shared.js?id=a7e1f2b5096c12b0d23a",
|
||||
"/chunks/app-appearance.js": "/chunks/app-appearance.js?id=18f8d651b94fbd837c54",
|
||||
"/chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/app-index~chunks/app-others~chunks~2a5ca68e.js": "/chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/app-index~chunks/app-others~chunks~2a5ca68e.js?id=988a6dd68e8842584a2f",
|
||||
"/chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/app-index~chunks/app-others~chunks~262a2a36.js": "/chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/app-index~chunks/app-others~chunks~262a2a36.js?id=e6505b93727b56256f92",
|
||||
"/chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/app-index~chunks/app-others~chunks~2e0b85bd.js": "/chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/app-index~chunks/app-others~chunks~2e0b85bd.js?id=d4fb46f05374a298ac1b",
|
||||
"/chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/app-index~chunks/app-others~chunks~c329baf3.js": "/chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/app-index~chunks/app-others~chunks~c329baf3.js?id=917423b1c6ec5a0c7435",
|
||||
"/chunks/app-billings.js": "/chunks/app-billings.js?id=19c8e17aa15e387e3383",
|
||||
"/chunks/app-email.js": "/chunks/app-email.js?id=c766715f37d61d6f9f3f",
|
||||
"/chunks/app-index.js": "/chunks/app-index.js?id=f720d72cc83a99a4640b",
|
||||
"/chunks/app-language.js": "/chunks/app-language.js?id=1f5519055f0f5dab0581",
|
||||
"/chunks/app-language~chunks/app-settings~chunks/dashboard~chunks/dashboard-oasis~chunks/invoices~chun~860c81f3.js": "/chunks/app-language~chunks/app-settings~chunks/dashboard~chunks/dashboard-oasis~chunks/invoices~chun~860c81f3.js?id=32f0f57fa68fadd9ab6d",
|
||||
"/chunks/app-language~chunks/app-settings~chunks/dashboard~chunks/dashboard-oasis~chunks/invoices~chun~93101a7f.js": "/chunks/app-language~chunks/app-settings~chunks/dashboard~chunks/dashboard-oasis~chunks/invoices~chun~93101a7f.js?id=93fb27b76209e5b7b2d9",
|
||||
"/chunks/app-language~chunks/dashboard~chunks/dashboard-oasis~chunks/files~chunks/invoices~chunks/oasi~c6e9de01.js": "/chunks/app-language~chunks/dashboard~chunks/dashboard-oasis~chunks/files~chunks/invoices~chunks/oasi~c6e9de01.js?id=f9af3b7905bb7c35023d",
|
||||
"/chunks/app-others.js": "/chunks/app-others.js?id=a8c80eac752e1ebc0b37",
|
||||
"/chunks/app-payments.js": "/chunks/app-payments.js?id=82cca8cd2ee51c71f087",
|
||||
@@ -51,13 +51,14 @@
|
||||
"/chunks/invoices.js": "/chunks/invoices.js?id=1deb187f6d3eb1e81ad0",
|
||||
"/chunks/not-found-shared.js": "/chunks/not-found-shared.js?id=7fc7f9b6f10bdfac770e",
|
||||
"/chunks/oasis/homepage.js": "/chunks/oasis/homepage.js?id=a1885dd8814f9eb63a1c",
|
||||
"/chunks/oasis/invoices.js": "/chunks/oasis/invoices.js?id=8828ef75055bc5e151c2",
|
||||
"/chunks/oasis/invoices.js": "/chunks/oasis/invoices.js?id=44eaa1aabc42857a86d8",
|
||||
"/chunks/oasis/invoices/client.js": "/chunks/oasis/invoices/client.js?id=63a83703890e6cf422f4",
|
||||
"/chunks/oasis/invoices/client-detail.js": "/chunks/oasis/invoices/client-detail.js?id=2414e131ef16f6f2a27a",
|
||||
"/chunks/oasis/invoices/client-invoices.js": "/chunks/oasis/invoices/client-invoices.js?id=fbf2f836d458e66846a3",
|
||||
"/chunks/oasis/invoices/client-invoices.js": "/chunks/oasis/invoices/client-invoices.js?id=988b280cc50ad75eec8c",
|
||||
"/chunks/oasis/invoices/create-client.js": "/chunks/oasis/invoices/create-client.js?id=03f3f613dbea4bb786cb",
|
||||
"/chunks/oasis/invoices/create-invoice.js": "/chunks/oasis/invoices/create-invoice.js?id=dce8aeae9b5ee74658c3",
|
||||
"/chunks/oasis/invoices/list.js": "/chunks/oasis/invoices/list.js?id=a622e568efb24e955520",
|
||||
"/chunks/oasis/invoices/create-invoice.js": "/chunks/oasis/invoices/create-invoice.js?id=8dafd9d9bc583b487df4",
|
||||
"/chunks/oasis/invoices/edit-invoice.js": "/chunks/oasis/invoices/edit-invoice.js?id=f46025ebb44bb463b0e4",
|
||||
"/chunks/oasis/invoices/list.js": "/chunks/oasis/invoices/list.js?id=fc7eab97714b6151c10c",
|
||||
"/chunks/oasis/invoices/profile.js": "/chunks/oasis/invoices/profile.js?id=ea95035cbe1e905f0e95",
|
||||
"/chunks/oasis/invoices~chunks/platform~chunks/shared.js": "/chunks/oasis/invoices~chunks/platform~chunks/shared.js?id=865f72ddd4457b2f06a7",
|
||||
"/chunks/oasis/platba.js": "/chunks/oasis/platba.js?id=74bc76fa643e04156e64",
|
||||
@@ -81,7 +82,7 @@
|
||||
"/chunks/purchase-code.js": "/chunks/purchase-code.js?id=4873b06c3bbca3fe2c36",
|
||||
"/chunks/settings.js": "/chunks/settings.js?id=fcc97a29894164e2977c",
|
||||
"/chunks/settings-create-payment-methods.js": "/chunks/settings-create-payment-methods.js?id=56e2297d23c5070fc493",
|
||||
"/chunks/settings-invoices.js": "/chunks/settings-invoices.js?id=5cd026f533ab926f5c24",
|
||||
"/chunks/settings-invoices.js": "/chunks/settings-invoices.js?id=31a4a51a71c3e9fba43c",
|
||||
"/chunks/settings-password.js": "/chunks/settings-password.js?id=554b31fb2a301c5f1346",
|
||||
"/chunks/settings-payment-methods.js": "/chunks/settings-payment-methods.js?id=07a462a9a6f9bf39f096",
|
||||
"/chunks/settings-storage.js": "/chunks/settings-storage.js?id=3763d6291aa27e295a81",
|
||||
@@ -108,85 +109,56 @@
|
||||
"/chunks/user-storage.js": "/chunks/user-storage.js?id=eca49ccfadab81f08cf3",
|
||||
"/chunks/user-subscription.js": "/chunks/user-subscription.js?id=32b823b73166fcaf70c4",
|
||||
"/chunks/users.js": "/chunks/users.js?id=178dc8d8c83a43d6e77f",
|
||||
"/vendors~chunks/admin~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~7e795377.js": "/vendors~chunks/admin~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~7e795377.js?id=fa4b880e7f3c8341dab9",
|
||||
"/vendors~chunks/admin~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~a77ef2b6.js": "/vendors~chunks/admin~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~a77ef2b6.js?id=d08013f096cb8da8d64c",
|
||||
"/vendors~chunks/admin~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~bc1bf558.js": "/vendors~chunks/admin~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~bc1bf558.js?id=034c637712e863643bd6",
|
||||
"/vendors~chunks/admin~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~ebd71fa1.js": "/vendors~chunks/admin~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~ebd71fa1.js?id=47a427056410805b2f8f",
|
||||
"/vendors~chunks/files~chunks/oasis/invoices~chunks/platform~chunks/shared~chunks/shared-files~chunks/~9b82b04f.js": "/vendors~chunks/files~chunks/oasis/invoices~chunks/platform~chunks/shared~chunks/shared-files~chunks/~9b82b04f.js?id=548bff41ffa0385b8f01",
|
||||
"/vendors~chunks/oasis/invoices~chunks/platform~chunks/shared.js": "/vendors~chunks/oasis/invoices~chunks/platform~chunks/shared.js?id=03d3cf785cbafa4d31f0",
|
||||
"/chunks/oasis/invoices~chunks/platform~chunks/shared.d01504a98f33ea78de87.hot-update.js": "/chunks/oasis/invoices~chunks/platform~chunks/shared.d01504a98f33ea78de87.hot-update.js",
|
||||
"/chunks/oasis/invoices~chunks/platform~chunks/shared.8090367193e191d47e00.hot-update.js": "/chunks/oasis/invoices~chunks/platform~chunks/shared.8090367193e191d47e00.hot-update.js",
|
||||
"/chunks/oasis/invoices~chunks/platform~chunks/shared.df8792b06520b09d6e2a.hot-update.js": "/chunks/oasis/invoices~chunks/platform~chunks/shared.df8792b06520b09d6e2a.hot-update.js",
|
||||
"/chunks/oasis/invoices~chunks/platform~chunks/shared.9220658bdf35e1954bd2.hot-update.js": "/chunks/oasis/invoices~chunks/platform~chunks/shared.9220658bdf35e1954bd2.hot-update.js",
|
||||
"/chunks/oasis/invoices~chunks/platform~chunks/shared.ef472cf1f9eed1ff02e3.hot-update.js": "/chunks/oasis/invoices~chunks/platform~chunks/shared.ef472cf1f9eed1ff02e3.hot-update.js",
|
||||
"/chunks/oasis/invoices~chunks/platform~chunks/shared.a5477b49dd0cf22c838e.hot-update.js": "/chunks/oasis/invoices~chunks/platform~chunks/shared.a5477b49dd0cf22c838e.hot-update.js",
|
||||
"/chunks/oasis/invoices~chunks/platform~chunks/shared.9fccaf5402b0af0812a6.hot-update.js": "/chunks/oasis/invoices~chunks/platform~chunks/shared.9fccaf5402b0af0812a6.hot-update.js",
|
||||
"/chunks/oasis/invoices~chunks/platform~chunks/shared.cb6c41b94733c701922a.hot-update.js": "/chunks/oasis/invoices~chunks/platform~chunks/shared.cb6c41b94733c701922a.hot-update.js",
|
||||
"/chunks/oasis/invoices~chunks/platform~chunks/shared.2ed4bb7dfe1d80d98e75.hot-update.js": "/chunks/oasis/invoices~chunks/platform~chunks/shared.2ed4bb7dfe1d80d98e75.hot-update.js",
|
||||
"/chunks/oasis/invoices/profile.e02ea8b693ec6452b894.hot-update.js": "/chunks/oasis/invoices/profile.e02ea8b693ec6452b894.hot-update.js",
|
||||
"/chunks/admin.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/admin.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/admin-account.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/admin-account.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/app-appearance.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/app-appearance.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/app-billings.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/app-billings.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/app-email.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/app-email.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/app-index.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/app-index.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/app-language.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/app-language.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/app-others.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/app-others.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/app-payments.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/app-payments.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/app-setup.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/app-setup.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/billings-detail.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/billings-detail.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/contact-us.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/contact-us.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/database.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/database.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/environment-setup.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/environment-setup.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/files~chunks/oasis/invoices/list~chunks/platform~chunks/shared-files~chunks/shared/file-browser.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/files~chunks/oasis/invoices/list~chunks/platform~chunks/shared-files~chunks/shared/file-browser.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/files~chunks/oasis/invoices~chunks/platform~chunks/shared~chunks/shared-files~chunks/shared/f~9f6a6eef.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/files~chunks/oasis/invoices~chunks/platform~chunks/shared~chunks/shared-files~chunks/shared/f~9f6a6eef.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/installation-disclaimer.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/installation-disclaimer.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/oasis/invoices/client-detail.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/oasis/invoices/client-detail.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/oasis/invoices/client-invoices.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/oasis/invoices/client-invoices.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/oasis/invoices/create-client.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/oasis/invoices/create-client.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/oasis/invoices/create-invoice.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/oasis/invoices/create-invoice.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/oasis/invoices/profile.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/oasis/invoices/profile.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/oasis/platba.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/oasis/platba.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/oasis/upgrade-billing.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/oasis/upgrade-billing.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/oasis/upgrade-plan.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/oasis/upgrade-plan.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/oasis/user-create.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/oasis/user-create.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/page-edit.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/page-edit.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/plan-create.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/plan-create.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/plan-delete.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/plan-delete.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/plan-settings.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/plan-settings.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/plan-subscribers.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/plan-subscribers.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/platform.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/platform.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/platform~chunks/shared.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/platform~chunks/shared.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/profile.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/profile.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/settings-create-payment-methods.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/settings-create-payment-methods.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/settings-invoices.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/settings-invoices.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/settings-password.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/settings-password.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/settings-payment-methods.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/settings-payment-methods.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/stripe-credentials.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/stripe-credentials.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/subscription-plans.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/subscription-plans.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/upgrade-billing.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/upgrade-billing.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/upgrade-plan.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/upgrade-plan.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/user-create.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/user-create.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/user-delete.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/user-delete.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/user-detail.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/user-detail.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/user-invoices.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/user-invoices.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/user-password.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/user-password.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/user-storage.82ee7e6c3bfcbafe37b1.hot-update.js": "/chunks/user-storage.82ee7e6c3bfcbafe37b1.hot-update.js",
|
||||
"/chunks/oasis/invoices/create-invoice.9d0b758babe362ca1ce1.hot-update.js": "/chunks/oasis/invoices/create-invoice.9d0b758babe362ca1ce1.hot-update.js",
|
||||
"/chunks/oasis/invoices/create-invoice.d6b80cab31e1d1816a97.hot-update.js": "/chunks/oasis/invoices/create-invoice.d6b80cab31e1d1816a97.hot-update.js",
|
||||
"/chunks/oasis/invoices/create-invoice.343866a7a2186b0a43a8.hot-update.js": "/chunks/oasis/invoices/create-invoice.343866a7a2186b0a43a8.hot-update.js",
|
||||
"/chunks/oasis/invoices/create-invoice.ef9d1674f312c1e3058a.hot-update.js": "/chunks/oasis/invoices/create-invoice.ef9d1674f312c1e3058a.hot-update.js",
|
||||
"/chunks/oasis/invoices/create-invoice.13743a1fa2ecb8f8dffd.hot-update.js": "/chunks/oasis/invoices/create-invoice.13743a1fa2ecb8f8dffd.hot-update.js",
|
||||
"/chunks/oasis/invoices/create-invoice.222d07ee6426d41b510a.hot-update.js": "/chunks/oasis/invoices/create-invoice.222d07ee6426d41b510a.hot-update.js",
|
||||
"/chunks/oasis/invoices/create-invoice.d9f2f3c6d2786f0d51fa.hot-update.js": "/chunks/oasis/invoices/create-invoice.d9f2f3c6d2786f0d51fa.hot-update.js",
|
||||
"/chunks/oasis/invoices/create-invoice.024c2975609b942d905f.hot-update.js": "/chunks/oasis/invoices/create-invoice.024c2975609b942d905f.hot-update.js",
|
||||
"/chunks/oasis/invoices/create-invoice.36ba7461657db0ce3a04.hot-update.js": "/chunks/oasis/invoices/create-invoice.36ba7461657db0ce3a04.hot-update.js",
|
||||
"/chunks/oasis/invoices/create-invoice.a32813e4f2bb0cbf1247.hot-update.js": "/chunks/oasis/invoices/create-invoice.a32813e4f2bb0cbf1247.hot-update.js",
|
||||
"/chunks/oasis/invoices/create-invoice.79d9f6033401a3a95819.hot-update.js": "/chunks/oasis/invoices/create-invoice.79d9f6033401a3a95819.hot-update.js",
|
||||
"/chunks/oasis/invoices/create-invoice.a393ef2ea5018e29b5aa.hot-update.js": "/chunks/oasis/invoices/create-invoice.a393ef2ea5018e29b5aa.hot-update.js",
|
||||
"/chunks/oasis/invoices/create-invoice.cadb56f396c5d87b6df8.hot-update.js": "/chunks/oasis/invoices/create-invoice.cadb56f396c5d87b6df8.hot-update.js",
|
||||
"/chunks/oasis/invoices/create-invoice.fde88ca01d1be618a75c.hot-update.js": "/chunks/oasis/invoices/create-invoice.fde88ca01d1be618a75c.hot-update.js",
|
||||
"/chunks/oasis/invoices/create-invoice.d8ee5cf3bef05f07cb98.hot-update.js": "/chunks/oasis/invoices/create-invoice.d8ee5cf3bef05f07cb98.hot-update.js",
|
||||
"/chunks/oasis/invoices/create-invoice.67c3c026313bdaf90bc5.hot-update.js": "/chunks/oasis/invoices/create-invoice.67c3c026313bdaf90bc5.hot-update.js",
|
||||
"/chunks/oasis/invoices/create-invoice.094e78c3f2d2b80a8392.hot-update.js": "/chunks/oasis/invoices/create-invoice.094e78c3f2d2b80a8392.hot-update.js",
|
||||
"/chunks/oasis/invoices/create-invoice.837a0452f3c67826b850.hot-update.js": "/chunks/oasis/invoices/create-invoice.837a0452f3c67826b850.hot-update.js",
|
||||
"/chunks/oasis/invoices/create-invoice.b46d0fbd60719211ec56.hot-update.js": "/chunks/oasis/invoices/create-invoice.b46d0fbd60719211ec56.hot-update.js"
|
||||
"/chunks/oasis/invoices/list.026f4ba9898058caf041.hot-update.js": "/chunks/oasis/invoices/list.026f4ba9898058caf041.hot-update.js",
|
||||
"/chunks/oasis/invoices/edit-invoice.4eddb775c74335508f0a.hot-update.js": "/chunks/oasis/invoices/edit-invoice.4eddb775c74335508f0a.hot-update.js",
|
||||
"/chunks/oasis/invoices/edit-invoice.0e2a2f7c01c9d8f7bd89.hot-update.js": "/chunks/oasis/invoices/edit-invoice.0e2a2f7c01c9d8f7bd89.hot-update.js",
|
||||
"/chunks/oasis/invoices/edit-invoice.63a0d4c1bbf0fa598abe.hot-update.js": "/chunks/oasis/invoices/edit-invoice.63a0d4c1bbf0fa598abe.hot-update.js",
|
||||
"/js/main.f715490e36d652014460.hot-update.js": "/js/main.f715490e36d652014460.hot-update.js",
|
||||
"/chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/app-index~chu~f7b5598c.js": "/chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/app-index~chu~f7b5598c.js?id=561bbeab3ee2be3482d1",
|
||||
"/chunks/admin~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/~968e2d44.js": "/chunks/admin~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/~968e2d44.js?id=e84800d9aeaa44d365c5",
|
||||
"/chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/app-index~chunks/app-others~chunks~2a5ca68e.js": "/chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/app-index~chunks/app-others~chunks~2a5ca68e.js?id=988a6dd68e8842584a2f",
|
||||
"/chunks/app-language~chunks/app-settings~chunks/dashboard~chunks/dashboard-oasis~chunks/invoices~chun~860c81f3.js": "/chunks/app-language~chunks/app-settings~chunks/dashboard~chunks/dashboard-oasis~chunks/invoices~chun~860c81f3.js?id=32f0f57fa68fadd9ab6d",
|
||||
"/chunks/oasis/invoices/edit-invoice.f715490e36d652014460.hot-update.js": "/chunks/oasis/invoices/edit-invoice.f715490e36d652014460.hot-update.js",
|
||||
"/vendors~chunks/admin~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~7e795377.js": "/vendors~chunks/admin~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~7e795377.js?id=fa4b880e7f3c8341dab9",
|
||||
"/vendors~chunks/admin~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~a77ef2b6.js": "/vendors~chunks/admin~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~a77ef2b6.js?id=d08013f096cb8da8d64c",
|
||||
"/chunks/oasis/invoices/list.899af304fb7a63894193.hot-update.js": "/chunks/oasis/invoices/list.899af304fb7a63894193.hot-update.js",
|
||||
"/js/main.56461b40fb3fb6f4c9fc.hot-update.js": "/js/main.56461b40fb3fb6f4c9fc.hot-update.js",
|
||||
"/chunks/oasis/invoices.56461b40fb3fb6f4c9fc.hot-update.js": "/chunks/oasis/invoices.56461b40fb3fb6f4c9fc.hot-update.js",
|
||||
"/chunks/oasis/invoices/client-invoices.56461b40fb3fb6f4c9fc.hot-update.js": "/chunks/oasis/invoices/client-invoices.56461b40fb3fb6f4c9fc.hot-update.js",
|
||||
"/chunks/oasis/invoices/edit-invoice.56461b40fb3fb6f4c9fc.hot-update.js": "/chunks/oasis/invoices/edit-invoice.56461b40fb3fb6f4c9fc.hot-update.js",
|
||||
"/chunks/oasis/invoices/list.56461b40fb3fb6f4c9fc.hot-update.js": "/chunks/oasis/invoices/list.56461b40fb3fb6f4c9fc.hot-update.js",
|
||||
"/chunks/oasis/invoices/edit-invoice.af27cf38064ea659e2c4.hot-update.js": "/chunks/oasis/invoices/edit-invoice.af27cf38064ea659e2c4.hot-update.js",
|
||||
"/chunks/oasis/invoices/edit-invoice.d348d20e525ce5579274.hot-update.js": "/chunks/oasis/invoices/edit-invoice.d348d20e525ce5579274.hot-update.js",
|
||||
"/chunks/oasis/invoices/edit-invoice.4ff8e31134d4c3ef3833.hot-update.js": "/chunks/oasis/invoices/edit-invoice.4ff8e31134d4c3ef3833.hot-update.js",
|
||||
"/chunks/oasis/invoices/edit-invoice.41fc16199810702a0399.hot-update.js": "/chunks/oasis/invoices/edit-invoice.41fc16199810702a0399.hot-update.js",
|
||||
"/chunks/oasis/invoices/list.7bb780bfed72b74b5b0f.hot-update.js": "/chunks/oasis/invoices/list.7bb780bfed72b74b5b0f.hot-update.js",
|
||||
"/chunks/oasis/invoices/create-invoice.48e2ec0329a24604e772.hot-update.js": "/chunks/oasis/invoices/create-invoice.48e2ec0329a24604e772.hot-update.js",
|
||||
"/chunks/oasis/invoices/create-invoice.78477379f3f48137c8c0.hot-update.js": "/chunks/oasis/invoices/create-invoice.78477379f3f48137c8c0.hot-update.js",
|
||||
"/chunks/oasis/invoices/create-invoice.9d09da188e2a535bdf58.hot-update.js": "/chunks/oasis/invoices/create-invoice.9d09da188e2a535bdf58.hot-update.js",
|
||||
"/chunks/oasis/invoices/edit-invoice.611d4ff1848396f4d487.hot-update.js": "/chunks/oasis/invoices/edit-invoice.611d4ff1848396f4d487.hot-update.js",
|
||||
"/chunks/oasis/invoices/edit-invoice.815ffe2ce16f8f9a13d5.hot-update.js": "/chunks/oasis/invoices/edit-invoice.815ffe2ce16f8f9a13d5.hot-update.js",
|
||||
"/chunks/oasis/invoices/edit-invoice.a98fb514aae350478e29.hot-update.js": "/chunks/oasis/invoices/edit-invoice.a98fb514aae350478e29.hot-update.js",
|
||||
"/chunks/settings-invoices.ba300614b6cfac28ecf2.hot-update.js": "/chunks/settings-invoices.ba300614b6cfac28ecf2.hot-update.js",
|
||||
"/chunks/oasis/invoices/edit-invoice.52146d054f77a2fddea3.hot-update.js": "/chunks/oasis/invoices/edit-invoice.52146d054f77a2fddea3.hot-update.js",
|
||||
"/chunks/oasis/invoices/edit-invoice.c2891d965396f19e73fa.hot-update.js": "/chunks/oasis/invoices/edit-invoice.c2891d965396f19e73fa.hot-update.js",
|
||||
"/chunks/oasis/invoices/edit-invoice.84852c4dca8df35c0da6.hot-update.js": "/chunks/oasis/invoices/edit-invoice.84852c4dca8df35c0da6.hot-update.js",
|
||||
"/chunks/oasis/invoices/edit-invoice.923b2ffca6b622513d08.hot-update.js": "/chunks/oasis/invoices/edit-invoice.923b2ffca6b622513d08.hot-update.js",
|
||||
"/chunks/oasis/invoices/edit-invoice.2dad59f98d87a20dfc1c.hot-update.js": "/chunks/oasis/invoices/edit-invoice.2dad59f98d87a20dfc1c.hot-update.js",
|
||||
"/chunks/oasis/invoices/edit-invoice.08c250011f233f62ed41.hot-update.js": "/chunks/oasis/invoices/edit-invoice.08c250011f233f62ed41.hot-update.js",
|
||||
"/chunks/oasis/invoices/edit-invoice.8a8486d58bbfbd70fbf8.hot-update.js": "/chunks/oasis/invoices/edit-invoice.8a8486d58bbfbd70fbf8.hot-update.js",
|
||||
"/chunks/oasis/invoices/edit-invoice.bc4f02507b8051750090.hot-update.js": "/chunks/oasis/invoices/edit-invoice.bc4f02507b8051750090.hot-update.js",
|
||||
"/chunks/oasis/invoices/edit-invoice.7a3c56c1d20c5b1b3516.hot-update.js": "/chunks/oasis/invoices/edit-invoice.7a3c56c1d20c5b1b3516.hot-update.js",
|
||||
"/chunks/oasis/invoices/edit-invoice.ef33517e3b97aef5dd0f.hot-update.js": "/chunks/oasis/invoices/edit-invoice.ef33517e3b97aef5dd0f.hot-update.js",
|
||||
"/chunks/oasis/invoices/edit-invoice.fe68c7be6dbd18ac8c17.hot-update.js": "/chunks/oasis/invoices/edit-invoice.fe68c7be6dbd18ac8c17.hot-update.js",
|
||||
"/chunks/oasis/invoices/edit-invoice.a85b437e975e59b79683.hot-update.js": "/chunks/oasis/invoices/edit-invoice.a85b437e975e59b79683.hot-update.js",
|
||||
"/chunks/oasis/invoices/edit-invoice.19c86b7bb6f4f540a01c.hot-update.js": "/chunks/oasis/invoices/edit-invoice.19c86b7bb6f4f540a01c.hot-update.js",
|
||||
"/chunks/oasis/invoices/edit-invoice.cb4f67dd12024e29db04.hot-update.js": "/chunks/oasis/invoices/edit-invoice.cb4f67dd12024e29db04.hot-update.js",
|
||||
"/chunks/oasis/invoices/edit-invoice.80a52aeb3183100af99d.hot-update.js": "/chunks/oasis/invoices/edit-invoice.80a52aeb3183100af99d.hot-update.js",
|
||||
"/chunks/oasis/invoices/edit-invoice.ffea9fa001d9b2ac34eb.hot-update.js": "/chunks/oasis/invoices/edit-invoice.ffea9fa001d9b2ac34eb.hot-update.js",
|
||||
"/chunks/oasis/invoices/edit-invoice.91f9c200784731462be0.hot-update.js": "/chunks/oasis/invoices/edit-invoice.91f9c200784731462be0.hot-update.js",
|
||||
"/chunks/oasis/invoices/client-invoices.5072ebf8fa7df556cb57.hot-update.js": "/chunks/oasis/invoices/client-invoices.5072ebf8fa7df556cb57.hot-update.js"
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<tr>
|
||||
<td>
|
||||
<span class="cell-item">
|
||||
{{ row.data.attributes.invoiceNumber }}
|
||||
{{ row.data.attributes.invoice_number }}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
@@ -32,7 +32,7 @@
|
||||
<a @click="downloadItem(row)">
|
||||
<DownloadCloudIcon size="15" class="icon" />
|
||||
</a>
|
||||
<router-link :to="{name: 'ClientDetail'}">
|
||||
<router-link :to="{name: 'EditInvoice', params: {id: row.data.id}}">
|
||||
<edit2-icon size="15" class="icon" />
|
||||
</router-link>
|
||||
</div>
|
||||
|
||||
@@ -277,7 +277,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div :class="{'is-offset': isDiscount && invoice.discount_rate > 0}">
|
||||
<div v-if="isVatPayer" :class="{'is-offset': isDiscount && invoice.discount_rate > 0}">
|
||||
<div v-for="(tax, i) in taxBased" :key="i" class="row small">
|
||||
<div class="cell">
|
||||
<span>{{ $t('in_editor.summary.vat_base') }} {{ tax.rate }}%</span>
|
||||
@@ -288,7 +288,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div :class="{'is-offset': taxSummary.length > 1}">
|
||||
<div v-if="isVatPayer" :class="{'is-offset': taxSummary.length > 1}">
|
||||
<div v-for="(tax, i) in taxSummary" :key="i" class="row small">
|
||||
<div class="cell">
|
||||
<span>{{ $t('in_editor.summary.vat') }} {{ tax.rate }}%</span>
|
||||
@@ -474,7 +474,7 @@
|
||||
let total_without_tax = (item.price * item.amount)
|
||||
|
||||
// Count tax
|
||||
if (item.tax_rate) {
|
||||
if (this.isVatPayer && item.tax_rate) {
|
||||
total_without_tax += total_without_tax * (item.tax_rate / 100)
|
||||
}
|
||||
|
||||
@@ -535,8 +535,8 @@
|
||||
price: undefined,
|
||||
}
|
||||
],
|
||||
discount_type: undefined,
|
||||
discount_rate: undefined,
|
||||
discount_type: 'percent',
|
||||
discount_rate: 10,
|
||||
client: '',
|
||||
client_avatar: '',
|
||||
client_name: '',
|
||||
@@ -552,16 +552,6 @@
|
||||
send_invoice: true,
|
||||
store_client: true,
|
||||
},
|
||||
invoiceTypeList: [
|
||||
{
|
||||
label: 'Regular Invoice',
|
||||
value: 'regular-invoice',
|
||||
},
|
||||
{
|
||||
label: 'Advance Invoice',
|
||||
value: 'advance-invoice',
|
||||
},
|
||||
],
|
||||
discountTypeList: [
|
||||
{
|
||||
label: this.$t('in_editor.discount_type_percent'),
|
||||
@@ -583,15 +573,6 @@
|
||||
this.invoice.client_city = response.data.city
|
||||
this.invoice.client_postal_code = response.data.addr_zip
|
||||
this.fullDetails = response.data.name + ' ' + response.data.addr_full
|
||||
|
||||
//this.$refs.createUser.reset()
|
||||
})
|
||||
.catch(error => {
|
||||
/*if (error.response.status == 404) {
|
||||
this.$refs.createUser.setErrors({
|
||||
'ICO': 'Nič sa nenašlo :('
|
||||
});
|
||||
}*/
|
||||
})
|
||||
}, 300),
|
||||
formatCurrency(value) {
|
||||
@@ -690,7 +671,6 @@
|
||||
})
|
||||
|
||||
this.$nextTick(() => this.$refs.duplicatorItemTitle.slice(-1).pop().focus())
|
||||
|
||||
},
|
||||
removeRow(item) {
|
||||
if (this.invoice.items.length > 1)
|
||||
|
||||
700
resources/js/Oasis/Invoices/Invoices/EditInvoice.vue
Normal file
700
resources/js/Oasis/Invoices/Invoices/EditInvoice.vue
Normal file
@@ -0,0 +1,700 @@
|
||||
<template>
|
||||
<div id="single-page">
|
||||
<MobileHeader :title="pageTitle" />
|
||||
<PageHeader :title="pageTitle" />
|
||||
|
||||
<div id="page-content">
|
||||
<div class="content-page" v-if="! isLoadingPage">
|
||||
<ValidationObserver @submit.prevent="updateInvoice" ref="updateInvoice" v-slot="{ invalid }" tag="form" class="form block-form">
|
||||
<PageTab>
|
||||
|
||||
<!--Properties-->
|
||||
<PageTabGroup>
|
||||
<FormLabel icon="tool">{{ $t('in_editor.properties') }}</FormLabel>
|
||||
|
||||
<div class="block-wrapper">
|
||||
<label>{{ $t('in_number') }}:</label>
|
||||
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="invoice_number" rules="required" v-slot="{ errors }">
|
||||
<input v-model.number="invoice.invoice_number" :placeholder="$t('in_editor.plac.invoice_number')" type="number" :class="{'is-error': errors[0]}" class="focus-border-theme" />
|
||||
<small v-if="latestInvoiceNumber" class="input-help">
|
||||
{{ $t('in_number_desc', {number: latestInvoiceNumber}) }}
|
||||
</small>
|
||||
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
|
||||
</ValidationProvider>
|
||||
</div>
|
||||
|
||||
<div class="block-wrapper">
|
||||
<label>{{ $t('in_variable') }}:</label>
|
||||
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="variable_number" rules="required" v-slot="{ errors }">
|
||||
<input v-model.number="invoice.variable_number" :placeholder="$t('in_editor.plac.variable_number')" type="number" :class="{'is-error': errors[0]}" class="focus-border-theme" />
|
||||
<small v-if="latestInvoiceNumber" class="input-help">
|
||||
{{ $t('in_variable_desc') }}
|
||||
</small>
|
||||
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
|
||||
</ValidationProvider>
|
||||
</div>
|
||||
|
||||
<div class="block-wrapper">
|
||||
<label>{{ $t('in_delivery_at') }}:</label>
|
||||
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="delivery_at" rules="required" v-slot="{ errors }">
|
||||
<input v-model="invoice.delivery_at" type="date" :class="{'is-error': errors[0]}" class="focus-border-theme" />
|
||||
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
|
||||
</ValidationProvider>
|
||||
</div>
|
||||
</PageTabGroup>
|
||||
|
||||
<!--Client-->
|
||||
<PageTabGroup>
|
||||
<FormLabel icon="user">{{ $t('in_editor.client') }}</FormLabel>
|
||||
|
||||
<div class="block-wrapper">
|
||||
<label>{{ $t('in_editor.client') }}:</label>
|
||||
<div class="input-wrapper">
|
||||
<input v-model.number="invoice.client['name']" type="text" disabled />
|
||||
</div>
|
||||
</div>
|
||||
</PageTabGroup>
|
||||
|
||||
<!--Items-->
|
||||
<PageTabGroup>
|
||||
<FormLabel icon="edit">{{ $t('in_editor.items') }}</FormLabel>
|
||||
|
||||
<div class="duplicator">
|
||||
<div class="plan-item duplicator-item" v-for="(item, index) in invoice.items" :key="index++">
|
||||
<x-icon @click="removeRow(item)" v-if="index !== 1" size="22" class="delete-item hover-text-theme" />
|
||||
|
||||
<div class="block-wrapper">
|
||||
<label>{{ $t('in_editor.description') }}:</label>
|
||||
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="description" rules="required" v-slot="{ errors }">
|
||||
<input v-model="item.description" ref="duplicatorItemTitle" :placeholder="$t('in_editor.plac.item_desc')" type="text" :class="{'is-error': errors[0]}" class="focus-border-theme" />
|
||||
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
|
||||
</ValidationProvider>
|
||||
</div>
|
||||
|
||||
<div class="wrapper-inline">
|
||||
<div class="block-wrapper">
|
||||
<label>{{ $t('in_editor.amount') }}:</label>
|
||||
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="amount" rules="required" v-slot="{ errors }">
|
||||
<input v-model.number="item.amount" :placeholder="$t('in_editor.plac.item_amount')" type="number" :class="{'is-error': errors[0]}" class="focus-border-theme" />
|
||||
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
|
||||
</ValidationProvider>
|
||||
</div>
|
||||
|
||||
<div v-if="isVatPayer" class="block-wrapper">
|
||||
<label>{{ $t('in_editor.tax_rate') }}:</label>
|
||||
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="tax_rate" rules="required" v-slot="{ errors }">
|
||||
<input v-model.number="item.tax_rate" :placeholder="$t('in_editor.plac.item_tax_rate')" type="number" step="1" min="1" max="100" :class="{'is-error': errors[0]}" class="focus-border-theme" />
|
||||
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
|
||||
</ValidationProvider>
|
||||
</div>
|
||||
|
||||
<div class="block-wrapper">
|
||||
<label>{{ $t('in_editor.price') }}:</label>
|
||||
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="price" rules="required" v-slot="{ errors }">
|
||||
<input v-model.number="item.price" :placeholder="$t('in_editor.plac.item_price')" type="text" pattern="[0-9]{1,4}(\.[0-9]{2})?" step="0.01" :class="{'is-error': errors[0]}" class="focus-border-theme" />
|
||||
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
|
||||
</ValidationProvider>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ButtonBase @click.native="addRow" class="duplicator-add-button" button-style="theme">
|
||||
{{ $t('in_editor.add_item') }}
|
||||
</ButtonBase>
|
||||
</div>
|
||||
</PageTabGroup>
|
||||
|
||||
<!--Discount-->
|
||||
<PageTabGroup>
|
||||
<FormLabel icon="credit-card">
|
||||
{{ $t('in_editor.discount') }}
|
||||
</FormLabel>
|
||||
|
||||
<div class="block-wrapper">
|
||||
<div class="input-wrapper">
|
||||
<div class="inline-wrapper">
|
||||
<div class="switch-label">
|
||||
<label class="input-label">{{ $t('in_editor.apply_discount') }}:</label>
|
||||
<small class="input-help">{{ $t('in_editor.discount_help') }}</small>
|
||||
</div>
|
||||
<SwitchInput v-model="isDiscount" class="switch" :state="isDiscount" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="isDiscount" class="block-wrapper">
|
||||
<label>{{ $t('in_editor.discount_type') }}:</label>
|
||||
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="discount_type" rules="required" v-slot="{ errors }">
|
||||
<SelectInput v-model="invoice.discount_type" :default="invoice.discount_type" :options="discountTypeList" :placeholder="$t('in_editor.plac.discount_type')" :isError="errors[0]" />
|
||||
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
|
||||
</ValidationProvider>
|
||||
</div>
|
||||
|
||||
<div v-if="isDiscount" class="block-wrapper">
|
||||
<label>{{ $t('in_editor.discount_rate') }}:</label>
|
||||
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="discount_rate" rules="required" v-slot="{ errors }">
|
||||
<input v-model.number="invoice.discount_rate" :placeholder="$t('in_editor.plac.discount_rate')" max="100" min="0" type="number" :class="{'is-error': errors[0]}" class="focus-border-theme" />
|
||||
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
|
||||
</ValidationProvider>
|
||||
</div>
|
||||
</PageTabGroup>
|
||||
|
||||
<!--Others-->
|
||||
<PageTabGroup>
|
||||
<FormLabel icon="settings">{{ $t('in_editor.others') }}</FormLabel>
|
||||
|
||||
<div v-if="invoice.client_email" class="block-wrapper">
|
||||
<div class="input-wrapper">
|
||||
<div class="inline-wrapper">
|
||||
<div class="switch-label">
|
||||
<label class="input-label">{{ $t('in_editor.store_client') }}:</label>
|
||||
<small class="input-help">{{ $t('in_editor.store_client_notes') }}</small>
|
||||
</div>
|
||||
<SwitchInput v-model="invoice.send_invoice" class="switch" :state="invoice.send_invoice" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="block-wrapper">
|
||||
<div class="input-wrapper">
|
||||
<div class="inline-wrapper">
|
||||
<div class="switch-label">
|
||||
<label class="input-label">{{ $t('in_editor.send') }}:</label>
|
||||
<small class="input-help">{{ $t('in_editor.send_notes') }}</small>
|
||||
</div>
|
||||
<SwitchInput v-model="invoice.send_invoice" class="switch" :state="invoice.send_invoice" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</PageTabGroup>
|
||||
</PageTab>
|
||||
</ValidationObserver>
|
||||
<div class="summary">
|
||||
<FormLabel icon="credit-card">
|
||||
{{ $t('in_editor.summary') }}
|
||||
</FormLabel>
|
||||
<div class="summary-list" :class="{'is-error': isError}">
|
||||
|
||||
<div v-if="isDiscount && invoice.discount_rate > 0" class="row small">
|
||||
<div class="cell">
|
||||
<span>{{ $t('in_editor.discount') }}</span>
|
||||
</div>
|
||||
<div class="cell">
|
||||
<span>-{{ invoice.discount_type === 'percent' ? formatNumber(invoice.discount_rate) + '%' : formatCurrency(invoice.discount_rate) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="isVatPayer" :class="{'is-offset': isDiscount && invoice.discount_rate > 0}">
|
||||
<div v-for="(tax, i) in taxBased" :key="i" class="row small">
|
||||
<div class="cell">
|
||||
<span>{{ $t('in_editor.summary.vat_base') }} {{ tax.rate }}%</span>
|
||||
</div>
|
||||
<div class="cell">
|
||||
<span>{{ formatCurrency(tax.total) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="isVatPayer" :class="{'is-offset': taxSummary.length > 1}">
|
||||
<div v-for="(tax, i) in taxSummary" :key="i" class="row small">
|
||||
<div class="cell">
|
||||
<span>{{ $t('in_editor.summary.vat') }} {{ tax.rate }}%</span>
|
||||
</div>
|
||||
<div class="cell">
|
||||
<span>{{ formatCurrency(tax.total) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row" :class="{'row-summary': total > 0}">
|
||||
<div class="cell">
|
||||
<b>{{ $t('in_editor.summary.total') }}</b>
|
||||
</div>
|
||||
<div class="cell">
|
||||
<b>{{ formatCurrency(total) }}</b>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ButtonBase :disabled="isLoading" @click.native="deleteInvoice" button-style="danger" class="next-submit">
|
||||
Delete Invoice
|
||||
</ButtonBase>
|
||||
|
||||
<ButtonBase :disabled="isLoading" :loading="isLoading" @click.native="updateInvoice" button-style="theme-solid" class="next-submit" style="margin-top: 10px">
|
||||
{{ $t('in_editor.submit') }}
|
||||
</ButtonBase>
|
||||
<p class="error-message" v-if="isError">
|
||||
{{ errorMessage }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="loader" v-if="isLoadingPage">
|
||||
<Spinner />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {ValidationProvider, ValidationObserver} from 'vee-validate/dist/vee-validate.full'
|
||||
import PageTabGroup from '@/components/Others/Layout/PageTabGroup'
|
||||
import SwitchInput from '@/components/Others/Forms/SwitchInput'
|
||||
import SelectInput from '@/components/Others/Forms/SelectInput'
|
||||
import ImageInput from '@/components/Others/Forms/ImageInput'
|
||||
import FormLabel from '@/components/Others/Forms/FormLabel'
|
||||
import MobileHeader from '@/components/Mobile/MobileHeader'
|
||||
import ButtonBase from '@/components/FilesView/ButtonBase'
|
||||
import PageTab from '@/components/Others/Layout/PageTab'
|
||||
import PageHeader from '@/components/Others/PageHeader'
|
||||
import InfoBox from '@/components/Others/Forms/InfoBox'
|
||||
import Spinner from '@/components/FilesView/Spinner'
|
||||
import {required} from 'vee-validate/dist/rules'
|
||||
import {XIcon} from 'vue-feather-icons'
|
||||
import {mapGetters} from 'vuex'
|
||||
import {events} from "@/bus"
|
||||
import axios from "axios"
|
||||
import {debounce} from "lodash"
|
||||
|
||||
export default {
|
||||
name: 'CreateInvoice',
|
||||
components: {
|
||||
ValidationProvider,
|
||||
ValidationObserver,
|
||||
PageTabGroup,
|
||||
MobileHeader,
|
||||
SelectInput,
|
||||
SwitchInput,
|
||||
ImageInput,
|
||||
PageHeader,
|
||||
ButtonBase,
|
||||
FormLabel,
|
||||
required,
|
||||
Spinner,
|
||||
InfoBox,
|
||||
PageTab,
|
||||
XIcon,
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'countries',
|
||||
'config',
|
||||
]),
|
||||
pageTitle() {
|
||||
return {
|
||||
'regular-invoice': this.$t('in_editor.page.edit_regular_invoice'),
|
||||
'advance-invoice': this.$t('in_editor.page.edit_advance_invoice'),
|
||||
}[this.invoice.invoice_type]
|
||||
},
|
||||
taxBased() {
|
||||
let bag = [];
|
||||
|
||||
this.invoice.items.forEach(item => {
|
||||
|
||||
if (item.price && item.amount && item.tax_rate) {
|
||||
|
||||
if (!bag.find(bagItem => bagItem.rate === item.tax_rate)) {
|
||||
|
||||
bag.push({
|
||||
rate: item.tax_rate,
|
||||
total: (item.price * item.amount),
|
||||
})
|
||||
} else {
|
||||
bag.find(bagItem => {
|
||||
|
||||
// Count total tax rate for percentage
|
||||
if (bagItem.rate === item.tax_rate) {
|
||||
bagItem.total += (item.price * item.amount)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// Count discount
|
||||
if (this.isDiscount) {
|
||||
bag.forEach(bagItem => {
|
||||
|
||||
if (this.invoice.discount_type === 'percent') {
|
||||
bagItem.total -= bagItem.total * (this.invoice.discount_rate / 100)
|
||||
}
|
||||
|
||||
if (this.invoice.discount_type === 'value') {
|
||||
let percentage_of_discount = this.invoice.discount_rate / (this.total + this.invoice.discount_rate)
|
||||
|
||||
bagItem.total -= bagItem.total * percentage_of_discount
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return bag
|
||||
},
|
||||
taxSummary() {
|
||||
let bag = [];
|
||||
|
||||
this.invoice.items.forEach(item => {
|
||||
|
||||
if (item.price && item.amount && item.tax_rate) {
|
||||
|
||||
if (!bag.find(bagItem => bagItem.rate === item.tax_rate)) {
|
||||
|
||||
bag.push({
|
||||
rate: item.tax_rate,
|
||||
total: (item.price * item.amount) * (item.tax_rate / 100),
|
||||
})
|
||||
|
||||
} else {
|
||||
|
||||
bag.map(bagItem => {
|
||||
|
||||
// Count total tax rate for percentage
|
||||
if (bagItem.rate === item.tax_rate) {
|
||||
bagItem.total += (item.price * item.amount) * (item.tax_rate / 100)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// Count discount
|
||||
if (this.isDiscount) {
|
||||
bag.forEach(bagItem => {
|
||||
|
||||
if (this.invoice.discount_type === 'percent') {
|
||||
bagItem.total -= bagItem.total * (this.invoice.discount_rate / 100)
|
||||
}
|
||||
|
||||
if (this.invoice.discount_type === 'value') {
|
||||
let percentage_of_discount = this.invoice.discount_rate / (this.total + this.invoice.discount_rate)
|
||||
|
||||
bagItem.total -= bagItem.total * percentage_of_discount
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return bag
|
||||
},
|
||||
total() {
|
||||
let total = 0;
|
||||
|
||||
this.invoice.items.forEach(item => {
|
||||
if (item.price && item.amount) {
|
||||
|
||||
let total_without_tax = (item.price * item.amount)
|
||||
|
||||
// Count tax
|
||||
if (this.isVatPayer && item.tax_rate) {
|
||||
total_without_tax += total_without_tax * (item.tax_rate / 100)
|
||||
}
|
||||
|
||||
total += total_without_tax
|
||||
}
|
||||
})
|
||||
|
||||
// Count discount
|
||||
if (this.isDiscount) {
|
||||
|
||||
if (this.invoice.discount_type === 'percent') {
|
||||
total -= total * (this.invoice.discount_rate / 100)
|
||||
}
|
||||
|
||||
if (this.invoice.discount_type === 'value') {
|
||||
total -= this.invoice.discount_rate
|
||||
}
|
||||
}
|
||||
|
||||
return total
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
isDiscount(val) {
|
||||
if (!val) {
|
||||
this.invoice.discount_rate = null
|
||||
this.invoice.discount_type = null
|
||||
}
|
||||
},
|
||||
'invoice.invoice_number': function (val) {
|
||||
this.invoice.variable_number = val
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
fullDetails: undefined,
|
||||
isLoadingPage: true,
|
||||
isLoading: false,
|
||||
isError: false,
|
||||
isDiscount: false,
|
||||
isVatPayer: false,
|
||||
clients: [],
|
||||
latestInvoiceNumber: undefined,
|
||||
invoice: {
|
||||
invoice_type: '',
|
||||
invoice_number: '',
|
||||
variable_number: '',
|
||||
delivery_at: '',
|
||||
items: [
|
||||
{
|
||||
id: Math.floor(Math.random() * 10000000),
|
||||
description: '',
|
||||
amount: 1,
|
||||
tax_rate: 21,
|
||||
price: undefined,
|
||||
}
|
||||
],
|
||||
discount_type: undefined,
|
||||
discount_rate: undefined,
|
||||
client: '',
|
||||
send_invoice: false,
|
||||
},
|
||||
discountTypeList: [
|
||||
{
|
||||
label: this.$t('in_editor.discount_type_percent'),
|
||||
value: 'percent',
|
||||
},
|
||||
{
|
||||
label: this.$t('in_editor.discount_type_amount'),
|
||||
value: 'value',
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
formatCurrency(value) {
|
||||
return new Intl
|
||||
.NumberFormat('cs-CS', {
|
||||
style: 'currency',
|
||||
currency: 'CZK'
|
||||
})
|
||||
.format(value)
|
||||
},
|
||||
formatNumber(value) {
|
||||
return (Math.round(value * 100) / 100)
|
||||
.toFixed(2);
|
||||
},
|
||||
deleteInvoice() {
|
||||
events.$emit('confirm:open', {
|
||||
title: `Are you sure you want to delete this invoice?`,
|
||||
message: 'Your invoice will be permanently deleted.',
|
||||
buttonColor: 'danger-solid',
|
||||
action: {
|
||||
id: this.$route.params.id,
|
||||
operation: 'delete-invoice'
|
||||
}
|
||||
})
|
||||
},
|
||||
async updateInvoice() {
|
||||
const isValid = await this.$refs.updateInvoice.validate();
|
||||
|
||||
if (!isValid) {
|
||||
this.isError = true
|
||||
this.errorMessage = this.$t('in_editor.error')
|
||||
return
|
||||
}
|
||||
|
||||
// Start loading
|
||||
this.isLoading = true
|
||||
|
||||
// Create form
|
||||
let formData = new FormData()
|
||||
|
||||
// Append data to form
|
||||
Object.keys(this.invoice).forEach(key => {
|
||||
|
||||
if (key === 'items') {
|
||||
formData.append(key, JSON.stringify(this.invoice[key]))
|
||||
} else {
|
||||
if (this.invoice[key])
|
||||
formData.append(key, this.invoice[key])
|
||||
}
|
||||
})
|
||||
|
||||
// Send request to get user token
|
||||
axios
|
||||
.post(`/api/oasis/invoices/${this.$route.params.id}`, formData)
|
||||
.then(() => {
|
||||
|
||||
events.$emit('toaster', {
|
||||
type: 'success',
|
||||
message: 'The invoice was successfully edited.',
|
||||
})
|
||||
})
|
||||
.catch(error => {
|
||||
this.isError = true
|
||||
|
||||
if (error.response.status === 422) {
|
||||
|
||||
Object.keys(error.response.data.errors).forEach(key => {
|
||||
|
||||
let obj = {};
|
||||
obj[key] = error.response.data.errors[key]
|
||||
|
||||
this.$refs.updateInvoice.setErrors(obj);
|
||||
})
|
||||
|
||||
} else {
|
||||
events.$emit('alert:open', {
|
||||
title: this.$t('popup_error.title'),
|
||||
message: this.$t('popup_error.message'),
|
||||
})
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.isLoading = false
|
||||
})
|
||||
},
|
||||
addRow() {
|
||||
let lastTaxRate = this.invoice.items.slice(-1).pop()
|
||||
|
||||
this.invoice.items.push({
|
||||
id: Math.floor(Math.random() * 10000000),
|
||||
description: '',
|
||||
amount: 1,
|
||||
tax_rate: lastTaxRate?.tax_rate || 21,
|
||||
price: 1,
|
||||
})
|
||||
|
||||
this.$nextTick(() => this.$refs.duplicatorItemTitle.slice(-1).pop().focus())
|
||||
},
|
||||
removeRow(item) {
|
||||
if (this.invoice.items.length > 1)
|
||||
this.invoice.items = this.invoice.items.filter(obj => obj.id !== item.id)
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
axios.get('/api/oasis/invoices/editor')
|
||||
.then(response => {
|
||||
this.isVatPayer = response.data.isVatPayer
|
||||
})
|
||||
|
||||
axios.get(`/api/oasis/invoices/${this.$route.params.id}`)
|
||||
.then(response => {
|
||||
this.invoice.invoice_number = response.data.data.attributes.invoice_number
|
||||
this.invoice.variable_number = response.data.data.attributes.variable_number
|
||||
this.invoice.invoice_type = response.data.data.attributes.invoice_type
|
||||
this.invoice.delivery_at = response.data.data.attributes.delivery_at
|
||||
this.invoice.items = response.data.data.attributes.items
|
||||
this.invoice.discount_type = response.data.data.attributes.discount_type
|
||||
this.invoice.discount_rate = response.data.data.attributes.discount_rate
|
||||
this.invoice.client = response.data.data.attributes.client
|
||||
|
||||
if (this.invoice.discount_type && this.invoice.discount_rate) {
|
||||
this.isDiscount = true
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.isLoadingPage = false
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '@assets/vuefilemanager/_variables';
|
||||
@import '@assets/vuefilemanager/_mixins';
|
||||
@import '@assets/vuefilemanager/_forms';
|
||||
|
||||
#page-content {
|
||||
max-width: 1100px;
|
||||
}
|
||||
|
||||
.content-page {
|
||||
display: grid;
|
||||
grid-template-columns: 2fr 1fr;
|
||||
margin-bottom: 30px;
|
||||
gap: 50px;
|
||||
|
||||
.form {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.summary-list {
|
||||
box-shadow: 0 7px 20px 5px hsla(220, 36%, 16%, 0.06);
|
||||
border-radius: 8px;
|
||||
min-width: 300px;
|
||||
position: sticky;
|
||||
padding: 25px;
|
||||
top: 85px;
|
||||
|
||||
&.is-error {
|
||||
border: 2px solid $danger;
|
||||
box-shadow: 0 7px 20px 5px rgba($danger, 0.06);
|
||||
}
|
||||
|
||||
.error-message {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.next-submit {
|
||||
width: 100%;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.disclaimer {
|
||||
@include font-size(12);
|
||||
line-height: 1.6;
|
||||
display: block;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.is-offset {
|
||||
border-top: 1px solid $light_mode_border;
|
||||
display: block;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 15px 0;
|
||||
|
||||
&.small {
|
||||
padding: 0 0 10px;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
&.row-summary {
|
||||
border-top: 1px solid $light_mode_border;
|
||||
padding-bottom: 0;
|
||||
|
||||
b {
|
||||
font-weight: 800;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cell {
|
||||
b {
|
||||
display: block;
|
||||
@include font-size(18);
|
||||
}
|
||||
|
||||
small {
|
||||
color: $text-muted;
|
||||
@include font-size(12);
|
||||
}
|
||||
|
||||
span {
|
||||
@include font-size(14);
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.duplicator {
|
||||
|
||||
.wrapper-inline {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 970px) {
|
||||
.content-page {
|
||||
grid-template-columns: 1fr;
|
||||
margin-bottom: 30px;
|
||||
gap: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -4,7 +4,7 @@
|
||||
<!--Invoice-->
|
||||
<div v-show="isInvoice" class="menu-options" id="menu-list">
|
||||
<OptionGroup class="menu-option-group">
|
||||
<Option @click.native="" title="Edit Invoice" icon="rename" />
|
||||
<Option @click.native="editItem" title="Edit Invoice" icon="rename" />
|
||||
<Option @click.native="" title="Send Invoice" icon="send" />
|
||||
<Option @click.native="goToCompany" title="Go to Company" icon="user" />
|
||||
<Option @click.native="deleteItem" :title="$t('context_menu.delete')" icon="trash" />
|
||||
@@ -95,9 +95,12 @@ export default {
|
||||
// Show panel if is not open
|
||||
this.$store.dispatch('fileInfoToggle', true)
|
||||
},
|
||||
editItem() {
|
||||
this.$router.push({name: 'EditInvoice', params: {id: this.item.id}})
|
||||
},
|
||||
deleteItem() {
|
||||
events.$emit('confirm:open', {
|
||||
title: `Are you sure you want to delete invoice number ${this.item.invoiceNumber}?`,
|
||||
title: `Are you sure you want to delete invoice number ${this.item.invoice_number}?`,
|
||||
message: 'Your invoice will be permanently deleted.',
|
||||
buttonColor: 'danger-solid',
|
||||
action: {
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
<!--Invoice Controls-->
|
||||
<ToolbarGroup v-if="! $isMobile()">
|
||||
<ToolbarButton @click.native="shareInvoice" :class="{'is-inactive': canActiveInView }" source="send" :action="$t('actions.share')" />
|
||||
<ToolbarButton @click.native="shareInvoice" :class="{'is-inactive': canActiveInView }" source="rename" :action="$t('actions.share')" />
|
||||
<ToolbarButton @click.native="editInvoice" :class="{'is-inactive': canActiveInView }" source="rename" :action="$t('actions.share')" />
|
||||
<ToolbarButton @click.native="deleteInvoice" :class="{'is-inactive': canActiveInView }" source="trash" :action="$t('actions.delete')" />
|
||||
</ToolbarGroup>
|
||||
|
||||
@@ -131,7 +131,7 @@
|
||||
if (this.clipboard.length > 0) {
|
||||
|
||||
events.$emit('confirm:open', {
|
||||
title: `Are you sure you want to delete invoice number ${this.clipboard[0].invoiceNumber}?`,
|
||||
title: `Are you sure you want to delete invoice number ${this.clipboard[0].invoice_number}?`,
|
||||
message: 'Your invoice will be permanently deleted.',
|
||||
buttonColor: 'danger-solid',
|
||||
action: {
|
||||
@@ -144,6 +144,9 @@
|
||||
shareInvoice() {
|
||||
alert('Send Invoice')
|
||||
},
|
||||
editInvoice() {
|
||||
this.$router.push({name: 'EditInvoice', params: {id: this.clipboard[0].id}})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -60,8 +60,8 @@
|
||||
<div v-if="isSingleFile && !isEmpty" class="info-headline">
|
||||
<TitlePreview
|
||||
icon="file-text"
|
||||
:title="singleFile.clientName"
|
||||
:subtitle="'Invoice - ' + singleFile.invoiceNumber"
|
||||
:title="singleFile.client_name"
|
||||
:subtitle="'Invoice - ' + singleFile.invoice_number"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
|
||||
<ListInfoItem
|
||||
title="Invoice Number"
|
||||
:content="singleFile.invoiceNumber"
|
||||
:content="singleFile.invoice_number"
|
||||
/>
|
||||
|
||||
<ListInfoItem
|
||||
@@ -80,7 +80,7 @@
|
||||
|
||||
<ListInfoItem
|
||||
title="Client"
|
||||
:content="singleFile.clientName"
|
||||
:content="singleFile.client_name"
|
||||
/>
|
||||
|
||||
<!--Created At-->
|
||||
|
||||
@@ -15,12 +15,12 @@
|
||||
<div class="item-name">
|
||||
|
||||
<b :ref="item.id" class="name">
|
||||
{{ item.clientName }} - {{ item.total }}
|
||||
{{ item.client_name }} - {{ item.total }}
|
||||
</b>
|
||||
|
||||
<div class="item-info">
|
||||
<span class="item-size">
|
||||
{{ item.created_at }}, n. {{ item.invoiceNumber }}
|
||||
{{ item.created_at }}, n. {{ item.invoice_number }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
class="headline"
|
||||
icon="file-text"
|
||||
:title="clipboard[0].name"
|
||||
:subtitle="'Invoice - ' + clipboard[0].invoiceNumber"
|
||||
:subtitle="'Invoice - ' + clipboard[0].invoice_number"
|
||||
/>
|
||||
|
||||
<!--Trash location-->
|
||||
@@ -64,7 +64,7 @@ export default {
|
||||
},
|
||||
deleteInvoice() {
|
||||
events.$emit('confirm:open', {
|
||||
title: `Are you sure you want to delete invoice number ${this.clipboard[0].invoiceNumber}?`,
|
||||
title: `Are you sure you want to delete invoice number ${this.clipboard[0].invoice_number}?`,
|
||||
message: 'Your invoice will be permanently deleted.',
|
||||
buttonColor: 'danger-solid',
|
||||
action: {
|
||||
|
||||
9
resources/js/router.js
vendored
9
resources/js/router.js
vendored
@@ -121,6 +121,15 @@ const routesOasis = [
|
||||
requiresAuth: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'EditInvoice',
|
||||
path: '/invoice/edit-invoice/:id',
|
||||
component: () =>
|
||||
import(/* webpackChunkName: "chunks/oasis/invoices/edit-invoice" */ './Oasis/Invoices/Invoices/EditInvoice'),
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Client',
|
||||
path: '/invoice/client/:id',
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<template slot-scope="{ row }">
|
||||
<tr>
|
||||
<td>
|
||||
<a :href="'/invoice/' + row.data.attributes.customer + '/' + row.data.id" target="_blank" class="cell-item">
|
||||
<a :href="'/stripe-invoice/' + row.data.attributes.customer + '/' + row.data.id" target="_blank" class="cell-item">
|
||||
{{ row.data.attributes.order }}
|
||||
</a>
|
||||
</td>
|
||||
|
||||
@@ -28,14 +28,16 @@ Route::group(['middleware' => 'api', 'prefix' => '/api/oasis'], function () {
|
||||
Route::get('/advance', [InvoiceController::class, 'get_all_advance_invoices']);
|
||||
Route::get('/search', [InvoiceController::class, 'search']);
|
||||
|
||||
Route::post('/', [InvoiceController::class, 'store']);
|
||||
Route::delete('/{invoice}', [InvoiceController::class, 'destroy']);
|
||||
|
||||
Route::get('/profile', [InvoiceProfileController::class, 'show']);
|
||||
Route::post('/profile', [InvoiceProfileController::class, 'store']);
|
||||
Route::patch('/profile', [InvoiceProfileController::class, 'update']);
|
||||
|
||||
Route::get('/editor', [InvoiceController::class, 'editor']);
|
||||
|
||||
Route::get('/{invoice}', [InvoiceController::class, 'get_single_invoice']);
|
||||
Route::delete('/{invoice}', [InvoiceController::class, 'destroy']);
|
||||
Route::post('/{invoice}', [InvoiceController::class, 'update']);
|
||||
Route::post('/', [InvoiceController::class, 'store']);
|
||||
});
|
||||
|
||||
// Clients
|
||||
@@ -56,9 +58,9 @@ Route::group(['middleware' => 'api', 'prefix' => '/api/oasis'], function () {
|
||||
Route::group(['middleware' => 'web', 'prefix' => 'oasis'], function () {
|
||||
Route::post('/subscribe/{order}/set-password', [SubscriptionController::class, 'set_password']);
|
||||
|
||||
// Admin
|
||||
// Invoices
|
||||
Route::group(['middleware' => 'auth:sanctum'], function () {
|
||||
Route::get('/invoice/{invoice}', [InvoiceController::class, 'get_invoice']);
|
||||
Route::get('/invoice/{invoice}', [InvoiceController::class, 'download_invoice']);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ Route::post('/admin-setup', [SetupWizardController::class, 'create_admin_account
|
||||
Route::get('/translations/{lang}', [AppFunctionsController::class, 'get_translations']);
|
||||
|
||||
// Get user invoice from stripe service
|
||||
Route::get('/invoice/{customer}/{token}', [InvoiceController::class, 'show'])->middleware(['auth:sanctum']);
|
||||
Route::get('/stripe-invoice/{customer}/{token}', [InvoiceController::class, 'show'])->middleware(['auth:sanctum']);
|
||||
|
||||
// Get og site for web crawlers
|
||||
if (Crawler::isCrawler()) {
|
||||
|
||||
@@ -89,6 +89,9 @@ class OasisInvoiceTest extends TestCase
|
||||
public function it_test_invoice_total_net()
|
||||
{
|
||||
$invoice = [
|
||||
'user' => [
|
||||
'ic_dph' => 43123545233
|
||||
],
|
||||
'discount_type' => null,
|
||||
'currency' => 'CZK',
|
||||
'items' => [
|
||||
@@ -445,6 +448,48 @@ class OasisInvoiceTest extends TestCase
|
||||
Notification::assertTimesSent(1, InvoiceDeliveryNotification::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function user_update_existing_invoice()
|
||||
{
|
||||
PDF::fake();
|
||||
|
||||
$user = User::factory(User::class)
|
||||
->create(['role' => 'user']);
|
||||
|
||||
Sanctum::actingAs($user);
|
||||
|
||||
$profile = InvoiceProfile::factory(InvoiceProfile::class)
|
||||
->create(['user_id' => $user->id]);
|
||||
|
||||
$invoice = Invoice::factory(Invoice::class)
|
||||
->create([
|
||||
'user_id' => $user->id,
|
||||
'invoice_type' => 'regular-invoice',
|
||||
'user' => $profile->toArray(),
|
||||
]);
|
||||
|
||||
$this->postJson("/api/oasis/invoices/$invoice->id", [
|
||||
'invoice_number' => '2120001',
|
||||
'variable_number' => '2120001',
|
||||
'items' => json_encode($this->items),
|
||||
'discount_type' => 'value',
|
||||
'discount_rate' => 10,
|
||||
'delivery_at' => Carbon::now()->addWeek(),
|
||||
])->assertStatus(204);
|
||||
|
||||
$this->assertDatabaseHas('invoices', [
|
||||
'invoice_number' => '2120001',
|
||||
'discount_type' => 'value',
|
||||
'items' => json_encode($this->items),
|
||||
'discount_rate' => 10,
|
||||
'total_net' => 2030,
|
||||
]);
|
||||
|
||||
PDF::assertFileNameIs(storage_path("app/" . invoice_path(Invoice::first())));
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
@@ -495,7 +540,7 @@ class OasisInvoiceTest extends TestCase
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function it_get_invoice_from_url()
|
||||
public function it_download_invoice_from_url()
|
||||
{
|
||||
$user = User::factory(User::class)
|
||||
->create(['role' => 'user']);
|
||||
@@ -530,6 +575,32 @@ class OasisInvoiceTest extends TestCase
|
||||
->assertStatus(200);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function it_get_single_invoice()
|
||||
{
|
||||
$user = User::factory(User::class)
|
||||
->create(['role' => 'user']);
|
||||
|
||||
$profile = InvoiceProfile::factory(InvoiceProfile::class)
|
||||
->create(['user_id' => $user->id]);
|
||||
|
||||
Sanctum::actingAs($user);
|
||||
|
||||
$invoice = Invoice::factory(Invoice::class)
|
||||
->create([
|
||||
'user_id' => $user->id,
|
||||
'invoice_type' => 'regular-invoice',
|
||||
'user' => $profile->toArray(),
|
||||
]);
|
||||
|
||||
$this->getJson("/api/oasis/invoices/$invoice->id")
|
||||
->assertJsonFragment([
|
||||
'id' => $invoice->id,
|
||||
])->assertStatus(200);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
@@ -547,7 +618,7 @@ class OasisInvoiceTest extends TestCase
|
||||
->create([
|
||||
'user_id' => $user->id,
|
||||
'invoice_type' => 'regular-invoice',
|
||||
'user' => $profile,
|
||||
'user' => $profile->toArray(),
|
||||
]);
|
||||
|
||||
$this->getJson('/api/oasis/invoices/regular')
|
||||
@@ -573,7 +644,7 @@ class OasisInvoiceTest extends TestCase
|
||||
->create([
|
||||
'user_id' => $user->id,
|
||||
'invoice_type' => 'advance-invoice',
|
||||
'user' => $profile,
|
||||
'user' => $profile->toArray(),
|
||||
]);
|
||||
|
||||
$this->getJson('/api/oasis/invoices/advance')
|
||||
@@ -603,17 +674,17 @@ class OasisInvoiceTest extends TestCase
|
||||
'client' => [
|
||||
'name' => 'VueFileManager Inc.',
|
||||
],
|
||||
'user' => $profile,
|
||||
'user' => $profile->toArray(),
|
||||
]);
|
||||
|
||||
$this->getJson('/api/oasis/invoices/search?type=regular-invoice&query=2001212')
|
||||
->assertJsonFragment([
|
||||
'invoiceNumber' => '2001212',
|
||||
'invoice_number' => '2001212',
|
||||
])->assertStatus(200);
|
||||
|
||||
$this->getJson('/api/oasis/invoices/search?type=regular-invoice&query=Vue')
|
||||
->assertJsonFragment([
|
||||
'invoiceNumber' => '2001212',
|
||||
'invoice_number' => '2001212',
|
||||
])->assertStatus(200);
|
||||
}
|
||||
|
||||
@@ -687,7 +758,9 @@ class OasisInvoiceTest extends TestCase
|
||||
'client' => [
|
||||
'name' => 'VueFileManager Inc.',
|
||||
],
|
||||
'user' => 'test',
|
||||
'user' => [
|
||||
'ic_dph' => 423143124213
|
||||
],
|
||||
]);
|
||||
|
||||
$this->getJson('/api/oasis/invoices/editor')
|
||||
|
||||
Reference in New Issue
Block a user