diff --git a/app/BulkActions/Purchases/Bills.php b/app/BulkActions/Purchases/Bills.php
index 8d65a3277..c48e94d74 100644
--- a/app/BulkActions/Purchases/Bills.php
+++ b/app/BulkActions/Purchases/Bills.php
@@ -5,7 +5,7 @@ namespace App\BulkActions\Purchases;
use App\Abstracts\BulkAction;
use App\Events\Document\DocumentCancelled;
use App\Events\Document\DocumentReceived;
-use App\Exports\Purchases\Bills as Export;
+use App\Exports\Purchases\Bills\Bills as Export;
use App\Jobs\Banking\CreateBankingDocumentTransaction;
use App\Jobs\Document\CreateDocumentHistory;
use App\Jobs\Document\DeleteDocument;
diff --git a/app/BulkActions/Sales/Invoices.php b/app/BulkActions/Sales/Invoices.php
index 07e78051b..a079531d5 100644
--- a/app/BulkActions/Sales/Invoices.php
+++ b/app/BulkActions/Sales/Invoices.php
@@ -7,7 +7,7 @@ use App\Events\Document\DocumentCancelled;
use App\Events\Document\DocumentCreated;
use App\Events\Document\DocumentMarkedSent;
use App\Events\Document\PaymentReceived;
-use App\Exports\Sales\Invoices as Export;
+use App\Exports\Sales\Invoices\Invoices as Export;
use App\Jobs\Document\DeleteDocument;
use App\Models\Document\Document;
diff --git a/app/Exports/Banking/RecurringTransactions.php b/app/Exports/Banking/RecurringTransactions.php
new file mode 100644
index 000000000..87d51745c
--- /dev/null
+++ b/app/Exports/Banking/RecurringTransactions.php
@@ -0,0 +1,28 @@
+ids = $ids;
+ }
+
+ public function sheets(): array
+ {
+ return [
+ new Recurring($this->ids),
+ new Base($this->ids),
+ ];
+ }
+}
diff --git a/app/Exports/Banking/Sheets/Recurring.php b/app/Exports/Banking/Sheets/Recurring.php
new file mode 100644
index 000000000..286a19359
--- /dev/null
+++ b/app/Exports/Banking/Sheets/Recurring.php
@@ -0,0 +1,36 @@
+cursor();
+ }
+
+ public function map($model): array
+ {
+ $model->transaction_number = $model->recurable->number;
+
+ return parent::map($model);
+ }
+
+ public function fields(): array
+ {
+ return [
+ 'recurable_type',
+ 'transaction_number',
+ 'frequency',
+ 'interval',
+ 'started_at',
+ 'status',
+ 'limit_by',
+ 'limit_count',
+ 'auto_send',
+ ];
+ }
+}
diff --git a/app/Exports/Banking/Sheets/RecurringTransactions.php b/app/Exports/Banking/Sheets/RecurringTransactions.php
new file mode 100644
index 000000000..5e4b44ca5
--- /dev/null
+++ b/app/Exports/Banking/Sheets/RecurringTransactions.php
@@ -0,0 +1,53 @@
+isRecurring()->cursor();
+ }
+
+ public function map($model): array
+ {
+ $model->account_name = $model->account->name;
+ $model->contact_email = $model->contact->email;
+ $model->category_name = $model->category->name;
+ $model->invoice_bill_number = $model->document->document_number ?? 0;
+
+ return parent::map($model);
+ }
+
+ public function fields(): array
+ {
+ return [
+ 'type',
+ 'number',
+ 'paid_at',
+ 'amount',
+ 'currency_code',
+ 'currency_rate',
+ 'account_name',
+ 'invoice_bill_number',
+ 'contact_email',
+ 'category_name',
+ 'description',
+ 'payment_method',
+ 'reference',
+ 'reconciled',
+ ];
+ }
+
+ public function columnFormats(): array
+ {
+ return [
+ 'C' => NumberFormat::FORMAT_DATE_YYYYMMDD,
+ ];
+ }
+}
diff --git a/app/Exports/Purchases/Bills.php b/app/Exports/Purchases/Bills/Bills.php
similarity index 62%
rename from app/Exports/Purchases/Bills.php
rename to app/Exports/Purchases/Bills/Bills.php
index 3a5a9115b..dd4213e52 100644
--- a/app/Exports/Purchases/Bills.php
+++ b/app/Exports/Purchases/Bills/Bills.php
@@ -1,13 +1,13 @@
ids = $ids;
+ }
+
+ public function sheets(): array
+ {
+ return [
+ new Recurring($this->ids),
+ new Base($this->ids),
+ new RecurringBillItems($this->ids),
+ new RecurringBillItemTaxes($this->ids),
+ new RecurringBillHistories($this->ids),
+ new RecurringBillTotals($this->ids),
+ ];
+ }
+}
diff --git a/app/Exports/Purchases/RecurringBills/Sheets/Recurring.php b/app/Exports/Purchases/RecurringBills/Sheets/Recurring.php
new file mode 100644
index 000000000..20ef7354c
--- /dev/null
+++ b/app/Exports/Purchases/RecurringBills/Sheets/Recurring.php
@@ -0,0 +1,36 @@
+cursor();
+ }
+
+ public function map($model): array
+ {
+ $model->bill_number = $model->recurable->document_number;
+
+ return parent::map($model);
+ }
+
+ public function fields(): array
+ {
+ return [
+ 'recurable_type',
+ 'bill_number',
+ 'frequency',
+ 'interval',
+ 'started_at',
+ 'status',
+ 'limit_by',
+ 'limit_count',
+ 'auto_send',
+ ];
+ }
+}
diff --git a/app/Exports/Purchases/RecurringBills/Sheets/RecurringBillHistories.php b/app/Exports/Purchases/RecurringBills/Sheets/RecurringBillHistories.php
new file mode 100644
index 000000000..41af4ea76
--- /dev/null
+++ b/app/Exports/Purchases/RecurringBills/Sheets/RecurringBillHistories.php
@@ -0,0 +1,37 @@
+billRecurring()->collectForExport($this->ids, null, 'document_id');
+ }
+
+ public function map($model): array
+ {
+ $document = $model->document;
+
+ if (empty($document)) {
+ return [];
+ }
+
+ $model->bill_number = $document->document_number;
+
+ return parent::map($model);
+ }
+
+ public function fields(): array
+ {
+ return [
+ 'bill_number',
+ 'status',
+ 'notify',
+ 'description',
+ ];
+ }
+}
diff --git a/app/Exports/Purchases/RecurringBills/Sheets/RecurringBillItemTaxes.php b/app/Exports/Purchases/RecurringBills/Sheets/RecurringBillItemTaxes.php
new file mode 100644
index 000000000..1249a8160
--- /dev/null
+++ b/app/Exports/Purchases/RecurringBills/Sheets/RecurringBillItemTaxes.php
@@ -0,0 +1,39 @@
+billRecurring()->collectForExport($this->ids, null, 'document_id');
+ }
+
+ public function map($model): array
+ {
+ $document = $model->document;
+
+ if (empty($document)) {
+ return [];
+ }
+
+ $model->bill_number = $document->document_number;
+ $model->item_name = $model->item->name;
+ $model->tax_rate = $model->tax->rate;
+
+ return parent::map($model);
+ }
+
+ public function fields(): array
+ {
+ return [
+ 'bill_number',
+ 'item_name',
+ 'tax_rate',
+ 'amount',
+ ];
+ }
+}
diff --git a/app/Exports/Purchases/RecurringBills/Sheets/RecurringBillItems.php b/app/Exports/Purchases/RecurringBills/Sheets/RecurringBillItems.php
new file mode 100644
index 000000000..1e7eb345e
--- /dev/null
+++ b/app/Exports/Purchases/RecurringBills/Sheets/RecurringBillItems.php
@@ -0,0 +1,44 @@
+billRecurring()->collectForExport($this->ids, null, 'document_id');
+ }
+
+ public function map($model): array
+ {
+ $document = $model->document;
+
+ if (empty($document)) {
+ return [];
+ }
+
+ $model->bill_number = $document->document_number;
+ $model->item_name = $model->item->name;
+ $model->item_description = $model->item->description;
+ $model->item_type = $model->item->type;
+
+ return parent::map($model);
+ }
+
+ public function fields(): array
+ {
+ return [
+ 'bill_number',
+ 'item_name',
+ 'item_description',
+ 'item_type',
+ 'quantity',
+ 'price',
+ 'total',
+ 'tax',
+ ];
+ }
+}
diff --git a/app/Exports/Purchases/RecurringBills/Sheets/RecurringBillTotals.php b/app/Exports/Purchases/RecurringBills/Sheets/RecurringBillTotals.php
new file mode 100644
index 000000000..fdaadafc6
--- /dev/null
+++ b/app/Exports/Purchases/RecurringBills/Sheets/RecurringBillTotals.php
@@ -0,0 +1,38 @@
+billRecurring()->collectForExport($this->ids, null, 'document_id');
+ }
+
+ public function map($model): array
+ {
+ $document = $model->document;
+
+ if (empty($document)) {
+ return [];
+ }
+
+ $model->bill_number = $document->document_number;
+
+ return parent::map($model);
+ }
+
+ public function fields(): array
+ {
+ return [
+ 'bill_number',
+ 'code',
+ 'name',
+ 'amount',
+ 'sort_order',
+ ];
+ }
+}
diff --git a/app/Exports/Purchases/RecurringBills/Sheets/RecurringBills.php b/app/Exports/Purchases/RecurringBills/Sheets/RecurringBills.php
new file mode 100644
index 000000000..beda1e22c
--- /dev/null
+++ b/app/Exports/Purchases/RecurringBills/Sheets/RecurringBills.php
@@ -0,0 +1,65 @@
+billRecurring()->collectForExport($this->ids, ['document_number' => 'desc']);
+ }
+
+ public function map($model): array
+ {
+ $country = null;
+
+ if ($model->contact_country && array_key_exists($model->contact_country, trans('countries'))) {
+ $country = trans('countries.' . $model->contact_country);
+ }
+
+ $model->category_name = $model->category->name;
+ $model->bill_number = $model->document_number;
+ $model->billed_at = $model->issued_at;
+ $model->contact_country = $country;
+
+ return parent::map($model);
+ }
+
+ public function fields(): array
+ {
+ return [
+ 'bill_number',
+ 'order_number',
+ 'status',
+ 'billed_at',
+ 'due_at',
+ 'amount',
+ 'currency_code',
+ 'currency_rate',
+ 'category_name',
+ 'contact_name',
+ 'contact_email',
+ 'contact_tax_number',
+ 'contact_phone',
+ 'contact_address',
+ 'contact_country',
+ 'contact_state',
+ 'contact_zip_code',
+ 'contact_city',
+ 'notes',
+ ];
+ }
+
+ public function columnFormats(): array
+ {
+ return [
+ 'D' => NumberFormat::FORMAT_DATE_YYYYMMDD,
+ 'E' => NumberFormat::FORMAT_DATE_YYYYMMDD,
+ ];
+ }
+}
diff --git a/app/Exports/Sales/Invoices.php b/app/Exports/Sales/Invoices/Invoices.php
similarity index 62%
rename from app/Exports/Sales/Invoices.php
rename to app/Exports/Sales/Invoices/Invoices.php
index 3c2148d96..d24ba473e 100644
--- a/app/Exports/Sales/Invoices.php
+++ b/app/Exports/Sales/Invoices/Invoices.php
@@ -1,13 +1,13 @@
ids = $ids;
+ }
+
+ public function sheets(): array
+ {
+ return [
+ new Recurring($this->ids),
+ new Base($this->ids),
+ new RecurringInvoiceItems($this->ids),
+ new RecurringInvoiceItemTaxes($this->ids),
+ new RecurringInvoiceHistories($this->ids),
+ new RecurringInvoiceTotals($this->ids),
+ ];
+ }
+}
diff --git a/app/Exports/Sales/RecurringInvoices/Sheets/Recurring.php b/app/Exports/Sales/RecurringInvoices/Sheets/Recurring.php
new file mode 100644
index 000000000..08048a4fa
--- /dev/null
+++ b/app/Exports/Sales/RecurringInvoices/Sheets/Recurring.php
@@ -0,0 +1,36 @@
+cursor();
+ }
+
+ public function map($model): array
+ {
+ $model->invoice_number = $model->recurable->document_number;
+
+ return parent::map($model);
+ }
+
+ public function fields(): array
+ {
+ return [
+ 'recurable_type',
+ 'invoice_number',
+ 'frequency',
+ 'interval',
+ 'started_at',
+ 'status',
+ 'limit_by',
+ 'limit_count',
+ 'auto_send',
+ ];
+ }
+}
diff --git a/app/Exports/Sales/RecurringInvoices/Sheets/RecurringInvoiceHistories.php b/app/Exports/Sales/RecurringInvoices/Sheets/RecurringInvoiceHistories.php
new file mode 100644
index 000000000..df0dd0727
--- /dev/null
+++ b/app/Exports/Sales/RecurringInvoices/Sheets/RecurringInvoiceHistories.php
@@ -0,0 +1,37 @@
+invoiceRecurring()->collectForExport($this->ids, null, 'document_id');
+ }
+
+ public function map($model): array
+ {
+ $document = $model->document;
+
+ if (empty($document)) {
+ return [];
+ }
+
+ $model->invoice_number = $document->document_number;
+
+ return parent::map($model);
+ }
+
+ public function fields(): array
+ {
+ return [
+ 'invoice_number',
+ 'status',
+ 'notify',
+ 'description',
+ ];
+ }
+}
diff --git a/app/Exports/Sales/RecurringInvoices/Sheets/RecurringInvoiceItemTaxes.php b/app/Exports/Sales/RecurringInvoices/Sheets/RecurringInvoiceItemTaxes.php
new file mode 100644
index 000000000..fcf783945
--- /dev/null
+++ b/app/Exports/Sales/RecurringInvoices/Sheets/RecurringInvoiceItemTaxes.php
@@ -0,0 +1,39 @@
+invoiceRecurring()->collectForExport($this->ids, null, 'document_id');
+ }
+
+ public function map($model): array
+ {
+ $document = $model->document;
+
+ if (empty($document)) {
+ return [];
+ }
+
+ $model->invoice_number = $document->document_number;
+ $model->item_name = $model->item->name;
+ $model->tax_rate = $model->tax->rate;
+
+ return parent::map($model);
+ }
+
+ public function fields(): array
+ {
+ return [
+ 'invoice_number',
+ 'item_name',
+ 'tax_rate',
+ 'amount',
+ ];
+ }
+}
diff --git a/app/Exports/Sales/RecurringInvoices/Sheets/RecurringInvoiceItems.php b/app/Exports/Sales/RecurringInvoices/Sheets/RecurringInvoiceItems.php
new file mode 100644
index 000000000..fabc31c80
--- /dev/null
+++ b/app/Exports/Sales/RecurringInvoices/Sheets/RecurringInvoiceItems.php
@@ -0,0 +1,44 @@
+invoiceRecurring()->collectForExport($this->ids, null, 'document_id');
+ }
+
+ public function map($model): array
+ {
+ $document = $model->document;
+
+ if (empty($document)) {
+ return [];
+ }
+
+ $model->invoice_number = $document->document_number;
+ $model->item_name = $model->item->name;
+ $model->item_description = $model->item->description;
+ $model->item_type = $model->item->type;
+
+ return parent::map($model);
+ }
+
+ public function fields(): array
+ {
+ return [
+ 'invoice_number',
+ 'item_name',
+ 'item_description',
+ 'item_type',
+ 'quantity',
+ 'price',
+ 'total',
+ 'tax',
+ ];
+ }
+}
diff --git a/app/Exports/Sales/RecurringInvoices/Sheets/RecurringInvoiceTotals.php b/app/Exports/Sales/RecurringInvoices/Sheets/RecurringInvoiceTotals.php
new file mode 100644
index 000000000..8d7b7af4f
--- /dev/null
+++ b/app/Exports/Sales/RecurringInvoices/Sheets/RecurringInvoiceTotals.php
@@ -0,0 +1,38 @@
+invoiceRecurring()->collectForExport($this->ids, null, 'document_id');
+ }
+
+ public function map($model): array
+ {
+ $document = $model->document;
+
+ if (empty($document)) {
+ return [];
+ }
+
+ $model->invoice_number = $document->document_number;
+
+ return parent::map($model);
+ }
+
+ public function fields(): array
+ {
+ return [
+ 'invoice_number',
+ 'code',
+ 'name',
+ 'amount',
+ 'sort_order',
+ ];
+ }
+}
diff --git a/app/Exports/Sales/RecurringInvoices/Sheets/RecurringInvoices.php b/app/Exports/Sales/RecurringInvoices/Sheets/RecurringInvoices.php
new file mode 100644
index 000000000..923ee94e3
--- /dev/null
+++ b/app/Exports/Sales/RecurringInvoices/Sheets/RecurringInvoices.php
@@ -0,0 +1,67 @@
+invoiceRecurring()->collectForExport($this->ids, ['document_number' => 'desc']);
+ }
+
+ public function map($model): array
+ {
+ $country = null;
+
+ if ($model->contact_country && array_key_exists($model->contact_country, trans('countries'))) {
+ $country = trans('countries.' . $model->contact_country);
+ }
+
+ $model->category_name = $model->category->name;
+ $model->invoice_number = $model->document_number;
+ $model->invoiced_at = $model->issued_at;
+ $model->contact_country = $country;
+
+
+ return parent::map($model);
+ }
+
+ public function fields(): array
+ {
+ return [
+ 'invoice_number',
+ 'order_number',
+ 'status',
+ 'invoiced_at',
+ 'due_at',
+ 'amount',
+ 'currency_code',
+ 'currency_rate',
+ 'category_name',
+ 'contact_name',
+ 'contact_email',
+ 'contact_tax_number',
+ 'contact_phone',
+ 'contact_address',
+ 'contact_country',
+ 'contact_state',
+ 'contact_zip_code',
+ 'contact_city',
+ 'notes',
+ 'footer',
+ ];
+ }
+
+ public function columnFormats(): array
+ {
+ return [
+ 'D' => NumberFormat::FORMAT_DATE_YYYYMMDD,
+ 'E' => NumberFormat::FORMAT_DATE_YYYYMMDD,
+ ];
+ }
+}
diff --git a/app/Http/Controllers/Banking/RecurringTransactions.php b/app/Http/Controllers/Banking/RecurringTransactions.php
index 2f15bc89c..21ee0314c 100644
--- a/app/Http/Controllers/Banking/RecurringTransactions.php
+++ b/app/Http/Controllers/Banking/RecurringTransactions.php
@@ -3,7 +3,10 @@
namespace App\Http\Controllers\Banking;
use App\Abstracts\Http\Controller;
+use App\Exports\Banking\RecurringTransactions as Export;
use App\Http\Requests\Banking\Transaction as Request;
+use App\Http\Requests\Common\Import as ImportRequest;
+use App\Imports\Banking\RecurringTransactions as Import;
use App\Jobs\Banking\CreateTransaction;
use App\Jobs\Banking\UpdateTransaction;
use App\Models\Banking\Account;
@@ -97,7 +100,7 @@ class RecurringTransactions extends Controller
if ($response['success']) {
$response['redirect'] = route('recurring-transactions.show', $response['data']->id);
- $message = trans('messages.success.added', ['type' => trans_choice('general.transactions', 1)]);
+ $message = trans('messages.success.added', ['type' => trans_choice('general.recurring_transactions', 1)]);
flash($message)->success();
} else {
@@ -122,13 +125,37 @@ class RecurringTransactions extends Controller
{
$clone = $recurring_transaction->duplicate();
- $message = trans('messages.success.duplicated', ['type' => trans_choice('general.transactions', 1)]);
+ $message = trans('messages.success.duplicated', ['type' => trans_choice('general.recurring_transactions', 1)]);
flash($message)->success();
return redirect()->route('recurring-transactions.edit', $clone->id);
}
+ /**
+ * Import the specified resource.
+ *
+ * @param ImportRequest $request
+ *
+ * @return Response
+ */
+ public function import(ImportRequest $request)
+ {
+ $response = $this->importExcel(new Import, $request, trans_choice('general.recurring_transactions', 2));
+
+ if ($response['success']) {
+ $response['redirect'] = route('recurring-transactions.index');
+
+ flash($response['message'])->success();
+ } else {
+ $response['redirect'] = route('import.create', ['banking', 'recurring-transactions']);
+
+ flash($response['message'])->error()->important();
+ }
+
+ return response()->json($response);
+ }
+
/**
* Show the form for editing the specified resource.
*
@@ -174,7 +201,7 @@ class RecurringTransactions extends Controller
if ($response['success']) {
$response['redirect'] = route('recurring-transactions.show', $recurring_transaction->id);
- $message = trans('messages.success.updated', ['type' => trans_choice('general.transactions', 1)]);
+ $message = trans('messages.success.updated', ['type' => trans_choice('general.recurring_transactions', 1)]);
flash($message)->success();
} else {
@@ -187,6 +214,16 @@ class RecurringTransactions extends Controller
return response()->json($response);
}
+
+ /**
+ * Export the specified resource.
+ *
+ * @return Response
+ */
+ public function export()
+ {
+ return $this->exportExcel(new Export, trans_choice('general.recurring_transactions', 2));
+ }
/**
* End recurring template.
diff --git a/app/Http/Controllers/Purchases/Bills.php b/app/Http/Controllers/Purchases/Bills.php
index 5465fd625..69b615cfc 100644
--- a/app/Http/Controllers/Purchases/Bills.php
+++ b/app/Http/Controllers/Purchases/Bills.php
@@ -3,10 +3,10 @@
namespace App\Http\Controllers\Purchases;
use App\Abstracts\Http\Controller;
-use App\Exports\Purchases\Bills as Export;
+use App\Exports\Purchases\Bills\Bills as Export;
use App\Http\Requests\Common\Import as ImportRequest;
use App\Http\Requests\Document\Document as Request;
-use App\Imports\Purchases\Bills as Import;
+use App\Imports\Purchases\Bills\Bills as Import;
use App\Jobs\Document\CreateDocument;
use App\Jobs\Document\DeleteDocument;
use App\Jobs\Document\DuplicateDocument;
diff --git a/app/Http/Controllers/Purchases/RecurringBills.php b/app/Http/Controllers/Purchases/RecurringBills.php
index 4fb9f874f..ffa34b579 100644
--- a/app/Http/Controllers/Purchases/RecurringBills.php
+++ b/app/Http/Controllers/Purchases/RecurringBills.php
@@ -3,7 +3,10 @@
namespace App\Http\Controllers\Purchases;
use App\Abstracts\Http\Controller;
+use App\Exports\Purchases\RecurringBills\RecurringBills as Export;
+use App\Http\Requests\Common\Import as ImportRequest;
use App\Http\Requests\Document\Document as Request;
+use App\Imports\Purchases\RecurringBills\RecurringBills as Import;
use App\Jobs\Document\CreateDocument;
use App\Jobs\Document\DuplicateDocument;
use App\Jobs\Document\UpdateDocument;
@@ -114,6 +117,30 @@ class RecurringBills extends Controller
return redirect()->route('recurring-bills.edit', $clone->id);
}
+ /**
+ * Import the specified resource.
+ *
+ * @param ImportRequest $request
+ *
+ * @return Response
+ */
+ public function import(ImportRequest $request)
+ {
+ $response = $this->importExcel(new Import, $request, trans_choice('general.recurring_bills', 2));
+
+ if ($response['success']) {
+ $response['redirect'] = route('recurring-bills.index');
+
+ flash($response['message'])->success();
+ } else {
+ $response['redirect'] = route('import.create', ['purchases', 'recurring-bills']);
+
+ flash($response['message'])->error()->important();
+ }
+
+ return response()->json($response);
+ }
+
/**
* Show the form for editing the specified resource.
*
@@ -155,6 +182,16 @@ class RecurringBills extends Controller
return response()->json($response);
}
+ /**
+ * Export the specified resource.
+ *
+ * @return Response
+ */
+ public function export()
+ {
+ return $this->exportExcel(new Export, trans_choice('general.recurring_bills', 2));
+ }
+
/**
* End recurring template.
*
diff --git a/app/Http/Controllers/Sales/Invoices.php b/app/Http/Controllers/Sales/Invoices.php
index 3730c5d18..4dc622d51 100644
--- a/app/Http/Controllers/Sales/Invoices.php
+++ b/app/Http/Controllers/Sales/Invoices.php
@@ -3,10 +3,10 @@
namespace App\Http\Controllers\Sales;
use App\Abstracts\Http\Controller;
-use App\Exports\Sales\Invoices as Export;
+use App\Exports\Sales\Invoices\Invoices as Export;
use App\Http\Requests\Common\Import as ImportRequest;
use App\Http\Requests\Document\Document as Request;
-use App\Imports\Sales\Invoices as Import;
+use App\Imports\Sales\Invoices\Invoices as Import;
use App\Jobs\Document\CreateDocument;
use App\Jobs\Document\DeleteDocument;
use App\Jobs\Document\DuplicateDocument;
diff --git a/app/Http/Controllers/Sales/RecurringInvoices.php b/app/Http/Controllers/Sales/RecurringInvoices.php
index 265e036f6..e1a0bec87 100644
--- a/app/Http/Controllers/Sales/RecurringInvoices.php
+++ b/app/Http/Controllers/Sales/RecurringInvoices.php
@@ -3,7 +3,10 @@
namespace App\Http\Controllers\Sales;
use App\Abstracts\Http\Controller;
+use App\Exports\Sales\RecurringInvoices\RecurringInvoices as Export;
+use App\Http\Requests\Common\Import as ImportRequest;
use App\Http\Requests\Document\Document as Request;
+use App\Imports\Sales\RecurringInvoices\RecurringInvoices as Import;
use App\Jobs\Document\CreateDocument;
use App\Jobs\Document\DuplicateDocument;
use App\Jobs\Document\UpdateDocument;
@@ -114,6 +117,30 @@ class RecurringInvoices extends Controller
return redirect()->route('recurring-invoices.edit', $clone->id);
}
+ /**
+ * Import the specified resource.
+ *
+ * @param ImportRequest $request
+ *
+ * @return Response
+ */
+ public function import(ImportRequest $request)
+ {
+ $response = $this->importExcel(new Import, $request, trans_choice('general.recurring_invoices', 2));
+
+ if ($response['success']) {
+ $response['redirect'] = route('recurring-invoices.index');
+
+ flash($response['message'])->success();
+ } else {
+ $response['redirect'] = route('import.create', ['sales', 'recurring-invoices']);
+
+ flash($response['message'])->error()->important();
+ }
+
+ return response()->json($response);
+ }
+
/**
* Show the form for editing the specified resource.
*
@@ -155,6 +182,16 @@ class RecurringInvoices extends Controller
return response()->json($response);
}
+ /**
+ * Export the specified resource.
+ *
+ * @return Response
+ */
+ public function export()
+ {
+ return $this->exportExcel(new Export, trans_choice('general.recurring_invoices', 2));
+ }
+
/**
* End recurring template.
*
diff --git a/app/Imports/Banking/RecurringTransactions.php b/app/Imports/Banking/RecurringTransactions.php
new file mode 100644
index 000000000..22670959f
--- /dev/null
+++ b/app/Imports/Banking/RecurringTransactions.php
@@ -0,0 +1,18 @@
+ new Base(),
+ 'recurring' => new Recurring(),
+ ];
+ }
+}
diff --git a/app/Imports/Banking/Sheets/Recurring.php b/app/Imports/Banking/Sheets/Recurring.php
new file mode 100644
index 000000000..3d9ac9577
--- /dev/null
+++ b/app/Imports/Banking/Sheets/Recurring.php
@@ -0,0 +1,24 @@
+number($row['transaction_number'])->pluck('id')->first();
+
+ return $row;
+ }
+}
diff --git a/app/Imports/Banking/Sheets/RecurringTransactions.php b/app/Imports/Banking/Sheets/RecurringTransactions.php
new file mode 100644
index 000000000..bdec04a77
--- /dev/null
+++ b/app/Imports/Banking/Sheets/RecurringTransactions.php
@@ -0,0 +1,38 @@
+getCurrencyCode($row);
+ $row['account_id'] = $this->getAccountId($row);
+ $row['category_id'] = $this->getCategoryId($row, $transaction_type);
+ $row['contact_id'] = $this->getContactId($row, $transaction_type);
+
+ if ($transaction_type == 'income') {
+ $row['document_id'] = Document::invoiceRecurring()->number($row['invoice_bill_number'])->pluck('id')->first();
+ } else {
+ $row['document_id'] = Document::billRecurring()->number($row['invoice_bill_number'])->pluck('id')->first();
+ }
+
+ return $row;
+ }
+}
diff --git a/app/Imports/Purchases/Bills.php b/app/Imports/Purchases/Bills/Bills.php
similarity index 56%
rename from app/Imports/Purchases/Bills.php
rename to app/Imports/Purchases/Bills/Bills.php
index 18b383af2..541d98899 100644
--- a/app/Imports/Purchases/Bills.php
+++ b/app/Imports/Purchases/Bills/Bills.php
@@ -1,14 +1,14 @@
new Base(),
+ 'recurring_bill_items' => new RecurringBillItems(),
+ 'recurring_bill_item_taxes' => new RecurringBillItemTaxes(),
+ 'recurring_bill_histories' => new RecurringBillHistories(),
+ 'recurring_bill_totals' => new RecurringBillTotals(),
+ 'recurring' => new Recurring(),
+ ];
+ }
+}
diff --git a/app/Imports/Purchases/RecurringBills/Sheets/Recurring.php b/app/Imports/Purchases/RecurringBills/Sheets/Recurring.php
new file mode 100644
index 000000000..da034faa0
--- /dev/null
+++ b/app/Imports/Purchases/RecurringBills/Sheets/Recurring.php
@@ -0,0 +1,27 @@
+number($row['bill_number'])
+ ->pluck('id')
+ ->first();
+
+ return $row;
+ }
+}
diff --git a/app/Imports/Purchases/RecurringBills/Sheets/RecurringBillHistories.php b/app/Imports/Purchases/RecurringBills/Sheets/RecurringBillHistories.php
new file mode 100644
index 000000000..fafa4a14a
--- /dev/null
+++ b/app/Imports/Purchases/RecurringBills/Sheets/RecurringBillHistories.php
@@ -0,0 +1,49 @@
+isEmpty($row, 'bill_number')) {
+ return [];
+ }
+
+ $row['bill_number'] = (string) $row['bill_number'];
+
+ $row = parent::map($row);
+
+ $row['document_id'] = (int) Document::where('type', '=', Document::BILL_RECURRING_TYPE)
+ ->number($row['bill_number'])
+ ->pluck('id')
+ ->first();
+
+ $row['notify'] = (int) $row['notify'];
+
+ $row['type'] = Document::BILL_RECURRING_TYPE;
+
+ return $row;
+ }
+
+ public function prepareRules(array $rules): array
+ {
+ $rules['bill_number'] = 'required|string';
+
+ unset($rules['bill_id']);
+
+ return $rules;
+ }
+}
diff --git a/app/Imports/Purchases/RecurringBills/Sheets/RecurringBillItemTaxes.php b/app/Imports/Purchases/RecurringBills/Sheets/RecurringBillItemTaxes.php
new file mode 100644
index 000000000..daf80a71c
--- /dev/null
+++ b/app/Imports/Purchases/RecurringBills/Sheets/RecurringBillItemTaxes.php
@@ -0,0 +1,66 @@
+isEmpty($row, 'bill_number')) {
+ return [];
+ }
+
+ $row['bill_number'] = (string) $row['bill_number'];
+
+ $row = parent::map($row);
+
+ $row['document_id'] = (int) Document::where('type', '=', Document::BILL_RECURRING_TYPE)
+ ->number($row['bill_number'])
+ ->pluck('id')
+ ->first();
+
+ if (empty($row['document_item_id']) && !empty($row['item_name'])) {
+ $item_id = Item::name($row['item_name'])->pluck('id')->first();
+
+ $row['document_item_id'] = DocumentItem::where('type', '=', Document::BILL_RECURRING_TYPE)
+ ->where('item_id', $item_id)
+ ->pluck('id')
+ ->first();
+ }
+
+ $row['tax_id'] = $this->getTaxId($row);
+
+ if (empty($row['name']) && !empty($row['item_name'])) {
+ $row['name'] = $row['item_name'];
+ }
+
+ $row['amount'] = (double) $row['amount'];
+
+ $row['type'] = Document::BILL_RECURRING_TYPE;
+
+ return $row;
+ }
+
+ public function prepareRules(array $rules): array
+ {
+ $rules['bill_number'] = 'required|string';
+
+ unset($rules['bill_id']);
+
+ return $rules;
+ }
+}
diff --git a/app/Imports/Purchases/RecurringBills/Sheets/RecurringBillItems.php b/app/Imports/Purchases/RecurringBills/Sheets/RecurringBillItems.php
new file mode 100644
index 000000000..9a4ac6ca3
--- /dev/null
+++ b/app/Imports/Purchases/RecurringBills/Sheets/RecurringBillItems.php
@@ -0,0 +1,57 @@
+isEmpty($row, 'bill_number')) {
+ return [];
+ }
+
+ $row['bill_number'] = (string) $row['bill_number'];
+
+ $row = parent::map($row);
+
+ $row['document_id'] = (int) Document::where('type', '=', Document::BILL_RECURRING_TYPE)
+ ->number($row['bill_number'])
+ ->pluck('id')
+ ->first();
+
+ if (empty($row['item_id']) && !empty($row['item_name'])) {
+ $row['item_id'] = $this->getItemIdFromName($row);
+
+ $row['name'] = $row['item_name'];
+ }
+
+ $row['description'] = !empty($row['item_description']) ? $row['item_description'] : '';
+
+ $row['tax'] = (double) $row['tax'];
+ $row['tax_id'] = 0;
+ $row['type'] = Document::BILL_RECURRING_TYPE;
+
+ return $row;
+ }
+
+ public function prepareRules(array $rules): array
+ {
+ $rules['bill_number'] = 'required|string';
+
+ unset($rules['bill_id']);
+
+ return $rules;
+ }
+}
diff --git a/app/Imports/Purchases/RecurringBills/Sheets/RecurringBillTotals.php b/app/Imports/Purchases/RecurringBills/Sheets/RecurringBillTotals.php
new file mode 100644
index 000000000..d0038cef9
--- /dev/null
+++ b/app/Imports/Purchases/RecurringBills/Sheets/RecurringBillTotals.php
@@ -0,0 +1,47 @@
+isEmpty($row, 'bill_number')) {
+ return [];
+ }
+
+ $row['bill_number'] = (string) $row['bill_number'];
+
+ $row = parent::map($row);
+
+ $row['document_id'] = (int) Document::where('type', '=', Document::BILL_RECURRING_TYPE)
+ ->number($row['bill_number'])
+ ->pluck('id')
+ ->first();
+
+ $row['type'] = Document::BILL_RECURRING_TYPE;
+
+ return $row;
+ }
+
+ public function prepareRules(array $rules): array
+ {
+ $rules['bill_number'] = 'required|string';
+
+ unset($rules['bill_id']);
+
+ return $rules;
+ }
+}
diff --git a/app/Imports/Purchases/RecurringBills/Sheets/RecurringBills.php b/app/Imports/Purchases/RecurringBills/Sheets/RecurringBills.php
new file mode 100644
index 000000000..f52582643
--- /dev/null
+++ b/app/Imports/Purchases/RecurringBills/Sheets/RecurringBills.php
@@ -0,0 +1,52 @@
+isEmpty($row, 'bill_number')) {
+ return [];
+ }
+
+ $row['bill_number'] = (string) $row['bill_number'];
+
+ $row = parent::map($row);
+
+ $country = array_search($row['contact_country'], trans('countries'));
+
+ $row['document_number'] = $row['bill_number'];
+ $row['issued_at'] = $row['billed_at'];
+ $row['category_id'] = $this->getCategoryId($row, 'expense');
+ $row['contact_id'] = $this->getContactId($row, 'vendor');
+ $row['currency_code'] = $this->getCurrencyCode($row);
+ $row['type'] = Model::BILL_RECURRING_TYPE;
+ $row['contact_country'] = !empty($country) ? $country : null;
+
+ return $row;
+ }
+
+ public function prepareRules(array $rules): array
+ {
+ $rules['bill_number'] = Str::replaceFirst('unique:documents,NULL', 'unique:documents,document_number', $rules['document_number']);
+ $rules['billed_at'] = $rules['issued_at'];
+ $rules['currency_rate'] = 'required|gt:0';
+
+ unset($rules['document_number'], $rules['issued_at'], $rules['type']);
+
+ return $rules;
+ }
+}
diff --git a/app/Imports/Sales/Invoices.php b/app/Imports/Sales/Invoices/Invoices.php
similarity index 57%
rename from app/Imports/Sales/Invoices.php
rename to app/Imports/Sales/Invoices/Invoices.php
index 278091650..7dfa1b274 100644
--- a/app/Imports/Sales/Invoices.php
+++ b/app/Imports/Sales/Invoices/Invoices.php
@@ -1,14 +1,14 @@
new Base(),
+ 'recurring_invoice_items' => new RecurringInvoiceItems(),
+ 'recurring_invoice_item_taxes' => new RecurringInvoiceItemTaxes(),
+ 'recurring_invoice_histories' => new RecurringInvoiceHistories(),
+ 'recurring_invoice_totals' => new RecurringInvoiceTotals(),
+ 'recurring' => new Recurring(),
+ ];
+ }
+}
diff --git a/app/Imports/Sales/RecurringInvoices/Sheets/Recurring.php b/app/Imports/Sales/RecurringInvoices/Sheets/Recurring.php
new file mode 100644
index 000000000..bf71f3ef9
--- /dev/null
+++ b/app/Imports/Sales/RecurringInvoices/Sheets/Recurring.php
@@ -0,0 +1,27 @@
+number($row['invoice_number'])
+ ->pluck('id')
+ ->first();
+
+ return $row;
+ }
+}
diff --git a/app/Imports/Sales/RecurringInvoices/Sheets/RecurringInvoiceHistories.php b/app/Imports/Sales/RecurringInvoices/Sheets/RecurringInvoiceHistories.php
new file mode 100644
index 000000000..f04c36c64
--- /dev/null
+++ b/app/Imports/Sales/RecurringInvoices/Sheets/RecurringInvoiceHistories.php
@@ -0,0 +1,49 @@
+isEmpty($row, 'invoice_number')) {
+ return [];
+ }
+
+ $row['invoice_number'] = (string) $row['invoice_number'];
+
+ $row = parent::map($row);
+
+ $row['document_id'] = (int) Document::where('type', '=', Document::INVOICE_RECURRING_TYPE)
+ ->number($row['invoice_number'])
+ ->pluck('id')
+ ->first();
+
+ $row['notify'] = (int) $row['notify'];
+
+ $row['type'] = Document::INVOICE_RECURRING_TYPE;
+
+ return $row;
+ }
+
+ public function prepareRules(array $rules): array
+ {
+ $rules['invoice_number'] = 'required|string';
+
+ unset($rules['invoice_id']);
+
+ return $rules;
+ }
+}
diff --git a/app/Imports/Sales/RecurringInvoices/Sheets/RecurringInvoiceItemTaxes.php b/app/Imports/Sales/RecurringInvoices/Sheets/RecurringInvoiceItemTaxes.php
new file mode 100644
index 000000000..8b7c633d3
--- /dev/null
+++ b/app/Imports/Sales/RecurringInvoices/Sheets/RecurringInvoiceItemTaxes.php
@@ -0,0 +1,66 @@
+isEmpty($row, 'invoice_number')) {
+ return [];
+ }
+
+ $row['invoice_number'] = (string) $row['invoice_number'];
+
+ $row = parent::map($row);
+
+ $row['document_id'] = (int) Document::where('type', '=', Document::INVOICE_RECURRING_TYPE)
+ ->number($row['invoice_number'])
+ ->pluck('id')
+ ->first();
+
+ if (empty($row['document_item_id']) && !empty($row['item_name'])) {
+ $item_id = Item::name($row['item_name'])->pluck('id')->first();
+
+ $row['document_item_id'] = DocumentItem::where('type', '=', Document::INVOICE_RECURRING_TYPE)
+ ->where('item_id', $item_id)
+ ->pluck('id')
+ ->first();
+ }
+
+ $row['tax_id'] = $this->getTaxId($row);
+
+ if (empty($row['name']) && !empty($row['item_name'])) {
+ $row['name'] = $row['item_name'];
+ }
+
+ $row['amount'] = (double) $row['amount'];
+
+ $row['type'] = Document::INVOICE_RECURRING_TYPE;
+
+ return $row;
+ }
+
+ public function prepareRules(array $rules): array
+ {
+ $rules['invoice_number'] = 'required|string';
+
+ unset($rules['invoice_id']);
+
+ return $rules;
+ }
+}
diff --git a/app/Imports/Sales/RecurringInvoices/Sheets/RecurringInvoiceItems.php b/app/Imports/Sales/RecurringInvoices/Sheets/RecurringInvoiceItems.php
new file mode 100644
index 000000000..5f134e399
--- /dev/null
+++ b/app/Imports/Sales/RecurringInvoices/Sheets/RecurringInvoiceItems.php
@@ -0,0 +1,57 @@
+isEmpty($row, 'invoice_number')) {
+ return [];
+ }
+
+ $row['invoice_number'] = (string) $row['invoice_number'];
+
+ $row = parent::map($row);
+
+ $row['document_id'] = (int) Document::where('type', '=', Document::INVOICE_RECURRING_TYPE)
+ ->number($row['invoice_number'])
+ ->pluck('id')
+ ->first();
+
+ if (empty($row['item_id']) && ! empty($row['item_name'])) {
+ $row['item_id'] = $this->getItemIdFromName($row);
+
+ $row['name'] = $row['item_name'];
+ }
+
+ $row['description'] = !empty($row['item_description']) ? $row['item_description'] : '';
+
+ $row['tax'] = (double) $row['tax'];
+ $row['tax_id'] = 0;
+ $row['type'] = Document::INVOICE_RECURRING_TYPE;
+
+ return $row;
+ }
+
+ public function prepareRules(array $rules): array
+ {
+ $rules['invoice_number'] = 'required|string';
+
+ unset($rules['invoice_id']);
+
+ return $rules;
+ }
+}
diff --git a/app/Imports/Sales/RecurringInvoices/Sheets/RecurringInvoiceTotals.php b/app/Imports/Sales/RecurringInvoices/Sheets/RecurringInvoiceTotals.php
new file mode 100644
index 000000000..1dd454207
--- /dev/null
+++ b/app/Imports/Sales/RecurringInvoices/Sheets/RecurringInvoiceTotals.php
@@ -0,0 +1,47 @@
+isEmpty($row, 'invoice_number')) {
+ return [];
+ }
+
+ $row['invoice_number'] = (string) $row['invoice_number'];
+
+ $row = parent::map($row);
+
+ $row['document_id'] = (int) Document::where('type', '=', Document::INVOICE_RECURRING_TYPE)
+ ->number($row['invoice_number'])
+ ->pluck('id')
+ ->first();
+
+ $row['type'] = Document::INVOICE_RECURRING_TYPE;
+
+ return $row;
+ }
+
+ public function prepareRules(array $rules): array
+ {
+ $rules['invoice_number'] = 'required|string';
+
+ unset($rules['invoice_id']);
+
+ return $rules;
+ }
+}
diff --git a/app/Imports/Sales/RecurringInvoices/Sheets/RecurringInvoices.php b/app/Imports/Sales/RecurringInvoices/Sheets/RecurringInvoices.php
new file mode 100644
index 000000000..fb4dd810d
--- /dev/null
+++ b/app/Imports/Sales/RecurringInvoices/Sheets/RecurringInvoices.php
@@ -0,0 +1,52 @@
+isEmpty($row, 'invoice_number')) {
+ return [];
+ }
+
+ $row['invoice_number'] = (string) $row['invoice_number'];
+
+ $row = parent::map($row);
+
+ $country = array_search($row['contact_country'], trans('countries'));
+
+ $row['document_number'] = $row['invoice_number'];
+ $row['issued_at'] = $row['invoiced_at'];
+ $row['category_id'] = $this->getCategoryId($row, 'income');
+ $row['contact_id'] = $this->getContactId($row, 'customer');
+ $row['currency_code'] = $this->getCurrencyCode($row);
+ $row['type'] = Model::INVOICE_RECURRING_TYPE;
+ $row['contact_country'] = !empty($country) ? $country : null;
+
+ return $row;
+ }
+
+ public function prepareRules(array $rules): array
+ {
+ $rules['invoice_number'] = Str::replaceFirst('unique:documents,NULL', 'unique:documents,document_number', $rules['document_number']);
+ $rules['invoiced_at'] = $rules['issued_at'];
+ $rules['currency_rate'] = 'required|gt:0';
+
+ unset($rules['document_number'], $rules['issued_at'], $rules['type']);
+
+ return $rules;
+ }
+}
diff --git a/public/files/import/recurring-bills.xlsx b/public/files/import/recurring-bills.xlsx
new file mode 100644
index 000000000..9bbc38bc6
Binary files /dev/null and b/public/files/import/recurring-bills.xlsx differ
diff --git a/public/files/import/recurring-invoices.xlsx b/public/files/import/recurring-invoices.xlsx
new file mode 100644
index 000000000..eea3bc376
Binary files /dev/null and b/public/files/import/recurring-invoices.xlsx differ
diff --git a/public/files/import/recurring-transactions.xlsx b/public/files/import/recurring-transactions.xlsx
new file mode 100644
index 000000000..0adc49828
Binary files /dev/null and b/public/files/import/recurring-transactions.xlsx differ
diff --git a/resources/views/banking/recurring_transactions/index.blade.php b/resources/views/banking/recurring_transactions/index.blade.php
index fad645a4a..fec5c155c 100644
--- a/resources/views/banking/recurring_transactions/index.blade.php
+++ b/resources/views/banking/recurring_transactions/index.blade.php
@@ -21,6 +21,24 @@
@endcan
+
+
+
+ more_horiz
+
+
+ @can('create-banking-transactions')
+
+ {{ trans('import.import') }}
+
+ @endcan
+
+
+ {{ trans('general.export') }}
+
+
+
+
@if ($transactions->count() || request()->get('search', false))
@@ -141,23 +159,29 @@
@endif
diff --git a/resources/views/purchases/recurring_bills/index.blade.php b/resources/views/purchases/recurring_bills/index.blade.php
index 262790cb1..6127bbb1f 100644
--- a/resources/views/purchases/recurring_bills/index.blade.php
+++ b/resources/views/purchases/recurring_bills/index.blade.php
@@ -14,7 +14,7 @@
-
+
diff --git a/resources/views/sales/recurring_invoices/index.blade.php b/resources/views/sales/recurring_invoices/index.blade.php
index b604be522..c978a1151 100644
--- a/resources/views/sales/recurring_invoices/index.blade.php
+++ b/resources/views/sales/recurring_invoices/index.blade.php
@@ -14,7 +14,7 @@
-
+
diff --git a/routes/admin.php b/routes/admin.php
index 76703b253..ffa504952 100644
--- a/routes/admin.php
+++ b/routes/admin.php
@@ -80,6 +80,8 @@ Route::group(['prefix' => 'sales'], function () {
Route::get('recurring-invoices/{recurring_invoice}/duplicate', 'Sales\RecurringInvoices@duplicate')->name('recurring-invoices.duplicate');
Route::get('recurring-invoices/{recurring_invoice}/end', 'Sales\RecurringInvoices@end')->name('recurring-invoices.end');
+ Route::post('recurring-invoices/import', 'Sales\RecurringInvoices@import')->middleware('import')->name('recurring-invoices.import');
+ Route::get('recurring-invoices/export', 'Sales\RecurringInvoices@export')->name('recurring-invoices.export');
Route::resource('recurring-invoices', 'Sales\RecurringInvoices', ['middleware' => ['date.format', 'money', 'dropzone']]);
Route::get('customers/{customer}/create-invoice', 'Sales\Customers@createInvoice')->name('customers.create-invoice');
@@ -104,6 +106,8 @@ Route::group(['prefix' => 'purchases'], function () {
Route::get('recurring-bills/{recurring_bill}/duplicate', 'Purchases\RecurringBills@duplicate')->name('recurring-bills.duplicate');
Route::get('recurring-bills/{recurring_bill}/end', 'Purchases\RecurringBills@end')->name('recurring-bills.end');
+ Route::post('recurring-bills/import', 'Purchases\RecurringBills@import')->middleware('import')->name('recurring-bills.import');
+ Route::get('recurring-bills/export', 'Purchases\RecurringBills@export')->name('recurring-bills.export');
Route::resource('recurring-bills', 'Purchases\RecurringBills', ['middleware' => ['date.format', 'money', 'dropzone']]);
Route::get('vendors/{vendor}/create-bill', 'Purchases\Vendors@createBill')->name('vendors.create-bill');
@@ -142,6 +146,8 @@ Route::group(['prefix' => 'banking'], function () {
Route::get('recurring-transactions/{recurring_transaction}/duplicate', 'Banking\RecurringTransactions@duplicate')->name('recurring-transactions.duplicate');
Route::get('recurring-transactions/{recurring_transaction}/end', 'Banking\RecurringTransactions@end')->name('recurring-transactions.end');
+ Route::post('recurring-transactions/import', 'Banking\RecurringTransactions@import')->middleware('import')->name('recurring-transactions.import');
+ Route::get('recurring-transactions/export', 'Banking\RecurringTransactions@export')->name('recurring-transactions.export');
Route::resource('recurring-transactions', 'Banking\RecurringTransactions', ['middleware' => ['date.format', 'money', 'dropzone']]);
Route::get('transfers/{transfer}/print', 'Banking\Transfers@printTransfer')->name('transfers.print');
diff --git a/tests/Feature/Purchases/BillsTest.php b/tests/Feature/Purchases/BillsTest.php
index bd03a11ba..c879a2ea2 100644
--- a/tests/Feature/Purchases/BillsTest.php
+++ b/tests/Feature/Purchases/BillsTest.php
@@ -2,7 +2,7 @@
namespace Tests\Feature\Purchases;
-use App\Exports\Purchases\Bills as Export;
+use App\Exports\Purchases\Bills\Bills as Export;
use App\Jobs\Document\CreateDocument;
use App\Models\Document\Document;
use Illuminate\Http\UploadedFile;
diff --git a/tests/Feature/Sales/InvoicesTest.php b/tests/Feature/Sales/InvoicesTest.php
index e38d1ba26..3aad6da17 100644
--- a/tests/Feature/Sales/InvoicesTest.php
+++ b/tests/Feature/Sales/InvoicesTest.php
@@ -2,7 +2,7 @@
namespace Tests\Feature\Sales;
-use App\Exports\Sales\Invoices as Export;
+use App\Exports\Sales\Invoices\Invoices as Export;
use App\Jobs\Document\CreateDocument;
use App\Models\Document\Document;
use App\Notifications\Sale\Invoice as Notification;