From b119deca9ffd90707e48fe91c530d5e10f6765c5 Mon Sep 17 00:00:00 2001 From: denisdulici Date: Mon, 20 Jan 2020 23:18:47 +0300 Subject: [PATCH 1/7] items import/export --- app/Exports/Common/Items.php | 14 ++++++++++--- app/Imports/Common/Items.php | 35 +++++++++++++++++++++++++++++---- app/Models/Common/Item.php | 2 +- public/files/import/items.xlsx | Bin 6532 -> 9022 bytes 4 files changed, 43 insertions(+), 8 deletions(-) diff --git a/app/Exports/Common/Items.php b/app/Exports/Common/Items.php index 6c7bd6127..22c2aee92 100644 --- a/app/Exports/Common/Items.php +++ b/app/Exports/Common/Items.php @@ -9,7 +9,7 @@ class Items extends Export { public function collection() { - $model = Model::usingSearchString(request('search')); + $model = Model::with(['category', 'tax'])->usingSearchString(request('search')); if (!empty($this->ids)) { $model->whereIn('id', (array) $this->ids); @@ -18,6 +18,14 @@ class Items extends Export return $model->get(); } + public function map($model): array + { + $model->category_name = $model->category->name; + $model->tax_rate = $model->tax->rate; + + return parent::map($model); + } + public function fields(): array { return [ @@ -25,8 +33,8 @@ class Items extends Export 'description', 'sale_price', 'purchase_price', - 'category_id', - 'tax_id', + 'category_name', + 'tax_rate', 'enabled', ]; } diff --git a/app/Imports/Common/Items.php b/app/Imports/Common/Items.php index 44c2cbd26..31fa1dfb7 100644 --- a/app/Imports/Common/Items.php +++ b/app/Imports/Common/Items.php @@ -3,18 +3,45 @@ namespace App\Imports\Common; use App\Abstracts\Import; -use App\Models\Common\Item as Model; use App\Http\Requests\Common\Item as Request; -use App\Jobs\Common\CreateItem; +use App\Models\Common\Item as Model; +use App\Models\Setting\Category; +use App\Models\Setting\Tax; class Items extends Import { public function model(array $row) { return new Model($row); - //$request = (new Request())->merge($row); + } - //return dispatch_now(new CreateItem($request)); + public function map($row): array + { + $row = parent::map($row); + + if (empty($row['category_id']) && !empty($row['category_name'])) { + $row['category_id'] = Category::firstOrCreate([ + 'name' => $row['category_name'], + ], [ + 'company_id' => session('company_id'), + 'type' => 'income', + 'color' => '#' . dechex(rand(0x000000, 0xFFFFFF)), + 'enabled' => 1, + ])->id; + } + + if (empty($row['tax_id']) && !empty($row['tax_rate'])) { + $row['tax_id'] = Tax::firstOrCreate([ + 'rate' => $row['tax_rate'], + ], [ + 'company_id' => session('company_id'), + 'type' => 'normal', + 'name' => $row['tax_rate'], + 'enabled' => 1, + ])->id; + } + + return $row; } public function rules(): array diff --git a/app/Models/Common/Item.php b/app/Models/Common/Item.php index ea551dfc0..030cd03db 100644 --- a/app/Models/Common/Item.php +++ b/app/Models/Common/Item.php @@ -41,7 +41,7 @@ class Item extends Model public function tax() { - return $this->belongsTo('App\Models\Setting\Tax')->withDefault(['name' => trans('general.na')]); + return $this->belongsTo('App\Models\Setting\Tax')->withDefault(['name' => trans('general.na'), 'rate' => 0]); } public function bill_items() diff --git a/public/files/import/items.xlsx b/public/files/import/items.xlsx index b7955b7971dfc2d83278b41700304692e80dfa68..a40ac42572fd17ccc85d065041597a444be12f6c 100644 GIT binary patch literal 9022 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 Nz<_&@BPD*+`#-7ra-0AF literal 6532 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 VDxjhN0^uOO!-#{EO8V>H{{cp Date: Mon, 20 Jan 2020 23:50:19 +0300 Subject: [PATCH 2/7] revenues import/export --- app/Abstracts/Import.php | 105 ++++++++++++++++++ app/Exports/Sales/Revenues.php | 20 +++- app/Imports/Common/Items.php | 20 +--- app/Imports/Sales/Revenues.php | 31 +++++- app/Imports/Sales/Sheets/InvoiceItemTaxes.php | 9 +- app/Imports/Sales/Sheets/InvoiceItems.php | 10 +- .../Sales/Sheets/InvoiceTransactions.php | 61 +--------- app/Imports/Sales/Sheets/Invoices.php | 30 +---- public/files/import/items.xlsx | Bin 9022 -> 8978 bytes public/files/import/revenues.xlsx | Bin 6670 -> 9189 bytes 10 files changed, 163 insertions(+), 123 deletions(-) diff --git a/app/Abstracts/Import.php b/app/Abstracts/Import.php index ebd1fe995..2165336f6 100644 --- a/app/Abstracts/Import.php +++ b/app/Abstracts/Import.php @@ -2,6 +2,11 @@ namespace App\Abstracts; +use App\Models\Banking\Account; +use App\Models\Common\Contact; +use App\Models\Common\Item; +use App\Models\Setting\Category; +use App\Models\Setting\Tax; use Illuminate\Support\Str; use Jenssegers\Date\Date; use Maatwebsite\Excel\Concerns\Importable; @@ -86,4 +91,104 @@ abstract class Import implements ToModel, SkipsOnError, SkipsOnFailure, WithBatc { flash($e->getMessage())->error()->important(); } + + public function getAccountIdFromCurrency($row) + { + return Account::firstOrCreate([ + 'currency_code' => $row['currency_code'], + ], [ + 'company_id' => session('company_id'), + 'name' => $row['currency_code'], + 'number' => Account::max('number') + 1, + 'opening_balance' => 0, + 'enabled' => 1, + ])->id; + } + + public function getAccountIdFromName($row) + { + return Account::firstOrCreate([ + 'name' => $row['account_name'], + ], [ + 'company_id' => session('company_id'), + 'number' => Account::max('number') + 1, + 'currency_code' => setting('default.currency'), + 'opening_balance' => 0, + 'enabled' => 1, + ])->id; + } + + public function getAccountIdFromNumber($row) + { + return Account::firstOrCreate([ + 'number' => $row['account_number'], + ], [ + 'company_id' => session('company_id'), + 'name' => $row['account_number'], + 'currency_code' => setting('default.currency'), + 'opening_balance' => 0, + 'enabled' => 1, + ])->id; + } + + public function getCategoryIdFromName($row, $type) + { + return Category::firstOrCreate([ + 'name' => $row['category_name'], + ], [ + 'company_id' => session('company_id'), + 'type' => $type, + 'color' => '#' . dechex(rand(0x000000, 0xFFFFFF)), + 'enabled' => 1, + ])->id; + } + + public function getContactIdFromEmail($row, $type) + { + return Contact::firstOrCreate([ + 'email' => $row['contact_email'], + ], [ + 'company_id' => session('company_id'), + 'type' => $type, + 'name' => $row['contact_email'], + 'currency_code' => setting('default.currency'), + 'enabled' => 1, + ])->id; + } + + public function getContactIdFromName($row, $type) + { + return Contact::firstOrCreate([ + 'name' => $row['contact_name'], + ], [ + 'company_id' => session('company_id'), + 'type' => $type, + 'currency_code' => setting('default.currency'), + 'enabled' => 1, + ])->id; + } + + public function getItemIdFromName($row) + { + return Item::firstOrCreate([ + 'name' => $row['item_name'], + ], [ + 'company_id' => session('company_id'), + 'sale_price' => $row['price'], + 'purchase_price' => $row['price'], + 'enabled' => 1, + ])->id; + } + + public function getTaxIdFromRate($row, $type = 'normal') + { + return Tax::firstOrCreate([ + 'rate' => $row['tax_rate'], + ], [ + 'company_id' => session('company_id'), + 'type' => $type, + 'name' => $row['tax_rate'], + 'enabled' => 1, + ])->id; + } } diff --git a/app/Exports/Sales/Revenues.php b/app/Exports/Sales/Revenues.php index dd592bcbf..34e803906 100644 --- a/app/Exports/Sales/Revenues.php +++ b/app/Exports/Sales/Revenues.php @@ -9,7 +9,7 @@ class Revenues extends Export { public function collection() { - $model = Model::type('income')->usingSearchString(request('search')); + $model = Model::with(['account', 'category', 'contact', 'invoice'])->type('income')->usingSearchString(request('search')); if (!empty($this->ids)) { $model->whereIn('id', (array) $this->ids); @@ -18,6 +18,16 @@ class Revenues extends Export return $model->get(); } + public function map($model): array + { + $model->account_name = $model->account->name; + $model->invoice_number = $model->invoice ? $model->invoice->invoice_number : 0; + $model->contact_email = $model->contact->email; + $model->category_name = $model->category->name; + + return parent::map($model); + } + public function fields(): array { return [ @@ -25,10 +35,10 @@ class Revenues extends Export 'amount', 'currency_code', 'currency_rate', - 'account_id', - 'document_id', - 'contact_id', - 'category_id', + 'account_name', + 'invoice_number', + 'contact_email', + 'category_name', 'description', 'payment_method', 'reference', diff --git a/app/Imports/Common/Items.php b/app/Imports/Common/Items.php index 31fa1dfb7..6560b1ab9 100644 --- a/app/Imports/Common/Items.php +++ b/app/Imports/Common/Items.php @@ -5,8 +5,6 @@ namespace App\Imports\Common; use App\Abstracts\Import; use App\Http\Requests\Common\Item as Request; use App\Models\Common\Item as Model; -use App\Models\Setting\Category; -use App\Models\Setting\Tax; class Items extends Import { @@ -20,25 +18,11 @@ class Items extends Import $row = parent::map($row); if (empty($row['category_id']) && !empty($row['category_name'])) { - $row['category_id'] = Category::firstOrCreate([ - 'name' => $row['category_name'], - ], [ - 'company_id' => session('company_id'), - 'type' => 'income', - 'color' => '#' . dechex(rand(0x000000, 0xFFFFFF)), - 'enabled' => 1, - ])->id; + $row['category_id'] = $this->getCategoryIdFromName($row, 'item'); } if (empty($row['tax_id']) && !empty($row['tax_rate'])) { - $row['tax_id'] = Tax::firstOrCreate([ - 'rate' => $row['tax_rate'], - ], [ - 'company_id' => session('company_id'), - 'type' => 'normal', - 'name' => $row['tax_rate'], - 'enabled' => 1, - ])->id; + $row['tax_id'] = $this->getTaxIdFromRate($row); } return $row; diff --git a/app/Imports/Sales/Revenues.php b/app/Imports/Sales/Revenues.php index 5fe04dbf7..57e4da863 100644 --- a/app/Imports/Sales/Revenues.php +++ b/app/Imports/Sales/Revenues.php @@ -3,8 +3,9 @@ namespace App\Imports\Sales; use App\Abstracts\Import; -use App\Models\Banking\Transaction as Model; use App\Http\Requests\Banking\Transaction as Request; +use App\Models\Banking\Transaction as Model; +use App\Models\Sale\Invoice; class Revenues extends Import { @@ -19,6 +20,34 @@ class Revenues extends Import $row['type'] = 'income'; + if (empty($row['account_id']) && !empty($row['account_name'])) { + $row['account_id'] = $this->getAccountIdFromName($row); + } + + if (empty($row['account_id']) && !empty($row['account_number'])) { + $row['account_id'] = $this->getAccountIdFromNumber($row); + } + + if (empty($row['account_id']) && !empty($row['currency_code'])) { + $row['account_id'] = $this->getAccountIdFromCurrency($row); + } + + if (empty($row['contact_id']) && !empty($row['contact_name'])) { + $row['contact_id'] = $this->getContactIdFromName($row, 'customer'); + } + + if (empty($row['contact_id']) && !empty($row['contact_email'])) { + $row['contact_id'] = $this->getContactIdFromEmail($row, 'customer'); + } + + if (empty($row['category_id']) && !empty($row['category_name'])) { + $row['category_id'] = $this->getCategoryIdFromName($row, 'income'); + } + + if (!empty($row['invoice_number'])) { + $row['document_id'] = Invoice::number($row['invoice_number'])->pluck('id')->first(); + } + return $row; } diff --git a/app/Imports/Sales/Sheets/InvoiceItemTaxes.php b/app/Imports/Sales/Sheets/InvoiceItemTaxes.php index 0dbf13c2c..54a770c95 100644 --- a/app/Imports/Sales/Sheets/InvoiceItemTaxes.php +++ b/app/Imports/Sales/Sheets/InvoiceItemTaxes.php @@ -40,14 +40,7 @@ class InvoiceItemTaxes extends Import } if (empty($row['tax_id']) && !empty($row['tax_rate'])) { - $row['tax_id'] = Tax::firstOrCreate([ - 'rate' => $row['tax_rate'], - ], [ - 'company_id' => session('company_id'), - 'type' => 'normal', - 'name' => $row['tax_rate'], - 'enabled' => 1, - ])->id; + $row['tax_id'] = $this->getTaxIdFromRate($row); } if (empty($row['name']) && !empty($row['item_name'])) { diff --git a/app/Imports/Sales/Sheets/InvoiceItems.php b/app/Imports/Sales/Sheets/InvoiceItems.php index 8872923b9..0222bf547 100644 --- a/app/Imports/Sales/Sheets/InvoiceItems.php +++ b/app/Imports/Sales/Sheets/InvoiceItems.php @@ -4,7 +4,6 @@ namespace App\Imports\Sales\Sheets; use App\Abstracts\Import; use App\Http\Requests\Sale\InvoiceItem as Request; -use App\Models\Common\Item; use App\Models\Sale\Invoice; use App\Models\Sale\InvoiceItem as Model; @@ -22,14 +21,7 @@ class InvoiceItems extends Import $row['invoice_id'] = Invoice::number($row['invoice_number'])->pluck('id')->first(); if (empty($row['item_id']) && !empty($row['item_name'])) { - $row['item_id'] = Item::firstOrCreate([ - 'name' => $row['item_name'], - ], [ - 'company_id' => session('company_id'), - 'sale_price' => $row['price'], - 'purchase_price' => $row['price'], - 'enabled' => 1, - ])->id; + $row['item_id'] = $this->getItemIdFromName($row); $row['name'] = $row['item_name']; } diff --git a/app/Imports/Sales/Sheets/InvoiceTransactions.php b/app/Imports/Sales/Sheets/InvoiceTransactions.php index fd9fb41e9..429177e9d 100644 --- a/app/Imports/Sales/Sheets/InvoiceTransactions.php +++ b/app/Imports/Sales/Sheets/InvoiceTransactions.php @@ -4,11 +4,8 @@ namespace App\Imports\Sales\Sheets; use App\Abstracts\Import; use App\Http\Requests\Banking\Transaction as Request; -use App\Models\Banking\Account; use App\Models\Banking\Transaction as Model; -use App\Models\Common\Contact; use App\Models\Sale\Invoice; -use App\Models\Setting\Category; class InvoiceTransactions extends Import { @@ -24,73 +21,27 @@ class InvoiceTransactions extends Import $row['type'] = 'income'; if (empty($row['account_id']) && !empty($row['account_name'])) { - $row['account_id'] = Account::firstOrCreate([ - 'name' => $row['account_name'], - ], [ - 'company_id' => session('company_id'), - 'number' => Account::max('number') + 1, - 'currency_code' => setting('default.currency'), - 'opening_balance' => 0, - 'enabled' => 1, - ])->id; + $row['account_id'] = $this->getAccountIdFromName($row); } if (empty($row['account_id']) && !empty($row['account_number'])) { - $row['account_id'] = Account::firstOrCreate([ - 'number' => $row['account_number'], - ], [ - 'company_id' => session('company_id'), - 'name' => $row['account_number'], - 'currency_code' => setting('default.currency'), - 'opening_balance' => 0, - 'enabled' => 1, - ])->id; + $row['account_id'] = $this->getAccountIdFromNumber($row); } if (empty($row['account_id']) && !empty($row['currency_code'])) { - $row['account_id'] = Account::firstOrCreate([ - 'currency_code' => $row['currency_code'], - ], [ - 'company_id' => session('company_id'), - 'name' => $row['currency_code'], - 'number' => Account::max('number') + 1, - 'opening_balance' => 0, - 'enabled' => 1, - ])->id; + $row['account_id'] = $this->getAccountIdFromCurrency($row); } if (empty($row['contact_id']) && !empty($row['contact_name'])) { - $row['contact_id'] = Contact::firstOrCreate([ - 'name' => $row['contact_name'], - ], [ - 'company_id' => session('company_id'), - 'type' => 'customer', - 'currency_code' => setting('default.currency'), - 'enabled' => 1, - ])->id; + $row['contact_id'] = $this->getContactIdFromName($row, 'customer'); } if (empty($row['contact_id']) && !empty($row['contact_email'])) { - $row['contact_id'] = Contact::firstOrCreate([ - 'email' => $row['contact_email'], - ], [ - 'company_id' => session('company_id'), - 'type' => 'customer', - 'name' => $row['contact_email'], - 'currency_code' => setting('default.currency'), - 'enabled' => 1, - ])->id; + $row['contact_id'] = $this->getContactIdFromEmail($row, 'customer'); } if (empty($row['category_id']) && !empty($row['category_name'])) { - $row['category_id'] = Category::firstOrCreate([ - 'name' => $row['category_name'], - ], [ - 'company_id' => session('company_id'), - 'type' => 'income', - 'color' => '#' . dechex(rand(0x000000, 0xFFFFFF)), - 'enabled' => 1, - ])->id; + $row['category_id'] = $this->getCategoryIdFromName($row, 'income'); } $row['document_id'] = Invoice::number($row['invoice_number'])->pluck('id')->first(); diff --git a/app/Imports/Sales/Sheets/Invoices.php b/app/Imports/Sales/Sheets/Invoices.php index 58bbc812b..5d1afb140 100644 --- a/app/Imports/Sales/Sheets/Invoices.php +++ b/app/Imports/Sales/Sheets/Invoices.php @@ -4,9 +4,7 @@ namespace App\Imports\Sales\Sheets; use App\Abstracts\Import; use App\Http\Requests\Sale\Invoice as Request; -use App\Models\Common\Contact; use App\Models\Sale\Invoice as Model; -use App\Models\Setting\Category; class Invoices extends Import { @@ -20,37 +18,15 @@ class Invoices extends Import $row = parent::map($row); if (empty($row['contact_id']) && !empty($row['contact_name'])) { - $row['contact_id'] = Contact::firstOrCreate([ - 'name' => $row['contact_name'], - ], [ - 'company_id' => session('company_id'), - 'type' => 'customer', - 'currency_code' => setting('default.currency'), - 'enabled' => 1, - ])->id; + $row['contact_id'] = $this->getContactIdFromName($row, 'customer'); } if (empty($row['contact_id']) && !empty($row['contact_email'])) { - $row['contact_id'] = Contact::firstOrCreate([ - 'email' => $row['contact_email'], - ], [ - 'company_id' => session('company_id'), - 'type' => 'customer', - 'name' => $row['contact_email'], - 'currency_code' => setting('default.currency'), - 'enabled' => 1, - ])->id; + $row['contact_id'] = $this->getContactIdFromEmail($row, 'customer'); } if (empty($row['category_id']) && !empty($row['category_name'])) { - $row['category_id'] = Category::firstOrCreate([ - 'name' => $row['category_name'], - ], [ - 'company_id' => session('company_id'), - 'type' => 'income', - 'color' => '#' . dechex(rand(0x000000, 0xFFFFFF)), - 'enabled' => 1, - ])->id; + $row['category_id'] = $this->getCategoryIdFromName($row, 'income'); } return $row; diff --git a/public/files/import/items.xlsx b/public/files/import/items.xlsx index a40ac42572fd17ccc85d065041597a444be12f6c..bdc881fd8b9d65a409124086c38db3b63e571909 100644 GIT binary patch delta 3808 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 Aa{vGU From 04173eae782fdbdbc8e4db006e312d1529ec07ce Mon Sep 17 00:00:00 2001 From: denisdulici Date: Mon, 20 Jan 2020 23:50:29 +0300 Subject: [PATCH 3/7] bill scopes --- app/Models/Purchase/Bill.php | 5 +++++ app/Models/Purchase/BillItem.php | 2 +- app/Models/Purchase/BillItemTax.php | 11 ++++++++--- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/app/Models/Purchase/Bill.php b/app/Models/Purchase/Bill.php index 1fa14d2ce..46a018a31 100644 --- a/app/Models/Purchase/Bill.php +++ b/app/Models/Purchase/Bill.php @@ -117,6 +117,11 @@ class Bill extends Model return $query->where('status', '<>', 'paid'); } + public function scopeNumber($query, $number) + { + return $query->where('bill_number', '=', $number); + } + public function onCloning($src, $child = null) { $this->status = 'draft'; diff --git a/app/Models/Purchase/BillItem.php b/app/Models/Purchase/BillItem.php index d2f8da66a..76ae399e0 100644 --- a/app/Models/Purchase/BillItem.php +++ b/app/Models/Purchase/BillItem.php @@ -34,7 +34,7 @@ class BillItem extends Model public function item() { - return $this->belongsTo('App\Models\Common\Item'); + return $this->belongsTo('App\Models\Common\Item')->withDefault(['name' => trans('general.na')]); } public function taxes() diff --git a/app/Models/Purchase/BillItemTax.php b/app/Models/Purchase/BillItemTax.php index c13b1e405..06818f97c 100644 --- a/app/Models/Purchase/BillItemTax.php +++ b/app/Models/Purchase/BillItemTax.php @@ -4,11 +4,11 @@ namespace App\Models\Purchase; use App\Abstracts\Model; use App\Traits\Currencies; +use Znck\Eloquent\Traits\BelongsToThrough; class BillItemTax extends Model { - - use Currencies; + use Currencies, BelongsToThrough; protected $table = 'bill_item_taxes'; @@ -24,9 +24,14 @@ class BillItemTax extends Model return $this->belongsTo('App\Models\Purchase\Bill'); } + public function item() + { + return $this->belongsToThrough('App\Models\Common\Item', 'App\Models\Purchase\BillItem', 'bill_item_id'); + } + public function tax() { - return $this->belongsTo('App\Models\Setting\Tax'); + return $this->belongsTo('App\Models\Setting\Tax')->withDefault(['name' => trans('general.na')]); } /** From 9b42e2d1273a938b07438d607b7dcac393833c0e Mon Sep 17 00:00:00 2001 From: denisdulici Date: Tue, 21 Jan 2020 00:04:10 +0300 Subject: [PATCH 4/7] payments import/export --- app/Exports/Purchases/Payments.php | 20 +++++++++++++++----- app/Imports/Purchases/Payments.php | 29 +++++++++++++++++++++++++++++ public/files/import/payments.xlsx | Bin 6669 -> 9160 bytes 3 files changed, 44 insertions(+), 5 deletions(-) diff --git a/app/Exports/Purchases/Payments.php b/app/Exports/Purchases/Payments.php index 48a1a8288..731a8969b 100644 --- a/app/Exports/Purchases/Payments.php +++ b/app/Exports/Purchases/Payments.php @@ -9,7 +9,7 @@ class Payments extends Export { public function collection() { - $model = Model::type('expense')->usingSearchString(request('search')); + $model = Model::with(['account', 'bill', 'category', 'contact'])->type('expense')->usingSearchString(request('search')); if (!empty($this->ids)) { $model->whereIn('id', (array) $this->ids); @@ -18,6 +18,16 @@ class Payments extends Export return $model->get(); } + public function map($model): array + { + $model->account_name = $model->account->name; + $model->bill_number = $model->bill ? $model->bill->bill_number : 0; + $model->contact_email = $model->contact->email; + $model->category_name = $model->category->name; + + return parent::map($model); + } + public function fields(): array { return [ @@ -25,10 +35,10 @@ class Payments extends Export 'amount', 'currency_code', 'currency_rate', - 'account_id', - 'document_id', - 'contact_id', - 'category_id', + 'account_name', + 'bill_number', + 'contact_email', + 'category_name', 'description', 'payment_method', 'reference', diff --git a/app/Imports/Purchases/Payments.php b/app/Imports/Purchases/Payments.php index 41f6d6785..6c6a20e9f 100644 --- a/app/Imports/Purchases/Payments.php +++ b/app/Imports/Purchases/Payments.php @@ -5,6 +5,7 @@ namespace App\Imports\Purchases; use App\Abstracts\Import; use App\Models\Banking\Transaction as Model; use App\Http\Requests\Banking\Transaction as Request; +use App\Models\Purchase\Bill; class Payments extends Import { @@ -19,6 +20,34 @@ class Payments extends Import $row['type'] = 'expense'; + if (empty($row['account_id']) && !empty($row['account_name'])) { + $row['account_id'] = $this->getAccountIdFromName($row); + } + + if (empty($row['account_id']) && !empty($row['account_number'])) { + $row['account_id'] = $this->getAccountIdFromNumber($row); + } + + if (empty($row['account_id']) && !empty($row['currency_code'])) { + $row['account_id'] = $this->getAccountIdFromCurrency($row); + } + + if (empty($row['contact_id']) && !empty($row['contact_name'])) { + $row['contact_id'] = $this->getContactIdFromName($row, 'vendor'); + } + + if (empty($row['contact_id']) && !empty($row['contact_email'])) { + $row['contact_id'] = $this->getContactIdFromEmail($row, 'vendor'); + } + + if (empty($row['category_id']) && !empty($row['category_name'])) { + $row['category_id'] = $this->getCategoryIdFromName($row, 'expense'); + } + + if (!empty($row['bill_number'])) { + $row['document_id'] = Bill::number($row['bill_number'])->pluck('id')->first(); + } + return $row; } diff --git a/public/files/import/payments.xlsx b/public/files/import/payments.xlsx index c2a0f0f0e9ee9ef7a0cb3e9830ee7ff7381d78ae..fad84f1d46abe3060b6bbb8cf68ab04a3b3c66c8 100644 GIT binary patch literal 9160 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 From 75f17e546602807df966c54d7e18743a3f0cceaa Mon Sep 17 00:00:00 2001 From: denisdulici Date: Tue, 21 Jan 2020 09:10:12 +0300 Subject: [PATCH 5/7] transactions import/export --- app/Abstracts/Import.php | 108 +-------- app/Exports/Banking/Transactions.php | 31 ++- app/Imports/Banking/Transactions.php | 14 +- app/Imports/Common/Items.php | 9 +- app/Imports/Purchases/Payments.php | 33 +-- app/Imports/Sales/Revenues.php | 33 +-- app/Imports/Sales/Sheets/InvoiceItemTaxes.php | 8 +- .../Sales/Sheets/InvoiceTransactions.php | 31 +-- app/Imports/Sales/Sheets/Invoices.php | 13 +- app/Traits/Import.php | 212 ++++++++++++++++++ public/files/import/transactions.xlsx | Bin 6829 -> 9445 bytes 11 files changed, 270 insertions(+), 222 deletions(-) create mode 100644 app/Traits/Import.php diff --git a/app/Abstracts/Import.php b/app/Abstracts/Import.php index 2165336f6..66f5edefa 100644 --- a/app/Abstracts/Import.php +++ b/app/Abstracts/Import.php @@ -2,11 +2,7 @@ namespace App\Abstracts; -use App\Models\Banking\Account; -use App\Models\Common\Contact; -use App\Models\Common\Item; -use App\Models\Setting\Category; -use App\Models\Setting\Tax; +use App\Traits\Import as ImportHelpers; use Illuminate\Support\Str; use Jenssegers\Date\Date; use Maatwebsite\Excel\Concerns\Importable; @@ -22,7 +18,7 @@ use Maatwebsite\Excel\Validators\Failure; abstract class Import implements ToModel, SkipsOnError, SkipsOnFailure, WithBatchInserts, WithChunkReading, WithHeadingRow, WithMapping, WithValidation { - use Importable; + use Importable, ImportHelpers; public $empty_field = 'empty---'; @@ -91,104 +87,4 @@ abstract class Import implements ToModel, SkipsOnError, SkipsOnFailure, WithBatc { flash($e->getMessage())->error()->important(); } - - public function getAccountIdFromCurrency($row) - { - return Account::firstOrCreate([ - 'currency_code' => $row['currency_code'], - ], [ - 'company_id' => session('company_id'), - 'name' => $row['currency_code'], - 'number' => Account::max('number') + 1, - 'opening_balance' => 0, - 'enabled' => 1, - ])->id; - } - - public function getAccountIdFromName($row) - { - return Account::firstOrCreate([ - 'name' => $row['account_name'], - ], [ - 'company_id' => session('company_id'), - 'number' => Account::max('number') + 1, - 'currency_code' => setting('default.currency'), - 'opening_balance' => 0, - 'enabled' => 1, - ])->id; - } - - public function getAccountIdFromNumber($row) - { - return Account::firstOrCreate([ - 'number' => $row['account_number'], - ], [ - 'company_id' => session('company_id'), - 'name' => $row['account_number'], - 'currency_code' => setting('default.currency'), - 'opening_balance' => 0, - 'enabled' => 1, - ])->id; - } - - public function getCategoryIdFromName($row, $type) - { - return Category::firstOrCreate([ - 'name' => $row['category_name'], - ], [ - 'company_id' => session('company_id'), - 'type' => $type, - 'color' => '#' . dechex(rand(0x000000, 0xFFFFFF)), - 'enabled' => 1, - ])->id; - } - - public function getContactIdFromEmail($row, $type) - { - return Contact::firstOrCreate([ - 'email' => $row['contact_email'], - ], [ - 'company_id' => session('company_id'), - 'type' => $type, - 'name' => $row['contact_email'], - 'currency_code' => setting('default.currency'), - 'enabled' => 1, - ])->id; - } - - public function getContactIdFromName($row, $type) - { - return Contact::firstOrCreate([ - 'name' => $row['contact_name'], - ], [ - 'company_id' => session('company_id'), - 'type' => $type, - 'currency_code' => setting('default.currency'), - 'enabled' => 1, - ])->id; - } - - public function getItemIdFromName($row) - { - return Item::firstOrCreate([ - 'name' => $row['item_name'], - ], [ - 'company_id' => session('company_id'), - 'sale_price' => $row['price'], - 'purchase_price' => $row['price'], - 'enabled' => 1, - ])->id; - } - - public function getTaxIdFromRate($row, $type = 'normal') - { - return Tax::firstOrCreate([ - 'rate' => $row['tax_rate'], - ], [ - 'company_id' => session('company_id'), - 'type' => $type, - 'name' => $row['tax_rate'], - 'enabled' => 1, - ])->id; - } } diff --git a/app/Exports/Banking/Transactions.php b/app/Exports/Banking/Transactions.php index d991e6a22..828ef3e3c 100644 --- a/app/Exports/Banking/Transactions.php +++ b/app/Exports/Banking/Transactions.php @@ -9,7 +9,28 @@ class Transactions extends Export { public function collection() { - return Model::usingSearchString(request('search'))->get(); + $model = Model::with(['account', 'bill', 'category', 'contact', 'invoice'])->usingSearchString(request('search'))->get(); + + if (!empty($this->ids)) { + $model->whereIn('id', (array) $this->ids); + } + + return $model->get(); + } + + public function map($model): array + { + $model->account_name = $model->account->name; + $model->contact_email = $model->contact->email; + $model->category_name = $model->category->name; + + if ($model->type == 'income') { + $model->invoice_bill_number = $model->invoice ? $model->invoice->invoice_number : 0; + } else { + $model->invoice_bill_number = $model->bill ? $model->bill->bill_number : 0; + } + + return parent::map($model); } public function fields(): array @@ -20,10 +41,10 @@ class Transactions extends Export 'amount', 'currency_code', 'currency_rate', - 'account_id', - 'document_id', - 'contact_id', - 'category_id', + 'account_name', + 'invoice_bill_number', + 'contact_email', + 'category_name', 'description', 'payment_method', 'reference', diff --git a/app/Imports/Banking/Transactions.php b/app/Imports/Banking/Transactions.php index 75a25e98e..03d86d35a 100644 --- a/app/Imports/Banking/Transactions.php +++ b/app/Imports/Banking/Transactions.php @@ -3,8 +3,8 @@ namespace App\Imports\Banking; use App\Abstracts\Import; -use App\Models\Banking\Transaction as Model; use App\Http\Requests\Banking\Transaction as Request; +use App\Models\Banking\Transaction as Model; class Transactions extends Import { @@ -13,6 +13,18 @@ class Transactions extends Import return new Model($row); } + public function map($row): array + { + $row = parent::map($row); + + $row['account_id'] = $this->getAccountId($row); + $row['category_id'] = $this->getCategoryId($row); + $row['contact_id'] = $this->getContactId($row); + $row['document_id'] = $this->getDocumentId($row); + + return $row; + } + public function rules(): array { return (new Request())->rules(); diff --git a/app/Imports/Common/Items.php b/app/Imports/Common/Items.php index 6560b1ab9..f3e78b060 100644 --- a/app/Imports/Common/Items.php +++ b/app/Imports/Common/Items.php @@ -17,13 +17,8 @@ class Items extends Import { $row = parent::map($row); - if (empty($row['category_id']) && !empty($row['category_name'])) { - $row['category_id'] = $this->getCategoryIdFromName($row, 'item'); - } - - if (empty($row['tax_id']) && !empty($row['tax_rate'])) { - $row['tax_id'] = $this->getTaxIdFromRate($row); - } + $row['category_id'] = $this->getCategoryId($row, 'item'); + $row['tax_id'] = $this->getTaxId($row); return $row; } diff --git a/app/Imports/Purchases/Payments.php b/app/Imports/Purchases/Payments.php index 6c6a20e9f..e5b9a9dde 100644 --- a/app/Imports/Purchases/Payments.php +++ b/app/Imports/Purchases/Payments.php @@ -5,7 +5,6 @@ namespace App\Imports\Purchases; use App\Abstracts\Import; use App\Models\Banking\Transaction as Model; use App\Http\Requests\Banking\Transaction as Request; -use App\Models\Purchase\Bill; class Payments extends Import { @@ -19,34 +18,10 @@ class Payments extends Import $row = parent::map($row); $row['type'] = 'expense'; - - if (empty($row['account_id']) && !empty($row['account_name'])) { - $row['account_id'] = $this->getAccountIdFromName($row); - } - - if (empty($row['account_id']) && !empty($row['account_number'])) { - $row['account_id'] = $this->getAccountIdFromNumber($row); - } - - if (empty($row['account_id']) && !empty($row['currency_code'])) { - $row['account_id'] = $this->getAccountIdFromCurrency($row); - } - - if (empty($row['contact_id']) && !empty($row['contact_name'])) { - $row['contact_id'] = $this->getContactIdFromName($row, 'vendor'); - } - - if (empty($row['contact_id']) && !empty($row['contact_email'])) { - $row['contact_id'] = $this->getContactIdFromEmail($row, 'vendor'); - } - - if (empty($row['category_id']) && !empty($row['category_name'])) { - $row['category_id'] = $this->getCategoryIdFromName($row, 'expense'); - } - - if (!empty($row['bill_number'])) { - $row['document_id'] = Bill::number($row['bill_number'])->pluck('id')->first(); - } + $row['account_id'] = $this->getAccountId($row); + $row['category_id'] = $this->getCategoryId($row, 'expense'); + $row['contact_id'] = $this->getContactId($row, 'vendor'); + $row['document_id'] = $this->getDocumentId($row); return $row; } diff --git a/app/Imports/Sales/Revenues.php b/app/Imports/Sales/Revenues.php index 57e4da863..babc5e92a 100644 --- a/app/Imports/Sales/Revenues.php +++ b/app/Imports/Sales/Revenues.php @@ -5,7 +5,6 @@ namespace App\Imports\Sales; use App\Abstracts\Import; use App\Http\Requests\Banking\Transaction as Request; use App\Models\Banking\Transaction as Model; -use App\Models\Sale\Invoice; class Revenues extends Import { @@ -19,34 +18,10 @@ class Revenues extends Import $row = parent::map($row); $row['type'] = 'income'; - - if (empty($row['account_id']) && !empty($row['account_name'])) { - $row['account_id'] = $this->getAccountIdFromName($row); - } - - if (empty($row['account_id']) && !empty($row['account_number'])) { - $row['account_id'] = $this->getAccountIdFromNumber($row); - } - - if (empty($row['account_id']) && !empty($row['currency_code'])) { - $row['account_id'] = $this->getAccountIdFromCurrency($row); - } - - if (empty($row['contact_id']) && !empty($row['contact_name'])) { - $row['contact_id'] = $this->getContactIdFromName($row, 'customer'); - } - - if (empty($row['contact_id']) && !empty($row['contact_email'])) { - $row['contact_id'] = $this->getContactIdFromEmail($row, 'customer'); - } - - if (empty($row['category_id']) && !empty($row['category_name'])) { - $row['category_id'] = $this->getCategoryIdFromName($row, 'income'); - } - - if (!empty($row['invoice_number'])) { - $row['document_id'] = Invoice::number($row['invoice_number'])->pluck('id')->first(); - } + $row['account_id'] = $this->getAccountId($row); + $row['category_id'] = $this->getCategoryId($row, 'income'); + $row['contact_id'] = $this->getContactId($row, 'customer'); + $row['document_id'] = $this->getDocumentId($row); return $row; } diff --git a/app/Imports/Sales/Sheets/InvoiceItemTaxes.php b/app/Imports/Sales/Sheets/InvoiceItemTaxes.php index 54a770c95..58ab7e812 100644 --- a/app/Imports/Sales/Sheets/InvoiceItemTaxes.php +++ b/app/Imports/Sales/Sheets/InvoiceItemTaxes.php @@ -35,13 +35,7 @@ class InvoiceItemTaxes extends Import $row['invoice_item_id'] = InvoiceItem::where('item_id', $item_id)->pluck('id')->first(); } - if (empty($row['tax_id']) && !empty($row['tax_name'])) { - $row['tax_id'] = Tax::name($row['tax_name'])->pluck('id')->first(); - } - - if (empty($row['tax_id']) && !empty($row['tax_rate'])) { - $row['tax_id'] = $this->getTaxIdFromRate($row); - } + $row['tax_id'] = $this->getTaxId($row); if (empty($row['name']) && !empty($row['item_name'])) { $row['name'] = $row['item_name']; diff --git a/app/Imports/Sales/Sheets/InvoiceTransactions.php b/app/Imports/Sales/Sheets/InvoiceTransactions.php index 429177e9d..1b4ec7e9f 100644 --- a/app/Imports/Sales/Sheets/InvoiceTransactions.php +++ b/app/Imports/Sales/Sheets/InvoiceTransactions.php @@ -5,7 +5,6 @@ namespace App\Imports\Sales\Sheets; use App\Abstracts\Import; use App\Http\Requests\Banking\Transaction as Request; use App\Models\Banking\Transaction as Model; -use App\Models\Sale\Invoice; class InvoiceTransactions extends Import { @@ -19,32 +18,10 @@ class InvoiceTransactions extends Import $row = parent::map($row); $row['type'] = 'income'; - - if (empty($row['account_id']) && !empty($row['account_name'])) { - $row['account_id'] = $this->getAccountIdFromName($row); - } - - if (empty($row['account_id']) && !empty($row['account_number'])) { - $row['account_id'] = $this->getAccountIdFromNumber($row); - } - - if (empty($row['account_id']) && !empty($row['currency_code'])) { - $row['account_id'] = $this->getAccountIdFromCurrency($row); - } - - if (empty($row['contact_id']) && !empty($row['contact_name'])) { - $row['contact_id'] = $this->getContactIdFromName($row, 'customer'); - } - - if (empty($row['contact_id']) && !empty($row['contact_email'])) { - $row['contact_id'] = $this->getContactIdFromEmail($row, 'customer'); - } - - if (empty($row['category_id']) && !empty($row['category_name'])) { - $row['category_id'] = $this->getCategoryIdFromName($row, 'income'); - } - - $row['document_id'] = Invoice::number($row['invoice_number'])->pluck('id')->first(); + $row['account_id'] = $this->getAccountId($row); + $row['category_id'] = $this->getCategoryId($row, 'income'); + $row['contact_id'] = $this->getContactId($row, 'customer'); + $row['document_id'] = $this->getDocumentId($row); return $row; } diff --git a/app/Imports/Sales/Sheets/Invoices.php b/app/Imports/Sales/Sheets/Invoices.php index 5d1afb140..d13377113 100644 --- a/app/Imports/Sales/Sheets/Invoices.php +++ b/app/Imports/Sales/Sheets/Invoices.php @@ -17,17 +17,8 @@ class Invoices extends Import { $row = parent::map($row); - if (empty($row['contact_id']) && !empty($row['contact_name'])) { - $row['contact_id'] = $this->getContactIdFromName($row, 'customer'); - } - - if (empty($row['contact_id']) && !empty($row['contact_email'])) { - $row['contact_id'] = $this->getContactIdFromEmail($row, 'customer'); - } - - if (empty($row['category_id']) && !empty($row['category_name'])) { - $row['category_id'] = $this->getCategoryIdFromName($row, 'income'); - } + $row['category_id'] = $this->getCategoryId($row, 'income'); + $row['contact_id'] = $this->getContactId($row, 'customer'); return $row; } diff --git a/app/Traits/Import.php b/app/Traits/Import.php new file mode 100644 index 000000000..704c4c578 --- /dev/null +++ b/app/Traits/Import.php @@ -0,0 +1,212 @@ +getAccountIdFromName($row); + } + + if (empty($id) && !empty($row['account_number'])) { + $id = $this->getAccountIdFromNumber($row); + } + + if (empty($id) && !empty($row['currency_code'])) { + $id = $this->getAccountIdFromCurrency($row); + } + + return $id; + } + + public function getCategoryId($row, $type = null) + { + $id = isset($row['category_id']) ? $row['category_id'] : null; + + $type = !empty($type) ? $type : (!empty($row['type']) ? $row['type'] : 'income'); + + if (empty($id) && !empty($row['category_name'])) { + $id = $this->getCategoryIdFromName($row, $type); + } + + return $id; + } + + public function getContactId($row, $type = null) + { + $id = isset($row['contact_id']) ? $row['contact_id'] : null; + + $type = !empty($type) ? $type : (!empty($row['type']) ? (($row['type'] == 'income') ? 'customer' : 'vendor') : 'customer'); + + if (empty($id) && !empty($row['contact_name'])) { + $id = $this->getContactIdFromName($row, $type); + } + + if (empty($row['contact_id']) && !empty($row['contact_email'])) { + $id = $this->getContactIdFromEmail($row, $type); + } + + return $id; + } + + public function getDocumentId($row) + { + $id = isset($row['document_id']) ? $row['document_id'] : null; + + if (empty($id) && !empty($row['invoice_number'])) { + $id = Invoice::number($row['invoice_number'])->pluck('id')->first(); + } + + if (empty($id) && !empty($row['bill_number'])) { + $id = Bill::number($row['bill_number'])->pluck('id')->first(); + } + + if (empty($id) && !empty($row['invoice_bill_number'])) { + if ($row['type'] == 'income') { + $id = Invoice::number($row['invoice_bill_number'])->pluck('id')->first(); + } else { + $id = Bill::number($row['invoice_bill_number'])->pluck('id')->first(); + } + } + + return $id; + } + + public function getItemId($row) + { + $id = isset($row['item_id']) ? $row['item_id'] : null; + + if (empty($id) && !empty($row['item_name'])) { + $id = $this->getItemIdFromName($row); + } + + return $id; + } + + public function getTaxId($row) + { + $id = isset($row['tax_id']) ? $row['tax_id'] : null; + + if (empty($id) && !empty($row['tax_name'])) { + $id = Tax::name($row['tax_name'])->pluck('id')->first(); + } + + if (empty($id) && !empty($row['tax_rate'])) { + $id = $this->getTaxIdFromRate($row); + } + + return $id; + } + + public function getAccountIdFromCurrency($row) + { + return Account::firstOrCreate([ + 'currency_code' => $row['currency_code'], + ], [ + 'company_id' => session('company_id'), + 'name' => $row['currency_code'], + 'number' => Account::max('number') + 1, + 'opening_balance' => 0, + 'enabled' => 1, + ])->id; + } + + public function getAccountIdFromName($row) + { + return Account::firstOrCreate([ + 'name' => $row['account_name'], + ], [ + 'company_id' => session('company_id'), + 'number' => Account::max('number') + 1, + 'currency_code' => setting('default.currency'), + 'opening_balance' => 0, + 'enabled' => 1, + ])->id; + } + + public function getAccountIdFromNumber($row) + { + return Account::firstOrCreate([ + 'number' => $row['account_number'], + ], [ + 'company_id' => session('company_id'), + 'name' => $row['account_number'], + 'currency_code' => setting('default.currency'), + 'opening_balance' => 0, + 'enabled' => 1, + ])->id; + } + + public function getCategoryIdFromName($row, $type) + { + return Category::firstOrCreate([ + 'name' => $row['category_name'], + ], [ + 'company_id' => session('company_id'), + 'type' => $type, + 'color' => '#' . dechex(rand(0x000000, 0xFFFFFF)), + 'enabled' => 1, + ])->id; + } + + public function getContactIdFromEmail($row, $type) + { + return Contact::firstOrCreate([ + 'email' => $row['contact_email'], + ], [ + 'company_id' => session('company_id'), + 'type' => $type, + 'name' => $row['contact_email'], + 'currency_code' => setting('default.currency'), + 'enabled' => 1, + ])->id; + } + + public function getContactIdFromName($row, $type) + { + return Contact::firstOrCreate([ + 'name' => $row['contact_name'], + ], [ + 'company_id' => session('company_id'), + 'type' => $type, + 'currency_code' => setting('default.currency'), + 'enabled' => 1, + ])->id; + } + + public function getItemIdFromName($row) + { + return Item::firstOrCreate([ + 'name' => $row['item_name'], + ], [ + 'company_id' => session('company_id'), + 'sale_price' => $row['price'], + 'purchase_price' => $row['price'], + 'enabled' => 1, + ])->id; + } + + public function getTaxIdFromRate($row, $type = 'normal') + { + return Tax::firstOrCreate([ + 'rate' => $row['tax_rate'], + ], [ + 'company_id' => session('company_id'), + 'type' => $type, + 'name' => $row['tax_rate'], + 'enabled' => 1, + ])->id; + } +} diff --git a/public/files/import/transactions.xlsx b/public/files/import/transactions.xlsx index 7b6db1042b1414146211b29c33b6c1becb01dec3..a84bce0ba2bfaf8a650ca802e565ef15c9440d65 100644 GIT binary patch literal 9445 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 A*8l(j From 1383dd47585f5eda99ba8eff6bf93cf67dc74f09 Mon Sep 17 00:00:00 2001 From: denisdulici Date: Tue, 21 Jan 2020 09:55:12 +0300 Subject: [PATCH 6/7] bills import/export --- .../Purchases/Sheets/BillHistories.php | 11 ++++- .../Purchases/Sheets/BillItemTaxes.php | 18 +++++--- app/Exports/Purchases/Sheets/BillItems.php | 15 +++++-- app/Exports/Purchases/Sheets/BillTotals.php | 10 ++++- .../Purchases/Sheets/BillTransactions.php | 20 ++++++--- app/Exports/Purchases/Sheets/Bills.php | 12 +++-- app/Http/Requests/Purchase/BillItemTax.php | 34 +++++++++++++++ .../Purchases/Sheets/BillHistories.php | 17 +++++++- .../Purchases/Sheets/BillItemTaxes.php | 41 ++++++++++++++++++ app/Imports/Purchases/Sheets/BillItems.php | 28 +++++++++++- app/Imports/Purchases/Sheets/BillTotals.php | 19 +++++++- .../Purchases/Sheets/BillTransactions.php | 10 ++++- app/Imports/Purchases/Sheets/Bills.php | 10 +++++ app/Imports/Sales/Sheets/InvoiceHistories.php | 5 +++ app/Imports/Sales/Sheets/InvoiceItemTaxes.php | 3 -- app/Traits/Import.php | 40 ++++++++--------- public/files/import/bills.xlsx | Bin 13882 -> 14059 bytes public/files/import/customers.xlsx | Bin 6595 -> 9034 bytes 18 files changed, 242 insertions(+), 51 deletions(-) create mode 100644 app/Http/Requests/Purchase/BillItemTax.php diff --git a/app/Exports/Purchases/Sheets/BillHistories.php b/app/Exports/Purchases/Sheets/BillHistories.php index 177bfbd9c..86b26b0f9 100644 --- a/app/Exports/Purchases/Sheets/BillHistories.php +++ b/app/Exports/Purchases/Sheets/BillHistories.php @@ -9,7 +9,7 @@ class BillHistories extends Export { public function collection() { - $model = Model::usingSearchString(request('search')); + $model = Model::with(['bill'])->usingSearchString(request('search')); if (!empty($this->ids)) { $model->whereIn('bill_id', (array) $this->ids); @@ -18,10 +18,17 @@ class BillHistories extends Export return $model->get(); } + public function map($model): array + { + $model->bill_number = $model->bill->bill_number; + + return parent::map($model); + } + public function fields(): array { return [ - 'bill_id', + 'bill_number', 'status', 'notify', 'description', diff --git a/app/Exports/Purchases/Sheets/BillItemTaxes.php b/app/Exports/Purchases/Sheets/BillItemTaxes.php index 46ff81c08..7ceed7662 100644 --- a/app/Exports/Purchases/Sheets/BillItemTaxes.php +++ b/app/Exports/Purchases/Sheets/BillItemTaxes.php @@ -9,7 +9,7 @@ class BillItemTaxes extends Export { public function collection() { - $model = Model::usingSearchString(request('search')); + $model = Model::with(['bill', 'item', 'tax'])->usingSearchString(request('search')); if (!empty($this->ids)) { $model->whereIn('bill_id', (array) $this->ids); @@ -18,13 +18,21 @@ class BillItemTaxes extends Export return $model->get(); } + public function map($model): array + { + $model->bill_number = $model->bill->bill_number; + $model->item_name = $model->item->name; + $model->tax_rate = $model->tax->rate; + + return parent::map($model); + } + public function fields(): array { return [ - 'bill_id', - 'bill_item_id', - 'tax_id', - 'name', + 'bill_number', + 'item_name', + 'tax_rate', 'amount', ]; } diff --git a/app/Exports/Purchases/Sheets/BillItems.php b/app/Exports/Purchases/Sheets/BillItems.php index a77ef4c5a..b131339f2 100644 --- a/app/Exports/Purchases/Sheets/BillItems.php +++ b/app/Exports/Purchases/Sheets/BillItems.php @@ -9,7 +9,7 @@ class BillItems extends Export { public function collection() { - $model = Model::usingSearchString(request('search')); + $model = Model::with(['bill', 'item'])->usingSearchString(request('search')); if (!empty($this->ids)) { $model->whereIn('bill_id', (array) $this->ids); @@ -18,12 +18,19 @@ class BillItems extends Export return $model->get(); } + public function map($model): array + { + $model->bill_number = $model->bill->bill_number; + $model->item_name = $model->item->name; + + return parent::map($model); + } + public function fields(): array { return [ - 'bill_id', - 'item_id', - 'name', + 'bill_number', + 'item_name', 'quantity', 'price', 'total', diff --git a/app/Exports/Purchases/Sheets/BillTotals.php b/app/Exports/Purchases/Sheets/BillTotals.php index 2cc0ea82f..388574f5d 100644 --- a/app/Exports/Purchases/Sheets/BillTotals.php +++ b/app/Exports/Purchases/Sheets/BillTotals.php @@ -9,7 +9,7 @@ class BillTotals extends Export { public function collection() { - $model = Model::usingSearchString(request('search')); + $model = Model::with(['bill'])->usingSearchString(request('search')); if (!empty($this->ids)) { $model->whereIn('bill_id', (array) $this->ids); @@ -18,11 +18,17 @@ class BillTotals extends Export return $model->get(); } + public function map($model): array + { + $model->bill_number = $model->bill->bill_number; + + return parent::map($model); + } public function fields(): array { return [ - 'bill_id', + 'bill_number', 'code', 'name', 'amount', diff --git a/app/Exports/Purchases/Sheets/BillTransactions.php b/app/Exports/Purchases/Sheets/BillTransactions.php index 7325ad2b6..7b19345fc 100644 --- a/app/Exports/Purchases/Sheets/BillTransactions.php +++ b/app/Exports/Purchases/Sheets/BillTransactions.php @@ -9,7 +9,7 @@ class BillTransactions extends Export { public function collection() { - $model = Model::type('expense')->isDocument()->usingSearchString(request('search')); + $model = Model::with(['account', 'category', 'contact', 'bill'])->type('expense')->isDocument()->usingSearchString(request('search')); if (!empty($this->ids)) { $model->whereIn('document_id', (array) $this->ids); @@ -18,17 +18,27 @@ class BillTransactions extends Export return $model->get(); } + public function map($model): array + { + $model->bill_number = $model->bill->bill_number; + $model->account_name = $model->account->name; + $model->category_name = $model->category->name; + $model->contact_email = $model->contact->email; + + return parent::map($model); + } + public function fields(): array { return [ + 'bill_number', 'paid_at', 'amount', 'currency_code', 'currency_rate', - 'account_id', - 'document_id', - 'contact_id', - 'category_id', + 'account_name', + 'contact_email', + 'category_name', 'description', 'payment_method', 'reference', diff --git a/app/Exports/Purchases/Sheets/Bills.php b/app/Exports/Purchases/Sheets/Bills.php index 6e674c6aa..2cf71415e 100644 --- a/app/Exports/Purchases/Sheets/Bills.php +++ b/app/Exports/Purchases/Sheets/Bills.php @@ -9,7 +9,7 @@ class Bills extends Export { public function collection() { - $model = Model::usingSearchString(request('search')); + $model = Model::with(['category'])->usingSearchString(request('search')); if (!empty($this->ids)) { $model->whereIn('id', (array) $this->ids); @@ -18,6 +18,13 @@ class Bills extends Export return $model->get(); } + public function map($model): array + { + $model->category_name = $model->category->name; + + return parent::map($model); + } + public function fields(): array { return [ @@ -29,8 +36,7 @@ class Bills extends Export 'amount', 'currency_code', 'currency_rate', - 'category_id', - 'contact_id', + 'category_name', 'contact_name', 'contact_email', 'contact_tax_number', diff --git a/app/Http/Requests/Purchase/BillItemTax.php b/app/Http/Requests/Purchase/BillItemTax.php new file mode 100644 index 000000000..c60c0828b --- /dev/null +++ b/app/Http/Requests/Purchase/BillItemTax.php @@ -0,0 +1,34 @@ + 'required|integer', + 'bill_item_id' => 'required|integer', + 'tax_id' => 'required|integer', + 'name' => 'required|string', + 'amount' => 'required', + ]; + } +} diff --git a/app/Imports/Purchases/Sheets/BillHistories.php b/app/Imports/Purchases/Sheets/BillHistories.php index 6a3d18e38..b534ef5cf 100644 --- a/app/Imports/Purchases/Sheets/BillHistories.php +++ b/app/Imports/Purchases/Sheets/BillHistories.php @@ -3,13 +3,19 @@ namespace App\Imports\Purchases\Sheets; use App\Abstracts\Import; -use App\Models\Purchase\BillHistory as Model; use App\Http\Requests\Purchase\BillHistory as Request; +use App\Models\Purchase\Bill; +use App\Models\Purchase\BillHistory as Model; class BillHistories extends Import { public function model(array $row) { + // @todo remove after 3.2 release + if ($row['bill_number'] == $this->empty_field) { + return null; + } + return new Model($row); } @@ -17,6 +23,8 @@ class BillHistories extends Import { $row = parent::map($row); + $row['bill_id'] = Bill::number($row['bill_number'])->pluck('id')->first(); + $row['notify'] = (int) $row['notify']; return $row; @@ -24,6 +32,11 @@ class BillHistories extends Import public function rules(): array { - return (new Request())->rules(); + $rules = (new Request())->rules(); + + $rules['bill_number'] = 'required|string'; + unset($rules['bill_id']); + + return $rules; } } diff --git a/app/Imports/Purchases/Sheets/BillItemTaxes.php b/app/Imports/Purchases/Sheets/BillItemTaxes.php index f0ba171a8..817ccb955 100644 --- a/app/Imports/Purchases/Sheets/BillItemTaxes.php +++ b/app/Imports/Purchases/Sheets/BillItemTaxes.php @@ -3,12 +3,53 @@ namespace App\Imports\Purchases\Sheets; use App\Abstracts\Import; +use App\Http\Requests\Purchase\BillItemTax as Request; +use App\Models\Common\Item; +use App\Models\Purchase\Bill; +use App\Models\Purchase\BillItem; use App\Models\Purchase\BillItemTax as Model; class BillItemTaxes extends Import { public function model(array $row) { + // @todo remove after 3.2 release + if ($row['bill_number'] == $this->empty_field) { + return null; + } + return new Model($row); } + + public function map($row): array + { + $row = parent::map($row); + + $row['bill_id'] = Bill::number($row['bill_number'])->pluck('id')->first(); + + if (empty($row['invoice_item_id']) && !empty($row['item_name'])) { + $item_id = Item::name($row['item_name'])->pluck('id')->first(); + $row['invoice_item_id'] = BillItem::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']; + + return $row; + } + + public function rules(): array + { + $rules = (new Request())->rules(); + + $rules['bill_number'] = 'required|string'; + unset($rules['bill_id']); + + return $rules; + } } diff --git a/app/Imports/Purchases/Sheets/BillItems.php b/app/Imports/Purchases/Sheets/BillItems.php index 51acb287d..5e1f254e9 100644 --- a/app/Imports/Purchases/Sheets/BillItems.php +++ b/app/Imports/Purchases/Sheets/BillItems.php @@ -3,8 +3,9 @@ namespace App\Imports\Purchases\Sheets; use App\Abstracts\Import; -use App\Models\Purchase\BillItem as Model; use App\Http\Requests\Purchase\BillItem as Request; +use App\Models\Purchase\Bill; +use App\Models\Purchase\BillItem as Model; class BillItems extends Import { @@ -13,8 +14,31 @@ class BillItems extends Import return new Model($row); } + public function map($row): array + { + $row = parent::map($row); + + $row['bill_id'] = Bill::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['tax'] = (double) $row['tax']; + $row['tax_id'] = 0; + + return $row; + } + public function rules(): array { - return (new Request())->rules(); + $rules = (new Request())->rules(); + + $rules['bill_number'] = 'required|string'; + unset($rules['bill_id']); + + return $rules; } } diff --git a/app/Imports/Purchases/Sheets/BillTotals.php b/app/Imports/Purchases/Sheets/BillTotals.php index 18b93a0a2..b425d9f26 100644 --- a/app/Imports/Purchases/Sheets/BillTotals.php +++ b/app/Imports/Purchases/Sheets/BillTotals.php @@ -3,8 +3,9 @@ namespace App\Imports\Purchases\Sheets; use App\Abstracts\Import; -use App\Models\Purchase\BillTotal as Model; use App\Http\Requests\Purchase\BillTotal as Request; +use App\Models\Purchase\Bill; +use App\Models\Purchase\BillTotal as Model; class BillTotals extends Import { @@ -13,8 +14,22 @@ class BillTotals extends Import return new Model($row); } + public function map($row): array + { + $row = parent::map($row); + + $row['bill_id'] = Bill::number($row['bill_number'])->pluck('id')->first(); + + return $row; + } + public function rules(): array { - return (new Request())->rules(); + $rules = (new Request())->rules(); + + $rules['bill_number'] = 'required|string'; + unset($rules['bill_id']); + + return $rules; } } diff --git a/app/Imports/Purchases/Sheets/BillTransactions.php b/app/Imports/Purchases/Sheets/BillTransactions.php index dcbafbf0c..6f6952687 100644 --- a/app/Imports/Purchases/Sheets/BillTransactions.php +++ b/app/Imports/Purchases/Sheets/BillTransactions.php @@ -18,12 +18,20 @@ class BillTransactions extends Import $row = parent::map($row); $row['type'] = 'expense'; + $row['account_id'] = $this->getAccountId($row); + $row['category_id'] = $this->getCategoryId($row, 'expense'); + $row['contact_id'] = $this->getContactId($row, 'vendor'); + $row['document_id'] = $this->getDocumentId($row); return $row; } public function rules(): array { - return (new Request())->rules(); + $rules = (new Request())->rules(); + + $rules['bill_number'] = 'required|string'; + + return $rules; } } diff --git a/app/Imports/Purchases/Sheets/Bills.php b/app/Imports/Purchases/Sheets/Bills.php index f50ca9d45..768b1fa97 100644 --- a/app/Imports/Purchases/Sheets/Bills.php +++ b/app/Imports/Purchases/Sheets/Bills.php @@ -13,6 +13,16 @@ class Bills extends Import return new Model($row); } + public function map($row): array + { + $row = parent::map($row); + + $row['category_id'] = $this->getCategoryId($row, 'expense'); + $row['contact_id'] = $this->getContactId($row, 'vendor'); + + return $row; + } + public function rules(): array { return (new Request())->rules(); diff --git a/app/Imports/Sales/Sheets/InvoiceHistories.php b/app/Imports/Sales/Sheets/InvoiceHistories.php index f4b09d503..a40afcdd2 100644 --- a/app/Imports/Sales/Sheets/InvoiceHistories.php +++ b/app/Imports/Sales/Sheets/InvoiceHistories.php @@ -11,6 +11,11 @@ class InvoiceHistories extends Import { public function model(array $row) { + // @todo remove after 3.2 release + if ($row['invoice_number'] == $this->empty_field) { + return null; + } + return new Model($row); } diff --git a/app/Imports/Sales/Sheets/InvoiceItemTaxes.php b/app/Imports/Sales/Sheets/InvoiceItemTaxes.php index 58ab7e812..68cfaf91a 100644 --- a/app/Imports/Sales/Sheets/InvoiceItemTaxes.php +++ b/app/Imports/Sales/Sheets/InvoiceItemTaxes.php @@ -8,7 +8,6 @@ use App\Models\Common\Item; use App\Models\Sale\Invoice; use App\Models\Sale\InvoiceItem; use App\Models\Sale\InvoiceItemTax as Model; -use App\Models\Setting\Tax; class InvoiceItemTaxes extends Import { @@ -19,8 +18,6 @@ class InvoiceItemTaxes extends Import return null; } - $row['invoice_id'] = Invoice::number($row['invoice_number'])->pluck('id')->first(); - return new Model($row); } diff --git a/app/Traits/Import.php b/app/Traits/Import.php index 704c4c578..5644300f8 100644 --- a/app/Traits/Import.php +++ b/app/Traits/Import.php @@ -50,14 +50,14 @@ trait Import $type = !empty($type) ? $type : (!empty($row['type']) ? (($row['type'] == 'income') ? 'customer' : 'vendor') : 'customer'); - if (empty($id) && !empty($row['contact_name'])) { - $id = $this->getContactIdFromName($row, $type); - } - if (empty($row['contact_id']) && !empty($row['contact_email'])) { $id = $this->getContactIdFromEmail($row, $type); } + if (empty($id) && !empty($row['contact_name'])) { + $id = $this->getContactIdFromName($row, $type); + } + return $id; } @@ -116,9 +116,9 @@ trait Import 'currency_code' => $row['currency_code'], ], [ 'company_id' => session('company_id'), - 'name' => $row['currency_code'], - 'number' => Account::max('number') + 1, - 'opening_balance' => 0, + 'name' => !empty($row['account_name']) ? $row['account_name'] : $row['currency_code'], + 'number' => !empty($row['account_number']) ? $row['account_number'] : Account::max('number') + 1, + 'opening_balance' => !empty($row['opening_balance']) ? $row['opening_balance'] : 0, 'enabled' => 1, ])->id; } @@ -129,9 +129,9 @@ trait Import 'name' => $row['account_name'], ], [ 'company_id' => session('company_id'), - 'number' => Account::max('number') + 1, - 'currency_code' => setting('default.currency'), - 'opening_balance' => 0, + 'number' => !empty($row['account_number']) ? $row['account_number'] : Account::max('number') + 1, + 'currency_code' => !empty($row['currency_code']) ? $row['currency_code'] : setting('default.currency'), + 'opening_balance' => !empty($row['opening_balance']) ? $row['opening_balance'] : 0, 'enabled' => 1, ])->id; } @@ -142,9 +142,9 @@ trait Import 'number' => $row['account_number'], ], [ 'company_id' => session('company_id'), - 'name' => $row['account_number'], - 'currency_code' => setting('default.currency'), - 'opening_balance' => 0, + 'name' => !empty($row['account_name']) ? $row['account_name'] : $row['account_number'], + 'currency_code' => !empty($row['currency_code']) ? $row['currency_code'] : setting('default.currency'), + 'opening_balance' => !empty($row['opening_balance']) ? $row['opening_balance'] : 0, 'enabled' => 1, ])->id; } @@ -156,7 +156,7 @@ trait Import ], [ 'company_id' => session('company_id'), 'type' => $type, - 'color' => '#' . dechex(rand(0x000000, 0xFFFFFF)), + 'color' => !empty($row['category_color']) ? $row['category_color'] : '#' . dechex(rand(0x000000, 0xFFFFFF)), 'enabled' => 1, ])->id; } @@ -168,8 +168,8 @@ trait Import ], [ 'company_id' => session('company_id'), 'type' => $type, - 'name' => $row['contact_email'], - 'currency_code' => setting('default.currency'), + 'name' => !empty($row['contact_name']) ? $row['contact_name'] : $row['contact_email'], + 'currency_code' => !empty($row['contact_currency']) ? $row['contact_currency'] : setting('default.currency'), 'enabled' => 1, ])->id; } @@ -181,7 +181,7 @@ trait Import ], [ 'company_id' => session('company_id'), 'type' => $type, - 'currency_code' => setting('default.currency'), + 'currency_code' => !empty($row['contact_currency']) ? $row['contact_currency'] : setting('default.currency'), 'enabled' => 1, ])->id; } @@ -192,8 +192,8 @@ trait Import 'name' => $row['item_name'], ], [ 'company_id' => session('company_id'), - 'sale_price' => $row['price'], - 'purchase_price' => $row['price'], + 'sale_price' => !empty($row['sale_price']) ? $row['sale_price'] : $row['price'], + 'purchase_price' => !empty($row['purchase_price']) ? $row['purchase_price'] : $row['price'], 'enabled' => 1, ])->id; } @@ -205,7 +205,7 @@ trait Import ], [ 'company_id' => session('company_id'), 'type' => $type, - 'name' => $row['tax_rate'], + 'name' => !empty($row['tax_name']) ? $row['tax_name'] : $row['tax_rate'], 'enabled' => 1, ])->id; } diff --git a/public/files/import/bills.xlsx b/public/files/import/bills.xlsx index a9703953135ae1d943f04c5c62aa45354672fb89..053cd85099cb889dd33625e76b14ef0d53e75fcc 100644 GIT binary patch literal 14059 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

-75I@Z#2tFkF@Q|HCPT-57*?@?S*|2q*eFd zxfK*g$3Viygyc?~lCNxehneJb06P@QGrkzA=n&Y3eLZR3+*>MKK>~6Z{Bp!uB85vV z(wC=}V}|Chp|(8i*$0zfR(RCi0i`yYXozZc6y{G|)HH3tR8-2l;dl8E0tTlCVnsdTpJW_OhO!b9S*vxo z3VGzIG46blNNP2~!bVI7s|=A2_)0U)y5Q5U?k_SghtaD0(UYu?)Xk6C9tRG#D)nC4 zG)d)<6YQk*+RN6RvwaN{ntb=q-bVzB}5sF>pP_lve8A~*QNaL`Y1s*6FmY#wv)*4;2X z6Fi|YrxVN60lzfXarvHfm(|A=me{Z4$Og>*5YaJ{-wSF!&AbEWy!u%z#9Z@{Zq&I{{%Q!1)n>vPGrj5h(;>G*6YPkoPmI#f3dpkl0>G8!u7@!KrzffRAgZ5<09nlPylX3wp2Y285sibU}S{0M5> znF$vTNYYF%lMBr0AR}Yt)7t@9B=qJMmK|xI#gln|etfr)+Urrl2RofFW+de8(EN0_ zk`a~?EF@QH72Odqdv$^OXflU9kmka8y@#{DIct^oUvrczY$g*uY5FGsbmK#>VbE({a+2j)InVVK?TA3bQpl|mwadA7Cn`1#=+|00!*3U7$heFHxx zcpTo(;jY_wYJRGI+LKh|a0`(siMFH#p!X00n~+sh$)`NN_d$O>9Tc3}O@&Z9j;axX5+O|?Ax zsB2=DWI#=NgnJ|go}k=yT|q@os*d4#(-zYN89ghGiBRK!j3r0v?QD&xM*U}V+*I~` z0RI_6JrVUyIK0`9;ak@8za$P=f7_3$mQ6Z6hF5m|tM5-5*u=h7gg0?iTv;YG`kq z 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%0DkU~dq&_;rQot)Jv!Kt*sHU00t|x7 zr!GUB;C+9K%UzC|d`+kmC^7ugM}rXY?eLe7ND^nqmW(8G;BJRnCQ z^c+?c5*RVN$(>6Gn`P3Dh%y@w=&DFU;Bw202E>TPF-lO8*f>*RO{Tr}vg9@8+ZiE( zB=V)&$Ah2s2r~l;@>ZE!z!uM4_NA+dVw7|UJ;BGhWGxCpprKa1oojT3$hzDzNVeCK z-H0J{1%o#dl)>8UfthST{b?INCDO%HjJ+_X5TmPRGM3i-p7mCcB`+Ok;luXIcG|a) zrHaU<2l|yH1}%J(I!2S7K4L0EBz#gGOb0I+gWJ(D?|0W&BOx?ozv_+~-mZav)gEgJ z*;qRoTRZA1yV)8$eEj8c#*;Q=d+AX^&SX483Y$!*a*zx$wD0#7CHlcjPB66=my3!C z+B-}^rHLV=>9Oi3n+ z3XP!oT26JfA4H*{(dT`Nq8ROHy35EP%SB4Xfc~t?xI?*hI3Lx5YEL-W%~heAB9+f$ zhX2GFaN`jZ8)kl(U(CUy^O>DIP6U25iiOI!ceysUH-RGCyg?vLEijO>4{r=QLam_Z zURAK;l1oqJPBPyv$lr`S!v_)7+}3z^3Ns=jFn*0fi&-Wa6^YzXa~cAvL`yZtKq_w2 z6L4dKYiWkv3{H2lq|#bCBacnRVNbM=u^$H_I|avKi@(E7%!U|GM(l{6d<@W2g_N&$ zp=zYDW&zJzq4z7O-~nE3aSW7eb7Kr1f9MkMPiE^&{jpuM#l3p-9}*-`UT-x&h%<*u z;};)aQNBDu_rUUSlHm>O@>EXt@9ar)TTk}qKW*S~|8#uPm6rkpLirsd{LxDBUSn@c z0{{ddc>CQ=_pkc<1K_`Vt6u!vEgs-_P4G6*QEd3=J1~VeLeo)?80vs zzJIg-Rh|F;E&7e)&+%)~4j_NltN&W=zpLb*Qc|G(&G5f2@Sjq8?*xBM^oNvO|C8z`}Sd%IWv>l*I;jPLL3{+{vc zf3p33d-opTeVp|-fFjlJdH+*v|KCIZYBBg@{L*mZ9~%C}{8z)lKehJ0<=_|Zp9cJY zc>iudc>nnCYn=Z^NrL$6@&9~+-!H!_p5LRqF9iJ?rSUCDc@zGBtm8Mz@3PSMDDMmF z{zfT(6VAV&{4TS5kMh1E>2H*lx9+5WLHS*u^d9AXUB=%i4{zVI{srZCm4>_&=&!&H R0PXF^_${QcW%%{(e*h8dvb_KR literal 13882 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 S;H@1EBxrO)u|um1-mJ$NVp diff --git a/public/files/import/customers.xlsx b/public/files/import/customers.xlsx index 286a860322be008a8d2b0332f463e6fb4eb5fc5d..06c6044a1b007fa05180f8aaff11b90098ec89b1 100644 GIT binary patch literal 9034 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 literal 6595 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 Date: Tue, 21 Jan 2020 09:56:45 +0300 Subject: [PATCH 7/7] styling --- app/Abstracts/Import.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Abstracts/Import.php b/app/Abstracts/Import.php index 66f5edefa..a84907497 100644 --- a/app/Abstracts/Import.php +++ b/app/Abstracts/Import.php @@ -2,7 +2,7 @@ namespace App\Abstracts; -use App\Traits\Import as ImportHelpers; +use App\Traits\Import as ImportHelper; use Illuminate\Support\Str; use Jenssegers\Date\Date; use Maatwebsite\Excel\Concerns\Importable; @@ -18,7 +18,7 @@ use Maatwebsite\Excel\Validators\Failure; abstract class Import implements ToModel, SkipsOnError, SkipsOnFailure, WithBatchInserts, WithChunkReading, WithHeadingRow, WithMapping, WithValidation { - use Importable, ImportHelpers; + use Importable, ImportHelper; public $empty_field = 'empty---';