Edit invoice

This commit is contained in:
Peter Papp
2021-05-05 17:07:36 +02:00
parent bdfd92872e
commit 599b238ab4
22 changed files with 976 additions and 162 deletions

View File

@@ -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

View File

@@ -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',

View File

@@ -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'),
],
],
];

View File

@@ -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'),

View File

@@ -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);
}

View File

@@ -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));
});

View File

@@ -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',

View File

@@ -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', [

View File

@@ -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"
}

View File

@@ -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>

View File

@@ -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)

View 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>

View File

@@ -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: {

View File

@@ -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>

View File

@@ -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-->

View File

@@ -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>

View File

@@ -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: {

View File

@@ -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',

View File

@@ -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>

View File

@@ -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']);
});
});

View File

@@ -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()) {

View File

@@ -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')