diff --git a/app/Abstracts/Import.php b/app/Abstracts/Import.php index 6a67407dd..ebd1fe995 100644 --- a/app/Abstracts/Import.php +++ b/app/Abstracts/Import.php @@ -4,7 +4,10 @@ namespace App\Abstracts; use Illuminate\Support\Str; use Jenssegers\Date\Date; +use Maatwebsite\Excel\Concerns\Importable; use Maatwebsite\Excel\Concerns\ToModel; +use Maatwebsite\Excel\Concerns\SkipsOnError; +use Maatwebsite\Excel\Concerns\SkipsOnFailure; use Maatwebsite\Excel\Concerns\WithBatchInserts; use Maatwebsite\Excel\Concerns\WithChunkReading; use Maatwebsite\Excel\Concerns\WithHeadingRow; @@ -12,8 +15,12 @@ use Maatwebsite\Excel\Concerns\WithMapping; use Maatwebsite\Excel\Concerns\WithValidation; use Maatwebsite\Excel\Validators\Failure; -abstract class Import implements ToModel, WithBatchInserts, WithChunkReading, WithHeadingRow, WithMapping, WithValidation +abstract class Import implements ToModel, SkipsOnError, SkipsOnFailure, WithBatchInserts, WithChunkReading, WithHeadingRow, WithMapping, WithValidation { + use Importable; + + public $empty_field = 'empty---'; + public function map($row): array { $row['company_id'] = session('company_id'); @@ -60,13 +67,23 @@ abstract class Import implements ToModel, WithBatchInserts, WithChunkReading, Wi $sheet = Str::snake((new \ReflectionClass($this))->getShortName()); foreach ($failures as $failure) { + // @todo remove after 3.2 release https://github.com/Maatwebsite/Laravel-Excel/issues/1834#issuecomment-474340743 + if (collect($failure->values())->first() == $this->empty_field) { + continue; + } + $message = trans('messages.error.import_column', [ - 'message' => $failure->errors()->first(), + 'message' => collect($failure->errors())->first(), 'sheet' => $sheet, - 'line' => $failure->attribute(), + 'line' => $failure->row(), ]); flash($message)->error()->important(); } } + + public function onError(\Throwable $e) + { + flash($e->getMessage())->error()->important(); + } } diff --git a/app/Exports/Sales/Sheets/InvoiceHistories.php b/app/Exports/Sales/Sheets/InvoiceHistories.php index 7acdc0475..c31082d2e 100644 --- a/app/Exports/Sales/Sheets/InvoiceHistories.php +++ b/app/Exports/Sales/Sheets/InvoiceHistories.php @@ -9,7 +9,7 @@ class InvoiceHistories extends Export { public function collection() { - $model = Model::usingSearchString(request('search')); + $model = Model::with(['invoice'])->usingSearchString(request('search')); if (!empty($this->ids)) { $model->whereIn('invoice_id', (array) $this->ids); @@ -18,10 +18,17 @@ class InvoiceHistories extends Export return $model->get(); } + public function map($model): array + { + $model->invoice_number = $model->invoice->invoice_number; + + return parent::map($model); + } + public function fields(): array { return [ - 'invoice_id', + 'invoice_number', 'status', 'notify', 'description', diff --git a/app/Exports/Sales/Sheets/InvoiceItemTaxes.php b/app/Exports/Sales/Sheets/InvoiceItemTaxes.php index e5ff48592..fac9553d7 100644 --- a/app/Exports/Sales/Sheets/InvoiceItemTaxes.php +++ b/app/Exports/Sales/Sheets/InvoiceItemTaxes.php @@ -9,7 +9,7 @@ class InvoiceItemTaxes extends Export { public function collection() { - $model = Model::usingSearchString(request('search')); + $model = Model::with(['invoice', 'item', 'tax'])->usingSearchString(request('search')); if (!empty($this->ids)) { $model->whereIn('invoice_id', (array) $this->ids); @@ -18,13 +18,21 @@ class InvoiceItemTaxes extends Export return $model->get(); } + public function map($model): array + { + $model->invoice_number = $model->invoice->invoice_number; + $model->item_name = $model->item->name; + $model->tax_rate = $model->tax->rate; + + return parent::map($model); + } + public function fields(): array { return [ - 'invoice_id', - 'invoice_item_id', - 'tax_id', - 'name', + 'invoice_number', + 'item_name', + 'tax_rate', 'amount', ]; } diff --git a/app/Exports/Sales/Sheets/InvoiceItems.php b/app/Exports/Sales/Sheets/InvoiceItems.php index bcbe876e5..5705cb52c 100644 --- a/app/Exports/Sales/Sheets/InvoiceItems.php +++ b/app/Exports/Sales/Sheets/InvoiceItems.php @@ -9,7 +9,7 @@ class InvoiceItems extends Export { public function collection() { - $model = Model::usingSearchString(request('search')); + $model = Model::with(['invoice', 'item'])->usingSearchString(request('search')); if (!empty($this->ids)) { $model->whereIn('invoice_id', (array) $this->ids); @@ -18,12 +18,19 @@ class InvoiceItems extends Export return $model->get(); } + public function map($model): array + { + $model->invoice_number = $model->invoice->invoice_number; + $model->item_name = $model->item->name; + + return parent::map($model); + } + public function fields(): array { return [ - 'invoice_id', - 'item_id', - 'name', + 'invoice_number', + 'item_name', 'quantity', 'price', 'total', diff --git a/app/Exports/Sales/Sheets/InvoiceTotals.php b/app/Exports/Sales/Sheets/InvoiceTotals.php index 461d95517..7c8ac4b43 100644 --- a/app/Exports/Sales/Sheets/InvoiceTotals.php +++ b/app/Exports/Sales/Sheets/InvoiceTotals.php @@ -9,7 +9,7 @@ class InvoiceTotals extends Export { public function collection() { - $model = Model::usingSearchString(request('search')); + $model = Model::with(['invoice'])->usingSearchString(request('search')); if (!empty($this->ids)) { $model->whereIn('invoice_id', (array) $this->ids); @@ -18,10 +18,17 @@ class InvoiceTotals extends Export return $model->get(); } + public function map($model): array + { + $model->invoice_number = $model->invoice->invoice_number; + + return parent::map($model); + } + public function fields(): array { return [ - 'invoice_id', + 'invoice_number', 'code', 'name', 'amount', diff --git a/app/Exports/Sales/Sheets/InvoiceTransactions.php b/app/Exports/Sales/Sheets/InvoiceTransactions.php index 7a3beb61c..b4d7f660d 100644 --- a/app/Exports/Sales/Sheets/InvoiceTransactions.php +++ b/app/Exports/Sales/Sheets/InvoiceTransactions.php @@ -9,7 +9,7 @@ class InvoiceTransactions extends Export { public function collection() { - $model = Model::type('income')->isDocument()->usingSearchString(request('search')); + $model = Model::with(['account', 'category', 'contact', 'invoice'])->type('income')->isDocument()->usingSearchString(request('search')); if (!empty($this->ids)) { $model->whereIn('document_id', (array) $this->ids); @@ -18,17 +18,27 @@ class InvoiceTransactions extends Export return $model->get(); } + public function map($model): array + { + $model->invoice_number = $model->invoice->invoice_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 [ + 'invoice_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/Sales/Sheets/Invoices.php b/app/Exports/Sales/Sheets/Invoices.php index de56cebde..653611742 100644 --- a/app/Exports/Sales/Sheets/Invoices.php +++ b/app/Exports/Sales/Sheets/Invoices.php @@ -9,7 +9,7 @@ class Invoices 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 Invoices 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 Invoices 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/Sale/InvoiceItemTax.php b/app/Http/Requests/Sale/InvoiceItemTax.php new file mode 100644 index 000000000..b072fabf8 --- /dev/null +++ b/app/Http/Requests/Sale/InvoiceItemTax.php @@ -0,0 +1,34 @@ + 'required|integer', + 'invoice_item_id' => 'required|integer', + 'tax_id' => 'required|integer', + 'name' => 'required|string', + 'amount' => 'required', + ]; + } +} diff --git a/app/Imports/Sales/Invoices.php b/app/Imports/Sales/Invoices.php index 6edd87328..ad99d8689 100644 --- a/app/Imports/Sales/Invoices.php +++ b/app/Imports/Sales/Invoices.php @@ -7,7 +7,7 @@ use App\Imports\Sales\Sheets\InvoiceItems; use App\Imports\Sales\Sheets\InvoiceItemTaxes; use App\Imports\Sales\Sheets\InvoiceHistories; use App\Imports\Sales\Sheets\InvoiceTotals; -use App\Imports\Sales\Sheets\InvoiceTranactions; +use App\Imports\Sales\Sheets\InvoiceTransactions; use Maatwebsite\Excel\Concerns\WithMultipleSheets; class Invoices implements WithMultipleSheets @@ -20,7 +20,7 @@ class Invoices implements WithMultipleSheets 'invoice_item_taxes' => new InvoiceItemTaxes(), 'invoice_histories' => new InvoiceHistories(), 'invoice_totals' => new InvoiceTotals(), - 'invoice_transactions' => new InvoiceTranactions(), + 'invoice_transactions' => new InvoiceTransactions(), ]; } } diff --git a/app/Imports/Sales/Sheets/InvoiceHistories.php b/app/Imports/Sales/Sheets/InvoiceHistories.php index 24848d997..f4b09d503 100644 --- a/app/Imports/Sales/Sheets/InvoiceHistories.php +++ b/app/Imports/Sales/Sheets/InvoiceHistories.php @@ -3,8 +3,9 @@ namespace App\Imports\Sales\Sheets; use App\Abstracts\Import; -use App\Models\Sale\InvoiceHistory as Model; use App\Http\Requests\Sale\InvoiceHistory as Request; +use App\Models\Sale\Invoice; +use App\Models\Sale\InvoiceHistory as Model; class InvoiceHistories extends Import { @@ -17,6 +18,8 @@ class InvoiceHistories extends Import { $row = parent::map($row); + $row['invoice_id'] = Invoice::number($row['invoice_number'])->pluck('id')->first(); + $row['notify'] = (int) $row['notify']; return $row; @@ -24,6 +27,11 @@ class InvoiceHistories extends Import public function rules(): array { - return (new Request())->rules(); + $rules = (new Request())->rules(); + + $rules['invoice_number'] = 'required|string'; + unset($rules['invoice_id']); + + return $rules; } } diff --git a/app/Imports/Sales/Sheets/InvoiceItemTaxes.php b/app/Imports/Sales/Sheets/InvoiceItemTaxes.php index f6100e4ab..0dbf13c2c 100644 --- a/app/Imports/Sales/Sheets/InvoiceItemTaxes.php +++ b/app/Imports/Sales/Sheets/InvoiceItemTaxes.php @@ -3,12 +3,69 @@ namespace App\Imports\Sales\Sheets; use App\Abstracts\Import; +use App\Http\Requests\Sale\InvoiceItemTax as Request; +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 { public function model(array $row) { + // @todo remove after 3.2 release + if ($row['invoice_number'] == $this->empty_field) { + return null; + } + + $row['invoice_id'] = Invoice::number($row['invoice_number'])->pluck('id')->first(); + return new Model($row); } + + public function map($row): array + { + $row = parent::map($row); + + $row['invoice_id'] = Invoice::number($row['invoice_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'] = 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'] = Tax::firstOrCreate([ + 'rate' => $row['tax_rate'], + ], [ + 'company_id' => session('company_id'), + 'type' => 'normal', + 'name' => $row['tax_rate'], + 'enabled' => 1, + ])->id; + } + + 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['invoice_number'] = 'required|string'; + unset($rules['invoice_id']); + + return $rules; + } } diff --git a/app/Imports/Sales/Sheets/InvoiceItems.php b/app/Imports/Sales/Sheets/InvoiceItems.php index 0f5ebf726..8872923b9 100644 --- a/app/Imports/Sales/Sheets/InvoiceItems.php +++ b/app/Imports/Sales/Sheets/InvoiceItems.php @@ -3,8 +3,10 @@ namespace App\Imports\Sales\Sheets; use App\Abstracts\Import; -use App\Models\Sale\InvoiceItem as Model; 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; class InvoiceItems extends Import { @@ -13,8 +15,38 @@ class InvoiceItems extends Import return new Model($row); } + public function map($row): array + { + $row = parent::map($row); + + $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['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['invoice_number'] = 'required|string'; + unset($rules['invoice_id']); + + return $rules; } } diff --git a/app/Imports/Sales/Sheets/InvoiceTotals.php b/app/Imports/Sales/Sheets/InvoiceTotals.php index d36c0d1d4..3d8606497 100644 --- a/app/Imports/Sales/Sheets/InvoiceTotals.php +++ b/app/Imports/Sales/Sheets/InvoiceTotals.php @@ -3,8 +3,9 @@ namespace App\Imports\Sales\Sheets; use App\Abstracts\Import; -use App\Models\Sale\InvoiceTotal as Model; use App\Http\Requests\Sale\InvoiceTotal as Request; +use App\Models\Sale\Invoice; +use App\Models\Sale\InvoiceTotal as Model; class InvoiceTotals extends Import { @@ -13,8 +14,22 @@ class InvoiceTotals extends Import return new Model($row); } + public function map($row): array + { + $row = parent::map($row); + + $row['invoice_id'] = Invoice::number($row['invoice_number'])->pluck('id')->first(); + + return $row; + } + public function rules(): array { - return (new Request())->rules(); + $rules = (new Request())->rules(); + + $rules['invoice_number'] = 'required|string'; + unset($rules['invoice_id']); + + return $rules; } } diff --git a/app/Imports/Sales/Sheets/InvoiceTranactions.php b/app/Imports/Sales/Sheets/InvoiceTranactions.php deleted file mode 100644 index 0618d3f0f..000000000 --- a/app/Imports/Sales/Sheets/InvoiceTranactions.php +++ /dev/null @@ -1,29 +0,0 @@ -rules(); - } -} diff --git a/app/Imports/Sales/Sheets/InvoiceTransactions.php b/app/Imports/Sales/Sheets/InvoiceTransactions.php new file mode 100644 index 000000000..fd9fb41e9 --- /dev/null +++ b/app/Imports/Sales/Sheets/InvoiceTransactions.php @@ -0,0 +1,109 @@ + $row['account_name'], + ], [ + 'company_id' => session('company_id'), + 'number' => Account::max('number') + 1, + 'currency_code' => setting('default.currency'), + 'opening_balance' => 0, + 'enabled' => 1, + ])->id; + } + + 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; + } + + 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; + } + + 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; + } + + 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; + } + + 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['document_id'] = Invoice::number($row['invoice_number'])->pluck('id')->first(); + + return $row; + } + + public function rules(): array + { + $rules = (new Request())->rules(); + + $rules['invoice_number'] = 'required|string'; + + return $rules; + } +} diff --git a/app/Imports/Sales/Sheets/Invoices.php b/app/Imports/Sales/Sheets/Invoices.php index dd5e0b75d..58bbc812b 100644 --- a/app/Imports/Sales/Sheets/Invoices.php +++ b/app/Imports/Sales/Sheets/Invoices.php @@ -3,8 +3,10 @@ namespace App\Imports\Sales\Sheets; use App\Abstracts\Import; -use App\Models\Sale\Invoice as Model; 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 { @@ -13,6 +15,47 @@ class Invoices extends Import return new Model($row); } + public function map($row): array + { + $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; + } + + 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; + } + + 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; + } + + return $row; + } + public function rules(): array { return (new Request())->rules(); diff --git a/app/Models/Banking/Account.php b/app/Models/Banking/Account.php index 094b073b1..72a9211be 100644 --- a/app/Models/Banking/Account.php +++ b/app/Models/Banking/Account.php @@ -49,6 +49,16 @@ class Account extends Model return $this->hasMany('App\Models\Banking\Transaction'); } + public function scopeName($query, $name) + { + return $query->where('name', '=', $name); + } + + public function scopeNumber($query, $number) + { + return $query->where('number', '=', $number); + } + /** * Convert opening balance to double. * diff --git a/app/Models/Common/Contact.php b/app/Models/Common/Contact.php index d54b54c71..f89527060 100644 --- a/app/Models/Common/Contact.php +++ b/app/Models/Common/Contact.php @@ -79,6 +79,11 @@ class Contact extends Model return $query->whereIn('type', (array) $types); } + public function scopeEmail($query, $email) + { + return $query->where('email', '=', $email); + } + public function onCloning($src, $child = null) { $this->user_id = null; diff --git a/app/Models/Common/Item.php b/app/Models/Common/Item.php index 7e824a545..ea551dfc0 100644 --- a/app/Models/Common/Item.php +++ b/app/Models/Common/Item.php @@ -36,12 +36,12 @@ class Item extends Model public function category() { - return $this->belongsTo('App\Models\Setting\Category'); + return $this->belongsTo('App\Models\Setting\Category')->withDefault(['name' => trans('general.na')]); } public function tax() { - return $this->belongsTo('App\Models\Setting\Tax'); + return $this->belongsTo('App\Models\Setting\Tax')->withDefault(['name' => trans('general.na')]); } public function bill_items() @@ -54,6 +54,11 @@ class Item extends Model return $this->hasMany('App\Models\Sale\InvoiceItem'); } + public function scopeName($query, $name) + { + return $query->where('name', '=', $name); + } + /** * Convert sale price to double. * diff --git a/app/Models/Sale/Invoice.php b/app/Models/Sale/Invoice.php index 3540d6ab2..ddd752560 100644 --- a/app/Models/Sale/Invoice.php +++ b/app/Models/Sale/Invoice.php @@ -125,6 +125,11 @@ class Invoice extends Model return $query->where('status', '<>', 'paid'); } + public function scopeNumber($query, $number) + { + return $query->where('invoice_number', '=', $number); + } + public function onCloning($src, $child = null) { $this->status = 'draft'; diff --git a/app/Models/Sale/InvoiceItem.php b/app/Models/Sale/InvoiceItem.php index 3e50bab2a..4fee1a529 100644 --- a/app/Models/Sale/InvoiceItem.php +++ b/app/Models/Sale/InvoiceItem.php @@ -34,7 +34,7 @@ class InvoiceItem 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/Sale/InvoiceItemTax.php b/app/Models/Sale/InvoiceItemTax.php index f21a58136..b11af4539 100644 --- a/app/Models/Sale/InvoiceItemTax.php +++ b/app/Models/Sale/InvoiceItemTax.php @@ -4,11 +4,11 @@ namespace App\Models\Sale; use App\Abstracts\Model; use App\Traits\Currencies; +use Znck\Eloquent\Traits\BelongsToThrough; class InvoiceItemTax extends Model { - - use Currencies; + use Currencies, BelongsToThrough; protected $table = 'invoice_item_taxes'; @@ -24,9 +24,14 @@ class InvoiceItemTax extends Model return $this->belongsTo('App\Models\Sale\Invoice'); } + public function item() + { + return $this->belongsToThrough('App\Models\Common\Item', 'App\Models\Sale\InvoiceItem', 'invoice_item_id')->withDefault(['name' => trans('general.na')]); + } + public function tax() { - return $this->belongsTo('App\Models\Setting\Tax'); + return $this->belongsTo('App\Models\Setting\Tax')->withDefault(['name' => trans('general.na')]); } /** diff --git a/app/Models/Setting/Category.php b/app/Models/Setting/Category.php index 6dcf184bf..3c8341222 100644 --- a/app/Models/Setting/Category.php +++ b/app/Models/Setting/Category.php @@ -68,6 +68,11 @@ class Category extends Model return $query->whereIn('type', (array) $types); } + public function scopeName($query, $name) + { + return $query->where('name', '=', $name); + } + /** * Scope transfer category. * diff --git a/app/Models/Setting/Tax.php b/app/Models/Setting/Tax.php index 39a26cb95..e359ef18e 100644 --- a/app/Models/Setting/Tax.php +++ b/app/Models/Setting/Tax.php @@ -44,6 +44,16 @@ class Tax extends Model return $this->hasMany('App\Models\Sale\InvoiceItemTax'); } + public function scopeName($query, $name) + { + return $query->where('name', '=', $name); + } + + public function scopeRate($query, $rate) + { + return $query->where('rate', '=', $rate); + } + /** * Convert rate to double. * diff --git a/composer.json b/composer.json index ffafdd888..7b3ab6487 100644 --- a/composer.json +++ b/composer.json @@ -44,6 +44,7 @@ "plank/laravel-mediable": "3.0.*", "santigarcor/laratrust": "5.2.*", "simshaun/recurr": "4.0.*", + "staudenmeir/belongs-to-through": "2.9", "staudenmeir/eloquent-has-many-deep": "1.11" }, "require-dev": { diff --git a/composer.lock b/composer.lock index 911b7b2dd..011b67421 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "da7fd36fd1e0ebe5d9534e3db6ce40d5", + "content-hash": "f3cd099f0849563142edd289998d8bd9", "packages": [ { "name": "akaunting/firewall", @@ -5477,6 +5477,50 @@ ], "time": "2016-07-28T15:35:24+00:00" }, + { + "name": "staudenmeir/belongs-to-through", + "version": "v2.9", + "source": { + "type": "git", + "url": "https://github.com/staudenmeir/belongs-to-through.git", + "reference": "8f16bb7b51d081d90d9b093ba6f380f71a96d79f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/staudenmeir/belongs-to-through/zipball/8f16bb7b51d081d90d9b093ba6f380f71a96d79f", + "reference": "8f16bb7b51d081d90d9b093ba6f380f71a96d79f", + "shasum": "" + }, + "require": { + "illuminate/database": "^6.0", + "php": "^7.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Znck\\Eloquent\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Rahul Kadyan", + "email": "hi@znck.me" + }, + { + "name": "Jonas Staudenmeir", + "email": "mail@jonas-staudenmeir.de" + } + ], + "description": "Laravel Eloquent BelongsToThrough relationship", + "time": "2019-12-29T10:58:12+00:00" + }, { "name": "staudenmeir/eloquent-has-many-deep", "version": "v1.11", @@ -7882,24 +7926,24 @@ }, { "name": "phpspec/prophecy", - "version": "1.10.1", + "version": "v1.10.2", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "cbe1df668b3fe136bcc909126a0f529a78d4cbbc" + "reference": "b4400efc9d206e83138e2bb97ed7f5b14b831cd9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/cbe1df668b3fe136bcc909126a0f529a78d4cbbc", - "reference": "cbe1df668b3fe136bcc909126a0f529a78d4cbbc", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/b4400efc9d206e83138e2bb97ed7f5b14b831cd9", + "reference": "b4400efc9d206e83138e2bb97ed7f5b14b831cd9", "shasum": "" }, "require": { "doctrine/instantiator": "^1.0.2", "php": "^5.3|^7.0", "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0", - "sebastian/comparator": "^1.2.3|^2.0|^3.0", - "sebastian/recursion-context": "^1.0|^2.0|^3.0" + "sebastian/comparator": "^1.2.3|^2.0|^3.0|^4.0", + "sebastian/recursion-context": "^1.0|^2.0|^3.0|^4.0" }, "require-dev": { "phpspec/phpspec": "^2.5 || ^3.2", @@ -7941,7 +7985,7 @@ "spy", "stub" ], - "time": "2019-12-22T21:05:45+00:00" + "time": "2020-01-20T15:57:02+00:00" }, { "name": "phpunit/php-code-coverage", diff --git a/public/files/import/invoices.xlsx b/public/files/import/invoices.xlsx index d53546af0..fb49975f0 100644 Binary files a/public/files/import/invoices.xlsx and b/public/files/import/invoices.xlsx differ