Merge Invoice and Bill into Document

This commit is contained in:
Burak Çakırel 2020-12-24 01:28:38 +03:00
parent 830cc05957
commit 0c1424db47
No known key found for this signature in database
GPG Key ID: 48FFBB7771B99C7C
436 changed files with 31655 additions and 37350 deletions

1
.gitignore vendored
View File

@ -95,4 +95,5 @@ _ide_helper_models.php
modules/*
!modules/OfflinePayments
!modules/PaypalStandard
!modules/BC21
.laravelstatsrc

View File

@ -1,196 +0,0 @@
<?php
namespace App\Abstracts;
use App\Abstracts\Model;
use App\Models\Setting\Tax;
use App\Traits\Currencies;
use App\Traits\DateTime;
use App\Traits\Media;
use App\Traits\Recurring;
use Bkwld\Cloner\Cloneable;
abstract class DocumentModel extends Model
{
use Cloneable, Currencies, DateTime, Media, Recurring;
public function totals_sorted()
{
return $this->totals()->orderBy('sort_order');
}
public function scopeDue($query, $date)
{
return $query->whereDate('due_at', '=', $date);
}
public function scopeAccrued($query)
{
return $query->whereNotIn('status', ['draft', 'cancelled']);
}
public function scopePaid($query)
{
return $query->where('status', '=', 'paid');
}
public function scopeNotPaid($query)
{
return $query->where('status', '<>', 'paid');
}
/**
* Get the current balance.
*
* @return string
*/
public function getAttachmentAttribute($value)
{
if (!empty($value) && !$this->hasMedia('attachment')) {
return $value;
} elseif (!$this->hasMedia('attachment')) {
return false;
}
return $this->getMedia('attachment')->last();
}
/**
* Get the discount percentage.
*
* @return string
*/
public function getDiscountAttribute()
{
$percent = 0;
$discount = $this->totals->where('code', 'discount')->makeHidden('title')->pluck('amount')->first();
if ($discount) {
$sub_total = $this->totals->where('code', 'sub_total')->makeHidden('title')->pluck('amount')->first();
$percent = number_format((($discount * 100) / $sub_total), 0);
}
return $percent;
}
/**
* Get the paid amount.
*
* @return string
*/
public function getPaidAttribute()
{
if (empty($this->amount)) {
return false;
}
$paid = 0;
$reconciled = $reconciled_amount = 0;
$code = $this->currency_code;
$rate = config('money.' . $code . '.rate');
$precision = config('money.' . $code . '.precision');
if ($this->transactions->count()) {
foreach ($this->transactions as $item) {
$amount = $item->amount;
if ($code != $item->currency_code) {
$amount = $this->convertBetween($amount, $item->currency_code, $item->currency_rate, $code, $rate);
}
$paid += $amount;
if ($item->reconciled) {
$reconciled_amount = +$amount;
}
}
}
if (bccomp(round($this->amount, $precision), round($reconciled_amount, $precision), $precision) === 0) {
$reconciled = 1;
}
$this->setAttribute('reconciled', $reconciled);
return round($paid, $precision);
}
/**
* Get the status label.
*
* @return string
*/
public function getStatusLabelAttribute()
{
switch ($this->status) {
case 'paid':
$label = 'success';
break;
case 'partial':
$label = 'info';
break;
case 'sent':
case 'received':
$label = 'danger';
break;
case 'viewed':
$label = 'warning';
break;
case 'cancelled':
$label = 'dark';
break;
default:
$label = 'primary';
break;
}
return $label;
}
/**
* Get the amount without tax.
*
* @return string
*/
public function getAmountWithoutTaxAttribute()
{
$amount = $this->amount;
$this->totals->where('code', 'tax')->each(function ($total) use(&$amount) {
$tax = Tax::name($total->name)->first();
if (!empty($tax) && ($tax->type == 'withholding')) {
return;
}
$amount -= $total->amount;
});
return $amount;
}
/**
* Convert amount to double.
*
* @param string $value
* @return void
*/
public function setAmountAttribute($value)
{
$this->attributes['amount'] = (double) $value;
}
/**
* Convert currency rate to double.
*
* @param string $value
* @return void
*/
public function setCurrencyRateAttribute($value)
{
$this->attributes['currency_rate'] = (double) $value;
}
}

View File

@ -15,9 +15,15 @@ abstract class Export implements FromCollection, ShouldAutoSize, WithHeadings, W
{
public $ids;
public function __construct($ids = null)
/**
* @var string
*/
protected $type;
public function __construct($ids = null, string $type = '')
{
$this->ids = $ids;
$this->type = $type;
}
public function title(): string

View File

@ -3,13 +3,25 @@
namespace App\Abstracts;
use App\Models\Auth\User;
use App\Models\Common\Company;
use App\Traits\Jobs;
use Illuminate\Database\Eloquent\Factories\Factory as BaseFactory;
use Illuminate\Database\Eloquent\Model as EloquentModel;
abstract class Factory extends BaseFactory
{
use Jobs;
/**
* @var Company
*/
protected $company;
/**
* @var User|EloquentModel|object|null
*/
protected $user;
public function __construct(...$arguments)
{
parent::__construct(...$arguments);

View File

@ -2,9 +2,9 @@
namespace App\Abstracts\Http;
use App\Events\Sale\PaymentReceived;
use App\Events\Document\PaymentReceived;
use App\Http\Requests\Portal\InvoicePayment as PaymentRequest;
use App\Models\Sale\Invoice;
use App\Models\Document\Document;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Support\Facades\URL;
use Monolog\Logger;
@ -41,15 +41,15 @@ abstract class PaymentController extends BaseController
});
}
public function show(Invoice $invoice, PaymentRequest $request)
public function show(Document $document, PaymentRequest $request)
{
$this->setContactFirstLastName($invoice);
$this->setContactFirstLastName($document);
$confirm_url = $this->getConfirmUrl($invoice);
$confirm_url = $this->getConfirmUrl($document);
$html = view('partials.portal.payment_method.' . $this->type, [
'setting' => $this->setting,
'invoice' => $invoice,
'invoice' => $document,
'confirm_url' => $confirm_url,
])->render();
@ -62,12 +62,12 @@ abstract class PaymentController extends BaseController
]);
}
public function signed(Invoice $invoice, PaymentRequest $request)
public function signed(Document $document, PaymentRequest $request)
{
return $this->show($invoice, $request);
return $this->show($document, $request);
}
public function cancel(Invoice $invoice, $force_redirect = false)
public function cancel(Document $invoice, $force_redirect = false)
{
$message = trans('messages.warning.payment_cancel', ['method' => setting($this->alias . '.name')]);

View File

@ -25,6 +25,16 @@ abstract class Import implements ToModel, SkipsOnError, SkipsOnFailure, WithBatc
public $empty_field = 'empty---';
/**
* @var string
*/
protected $type;
public function __construct(string $type = '')
{
$this->type = $type;
}
public function map($row): array
{
$row['company_id'] = session('company_id');

View File

@ -22,6 +22,11 @@ abstract class Model extends Eloquent
'enabled' => 'boolean',
];
public static function observe($classes)
{
parent::observe($classes);
}
/**
* The "booting" method of the model.
*

View File

@ -12,7 +12,7 @@ use App\Events\Report\RowsShowing;
use App\Exports\Common\Reports as Export;
use App\Models\Banking\Transaction;
use App\Models\Common\Report as Model;
use App\Models\Sale\Invoice;
use App\Models\Document\Document;
use App\Traits\Charts;
use App\Traits\DateTime;
use App\Utilities\Chartjs;
@ -355,7 +355,7 @@ abstract class Report
$amount = $item->getAmountConvertedToDefault(false, $with_tax);
$type = (($item instanceof Invoice) || (($item instanceof Transaction) && ($item->type == 'income'))) ? 'income' : 'expense';
$type = ($item->type === Document::INVOICE_TYPE || $item->type === 'income') ? 'income' : 'expense';
if (($check_type == false) || ($type == 'income')) {
$this->row_values[$table][$item->$id_field][$date] += $amount;

View File

@ -0,0 +1,34 @@
<?php
namespace App\Abstracts\View\Components;
use Illuminate\View\Component;
use Illuminate\Support\Str;
abstract class DocumentForm extends Component
{
public $type;
public $documents;
public $bulkActions;
/** @var bool */
public $hideBulkAction;
/**
* Create a new component instance.
*
* @return void
*/
public function __construct(
$type, $documents = [], $bulkActions = [],
bool $hideBulkAction = false
) {
$this->type = $type;
$this->documents = $documents;
$this->bulkActions = $bulkActions;
$this->hideBulkAction = $hideBulkAction;
}
}

View File

@ -0,0 +1,933 @@
<?php
namespace App\Abstracts\View\Components;
use Illuminate\View\Component;
use Illuminate\Support\Str;
use App\Events\Common\BulkActionsAdding;
abstract class DocumentIndex extends Component
{
/** @var string */
public $type;
public $documents;
/** @var string */
public $page;
/** @var string */
public $docsPath;
/** @var bool */
public $checkCreatePermission;
/** @var string */
public $createPermission;
/** @var string */
public $createRoute;
/** @var string */
public $importRoute;
/** @var array */
public $importRouteParameters;
/** @var string */
public $exportRoute;
/** @var bool */
public $hideCreate;
/** @var bool */
public $hideImport;
/** @var bool */
public $hideExport;
/* -- Card Header Start -- */
/** @var string */
public $textBulkAction;
/** @var string */
public $bulkActionClass;
/** @var array */
public $bulkActions;
/** @var array */
public $bulkActionRouteParameters;
/** @var string */
public $formCardHeaderRoute;
/** @var bool */
public $hideBulkAction;
/** @var string */
public $classBulkAction;
/** @var string */
public $searchStringModel;
/** @var bool */
public $hideSearchString;
/* -- Card Header End -- */
/* -- Card Body Start -- */
/** @var string */
public $textDocumentNumber;
/** @var string */
public $textContactName;
/** @var string */
public $textIssueAt;
/** @var string */
public $textDueAt;
/** @var string */
public $textDocumentStatus;
/** @var bool */
public $checkButtonReconciled;
/** @var bool */
public $checkButtonCancelled;
/** @var bool */
public $hideDocumentNumber;
/** @var string */
public $classDocumentNumber;
/** @var bool */
public $hideContactName;
/** @var string */
public $classContactName;
/** @var bool */
public $hideAmount;
/** @var string */
public $classAmount;
/** @var bool */
public $hideIssuedAt;
/** @var string */
public $classIssuedAt;
/** @var bool */
public $hideDueAt;
/** @var string */
public $classDueAt;
/** @var bool */
public $hideStatus;
/** @var string */
public $classStatus;
/** @var bool */
public $hideActions;
/** @var string */
public $routeButtonShow;
/** @var string */
public $routeButtonEdit;
/** @var string */
public $routeButtonDuplicate;
/** @var string */
public $routeButtonCancelled;
/** @var string */
public $routeButtonDelete;
/** @var bool */
public $hideButtonShow;
/** @var bool */
public $hideButtonEdit;
/** @var bool */
public $hideButtonDuplicate;
/** @var bool */
public $hideButtonCancel;
/** @var bool */
public $hideButtonDelete;
/** @var string */
public $permissionDocumentCreate;
/** @var string */
public $permissionDocumentUpdate;
/** @var string */
public $permissionDocumentDelete;
/* -- Card Body End -- */
public $limits;
public $hideEmptyPage;
public $classActions;
public $class_count;
/**
* Create a new component instance.
*
* @return void
*/
public function __construct(
string $type, $documents = [], string $page = '', string $docsPath = '', $limits = [], $hideEmptyPage = false,
bool $checkCreatePermission = true, string $createPermission = '', string $createRoute = '', string $importRoute = '', array $importRouteParameters = [], string $exportRoute = '',
bool $hideCreate = false, bool $hideImport = false, bool $hideExport = false, // Advanced
string $textBulkAction = '', array $bulkActions = [], string $bulkActionClass = '', array $bulkActionRouteParameters = [], string $formCardHeaderRoute = '', string $searchStringModel = '',
bool $hideBulkAction = false, bool $hideSearchString = false,
string $classActions = '', string $classBulkAction = '', string $classDocumentNumber = '', string $classContactName = '', string $classIssuedAt = '', string $classDueAt = '', string $classStatus = '',
string $textDocumentNumber = '', string $textContactName = '', string $classAmount = '', string $textIssueAt = '', string $textDueAt = '', string $textDocumentStatus = '',
bool $checkButtonReconciled = true, bool $checkButtonCancelled = true,
string $routeButtonShow = '', string $routeButtonEdit = '', string $routeButtonDuplicate = '', string $routeButtonCancelled = '', string $routeButtonDelete = '',
bool $hideDocumentNumber = false, bool $hideContactName = false, bool $hideAmount = false, bool $hideIssuedAt = false, bool $hideDueAt = false, bool $hideStatus = false, bool $hideActions = false,
bool $hideButtonShow = false, bool $hideButtonEdit = false, bool $hideButtonDuplicate = false, bool $hideButtonCancel = false, bool $hideButtonDelete = false,
string $permissionDocumentCreate = '', string $permissionDocumentUpdate = '', string $permissionDocumentDelete = ''
) {
$this->type = $type;
$this->documents = $documents;
$this->page = $this->getPage($type, $page);
$this->docsPath = $this->getDocsPath($type, $docsPath);
$this->hideEmptyPage = $hideEmptyPage;
/* -- Top Buttons Start -- */
$this->checkCreatePermission = $checkCreatePermission;
$this->createPermission = $this->getCreatePermission($type, $createPermission);
$this->createRoute = $this->getCreateRoute($type, $createRoute);
$this->importRoute = $this->getImportRoute($importRoute);
$this->importRouteParameters = $this->getImportRouteParameters($type, $importRouteParameters);
$this->exportRoute = $this->getExportRoute($type, $exportRoute);
$this->hideCreate = $hideCreate;
$this->hideImport = $hideImport;
$this->hideExport = $hideExport;
/* -- Top Buttons End -- */
/* -- Card Header Start -- */
$this->textBulkAction = $this->getTextBulkAction($type, $textBulkAction);
$this->bulkActionClass = $bulkActionClass;
$this->bulkActions = $this->getBulkActions($type, $bulkActions, $bulkActionClass);
$this->bulkActionRouteParameters = $this->getBulkActionRouteParameters($type, $bulkActionRouteParameters);
$this->formCardHeaderRoute = $this->getRoute($type, $formCardHeaderRoute);
$this->searchStringModel = $this->getSearchStringModel($type, $searchStringModel);
$this->hideBulkAction = $hideBulkAction;
$this->hideSearchString = $hideSearchString;
/* -- Card Header End -- */
/* -- Card Body Start -- */
$this->textDocumentNumber = $this->getTextDocumentNumber($textDocumentNumber);
$this->textContactName = $this->getTextContactName($type, $textContactName);
$this->textIssueAt = $this->getTextIssueAt($type, $textIssueAt);
$this->textDueAt = $this->getTextDueAt($type, $textDueAt);
$this->textDocumentStatus = $this->getTextDocumentStatus($type, $textDocumentStatus);
$this->checkButtonReconciled = $checkButtonReconciled;
$this->checkButtonCancelled = $checkButtonCancelled;
$this->routeButtonShow = $this->getRouteButtonShow($type, $routeButtonShow);
$this->routeButtonEdit = $this->getRouteButtonEdit($type, $routeButtonEdit);
$this->routeButtonDuplicate = $this->getRouteButtonDuplicate($type, $routeButtonDuplicate);
$this->routeButtonCancelled = $this->getRouteButtonCancelled($type, $routeButtonCancelled);
$this->routeButtonDelete = $this->getRouteButtonDelete($type, $routeButtonDelete);
$this->hideBulkAction = $hideBulkAction;
$this->hideDocumentNumber = $hideDocumentNumber;
$this->hideContactName = $hideContactName;
$this->hideAmount = $hideAmount;
$this->hideIssuedAt = $hideIssuedAt;
$this->hideDueAt = $hideDueAt;
$this->hideStatus = $hideStatus;
$this->hideActions = $hideActions;
$this->class_count = 12;
$this->calculateClass();
$this->classBulkAction = $this->getClassBulkAction($type, $classBulkAction);
$this->classDocumentNumber = $this->getClassDocumentNumber($type, $classDocumentNumber);
$this->classContactName = $this->getClassContactName($type, $classContactName);
$this->classAmount = $this->getClassAmount($type, $classAmount);
$this->classIssuedAt = $this->getclassIssuedAt($type, $classIssuedAt);
$this->classDueAt = $this->getClassDueAt($type, $classDueAt);
$this->classStatus = $this->getClassStatus($type, $classStatus);
$this->classActions = $this->getClassActions($type, $classActions);
$this->hideButtonShow = $hideButtonShow;
$this->hideButtonEdit = $hideButtonEdit;
$this->hideButtonDuplicate = $hideButtonDuplicate;
$this->hideButtonCancel = $hideButtonCancel;
$this->hideButtonDelete = $hideButtonDelete;
$this->permissionDocumentCreate = $this->getPermissionDocumentCreate($type, $permissionDocumentCreate);
$this->permissionDocumentUpdate = $this->getPermissionDocumentUpdate($type, $permissionDocumentUpdate);
$this->permissionDocumentDelete = $this->getPermissionDocumentDelete($type, $permissionDocumentDelete);
/* -- Card Body End -- */
$this->limits = ($limits) ? $limits : ['10' => '10', '25' => '25', '50' => '50', '100' => '100'];
}
protected function getPage($type, $page)
{
if (!empty($page)) {
return $page;
}
return Str::plural($type, 2);
}
protected function getDocsPath($type, $docsPath)
{
if (!empty($docsPath)) {
return $docsPath;
}
switch ($type) {
case 'sale':
case 'income':
case 'invoice':
$docsPath = 'sales/invoices';
break;
case 'bill':
case 'expense':
case 'purchase':
$docsPath = 'purchases/bills';
break;
}
return $docsPath;
}
protected function getCreatePermission($type, $createPermission)
{
if (!empty($createPermission)) {
return $createPermission;
}
switch ($type) {
case 'sale':
case 'income':
case 'invoice':
$createPermission = 'create-sales-invoices';
break;
case 'bill':
case 'expense':
case 'purchase':
$createPermission = 'create-purchases-bills';
break;
}
return $createPermission;
}
protected function getCreateRoute($type, $createRoute)
{
if (!empty($createRoute)) {
return $createRoute;
}
$page = Str::plural($type, 2);
$route = $page . '.create';
try {
route($route);
} catch (\Exception $e) {
$route = '';
}
return $route;
}
protected function getImportRoute($importRoute)
{
if (!empty($importRoute)) {
return $importRoute;
}
$route = 'import.create';
return $route;
}
protected function getImportRouteParameters($type, $importRouteParameters)
{
if (!empty($importRouteParameters)) {
return $importRouteParameters;
}
$importRouteParameters = [
'group' => ($type == 'invoice') ? 'sales' : 'purchases',
'type' => Str::plural($type, 2)
];
return $importRouteParameters;
}
protected function getExportRoute($type, $exportRoute)
{
if (!empty($exportRoute)) {
return $exportRoute;
}
$page = Str::plural($type, 2);
$route = $page . '.export';
try {
route($route);
} catch (\Exception $e) {
$route = '';
}
return $route;
}
protected function getRoute($type, $formCardHeaderRoute)
{
if (!empty($formCardHeaderRoute)) {
return $formCardHeaderRoute;
}
$page = Str::plural($type, 2);
$route = $page . '.index';
try {
route($route);
} catch (\Exception $e) {
$route = '';
}
return $route;
}
protected function getSearchStringModel($type, $searchStringModel)
{
if (!empty($searchStringModel)) {
return $searchStringModel;
}
switch ($type) {
case 'sale':
case 'income':
case 'invoice':
$searchStringModel = 'App\Models\Sale\Invoice';
break;
case 'bill':
case 'expense':
case 'purchase':
$searchStringModel = 'App\Models\Purchase\Bill';
break;
}
return $searchStringModel;
}
protected function getTextBulkAction($type, $textBulkAction)
{
if (!empty($textBulkAction)) {
return $textBulkAction;
}
$textBulkAction = 'general.' . Str::plural($type, 2);
return $textBulkAction;
}
protected function getBulkActions($type, $bulkActions, $bulkActionClass)
{
if (!empty($bulkActions)) {
return $bulkActions;
}
switch ($type) {
case 'sale':
case 'income':
case 'invoice':
$bulkActionClass = 'App\BulkActions\Sales\Invoices';
break;
case 'bill':
case 'expense':
case 'purchase':
$bulkActionClass = 'App\BulkActions\Purchases\Bills';
break;
}
if (class_exists($bulkActionClass)) {
event(new BulkActionsAdding(app($bulkActionClass)));
$bulkActions = app($bulkActionClass)->actions;
} else {
$b = new \stdClass();
$b->actions = [];
event(new BulkActionsAdding($b));
$bulkActions = $b->actions;
}
return $bulkActions;
}
protected function getBulkActionRouteParameters($type, $bulkActionRouteParameters)
{
if (!empty($bulkActionRouteParameters)) {
return $bulkActionRouteParameters;
}
$bulkActionRouteParameters = [
'group' => ($type == 'invoice') ? 'sales' : 'purchases',
'type' => Str::plural($type, 2)
];
return $bulkActionRouteParameters;
}
protected function getClassBulkAction($type, $classBulkAction)
{
if (!empty($classBulkAction)) {
return $classBulkAction;
}
return 'col-sm-2 col-md-1 col-lg-1 col-xl-1 d-none d-sm-block';
}
protected function getTextDocumentNumber($textDocumentNumber)
{
if (!empty($textDocumentNumber)) {
return $textDocumentNumber;
}
return trans_choice('general.numbers', 1);
}
protected function getClassDocumentNumber($type, $classDocumentNumber)
{
if (!empty($classDocumentNumber)) {
return $classDocumentNumber;
}
if ($classDocumentNumber = $this->getClass('classDocumentNumber')) {
return $classDocumentNumber;
}
return 'col-md-2 col-lg-1 col-xl-1 d-none d-md-block';
}
protected function getTextContactName($type, $textContactName)
{
if (!empty($textContactName)) {
return $textContactName;
}
switch ($type) {
case 'sale':
case 'income':
case 'invoice':
$textContactName = trans_choice('general.customers', 1);
break;
case 'bill':
case 'expense':
case 'purchase':
$textContactName = trans_choice('general.vendors', 1);
break;
}
return $textContactName;
}
protected function getClassContactName($type, $classContactName)
{
if (!empty($classContactName)) {
return $classContactName;
}
if ($classContactName = $this->getClass('classContactName')) {
return $classContactName;
}
return 'col-xs-4 col-sm-4 col-md-4 col-lg-2 col-xl-2 text-left';
}
protected function getClassAmount($type, $classAmount)
{
if (!empty($classAmount)) {
return $classAmount;
}
if ($classAmount = $this->getClass('classAmount')) {
return $classAmount;
}
return 'col-xs-4 col-sm-4 col-md-3 col-lg-2 col-xl-2 text-right';
}
protected function getTextIssueAt($type, $textIssueAt)
{
if (!empty($textIssueAt)) {
return $textIssueAt;
}
switch ($type) {
case 'sale':
case 'income':
case 'invoice':
$textIssueAt = trans('invoices.invoice_date');
break;
case 'bill':
case 'expense':
case 'purchase':
$textIssueAt = trans('bills.bill_date');
break;
}
return $textIssueAt;
}
protected function getclassIssuedAt($type, $classIssuedAt)
{
if (!empty($classIssuedAt)) {
return $classIssuedAt;
}
if ($classIssuedAt = $this->getClass('classIssuedAt')) {
return $classIssuedAt;
}
return 'col-lg-2 col-xl-2 d-none d-lg-block text-left';
}
protected function getTextDueAt($type, $textDueAt)
{
if (!empty($textDueAt)) {
return $textDueAt;
}
switch ($type) {
case 'sale':
case 'income':
case 'invoice':
$textDueAt = trans('invoices.due_date');
break;
case 'bill':
case 'expense':
case 'purchase':
$textDueAt = trans('bills.due_date');
break;
}
return $textDueAt;
}
protected function getClassDueAt($type, $classDueAt)
{
if (!empty($classDueAt)) {
return $classDueAt;
}
if ($classDueAt = $this->getClass('classDueAt')) {
return $classDueAt;
}
return 'col-lg-2 col-xl-2 d-none d-lg-block text-left';
}
protected function getTextDocumentStatus($type, $textDocumentStatus)
{
if (!empty($textDocumentStatus)) {
return $textDocumentStatus;
}
switch ($type) {
case 'sale':
case 'income':
case 'invoice':
$textDocumentStatus = 'invoices.statuses.';
break;
case 'bill':
case 'expense':
case 'purchase':
$textDocumentStatus = 'bills.statuses.';
break;
}
return $textDocumentStatus;
}
protected function getClassStatus($type, $classStatus)
{
if (!empty($classStatus)) {
return $classStatus;
}
if ($classStatus = $this->getClass('classStatus')) {
return $classStatus;
}
return 'col-lg-1 col-xl-1 d-none d-lg-block text-center';
}
protected function getClassActions($type, $classActions)
{
if (!empty($classActions)) {
return $classActions;
}
if ($classActions = $this->getClass('classActions')) {
return $classActions;
}
return 'col-xs-4 col-sm-2 col-md-2 col-lg-1 col-xl-1 text-center';
}
protected function getRouteButtonShow($type, $routeButtonShow)
{
if (!empty($routeButtonShow)) {
return $routeButtonShow;
}
$page = Str::plural($type, 2);
$route = $page . '.show';
try {
//example route parameter.
$parameter = 1;
route($route, $parameter);
} catch (\Exception $e) {
$route = '';
}
return $route;
}
protected function getRouteButtonEdit($type, $routeButtonEdit)
{
if (!empty($routeButtonEdit)) {
return $routeButtonEdit;
}
$page = Str::plural($type, 2);
$route = $page . '.edit';
try {
//example route parameter.
$parameter = 1;
route($route, $parameter);
} catch (\Exception $e) {
$route = '';
}
return $route;
}
protected function getRouteButtonDuplicate($type, $routeButtonDuplicate)
{
if (!empty($routeButtonDuplicate)) {
return $routeButtonDuplicate;
}
$page = Str::plural($type, 2);
$route = $page . '.duplicate';
try {
//example route parameter.
$parameter = 1;
route($route, $parameter);
} catch (\Exception $e) {
$route = '';
}
return $route;
}
protected function getRouteButtonCancelled($type, $routeButtonCancelled)
{
if (!empty($routeButtonCancelled)) {
return $routeButtonCancelled;
}
$page = Str::plural($type, 2);
$route = $page . '.cancelled';
try {
//example route parameter.
$parameter = 1;
route($route, $parameter);
} catch (\Exception $e) {
$route = '';
}
return $route;
}
protected function getRouteButtonDelete($type, $routeButtonDelete)
{
if (!empty($routeButtonDelete)) {
return $routeButtonDelete;
}
$page = Str::plural($type, 2);
$route = $page . '.destroy';
try {
//example route parameter.
$parameter = 1;
route($route, $parameter);
} catch (\Exception $e) {
$route = '';
}
return $route;
}
protected function getPermissionDocumentCreate($type, $permissionDocumentCreate)
{
if (!empty($permissionDocumentCreate)) {
return $permissionDocumentCreate;
}
switch ($type) {
case 'sale':
case 'income':
case 'invoice':
$permissionDocumentCreate = 'create-sales-invoices';
break;
case 'bill':
case 'expense':
case 'purchase':
$permissionDocumentCreate = 'create-purchases-bills';
break;
}
return $permissionDocumentCreate;
}
protected function getPermissionDocumentUpdate($type, $permissionDocumentUpdate)
{
if (!empty($permissionDocumentUpdate)) {
return $permissionDocumentUpdate;
}
switch ($type) {
case 'sale':
case 'income':
case 'invoice':
$permissionDocumentUpdate = 'update-sales-invoices';
break;
case 'bill':
case 'expense':
case 'purchase':
$permissionDocumentUpdate = 'update-purchases-bills';
break;
}
return $permissionDocumentUpdate;
}
protected function getPermissionDocumentDelete($type, $permissionDocumentDelete)
{
if (!empty($permissionDocumentDelete)) {
return $permissionDocumentDelete;
}
switch ($type) {
case 'sale':
case 'income':
case 'invoice':
$permissionDocumentDelete = 'delete-sales-invoices';
break;
case 'bill':
case 'expense':
case 'purchase':
$permissionDocumentDelete = 'delete-purchases-bills';
break;
}
return $permissionDocumentDelete;
}
protected function calculateClass()
{
$hides = [
'BulkAction' => '1',
'DocumentNumber' => '1',
'ContactName' => '2',
'Amount' => '2',
'IssuedAt' => '2',
'DueAt' => '2',
'Status' => '1',
'Actions' => '1',
];
foreach ($hides as $hide => $count) {
if ($this->{'hide'. $hide}) {
$this->class_count -= $count;
}
}
}
protected function getClass($type)
{
$hide_count = 12 - $this->class_count;
if (empty($hide_count)) {
//return false;
}
$class = false;
switch($type) {
case 'classDocumentNumber':
switch ($hide_count) {
case 1:
$class = 'col-md-3 col-lg-2 col-xl-2 d-none d-md-block';
$this->class_count++;
break;
case 2:
$class = 'col-md-4 col-lg-2 col-xl-2 d-none d-md-block';
$this->class_count += 2;
break;
case 3:
$class = 'col-md-5 col-lg-2 col-xl-2 d-none d-md-block';
$this->class_count += 3;
break;
}
}
return $class;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,597 @@
<?php
namespace App\Abstracts\View\Components;
use Illuminate\View\Component;
use Illuminate\Support\Str;
use App\Traits\DateTime;
use App\Models\Common\Media;
use File;
use Image;
use Storage;
abstract class DocumentTemplate extends Component
{
use DateTime;
public $type;
public $document;
/** @var string */
public $documentTemplate;
public $date_format;
public $logo;
public $backGroundColor;
public $hideFooter;
public $hideCompanyLogo;
public $hideCompanyDetails;
public $hideCompanyName;
public $hideCompanyAddress;
public $hideCompanyTaxNumber;
public $hideCompanyPhone;
public $hideCompanyEmail;
public $hideContactInfo;
public $hideContactName;
public $hideContactAddress;
public $hideContactTaxNumber;
public $hideContactPhone;
public $hideContactEmail;
public $hideOrderNumber;
public $hideDocumentNumber;
public $hideIssuedAt;
public $hideDueAt;
public $textContactInfo;
/** @var string */
public $textIssuedAt;
/** @var string */
public $textDueAt;
/** @var string */
public $textDocumentNumber;
/** @var string */
public $textOrderNumber;
public $hideItems;
public $hideName;
public $hideDescription;
public $hideQuantity;
public $hidePrice;
public $hideDiscount;
public $hideAmount;
/** @var string */
public $textItems;
/** @var string */
public $textQuantity;
/** @var string */
public $textPrice;
/** @var string */
public $textAmount;
public $hideNote;
/**
* Create a new component instance.
*
* @return void
*/
public function __construct(
$type, $document, $documentTemplate = '', $logo = '', $backgroundColor = '',
bool $hideFooter = false, bool $hideCompanyLogo = false, bool $hideCompanyDetails = false,
bool $hideCompanyName = false, bool $hideCompanyAddress = false, bool $hideCompanyTaxNumber = false, bool $hideCompanyPhone = false, bool $hideCompanyEmail = false, bool $hideContactInfo = false,
bool $hideContactName = false, bool $hideContactAddress = false, bool $hideContactTaxNumber = false, bool $hideContactPhone = false, bool $hideContactEmail = false,
bool $hideOrderNumber = false, bool $hideDocumentNumber = false, bool $hideIssuedAt = false, bool $hideDueAt = false,
string $textContactInfo = '', string $textDocumentNumber = '', string $textOrderNumber = '', string $textIssuedAt = '', string $textDueAt = '',
bool $hideItems = false, bool $hideName = false, bool $hideDescription = false, bool $hideQuantity = false, bool $hidePrice = false, bool $hideDiscount = false, bool $hideAmount = false, bool $hideNote = false,
string $textItems = '', string $textQuantity = '', string $textPrice = '', string $textAmount = ''
) {
$this->type = $type;
$this->document = $document;
$this->documentTemplate = $this->getDocumentTemplate($type, $documentTemplate);
$this->logo = $this->getLogo($logo);
$this->backGroundColor = $this->getBackgroundColor($type, $backgroundColor);
$this->hideFooter = $hideFooter;
$this->hideCompanyLogo = $hideCompanyLogo;
$this->hideCompanyDetails = $hideCompanyDetails;
$this->hideCompanyName = $hideCompanyName;
$this->hideCompanyAddress = $hideCompanyAddress;
$this->hideCompanyTaxNumber = $hideCompanyTaxNumber;
$this->hideCompanyPhone = $hideCompanyPhone;
$this->hideCompanyEmail = $hideCompanyEmail;
$this->hideContactInfo = $hideContactInfo;
$this->hideContactName = $hideContactName;
$this->hideContactAddress = $hideContactAddress;
$this->hideContactTaxNumber = $hideContactTaxNumber;
$this->hideContactPhone = $hideContactPhone;
$this->hideContactEmail = $hideContactEmail;
$this->hideOrderNumber = $hideOrderNumber;
$this->hideDocumentNumber = $hideDocumentNumber;
$this->hideIssuedAt = $hideIssuedAt;
$this->hideDueAt = $hideDueAt;
$this->textContactInfo = $this->getTextContactInfo($type, $textContactInfo);
$this->textIssuedAt = $this->gettextIssuedAt($type, $textIssuedAt);
$this->textDocumentNumber = $this->getTextDocumentNumber($type, $textDocumentNumber);
$this->textDueAt = $this->getTextDueAt($type, $textDueAt);
$this->textOrderNumber = $this->getTextOrderNumber($type, $textOrderNumber);
$this->hideItems = $this->getHideItems($type, $hideItems, $hideName, $hideDescription);
$this->hideName = $this->getHideName($type, $hideName);
$this->hideDescription = $this->getHideDescription($type, $hideDescription);
$this->hideQuantity = $this->getHideQuantity($type, $hideQuantity);
$this->hidePrice = $this->getHidePrice($type, $hidePrice);
$this->hideDiscount = $this->getHideDiscount($type, $hideDiscount);
$this->hideAmount = $this->getHideAmount($type, $hideAmount);
$this->hideNote = $hideNote;
$this->textItems = $this->getTextItems($type, $textItems);
$this->textQuantity = $this->getTextQuantity($type, $textQuantity);
$this->textPrice = $this->getTextPrice($type, $textPrice);
$this->textAmount = $this->getTextAmount($type, $textAmount);
}
protected function getDocumentTemplate($type, $documentTemplate)
{
if (!empty($documentTemplate)) {
return $documentTemplate;
}
// $documentTemplate = 'components.documents.template.default';
$documentTemplate = 'default';
switch ($type) {
case 'sale':
case 'income':
case 'invoice':
// $documentTemplate = 'components.documents.template.' . setting('invoice.template', 'default');
$documentTemplate = setting('invoice.template', 'default');
break;
}
return $documentTemplate;
}
protected function getLogo($logo)
{
if (!empty($logo)) {
return $logo;
}
$media = Media::find(setting('company.logo'));
if (!empty($media)) {
$path = Storage::path($media->getDiskPath());
if (!is_file($path)) {
return $logo;
}
} else {
$path = base_path('public/img/company.png');
}
$image = Image::cache(function($image) use ($path) {
$width = $height = setting('invoice.logo_size', 128);
$image->make($path)->resize($width, $height)->encode();
});
if (empty($image)) {
return $logo;
}
$extension = File::extension($path);
return 'data:image/' . $extension . ';base64,' . base64_encode($image);
}
protected function getBackgroundColor($type, $backgroundColor)
{
if (!empty($backgroundColor)) {
return $backgroundColor;
}
$backgroundColor = '#55588b';
switch ($type) {
case 'sale':
case 'income':
case 'invoice':
$backgroundColor = setting('invoice.color');
break;
case 'bill':
case 'expense':
case 'purchase':
$backgroundColor = setting('bill.color');
break;
}
return $backgroundColor;
}
protected function getTextDocumentNumber($type, $textDocumentNumber)
{
if (!empty($textDocumentNumber)) {
return $textDocumentNumber;
}
switch ($type) {
case 'sale':
case 'income':
case 'invoice':
$textDocumentNumber = trans('invoices.invoice_number');
break;
case 'bill':
case 'expense':
case 'purchase':
$textDocumentNumber = trans('bills.bill_number');
break;
}
return $textDocumentNumber;
}
protected function getTextOrderNumber($type, $textOrderNumber)
{
if (!empty($textOrderNumber)) {
return $textOrderNumber;
}
switch ($type) {
case 'sale':
case 'income':
case 'invoice':
$textOrderNumber = trans('invoices.order_number');
break;
case 'bill':
case 'expense':
case 'purchase':
$textOrderNumber = trans('bills.order_number');
break;
}
return $textOrderNumber;
}
protected function getTextContactInfo($type, $textContactInfo)
{
if (!empty($textContactInfo)) {
return $textContactInfo;
}
switch ($type) {
case 'sale':
case 'income':
case 'invoice':
$textContactInfo = trans('invoices.bill_to');
break;
case 'bill':
case 'expense':
case 'purchase':
$textContactInfo = trans('bills.bill_from');
break;
}
return $textContactInfo;
}
protected function gettextIssuedAt($type, $textIssuedAt)
{
if (!empty($textIssuedAt)) {
return $textIssuedAt;
}
switch ($type) {
case 'sale':
case 'income':
case 'invoice':
$textIssuedAt = trans('invoices.invoice_date');
break;
case 'bill':
case 'expense':
case 'purchase':
$textIssuedAt = trans('bills.bill_date');
break;
}
return $textIssuedAt;
}
protected function getTextDueAt($type, $textDueAt)
{
if (!empty($textDueAt)) {
return $textDueAt;
}
switch ($type) {
case 'sale':
case 'income':
case 'invoice':
$textDueAt = trans('invoices.due_date');
break;
case 'bill':
case 'expense':
case 'purchase':
$textDueAt = trans('bills.due_date');
break;
}
return $textDueAt;
}
protected function getTextItems($type, $text_items)
{
if (!empty($text_items)) {
return $text_items;
}
switch ($type) {
case 'sale':
case 'income':
case 'invoice':
$text_items = trans_choice(setting('invoice.item_name', 'general.items'), 2);
if ($text_items == 'custom') {
$text_items = setting('invoice.item_name_input');
}
break;
case 'bill':
case 'expense':
case 'purchase':
$text_items = trans_choice('general.items', 2);
break;
}
return $text_items;
}
protected function getTextQuantity($type, $text_quantity)
{
if (!empty($text_quantity)) {
return $text_quantity;
}
switch ($type) {
case 'sale':
case 'income':
case 'invoice':
$text_quantity = trans(setting('invoice.quantity_name', 'invoices.quantity'));
if ($text_quantity == 'custom') {
$text_quantity = setting('invoice.quantity_name_input');
}
break;
case 'bill':
case 'expense':
case 'purchase':
$text_quantity = trans('bills.quantity');
break;
}
return $text_quantity;
}
protected function getTextPrice($type, $text_price)
{
if (!empty($text_price)) {
return $text_price;
}
switch ($type) {
case 'sale':
case 'income':
case 'invoice':
$text_price = trans(setting('invoice.price_name', 'invoices.price'));
if ($text_price == 'custom') {
$text_price = setting('invoice.price_name_input');
}
break;
case 'bill':
case 'expense':
case 'purchase':
$text_price = trans('bills.price');
break;
}
return $text_price;
}
protected function getTextAmount($type, $text_amount)
{
if (!empty($text_amount)) {
return $text_amount;
}
switch ($type) {
case 'sale':
case 'income':
case 'invoice':
case 'bill':
case 'expense':
case 'purchase':
$text_amount = trans('general.amount');
break;
}
return $text_amount;
}
protected function getHideItems($type, $hideItems, $hideName, $hideDescription)
{
if (!empty($hideItems)) {
return $hideItems;
}
$hideItems = ($this->getHideName($type, $hideName) & $this->getHideDescription($type, $hideDescription)) ? true : false;
return $hideItems;
}
protected function getHideName($type, $hideName)
{
if (!empty($hideName)) {
return $hideName;
}
switch ($type) {
case 'sale':
case 'income':
case 'invoice':
$hideName = setting('invoice.hide_item_name', $hideName);
break;
case 'bill':
case 'expense':
case 'purchase':
$hideName = setting('bill.hide_item_name', $hideName);
break;
}
return $hideName;
}
protected function getHideDescription($type, $hideDescription)
{
if (!empty($hideDescription)) {
return $hideDescription;
}
switch ($type) {
case 'sale':
case 'income':
case 'invoice':
$hideDescription = setting('invoice.hide_item_description', $hideDescription);
break;
case 'bill':
case 'expense':
case 'purchase':
$hideDescription = setting('bill.hide_item_description', $hideDescription);
break;
}
return $hideDescription;
}
protected function getHideQuantity($type, $hideQuantity)
{
if (!empty($hideQuantity)) {
return $hideQuantity;
}
switch ($type) {
case 'sale':
case 'income':
case 'invoice':
$hideQuantity = setting('invoice.hide_quantity', $hideQuantity);
break;
case 'bill':
case 'expense':
case 'purchase':
$hideQuantity = setting('bill.hide_quantity', $hideQuantity);
break;
}
return $hideQuantity;
}
protected function getHidePrice($type, $hidePrice)
{
if (!empty($hidePrice)) {
return $hidePrice;
}
switch ($type) {
case 'sale':
case 'income':
case 'invoice':
$hidePrice = setting('invoice.hide_price', $hidePrice);
break;
case 'bill':
case 'expense':
case 'purchase':
$hidePrice = setting('bill.hide_price', $hidePrice);
break;
}
return $hidePrice;
}
protected function getHideDiscount($type, $hideDiscount)
{
if (!empty($hideDiscount)) {
return $hideDiscount;
}
switch ($type) {
case 'sale':
case 'income':
case 'invoice':
$hideDiscount = setting('invoice.hide_discount', $hideDiscount);
break;
case 'bill':
case 'expense':
case 'purchase':
$hideDiscount = setting('bill.hide_discount', $hideDiscount);
break;
}
return $hideDiscount;
}
protected function getHideAmount($type, $hideAmount)
{
if (!empty($hideAmount)) {
return $hideAmount;
}
switch ($type) {
case 'sale':
case 'income':
case 'invoice':
$hideAmount = setting('invoice.hide_amount', $hideAmount);
break;
case 'bill':
case 'expense':
case 'purchase':
$hideAmount = setting('bill.hide_amount', $hideAmount);
break;
}
return $hideAmount;
}
}

View File

@ -3,17 +3,17 @@
namespace App\BulkActions\Purchases;
use App\Abstracts\BulkAction;
use App\Events\Purchase\BillCancelled;
use App\Events\Purchase\BillReceived;
use App\Exports\Purchases\Bills as Export;
use App\Jobs\Banking\CreateDocumentTransaction;
use App\Jobs\Purchase\CreateBillHistory;
use App\Jobs\Purchase\DeleteBill;
use App\Models\Purchase\Bill;
use App\Events\Document\DocumentCancelled;
use App\Events\Document\DocumentReceived;
use App\Exports\Document\Documents as Export;
use App\Jobs\Banking\CreateBankingDocumentTransaction;
use App\Jobs\Document\CreateDocumentHistory;
use App\Jobs\Document\DeleteDocument;
use App\Models\Document\Document;
class Bills extends BulkAction
{
public $model = Bill::class;
public $model = Document::class;
public $actions = [
'paid' => [
@ -48,7 +48,7 @@ class Bills extends BulkAction
$bills = $this->getSelectedRecords($request);
foreach ($bills as $bill) {
$this->dispatch(new CreateDocumentTransaction($bill, []));
$this->dispatch(new CreateBankingDocumentTransaction($bill, []));
}
}
@ -57,7 +57,7 @@ class Bills extends BulkAction
$bills = $this->getSelectedRecords($request);
foreach ($bills as $bill) {
event(new BillReceived($bill));
event(new DocumentReceived($bill));
}
}
@ -66,7 +66,7 @@ class Bills extends BulkAction
$bills = $this->getSelectedRecords($request);
foreach ($bills as $bill) {
event(new BillCancelled($bill));
event(new DocumentCancelled($bill));
}
}
@ -77,9 +77,9 @@ class Bills extends BulkAction
foreach ($bills as $bill) {
$clone = $bill->duplicate();
$description = trans('messages.success.added', ['type' => $clone->bill_number]);
$description = trans('messages.success.added', ['type' => $clone->document_number]);
$this->dispatch(new CreateBillHistory($clone, 0, $description));
$this->dispatch(new CreateDocumentHistory($clone, 0, $description));
}
}
@ -89,7 +89,7 @@ class Bills extends BulkAction
foreach ($bills as $bill) {
try {
$this->dispatch(new DeleteBill($bill));
$this->dispatch(new DeleteDocument($bill));
} catch (\Exception $e) {
flash($e->getMessage())->error();
}
@ -100,6 +100,6 @@ class Bills extends BulkAction
{
$selected = $this->getSelectedInput($request);
return \Excel::download(new Export($selected), \Str::filename(trans_choice('general.bills', 2)) . '.xlsx');
return \Excel::download(new Export($selected, Document::BILL_TYPE), \Str::filename(trans_choice('general.bills', 2)) . '.xlsx');
}
}

View File

@ -3,17 +3,17 @@
namespace App\BulkActions\Sales;
use App\Abstracts\BulkAction;
use App\Events\Sale\InvoiceCancelled;
use App\Events\Sale\InvoiceCreated;
use App\Events\Sale\InvoiceSent;
use App\Events\Sale\PaymentReceived;
use App\Exports\Sales\Invoices as Export;
use App\Jobs\Sale\DeleteInvoice;
use App\Models\Sale\Invoice;
use App\Events\Document\DocumentCancelled;
use App\Events\Document\DocumentCreated;
use App\Events\Document\DocumentSent;
use App\Events\Document\PaymentReceived;
use App\Exports\Document\Documents as Export;
use App\Jobs\Document\DeleteDocument;
use App\Models\Document\Document;
class Invoices extends BulkAction
{
public $model = Invoice::class;
public $model = Document::class;
public $actions = [
'paid' => [
@ -57,7 +57,7 @@ class Invoices extends BulkAction
$invoices = $this->getSelectedRecords($request);
foreach ($invoices as $invoice) {
event(new InvoiceSent($invoice));
event(new DocumentSent($invoice));
}
}
@ -66,7 +66,7 @@ class Invoices extends BulkAction
$invoices = $this->getSelectedRecords($request);
foreach ($invoices as $invoice) {
event(new InvoiceCancelled($invoice));
event(new DocumentCancelled($invoice));
}
}
@ -77,7 +77,7 @@ class Invoices extends BulkAction
foreach ($invoices as $invoice) {
$clone = $invoice->duplicate();
event(new InvoiceCreated($clone));
event(new DocumentCreated($clone));
}
}
@ -92,7 +92,7 @@ class Invoices extends BulkAction
foreach ($invoices as $invoice) {
try {
$this->dispatch(new DeleteInvoice($invoice));
$this->dispatch(new DeleteDocument($invoice));
} catch (\Exception $e) {
flash($e->getMessage())->error();
}
@ -103,6 +103,6 @@ class Invoices extends BulkAction
{
$selected = $this->getSelectedInput($request);
return \Excel::download(new Export($selected), \Str::filename(trans_choice('general.invoices', 2)) . '.xlsx');
return \Excel::download(new Export($selected, Document::INVOICE_TYPE), \Str::filename(trans_choice('general.invoices', 2)) . '.xlsx');
}
}

View File

@ -2,9 +2,9 @@
namespace App\Console\Commands;
use App\Events\Purchase\BillReminded;
use App\Events\Document\DocumentReminded;
use App\Models\Common\Company;
use App\Models\Purchase\Bill;
use App\Models\Document\Document;
use App\Utilities\Overrider;
use Date;
use Illuminate\Console\Command;
@ -80,11 +80,11 @@ class BillReminder extends Command
$date = Date::today()->addDays($day)->toDateString();
// Get upcoming bills
$bills = Bill::with('contact')->accrued()->notPaid()->due($date)->cursor();
$bills = Document::bill()->with('contact')->accrued()->notPaid()->due($date)->cursor();
foreach ($bills as $bill) {
try {
event(new BillReminded($bill));
event(new DocumentReminded($bill));
} catch (\Exception | \Throwable | \Swift_RfcComplianceException | \Illuminate\Database\QueryException $e) {
$this->error($e->getMessage());

View File

@ -2,9 +2,9 @@
namespace App\Console\Commands;
use App\Events\Sale\InvoiceReminded;
use App\Events\Document\DocumentReminded;
use App\Models\Common\Company;
use App\Models\Sale\Invoice;
use App\Models\Document\Document;
use App\Utilities\Overrider;
use Date;
use Illuminate\Console\Command;
@ -80,11 +80,11 @@ class InvoiceReminder extends Command
$date = Date::today()->subDays($day)->toDateString();
// Get upcoming invoices
$invoices = Invoice::with('contact')->accrued()->notPaid()->due($date)->cursor();
$invoices = Document::invoice()->with('contact')->accrued()->notPaid()->due($date)->cursor();
foreach ($invoices as $invoice) {
try {
event(new InvoiceReminded($invoice));
event(new DocumentReminded($invoice));
} catch (\Exception | \Throwable | \Swift_RfcComplianceException | \Illuminate\Database\QueryException $e) {
$this->error($e->getMessage());

View File

@ -4,13 +4,11 @@ namespace App\Console\Commands;
use App\Events\Banking\TransactionCreated;
use App\Events\Banking\TransactionRecurring;
use App\Events\Purchase\BillCreated;
use App\Events\Purchase\BillRecurring;
use App\Events\Sale\InvoiceCreated;
use App\Events\Sale\InvoiceRecurring;
use App\Events\Document\DocumentCreated;
use App\Events\Document\DocumentRecurring;
use App\Models\Banking\Transaction;
use App\Models\Common\Recurring;
use App\Models\Sale\Invoice;
use App\Models\Document\Document;
use App\Utilities\Date;
use App\Utilities\Overrider;
use Illuminate\Console\Command;
@ -136,16 +134,10 @@ class RecurringCheck extends Command
}
switch ($type) {
case 'App\Models\Purchase\Bill':
event(new BillCreated($clone));
case 'App\Models\Document\Document':
event(new DocumentCreated($clone));
event(new BillRecurring($clone));
break;
case 'App\Models\Sale\Invoice':
event(new InvoiceCreated($clone));
event(new InvoiceRecurring($clone));
event(new DocumentRecurring($clone));
break;
case 'App\Models\Banking\Transaction':
@ -272,11 +264,9 @@ class RecurringCheck extends Command
return 'paid_at';
}
if ($model instanceof Invoice) {
return 'invoiced_at';
if ($model instanceof Document) {
return 'issued_at';
}
return 'billed_at';
}
protected function getTable($model)
@ -285,10 +275,8 @@ class RecurringCheck extends Command
return 'transactions';
}
if ($model instanceof Invoice) {
return 'invoices';
if ($model instanceof Document) {
return 'documents';
}
return 'bills';
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace App\Events\Document;
use Illuminate\Queue\SerializesModels;
class DocumentCancelled
{
use SerializesModels;
public $document;
/**
* Create a new event instance.
*
* @param $document
*/
public function __construct($document)
{
$this->document = $document;
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace App\Events\Document;
use App\Abstracts\Event;
class DocumentCreated extends Event
{
public $document;
/**
* Create a new event instance.
*
* @param $document
*/
public function __construct($document)
{
$this->document = $document;
}
}

View File

@ -1,10 +1,10 @@
<?php
namespace App\Events\Sale;
namespace App\Events\Document;
use Illuminate\Queue\SerializesModels;
class InvoiceCreating
class DocumentCreating
{
use SerializesModels;

View File

@ -0,0 +1,22 @@
<?php
namespace App\Events\Document;
use Illuminate\Queue\SerializesModels;
class DocumentPrinting
{
use SerializesModels;
public $document;
/**
* Create a new event instance.
*
* @param $document
*/
public function __construct($document)
{
$this->document = $document;
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace App\Events\Document;
use Illuminate\Queue\SerializesModels;
class DocumentReceived
{
use SerializesModels;
public $document;
/**
* Create a new event instance.
*
* @param $document
*/
public function __construct($document)
{
$this->document = $document;
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace App\Events\Document;
use Illuminate\Queue\SerializesModels;
class DocumentRecurring
{
use SerializesModels;
public $document;
/**
* Create a new event instance.
*
* @param $document
*/
public function __construct($document)
{
$this->document = $document;
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace App\Events\Document;
use App\Abstracts\Event;
class DocumentReminded extends Event
{
public $document;
/**
* Create a new event instance.
*
* @param $document
*/
public function __construct($document)
{
$this->document = $document;
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace App\Events\Document;
use App\Abstracts\Event;
class DocumentSent extends Event
{
public $document;
/**
* Create a new event instance.
*
* @param $document
*/
public function __construct($document)
{
$this->document = $document;
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace App\Events\Document;
use App\Abstracts\Event;
class DocumentUpdated extends Event
{
public $document;
public $request;
/**
* Create a new event instance.
*
* @param $document
* @param $request
*/
public function __construct($document, $request)
{
$this->document = $document;
$this->request = $request;
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace App\Events\Document;
use App\Abstracts\Event;
class DocumentUpdating extends Event
{
public $document;
public $request;
/**
* Create a new event instance.
*
* @param $document
* @param $request
*/
public function __construct($document, $request)
{
$this->document = $document;
$this->request = $request;
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace App\Events\Document;
use App\Abstracts\Event;
class DocumentViewed extends Event
{
public $document;
/**
* Create a new event instance.
*
* @param $document
*/
public function __construct($document)
{
$this->document = $document;
}
}

View File

@ -0,0 +1,23 @@
<?php
namespace App\Events\Document;
use App\Abstracts\Event;
class PaymentReceived extends Event
{
public $document;
public $request;
/**
* Create a new event instance.
*
* @param $document
*/
public function __construct($document, $request = [])
{
$this->document = $document;
$this->request = $request;
}
}

View File

@ -1,22 +0,0 @@
<?php
namespace App\Events\Purchase;
use Illuminate\Queue\SerializesModels;
class BillCancelled
{
use SerializesModels;
public $bill;
/**
* Create a new event instance.
*
* @param $bill
*/
public function __construct($bill)
{
$this->bill = $bill;
}
}

View File

@ -1,22 +0,0 @@
<?php
namespace App\Events\Purchase;
use Illuminate\Queue\SerializesModels;
class BillCreated
{
use SerializesModels;
public $bill;
/**
* Create a new event instance.
*
* @param $bill
*/
public function __construct($bill)
{
$this->bill = $bill;
}
}

View File

@ -1,22 +0,0 @@
<?php
namespace App\Events\Purchase;
use Illuminate\Queue\SerializesModels;
class BillCreating
{
use SerializesModels;
public $request;
/**
* Create a new event instance.
*
* @param $request
*/
public function __construct($request)
{
$this->request = $request;
}
}

View File

@ -1,22 +0,0 @@
<?php
namespace App\Events\Purchase;
use Illuminate\Queue\SerializesModels;
class BillReceived
{
use SerializesModels;
public $bill;
/**
* Create a new event instance.
*
* @param $bill
*/
public function __construct($bill)
{
$this->bill = $bill;
}
}

View File

@ -1,22 +0,0 @@
<?php
namespace App\Events\Purchase;
use Illuminate\Queue\SerializesModels;
class BillRecurring
{
use SerializesModels;
public $bill;
/**
* Create a new event instance.
*
* @param $bill
*/
public function __construct($bill)
{
$this->bill = $bill;
}
}

View File

@ -1,22 +0,0 @@
<?php
namespace App\Events\Purchase;
use Illuminate\Queue\SerializesModels;
class BillReminded
{
use SerializesModels;
public $bill;
/**
* Create a new event instance.
*
* @param $bill
*/
public function __construct($bill)
{
$this->bill = $bill;
}
}

View File

@ -1,22 +0,0 @@
<?php
namespace App\Events\Purchase;
use Illuminate\Queue\SerializesModels;
class BillUpdated
{
use SerializesModels;
public $bill;
/**
* Create a new event instance.
*
* @param $bill
*/
public function __construct($bill)
{
$this->bill = $bill;
}
}

View File

@ -1,26 +0,0 @@
<?php
namespace App\Events\Purchase;
use Illuminate\Queue\SerializesModels;
class BillUpdating
{
use SerializesModels;
public $bill;
public $request;
/**
* Create a new event instance.
*
* @param $bill
* @param $request
*/
public function __construct($bill, $request)
{
$this->bill = $bill;
$this->request = $request;
}
}

View File

@ -1,22 +0,0 @@
<?php
namespace App\Events\Sale;
use Illuminate\Queue\SerializesModels;
class InvoiceCancelled
{
use SerializesModels;
public $invoice;
/**
* Create a new event instance.
*
* @param $invoice
*/
public function __construct($invoice)
{
$this->invoice = $invoice;
}
}

View File

@ -1,22 +0,0 @@
<?php
namespace App\Events\Sale;
use Illuminate\Queue\SerializesModels;
class InvoiceCreated
{
use SerializesModels;
public $invoice;
/**
* Create a new event instance.
*
* @param $invoice
*/
public function __construct($invoice)
{
$this->invoice = $invoice;
}
}

View File

@ -1,22 +0,0 @@
<?php
namespace App\Events\Sale;
use Illuminate\Queue\SerializesModels;
class InvoicePrinting
{
use SerializesModels;
public $invoice;
/**
* Create a new event instance.
*
* @param $invoice
*/
public function __construct($invoice)
{
$this->invoice = $invoice;
}
}

View File

@ -1,22 +0,0 @@
<?php
namespace App\Events\Sale;
use Illuminate\Queue\SerializesModels;
class InvoiceRecurring
{
use SerializesModels;
public $invoice;
/**
* Create a new event instance.
*
* @param $invoice
*/
public function __construct($invoice)
{
$this->invoice = $invoice;
}
}

View File

@ -1,22 +0,0 @@
<?php
namespace App\Events\Sale;
use Illuminate\Queue\SerializesModels;
class InvoiceReminded
{
use SerializesModels;
public $invoice;
/**
* Create a new event instance.
*
* @param $invoice
*/
public function __construct($invoice)
{
$this->invoice = $invoice;
}
}

View File

@ -1,22 +0,0 @@
<?php
namespace App\Events\Sale;
use Illuminate\Queue\SerializesModels;
class InvoiceSent
{
use SerializesModels;
public $invoice;
/**
* Create a new event instance.
*
* @param $invoice
*/
public function __construct($invoice)
{
$this->invoice = $invoice;
}
}

View File

@ -1,26 +0,0 @@
<?php
namespace App\Events\Sale;
use Illuminate\Queue\SerializesModels;
class InvoiceUpdated
{
use SerializesModels;
public $invoice;
public $request;
/**
* Create a new event instance.
*
* @param $invoice
* @param $request
*/
public function __construct($invoice, $request)
{
$this->invoice = $invoice;
$this->request = $request;
}
}

View File

@ -1,26 +0,0 @@
<?php
namespace App\Events\Sale;
use Illuminate\Queue\SerializesModels;
class InvoiceUpdating
{
use SerializesModels;
public $invoice;
public $request;
/**
* Create a new event instance.
*
* @param $invoice
* @param $request
*/
public function __construct($invoice, $request)
{
$this->invoice = $invoice;
$this->request = $request;
}
}

View File

@ -1,22 +0,0 @@
<?php
namespace App\Events\Sale;
use Illuminate\Queue\SerializesModels;
class InvoiceViewed
{
use SerializesModels;
public $invoice;
/**
* Create a new event instance.
*
* @param $invoice
*/
public function __construct($invoice)
{
$this->invoice = $invoice;
}
}

View File

@ -1,25 +0,0 @@
<?php
namespace App\Events\Sale;
use Illuminate\Queue\SerializesModels;
class PaymentReceived
{
use SerializesModels;
public $invoice;
public $request;
/**
* Create a new event instance.
*
* @param $invoice
*/
public function __construct($invoice, $request = [])
{
$this->invoice = $invoice;
$this->request = $request;
}
}

View File

@ -25,9 +25,9 @@ class Transactions extends Export
$model->category_name = $model->category->name;
if ($model->type == 'income') {
$model->invoice_bill_number = $model->invoice ? $model->invoice->invoice_number : 0;
$model->invoice_bill_number = $model->invoice->document_number ?? 0;
} else {
$model->invoice_bill_number = $model->bill ? $model->bill->bill_number : 0;
$model->invoice_bill_number = $model->bill->document_number ?? 0;
}
return parent::map($model);

View File

@ -0,0 +1,40 @@
<?php
namespace App\Exports\Document;
use App\Exports\Document\Sheets\Documents as Base;
use App\Exports\Document\Sheets\DocumentItems;
use App\Exports\Document\Sheets\DocumentItemTaxes;
use App\Exports\Document\Sheets\DocumentHistories;
use App\Exports\Document\Sheets\DocumentTotals;
use App\Exports\Document\Sheets\DocumentTransactions;
use Illuminate\Support\Str;
use Maatwebsite\Excel\Concerns\WithMultipleSheets;
class Documents implements WithMultipleSheets
{
public $ids;
/**
* @var string
*/
protected $type;
public function __construct($ids = null, string $type = '')
{
$this->ids = $ids;
$this->type = $type;
}
public function sheets(): array
{
return [
Str::plural($this->type) => new Base($this->ids, $this->type),
$this->type . '_items' => new DocumentItems($this->ids, $this->type),
$this->type . '_item_taxes' => new DocumentItemTaxes($this->ids, $this->type),
$this->type . '_histories' => new DocumentHistories($this->ids, $this->type),
$this->type . '_totals' => new DocumentTotals($this->ids, $this->type),
$this->type . '_transactions' => new DocumentTransactions($this->ids, $this->type),
];
}
}

View File

@ -0,0 +1,54 @@
<?php
namespace App\Exports\Document\Sheets;
use App\Abstracts\Export;
use App\Models\Document\Document;
use App\Models\Document\DocumentHistory as Model;
use Illuminate\Support\Str;
class DocumentHistories extends Export
{
public function collection()
{
$model = Model::{$this->type}()->with('document')->usingSearchString(request('search'));
if (!empty($this->ids)) {
$model->whereIn('document_id', (array) $this->ids);
}
return $model->cursor();
}
public function map($model): array
{
$document = $model->document;
if (empty($document)) {
return [];
}
if ($this->type === Document::INVOICE_TYPE) {
$model->invoice_number = $document->document_number;
} else {
$model->bill_number = $document->document_number;
}
return parent::map($model);
}
public function fields(): array
{
return [
$this->type === Document::INVOICE_TYPE ? 'invoice_number' : 'bill_number',
'status',
'notify',
'description',
];
}
public function title(): string
{
return Str::replaceFirst('document', $this->type, parent::title());
}
}

View File

@ -0,0 +1,57 @@
<?php
namespace App\Exports\Document\Sheets;
use App\Abstracts\Export;
use App\Models\Document\Document;
use App\Models\Document\DocumentItemTax as Model;
use Illuminate\Support\Str;
class DocumentItemTaxes extends Export
{
public function collection()
{
$model = Model::{$this->type}()->with('document', 'item', 'tax')->usingSearchString(request('search'));
if (!empty($this->ids)) {
$model->whereIn('document_id', (array) $this->ids);
}
return $model->cursor();
}
public function map($model): array
{
$document = $model->document;
if (empty($document)) {
return [];
}
if ($this->type === Document::INVOICE_TYPE) {
$model->invoice_number = $document->document_number;
} else {
$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 [
$this->type === Document::INVOICE_TYPE ? 'invoice_number' : 'bill_number',
'item_name',
'tax_rate',
'amount',
];
}
public function title(): string
{
return Str::replaceFirst('document', $this->type, parent::title());
}
}

View File

@ -0,0 +1,58 @@
<?php
namespace App\Exports\Document\Sheets;
use App\Abstracts\Export;
use App\Models\Document\Document;
use App\Models\Document\DocumentItem as Model;
use Illuminate\Support\Str;
class DocumentItems extends Export
{
public function collection()
{
$model = Model::{$this->type}()->with('document', 'item')->usingSearchString(request('search'));
if (!empty($this->ids)) {
$model->whereIn('document_id', (array) $this->ids);
}
return $model->cursor();
}
public function map($model): array
{
$document = $model->document;
if (empty($document)) {
return [];
}
if ($this->type === Document::INVOICE_TYPE) {
$model->invoice_number = $document->document_number;
} else {
$model->bill_number = $document->document_number;
}
$model->item_name = $model->item->name;
return parent::map($model);
}
public function fields(): array
{
return [
$this->type === Document::INVOICE_TYPE ? 'invoice_number' : 'bill_number',
'item_name',
'quantity',
'price',
'total',
'tax',
];
}
public function title(): string
{
return Str::replaceFirst('document', $this->type, parent::title());
}
}

View File

@ -0,0 +1,55 @@
<?php
namespace App\Exports\Document\Sheets;
use App\Abstracts\Export;
use App\Models\Document\Document;
use App\Models\Document\DocumentTotal as Model;
use Illuminate\Support\Str;
class DocumentTotals extends Export
{
public function collection()
{
$model = Model::{$this->type}()->with('document')->usingSearchString(request('search'));
if (!empty($this->ids)) {
$model->whereIn('document_id', (array) $this->ids);
}
return $model->cursor();
}
public function map($model): array
{
$document = $model->document;
if (empty($document)) {
return [];
}
if ($this->type === Document::INVOICE_TYPE) {
$model->invoice_number = $document->document_number;
} else {
$model->bill_number = $document->document_number;
}
return parent::map($model);
}
public function fields(): array
{
return [
$this->type === Document::INVOICE_TYPE ? 'invoice_number' : 'bill_number',
'code',
'name',
'amount',
'sort_order',
];
}
public function title(): string
{
return Str::replaceFirst('document', $this->type, parent::title());
}
}

View File

@ -1,17 +1,19 @@
<?php
namespace App\Exports\Purchases\Sheets;
namespace App\Exports\Document\Sheets;
use App\Abstracts\Export;
use App\Models\Banking\Transaction as Model;
use App\Models\Document\Document;
use Illuminate\Support\Str;
use Maatwebsite\Excel\Concerns\WithColumnFormatting;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
class BillTransactions extends Export implements WithColumnFormatting
class DocumentTransactions extends Export implements WithColumnFormatting
{
public function collection()
{
$model = Model::with('account', 'category', 'contact', 'bill')->expense()->isDocument()->usingSearchString(request('search'));
$model = Model::with('account', 'category', 'contact', 'document')->income()->isDocument()->usingSearchString(request('search'));
if (!empty($this->ids)) {
$model->whereIn('document_id', (array) $this->ids);
@ -22,13 +24,18 @@ class BillTransactions extends Export implements WithColumnFormatting
public function map($model): array
{
$bill = $model->bill;
$document = $model->document;
if (empty($bill)) {
if (empty($document)) {
return [];
}
$model->bill_number = $bill->bill_number;
if ($this->type === Document::INVOICE_TYPE) {
$model->invoice_number = $document->document_number;
} else {
$model->bill_number = $document->document_number;
}
$model->account_name = $model->account->name;
$model->category_name = $model->category->name;
$model->contact_email = $model->contact->email;
@ -39,7 +46,7 @@ class BillTransactions extends Export implements WithColumnFormatting
public function fields(): array
{
return [
'bill_number',
$this->type === Document::INVOICE_TYPE ? 'invoice_number' : 'bill_number',
'paid_at',
'amount',
'currency_code',
@ -60,4 +67,9 @@ class BillTransactions extends Export implements WithColumnFormatting
'B' => NumberFormat::FORMAT_DATE_YYYYMMDD,
];
}
public function title(): string
{
return Str::replaceFirst('document', $this->type, parent::title());
}
}

View File

@ -1,17 +1,17 @@
<?php
namespace App\Exports\Sales\Sheets;
namespace App\Exports\Document\Sheets;
use App\Abstracts\Export;
use App\Models\Sale\Invoice as Model;
use Maatwebsite\Excel\Concerns\WithColumnFormatting;
use App\Models\Document\Document as Model;
use Illuminate\Support\Str;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
class Invoices extends Export implements WithColumnFormatting
class Documents extends Export
{
public function collection()
{
$model = Model::with('category')->usingSearchString(request('search'));
$model = Model::{$this->type}()->with('category')->usingSearchString(request('search'));
if (!empty($this->ids)) {
$model->whereIn('id', (array) $this->ids);
@ -24,16 +24,24 @@ class Invoices extends Export implements WithColumnFormatting
{
$model->category_name = $model->category->name;
if ($this->type === Model::INVOICE_TYPE) {
$model->invoice_number = $model->document_number;
$model->invoiced_at = $model->issued_at;
} else {
$model->bill_number = $model->document_number;
$model->billed_at = $model->issued_at;
}
return parent::map($model);
}
public function fields(): array
{
return [
'invoice_number',
$this->type === Model::INVOICE_TYPE ? 'invoice_number' : 'bill_number',
'order_number',
'status',
'invoiced_at',
$this->type === Model::INVOICE_TYPE ? 'invoiced_at' : 'billed_at',
'due_at',
'amount',
'currency_code',
@ -49,6 +57,11 @@ class Invoices extends Export implements WithColumnFormatting
];
}
public function title(): string
{
return Str::replaceFirst('document', $this->type, parent::title());
}
public function columnFormats(): array
{
return [

View File

@ -1,33 +0,0 @@
<?php
namespace App\Exports\Purchases;
use App\Exports\Purchases\Sheets\Bills as Base;
use App\Exports\Purchases\Sheets\BillItems;
use App\Exports\Purchases\Sheets\BillItemTaxes;
use App\Exports\Purchases\Sheets\BillHistories;
use App\Exports\Purchases\Sheets\BillTotals;
use App\Exports\Purchases\Sheets\BillTransactions;
use Maatwebsite\Excel\Concerns\WithMultipleSheets;
class Bills implements WithMultipleSheets
{
public $ids;
public function __construct($ids = null)
{
$this->ids = $ids;
}
public function sheets(): array
{
return [
'bills' => new Base($this->ids),
'bill_items' => new BillItems($this->ids),
'bill_item_taxes' => new BillItemTaxes($this->ids),
'bill_histories' => new BillHistories($this->ids),
'bill_totals' => new BillTotals($this->ids),
'bill_transactions' => new BillTransactions($this->ids),
];
}
}

View File

@ -21,7 +21,7 @@ class Payments extends Export
public function map($model): array
{
$model->account_name = $model->account->name;
$model->bill_number = $model->bill ? $model->bill->bill_number : 0;
$model->bill_number = $model->bill->document_number ?? 0;
$model->contact_email = $model->contact->email;
$model->category_name = $model->category->name;

View File

@ -1,43 +0,0 @@
<?php
namespace App\Exports\Purchases\Sheets;
use App\Abstracts\Export;
use App\Models\Purchase\BillHistory as Model;
class BillHistories extends Export
{
public function collection()
{
$model = Model::with('bill')->usingSearchString(request('search'));
if (!empty($this->ids)) {
$model->whereIn('bill_id', (array) $this->ids);
}
return $model->cursor();
}
public function map($model): array
{
$bill = $model->bill;
if (empty($bill)) {
return [];
}
$model->bill_number = $bill->bill_number;
return parent::map($model);
}
public function fields(): array
{
return [
'bill_number',
'status',
'notify',
'description',
];
}
}

View File

@ -1,45 +0,0 @@
<?php
namespace App\Exports\Purchases\Sheets;
use App\Abstracts\Export;
use App\Models\Purchase\BillItemTax as Model;
class BillItemTaxes extends Export
{
public function collection()
{
$model = Model::with('bill', 'item', 'tax')->usingSearchString(request('search'));
if (!empty($this->ids)) {
$model->whereIn('bill_id', (array) $this->ids);
}
return $model->cursor();
}
public function map($model): array
{
$bill = $model->bill;
if (empty($bill)) {
return [];
}
$model->bill_number = $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_number',
'item_name',
'tax_rate',
'amount',
];
}
}

View File

@ -1,46 +0,0 @@
<?php
namespace App\Exports\Purchases\Sheets;
use App\Abstracts\Export;
use App\Models\Purchase\BillItem as Model;
class BillItems extends Export
{
public function collection()
{
$model = Model::with('bill', 'item')->usingSearchString(request('search'));
if (!empty($this->ids)) {
$model->whereIn('bill_id', (array) $this->ids);
}
return $model->cursor();
}
public function map($model): array
{
$bill = $model->bill;
if (empty($bill)) {
return [];
}
$model->bill_number = $bill->bill_number;
$model->item_name = $model->item->name;
return parent::map($model);
}
public function fields(): array
{
return [
'bill_number',
'item_name',
'quantity',
'price',
'total',
'tax',
];
}
}

View File

@ -1,44 +0,0 @@
<?php
namespace App\Exports\Purchases\Sheets;
use App\Abstracts\Export;
use App\Models\Purchase\BillTotal as Model;
class BillTotals extends Export
{
public function collection()
{
$model = Model::with('bill')->usingSearchString(request('search'));
if (!empty($this->ids)) {
$model->whereIn('bill_id', (array) $this->ids);
}
return $model->cursor();
}
public function map($model): array
{
$bill = $model->bill;
if (empty($bill)) {
return [];
}
$model->bill_number = $bill->bill_number;
return parent::map($model);
}
public function fields(): array
{
return [
'bill_number',
'code',
'name',
'amount',
'sort_order',
];
}
}

View File

@ -1,59 +0,0 @@
<?php
namespace App\Exports\Purchases\Sheets;
use App\Abstracts\Export;
use App\Models\Purchase\Bill as Model;
use Maatwebsite\Excel\Concerns\WithColumnFormatting;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
class Bills extends Export implements WithColumnFormatting
{
public function collection()
{
$model = Model::with('category')->usingSearchString(request('search'));
if (!empty($this->ids)) {
$model->whereIn('id', (array) $this->ids);
}
return $model->cursor();
}
public function map($model): array
{
$model->category_name = $model->category->name;
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',
'notes',
'footer',
];
}
public function columnFormats(): array
{
return [
'D' => NumberFormat::FORMAT_DATE_YYYYMMDD,
'E' => NumberFormat::FORMAT_DATE_YYYYMMDD,
];
}
}

View File

@ -1,33 +0,0 @@
<?php
namespace App\Exports\Sales;
use App\Exports\Sales\Sheets\Invoices as Base;
use App\Exports\Sales\Sheets\InvoiceItems;
use App\Exports\Sales\Sheets\InvoiceItemTaxes;
use App\Exports\Sales\Sheets\InvoiceHistories;
use App\Exports\Sales\Sheets\InvoiceTotals;
use App\Exports\Sales\Sheets\InvoiceTransactions;
use Maatwebsite\Excel\Concerns\WithMultipleSheets;
class Invoices implements WithMultipleSheets
{
public $ids;
public function __construct($ids = null)
{
$this->ids = $ids;
}
public function sheets(): array
{
return [
'invoices' => new Base($this->ids),
'invoice_items' => new InvoiceItems($this->ids),
'invoice_item_taxes' => new InvoiceItemTaxes($this->ids),
'invoice_histories' => new InvoiceHistories($this->ids),
'invoice_totals' => new InvoiceTotals($this->ids),
'invoice_transactions' => new InvoiceTransactions($this->ids),
];
}
}

View File

@ -21,7 +21,7 @@ class Revenues extends Export
public function map($model): array
{
$model->account_name = $model->account->name;
$model->invoice_number = $model->invoice ? $model->invoice->invoice_number : 0;
$model->invoice_number = $model->invoice->document_number ?? 0;
$model->contact_email = $model->contact->email;
$model->category_name = $model->category->name;

View File

@ -1,43 +0,0 @@
<?php
namespace App\Exports\Sales\Sheets;
use App\Abstracts\Export;
use App\Models\Sale\InvoiceHistory as Model;
class InvoiceHistories extends Export
{
public function collection()
{
$model = Model::with('invoice')->usingSearchString(request('search'));
if (!empty($this->ids)) {
$model->whereIn('invoice_id', (array) $this->ids);
}
return $model->cursor();
}
public function map($model): array
{
$invoice = $model->invoice;
if (empty($invoice)) {
return [];
}
$model->invoice_number = $invoice->invoice_number;
return parent::map($model);
}
public function fields(): array
{
return [
'invoice_number',
'status',
'notify',
'description',
];
}
}

View File

@ -1,45 +0,0 @@
<?php
namespace App\Exports\Sales\Sheets;
use App\Abstracts\Export;
use App\Models\Sale\InvoiceItemTax as Model;
class InvoiceItemTaxes extends Export
{
public function collection()
{
$model = Model::with('invoice', 'item', 'tax')->usingSearchString(request('search'));
if (!empty($this->ids)) {
$model->whereIn('invoice_id', (array) $this->ids);
}
return $model->cursor();
}
public function map($model): array
{
$invoice = $model->invoice;
if (empty($invoice)) {
return [];
}
$model->invoice_number = $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_number',
'item_name',
'tax_rate',
'amount',
];
}
}

View File

@ -1,46 +0,0 @@
<?php
namespace App\Exports\Sales\Sheets;
use App\Abstracts\Export;
use App\Models\Sale\InvoiceItem as Model;
class InvoiceItems extends Export
{
public function collection()
{
$model = Model::with('invoice', 'item')->usingSearchString(request('search'));
if (!empty($this->ids)) {
$model->whereIn('invoice_id', (array) $this->ids);
}
return $model->cursor();
}
public function map($model): array
{
$invoice = $model->invoice;
if (empty($invoice)) {
return [];
}
$model->invoice_number = $invoice->invoice_number;
$model->item_name = $model->item->name;
return parent::map($model);
}
public function fields(): array
{
return [
'invoice_number',
'item_name',
'quantity',
'price',
'total',
'tax',
];
}
}

View File

@ -1,44 +0,0 @@
<?php
namespace App\Exports\Sales\Sheets;
use App\Abstracts\Export;
use App\Models\Sale\InvoiceTotal as Model;
class InvoiceTotals extends Export
{
public function collection()
{
$model = Model::with('invoice')->usingSearchString(request('search'));
if (!empty($this->ids)) {
$model->whereIn('invoice_id', (array) $this->ids);
}
return $model->cursor();
}
public function map($model): array
{
$invoice = $model->invoice;
if (empty($invoice)) {
return [];
}
$model->invoice_number = $invoice->invoice_number;
return parent::map($model);
}
public function fields(): array
{
return [
'invoice_number',
'code',
'name',
'amount',
'sort_order',
];
}
}

View File

@ -1,63 +0,0 @@
<?php
namespace App\Exports\Sales\Sheets;
use App\Abstracts\Export;
use App\Models\Banking\Transaction as Model;
use Maatwebsite\Excel\Concerns\WithColumnFormatting;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
class InvoiceTransactions extends Export implements WithColumnFormatting
{
public function collection()
{
$model = Model::with('account', 'category', 'contact', 'invoice')->income()->isDocument()->usingSearchString(request('search'));
if (!empty($this->ids)) {
$model->whereIn('document_id', (array) $this->ids);
}
return $model->cursor();
}
public function map($model): array
{
$invoice = $model->invoice;
if (empty($invoice)) {
return [];
}
$model->invoice_number = $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_name',
'contact_email',
'category_name',
'description',
'payment_method',
'reference',
'reconciled',
];
}
public function columnFormats(): array
{
return [
'B' => NumberFormat::FORMAT_DATE_YYYYMMDD,
];
}
}

View File

@ -0,0 +1,79 @@
<?php
namespace App\Http\Controllers\Api\Document;
use App\Http\Requests\Banking\Transaction as Request;
use App\Jobs\Banking\CreateBankingDocumentTransaction;
use App\Jobs\Banking\DeleteTransaction;
use App\Models\Banking\Transaction;
use App\Models\Document\Document;
use App\Transformers\Banking\Transaction as Transformer;
use Dingo\Api\Routing\Helpers;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
class DocumentTransactions extends BaseController
{
use Helpers, AuthorizesRequests, DispatchesJobs, ValidatesRequests;
/**
* Display a listing of the resource.
*
* @param $document_id
* @return \Dingo\Api\Http\Response
*/
public function index($document_id)
{
$transactions = Transaction::document($document_id)->get();
return $this->response->collection($transactions, new Transformer());
}
/**
* Display the specified resource.
*
* @param $document_id
* @param $id
* @return \Dingo\Api\Http\Response
*/
public function show($document_id, $id)
{
$transaction = Transaction::document($document_id)->find($id);
return $this->response->item($transaction, new Transformer());
}
/**
* Store a newly created resource in storage.
*
* @param $document_id
* @param $request
* @return \Dingo\Api\Http\Response
*/
public function store($document_id, Request $request)
{
$document = Document::find($document_id);
$transaction = $this->dispatch(new CreateBankingDocumentTransaction($document, $request));
return $this->response->created(route('documents.transactions.show', [$document_id, $transaction->id]));
}
/**
* Remove the specified resource from storage.
*
* @param $document_id
* @param $id
* @return \Dingo\Api\Http\Response
*/
public function destroy($document_id, $id)
{
$transaction = Transaction::document($document_id)->find($id);
$this->dispatch(new DeleteTransaction($transaction));
return $this->response->noContent();
}
}

View File

@ -0,0 +1,91 @@
<?php
namespace App\Http\Controllers\Api\Document;
use App\Abstracts\Http\ApiController;
use App\Http\Requests\Document\Document as Request;
use App\Jobs\Document\CreateDocument;
use App\Jobs\Document\DeleteDocument;
use App\Jobs\Document\UpdateDocument;
use App\Models\Document\Document;
use App\Transformers\Document\Document as Transformer;
class Documents extends ApiController
{
/**
* Display a listing of the resource.
*
* @return \Dingo\Api\Http\Response
*/
public function index()
{
$documents = Document::with('contact', 'histories', 'items', 'transactions')->collect(['issued_at'=> 'desc']);
return $this->response->paginator($documents, new Transformer());
}
/**
* Display the specified resource.
*
* @param $id
* @return \Dingo\Api\Http\Response
*/
public function show($id)
{
// Check if we're querying by id or number
if (is_numeric($id)) {
$document = Document::find($id);
} else {
$document = Document::where('document_number', $id)->first();
}
return $this->response->item($document, new Transformer());
}
/**
* Store a newly created resource in storage.
*
* @param $request
*
* @return \Dingo\Api\Http\Response
*/
public function store(Request $request)
{
$document = $this->dispatch(new CreateDocument($request));
return $this->response->created(route('api.documents.show', $document->id));
}
/**
* Update the specified resource in storage.
*
* @param $document
* @param $request
*
* @return \Dingo\Api\Http\Response
*/
public function update(Document $document, Request $request)
{
$document = $this->dispatch(new UpdateDocument($document, $request));
return $this->response->item($document->fresh(), new Transformer());
}
/**
* Remove the specified resource from storage.
*
* @param Document $document
*
* @return \Dingo\Api\Http\Response
*/
public function destroy(Document $document)
{
try {
$this->dispatch(new DeleteDocument($document));
return $this->response->noContent();
} catch(\Exception $e) {
$this->response->errorUnauthorized($e->getMessage());
}
}
}

View File

@ -303,7 +303,7 @@ class Items extends Controller
break;
}
$item->total = money($total, $currency_code, true)->format();
$item->total = $total;
}
}

View File

@ -7,8 +7,7 @@ use App\Events\Common\GlobalSearched;
use App\Models\Banking\Account;
use App\Models\Banking\Transaction;
use App\Models\Common\Contact;
use App\Models\Purchase\Bill;
use App\Models\Sale\Invoice;
use App\Models\Document\Document;
use App\Models\Common\Item;
class Search extends Controller
@ -52,13 +51,13 @@ class Search extends Controller
}
}
$invoices = Invoice::usingSearchString($search->keyword)->get();
$invoices = Document::invoice()->usingSearchString($search->keyword)->get();
if ($invoices->count()) {
foreach ($invoices as $invoice) {
$search->results[] = (object) [
'id' => $invoice->id,
'name' => $invoice->invoice_number . ' - ' . $invoice->contact_name,
'name' => $invoice->document_number . ' - ' . $invoice->contact_name,
'type' => trans_choice('general.invoices', 1),
'color' => '#6da252',
'href' => route('invoices.show', $invoice->id),
@ -96,13 +95,13 @@ class Search extends Controller
}
}
$bills = Bill::usingSearchString($search->keyword)->get();
$bills = Document::bill()->usingSearchString($search->keyword)->get();
if ($bills->count()) {
foreach ($bills as $bill) {
$search->results[] = (object) [
'id' => $bill->id,
'name' => $bill->bill_number . ' - ' . $bill->contact_name,
'name' => $bill->document_number . ' - ' . $bill->contact_name,
'type' => trans_choice('general.bills', 1),
'color' => '#ef3232',
'href' => route('bills.show', $bill->id),

View File

@ -4,10 +4,10 @@ namespace App\Http\Controllers\Modals;
use App\Abstracts\Http\Controller;
use App\Http\Requests\Banking\Transaction as Request;
use App\Jobs\Banking\CreateDocumentTransaction;
use App\Jobs\Banking\CreateBankingDocumentTransaction;
use App\Models\Banking\Account;
use App\Models\Banking\Transaction;
use App\Models\Purchase\Bill;
use App\Models\Document\Document;
use App\Models\Setting\Currency;
use App\Utilities\Modules;
use App\Traits\Uploads;
@ -31,11 +31,11 @@ class BillTransactions extends Controller
/**
* Show the form for creating a new resource.
*
* @param Bill $bill
* @param Document $bill
*
* @return Response
*/
public function create(Bill $bill)
public function create(Document $bill)
{
$accounts = Account::enabled()->orderBy('name')->pluck('name', 'id');
@ -86,14 +86,14 @@ class BillTransactions extends Controller
/**
* Store a newly created resource in storage.
*
* @param Bill $bill
* @param Document $bill
* @param Request $request
*
* @return Response
*/
public function store(Bill $bill, Request $request)
public function store(Document $bill, Request $request)
{
$response = $this->ajaxDispatch(new CreateDocumentTransaction($bill, $request));
$response = $this->ajaxDispatch(new CreateBankingDocumentTransaction($bill, $request));
if ($response['success']) {
$response['redirect'] = route('bills.show', $bill->id);

View File

@ -0,0 +1,38 @@
<?php
namespace App\Http\Controllers\Modals;
use App\Abstracts\Http\Controller;
use App\Models\Common\Company;
class Companies extends Controller
{
/**
* Instantiate a new controller instance.
*/
public function __construct()
{
// Add CRUD permission check
$this->middleware('permission:read-settings-company')->only('index', 'show', 'edit', 'export');
$this->middleware('permission:update-settings-settings')->only('update', 'enable', 'disable');
}
/**
* Show the form for editing the specified resource.
*
* @param Company $company
*
* @return Response
*/
public function edit(Company $company)
{
$html = view('modals.companies.edit', compact('company'))->render();
return response()->json([
'success' => true,
'error' => false,
'message' => 'null',
'html' => $html,
]);
}
}

View File

@ -4,7 +4,9 @@ namespace App\Http\Controllers\Modals;
use App\Abstracts\Http\Controller;
use App\Http\Requests\Common\Contact as Request;
use App\Models\Common\Contact;
use App\Jobs\Common\CreateContact;
use App\Jobs\Common\UpdateContact;
use App\Models\Setting\Currency;
class Customers extends Controller
@ -60,6 +62,7 @@ class Customers extends Controller
$request['enabled'] = 1;
$response = $this->ajaxDispatch(new CreateContact($request));
$this->ajaxDispatch(new UpdateContact($customer, $request));
if ($response['success']) {
$response['message'] = trans('messages.success.added', ['type' => trans_choice('general.customers', 1)]);
@ -67,4 +70,54 @@ class Customers extends Controller
return response()->json($response);
}
/**
* Show the form for editing the specified resource.
*
* @param Contact $customer
*
* @return Response
*/
public function edit(Contact $customer)
{
$currencies = Currency::enabled()->pluck('name', 'code');
$contact_selector = false;
if (request()->has('contact_selector')) {
$contact_selector = request()->get('contact_selector');
}
$rand = rand();
$html = view('modals.customers.edit', compact('customer', 'currencies', 'contact_selector', 'rand'))->render();
return response()->json([
'success' => true,
'error' => false,
'message' => 'null',
'html' => $html,
]);
}
/**
* Update the specified resource in storage.
*
* @param Contact $customer
* @param Request $request
*
* @return Response
*/
public function update(Contact $customer, Request $request)
{
$request['enabled'] = 1;
$response = $this->ajaxDispatch(new UpdateContact($customer, $request));
if ($response['success']) {
$response['message'] = trans('messages.success.updated', ['type' => trans_choice('general.customers', 1)]);
}
return response()->json($response);
}
}

View File

@ -0,0 +1,116 @@
<?php
namespace App\Http\Controllers\Modals;
use App\Abstracts\Http\Controller;
use App\Http\Requests\Setting\Setting as Request;
class InvoiceItemColumns extends Controller
{
public $skip_keys = ['company_id', '_method', '_token', '_prefix', '_template'];
public function __construct()
{
// Add CRUD permission check
$this->middleware('permission:read-settings-settings')->only('index', 'edit');
$this->middleware('permission:update-settings-settings')->only('update', 'enable', 'disable');
}
/**
* Show the form for editing the specified resource.
*
* @param Contact $customer
*
* @return Response
*/
public function edit()
{
$item_names = [
'settings.invoice.item' => trans('settings.invoice.item'),
'settings.invoice.product' => trans('settings.invoice.product'),
'settings.invoice.service' => trans('settings.invoice.service'),
'custom' => trans('settings.invoice.custom'),
];
$price_names = [
'settings.invoice.price' => trans('settings.invoice.price'),
'settings.invoice.rate' => trans('settings.invoice.rate'),
'custom' => trans('settings.invoice.custom'),
];
$quantity_names = [
'settings.invoice.quantity' => trans('settings.invoice.quantity'),
'custom' => trans('settings.invoice.custom'),
];
$payment_terms = [
'0' => trans('settings.invoice.due_receipt'),
'15' => trans('settings.invoice.due_days', ['days' => 15]),
'30' => trans('settings.invoice.due_days', ['days' => 30]),
'45' => trans('settings.invoice.due_days', ['days' => 45]),
'60' => trans('settings.invoice.due_days', ['days' => 60]),
'90' => trans('settings.invoice.due_days', ['days' => 90]),
];
$html = view('modals.invoices.item_columns', compact(
'item_names',
'price_names',
'quantity_names',
'payment_terms'
))->render();
return response()->json([
'success' => true,
'error' => false,
'message' => 'null',
'html' => $html,
]);
}
/**
* Update the specified resource in storage.
*
* @param Request $request
*
* @return Response
*/
public function update(Request $request)
{
$fields = $request->all();
$prefix = $request->get('_prefix', 'invoice');
$company_id = $request->get('company_id');
if (empty($company_id)) {
$company_id = session('company_id');
}
foreach ($fields as $key => $value) {
$real_key = $prefix . '.' . $key;
// Don't process unwanted keys
if (in_array($key, $this->skip_keys)) {
continue;
}
setting()->set($real_key, $value);
}
// Save all settings
setting()->save();
$message = trans('messages.success.updated', ['type' => trans_choice('general.settings', 2)]);
$response = [
'status' => null,
'success' => true,
'error' => false,
'message' => $message,
'data' => null,
'redirect' => route('settings.invoice.edit'),
];
flash($message)->success();
return response()->json($response);
}
}

View File

@ -4,10 +4,10 @@ namespace App\Http\Controllers\Modals;
use App\Abstracts\Http\Controller;
use App\Http\Requests\Banking\Transaction as Request;
use App\Jobs\Banking\CreateDocumentTransaction;
use App\Jobs\Banking\CreateBankingDocumentTransaction;
use App\Models\Banking\Account;
use App\Models\Banking\Transaction;
use App\Models\Sale\Invoice;
use App\Models\Document\Document;
use App\Models\Setting\Currency;
use App\Utilities\Modules;
use App\Traits\Uploads;
@ -31,11 +31,11 @@ class InvoiceTransactions extends Controller
/**
* Show the form for creating a new resource.
*
* @param Invoice $invoice
* @param Document $invoice
*
* @return Response
*/
public function create(Invoice $invoice)
public function create(Document $invoice)
{
$accounts = Account::enabled()->orderBy('name')->pluck('name', 'id');
@ -91,14 +91,14 @@ class InvoiceTransactions extends Controller
/**
* Store a newly created resource in storage.
*
* @param Invoice $invoice
* @param Document $invoice
* @param Request $request
*
* @return Response
*/
public function store(Invoice $invoice, Request $request)
public function store(Document $invoice, Request $request)
{
$response = $this->ajaxDispatch(new CreateDocumentTransaction($invoice, $request));
$response = $this->ajaxDispatch(new CreateBankingDocumentTransaction($invoice, $request));
if ($response['success']) {
$response['redirect'] = route('invoices.show', $invoice->id);

View File

@ -4,7 +4,9 @@ namespace App\Http\Controllers\Modals;
use App\Abstracts\Http\Controller;
use App\Http\Requests\Common\Contact as Request;
use App\Models\Common\Contact;
use App\Jobs\Common\CreateContact;
use App\Jobs\Common\UpdateContact;
use App\Models\Setting\Currency;
class Vendors extends Controller
@ -67,4 +69,54 @@ class Vendors extends Controller
return response()->json($response);
}
/**
* Show the form for editing the specified resource.
*
* @param Contact $vendor
*
* @return Response
*/
public function edit(Contact $vendor)
{
$currencies = Currency::enabled()->pluck('name', 'code');
$contact_selector = false;
if (request()->has('contact_selector')) {
$contact_selector = request()->get('contact_selector');
}
$rand = rand();
$html = view('modals.vendors.edit', compact('vendor', 'currencies', 'contact_selector', 'rand'))->render();
return response()->json([
'success' => true,
'error' => false,
'message' => 'null',
'html' => $html,
]);
}
/**
* Update the specified resource in storage.
*
* @param Contact $vendor
* @param Request $request
*
* @return Response
*/
public function update(Contact $vendor, Request $request)
{
$request['enabled'] = 1;
$response = $this->ajaxDispatch(new UpdateContact($vendor, $request));
if ($response['success']) {
$response['message'] = trans('messages.success.updated', ['type' => trans_choice('general.vendors', 1)]);
}
return response()->json($response);
}
}

View File

@ -2,7 +2,7 @@
namespace App\Http\Controllers\Portal;
use App\Models\Sale\Invoice;
use App\Models\Document\Document;
use App\Traits\Charts;
use App\Utilities\Chartjs;
use Date;
@ -20,7 +20,7 @@ class Dashboard
{
$contact = user()->contact;
$invoices = Invoice::accrued()->where('contact_id', $contact->id)->get();
$invoices = Document::invoice()->accrued()->where('contact_id', $contact->id)->get();
$start = Date::parse(request('start', Date::today()->startOfYear()->format('Y-m-d')));
$end = Date::parse(request('end', Date::today()->endOfYear()->format('Y-m-d')));

View File

@ -4,18 +4,23 @@ namespace App\Http\Controllers\Portal;
use App\Abstracts\Http\Controller;
use App\Http\Requests\Portal\InvoiceShow as Request;
use App\Models\Sale\Invoice;
use App\Models\Document\Document;
use App\Models\Setting\Category;
use App\Traits\Currencies;
use App\Traits\DateTime;
use App\Traits\Sales;
use App\Traits\Documents;
use App\Traits\Uploads;
use App\Utilities\Modules;
use Illuminate\Support\Facades\URL;
class Invoices extends Controller
{
use DateTime, Currencies, Sales, Uploads;
use DateTime, Currencies, Documents, Uploads;
/**
* @var string
*/
public $type = Document::INVOICE_TYPE;
/**
* Display a listing of the resource.
@ -24,13 +29,13 @@ class Invoices extends Controller
*/
public function index()
{
$invoices = Invoice::with('contact', 'histories', 'items', 'payments')
$invoices = Document::invoice()->with('contact', 'histories', 'items', 'payments')
->accrued()->where('contact_id', user()->contact->id)
->collect(['invoice_number'=> 'desc']);
->collect(['document_number'=> 'desc']);
$categories = collect(Category::income()->enabled()->orderBy('name')->pluck('name', 'id'));
$statuses = $this->getInvoiceStatuses();
$statuses = $this->getDocumentStatuses(Document::INVOICE_TYPE);
return $this->response('portal.invoices.index', compact('invoices', 'categories', 'statuses'));
}
@ -38,15 +43,15 @@ class Invoices extends Controller
/**
* Show the form for viewing the specified resource.
*
* @param Invoice $invoice
* @param Document $invoice
*
* @return Response
*/
public function show(Invoice $invoice, Request $request)
public function show(Document $invoice, Request $request)
{
$payment_methods = Modules::getPaymentMethods();
event(new \App\Events\Sale\InvoiceViewed($invoice));
event(new \App\Events\Document\DocumentViewed($invoice));
return view('portal.invoices.show', compact('invoice', 'payment_methods'));
}
@ -54,11 +59,11 @@ class Invoices extends Controller
/**
* Show the form for viewing the specified resource.
*
* @param Invoice $invoice
* @param Document $invoice
*
* @return Response
*/
public function printInvoice(Invoice $invoice, Request $request)
public function printInvoice(Document $invoice, Request $request)
{
$invoice = $this->prepareInvoice($invoice);
@ -68,11 +73,11 @@ class Invoices extends Controller
/**
* Show the form for viewing the specified resource.
*
* @param Invoice $invoice
* @param Document $invoice
*
* @return Response
*/
public function pdfInvoice(Invoice $invoice, Request $request)
public function pdfInvoice(Document $invoice, Request $request)
{
$invoice = $this->prepareInvoice($invoice);
@ -91,16 +96,16 @@ class Invoices extends Controller
return $pdf->download($file_name);
}
protected function prepareInvoice(Invoice $invoice)
protected function prepareInvoice(Document $invoice)
{
$invoice->template_path = 'sales.invoices.print_' . setting('invoice.template' ,'default');
event(new \App\Events\Sale\InvoicePrinting($invoice));
event(new \App\Events\Document\DocumentPrinting($invoice));
return $invoice;
}
public function signed(Invoice $invoice)
public function signed(Document $invoice)
{
if (empty($invoice)) {
redirect()->route('login');
@ -121,7 +126,7 @@ class Invoices extends Controller
$print_action = URL::signedRoute('signed.invoices.print', [$invoice->id, 'company_id' => session('company_id')]);
$pdf_action = URL::signedRoute('signed.invoices.pdf', [$invoice->id, 'company_id' => session('company_id')]);
event(new \App\Events\Sale\InvoiceViewed($invoice));
event(new \App\Events\Document\DocumentViewed($invoice));
return view('portal.invoices.signed', compact('invoice', 'payment_methods', 'payment_actions', 'print_action', 'pdf_action'));
}

View File

@ -3,32 +3,37 @@
namespace App\Http\Controllers\Purchases;
use App\Abstracts\Http\Controller;
use App\Exports\Purchases\Bills as Export;
use App\Exports\Document\Documents as Export;
use App\Http\Requests\Common\Import as ImportRequest;
use App\Http\Requests\Purchase\Bill as Request;
use App\Http\Requests\Purchase\BillAddItem as ItemRequest;
use App\Imports\Purchases\Bills as Import;
use App\Jobs\Banking\CreateDocumentTransaction;
use App\Jobs\Purchase\CreateBill;
use App\Jobs\Purchase\DeleteBill;
use App\Jobs\Purchase\DuplicateBill;
use App\Jobs\Purchase\UpdateBill;
use App\Http\Requests\Document\Document as Request;
use App\Http\Requests\Document\DocumentAddItem as ItemRequest;
use App\Imports\Document\Documents as Import;
use App\Jobs\Banking\CreateBankingDocumentTransaction;
use App\Jobs\Document\CreateDocument;
use App\Jobs\Document\DeleteDocument;
use App\Jobs\Document\DuplicateDocument;
use App\Jobs\Document\UpdateDocument;
use App\Models\Banking\Account;
use App\Models\Common\Contact;
use App\Models\Common\Item;
use App\Models\Purchase\Bill;
use App\Models\Document\Document;
use App\Models\Setting\Category;
use App\Models\Setting\Currency;
use App\Models\Setting\Tax;
use App\Traits\Currencies;
use App\Traits\DateTime;
use App\Traits\Purchases;
use App\Traits\Documents;
use App\Traits\Uploads;
use App\Utilities\Modules;
class Bills extends Controller
{
use Currencies, DateTime, Purchases, Uploads;
use Currencies, DateTime, Documents, Uploads;
/**
* @var string
*/
public $type = Document::BILL_TYPE;
/**
* Display a listing of the resource.
@ -37,7 +42,7 @@ class Bills extends Controller
*/
public function index()
{
$bills = Bill::with('contact', 'transactions')->collect(['billed_at'=> 'desc']);
$bills = Document::bill()->with('contact', 'transactions')->collect(['issued_at' => 'desc']);
return $this->response('purchases.bills.index', compact('bills'));
}
@ -45,11 +50,11 @@ class Bills extends Controller
/**
* Show the form for viewing the specified resource.
*
* @param Bill $bill
* @param Document $bill
*
* @return Response
*/
public function show(Bill $bill)
public function show(Document $bill)
{
$accounts = Account::enabled()->orderBy('name')->pluck('name', 'id');
@ -100,11 +105,9 @@ class Bills extends Controller
$taxes = Tax::enabled()->orderBy('name')->get();
$categories = Category::expense()->enabled()->orderBy('name')->take(setting('default.select_limit'))->pluck('name', 'id');
$number = $this->getNextDocumentNumber(Document::BILL_TYPE);
$number = $this->getNextBillNumber();
return view('purchases.bills.create', compact('vendors', 'currencies', 'currency', 'items', 'taxes', 'categories', 'number'));
return view('purchases.bills.create', compact('vendors', 'currencies', 'currency', 'items', 'taxes', 'number'));
}
/**
@ -116,7 +119,7 @@ class Bills extends Controller
*/
public function store(Request $request)
{
$response = $this->ajaxDispatch(new CreateBill($request));
$response = $this->ajaxDispatch(new CreateDocument($request));
if ($response['success']) {
$response['redirect'] = route('bills.show', $response['data']->id);
@ -138,13 +141,13 @@ class Bills extends Controller
/**
* Duplicate the specified resource.
*
* @param Bill $bill
* @param Document $bill
*
* @return Response
*/
public function duplicate(Bill $bill)
public function duplicate(Document $bill)
{
$clone = $this->dispatch(new DuplicateBill($bill));
$clone = $this->dispatch(new DuplicateDocument($bill));
$message = trans('messages.success.duplicated', ['type' => trans_choice('general.bills', 1)]);
@ -163,7 +166,7 @@ class Bills extends Controller
public function import(ImportRequest $request)
{
try {
\Excel::import(new Import(), $request->file('import'));
\Excel::import(new Import(Document::BILL_TYPE), $request->file('import'));
} catch (\Maatwebsite\Excel\Exceptions\SheetNotFoundException $e) {
flash($e->getMessage())->error()->important();
@ -180,11 +183,11 @@ class Bills extends Controller
/**
* Show the form for editing the specified resource.
*
* @param Bill $bill
* @param Document $bill
*
* @return Response
*/
public function edit(Bill $bill)
public function edit(Document $bill)
{
$vendors = Contact::vendor()->enabled()->orderBy('name')->take(setting('default.select_limit'))->pluck('name', 'id');
@ -196,22 +199,20 @@ class Bills extends Controller
$taxes = Tax::enabled()->orderBy('name')->get();
$categories = Category::expense()->enabled()->orderBy('name')->take(setting('default.select_limit'))->pluck('name', 'id');
return view('purchases.bills.edit', compact('bill', 'vendors', 'currencies', 'currency', 'items', 'taxes', 'categories'));
return view('purchases.bills.edit', compact('bill', 'vendors', 'currencies', 'currency', 'items', 'taxes'));
}
/**
* Update the specified resource in storage.
*
* @param Bill $bill
* @param Request $request
* @param Document $bill
* @param Request $request
*
* @return Response
*/
public function update(Bill $bill, Request $request)
public function update(Document $bill, Request $request)
{
$response = $this->ajaxDispatch(new UpdateBill($bill, $request));
$response = $this->ajaxDispatch(new UpdateDocument($bill, $request));
if ($response['success']) {
$response['redirect'] = route('bills.show', $response['data']->id);
@ -237,9 +238,9 @@ class Bills extends Controller
*
* @return Response
*/
public function destroy(Bill $bill)
public function destroy(Document $bill)
{
$response = $this->ajaxDispatch(new DeleteBill($bill));
$response = $this->ajaxDispatch(new DeleteDocument($bill));
$response['redirect'] = route('bills.index');
@ -263,19 +264,19 @@ class Bills extends Controller
*/
public function export()
{
return \Excel::download(new Export(), \Str::filename(trans_choice('general.bills', 2)) . '.xlsx');
return \Excel::download(new Export(null, Document::BILL_TYPE), \Str::filename(trans_choice('general.bills', 2)) . '.xlsx');
}
/**
* Mark the bill as received.
*
* @param Bill $bill
* @param Document $bill
*
* @return Response
*/
public function markReceived(Bill $bill)
public function markReceived(Document $bill)
{
event(new \App\Events\Purchase\BillReceived($bill));
event(new \App\Events\Document\DocumentReceived($bill));
$message = trans('bills.messages.marked_received');
@ -287,13 +288,13 @@ class Bills extends Controller
/**
* Mark the bill as cancelled.
*
* @param Bill $bill
* @param Document $bill
*
* @return Response
*/
public function markCancelled(Bill $bill)
public function markCancelled(Document $bill)
{
event(new \App\Events\Purchase\BillCancelled($bill));
event(new \App\Events\Document\DocumentCancelled($bill));
$message = trans('bills.messages.marked_cancelled');
@ -305,11 +306,11 @@ class Bills extends Controller
/**
* Print the bill.
*
* @param Bill $bill
* @param Document $bill
*
* @return Response
*/
public function printBill(Bill $bill)
public function printBill(Document $bill)
{
$bill = $this->prepareBill($bill);
@ -321,11 +322,11 @@ class Bills extends Controller
/**
* Download the PDF file of bill.
*
* @param Bill $bill
* @param Document $bill
*
* @return Response
*/
public function pdfBill(Bill $bill)
public function pdfBill(Document $bill)
{
$bill = $this->prepareBill($bill);
@ -345,14 +346,14 @@ class Bills extends Controller
/**
* Mark the bill as paid.
*
* @param Bill $bill
* @param Document $bill
*
* @return Response
*/
public function markPaid(Bill $bill)
public function markPaid(Document $bill)
{
try {
$this->dispatch(new CreateDocumentTransaction($bill, []));
$this->dispatch(new CreateBankingDocumentTransaction($bill, []));
$message = trans('bills.messages.marked_paid');
@ -397,7 +398,7 @@ class Bills extends Controller
]);
}
protected function prepareBill(Bill $bill)
protected function prepareBill(Document $bill)
{
$paid = 0;

View File

@ -12,7 +12,7 @@ use App\Jobs\Common\DeleteContact;
use App\Jobs\Common\UpdateContact;
use App\Models\Banking\Transaction;
use App\Models\Common\Contact;
use App\Models\Purchase\Bill;
use App\Models\Document\Document;
use App\Models\Setting\Currency;
use App\Traits\Contacts;
use Date;
@ -51,7 +51,7 @@ class Vendors extends Controller
$counts = [];
// Handle bills
$bills = Bill::with('transactions')->where('contact_id', $vendor->id)->get();
$bills = Document::bill()->with('transactions')->where('contact_id', $vendor->id)->get();
$counts['bills'] = $bills->count();

View File

@ -12,7 +12,7 @@ use App\Jobs\Common\DeleteContact;
use App\Jobs\Common\UpdateContact;
use App\Models\Banking\Transaction;
use App\Models\Common\Contact;
use App\Models\Sale\Invoice;
use App\Models\Document\Document;
use App\Models\Setting\Currency;
use Date;
use Illuminate\Http\Request as BaseRequest;
@ -49,7 +49,7 @@ class Customers extends Controller
$counts = [];
// Handle invoices
$invoices = Invoice::with('transactions')->where('contact_id', $customer->id)->get();
$invoices = Document::invoice()->with('transactions')->where('contact_id', $customer->id)->get();
$counts['invoices'] = $invoices->count();
@ -87,7 +87,7 @@ class Customers extends Controller
$limit = request('limit', setting('default.list_limit', '25'));
$transactions = $this->paginate($transactions->sortByDesc('paid_at'), $limit);
$invoices = $this->paginate($invoices->sortByDesc('invoiced_at'), $limit);
$invoices = $this->paginate($invoices->sortByDesc('issued_at'), $limit);
return view('sales.customers.show', compact('customer', 'counts', 'amounts', 'transactions', 'invoices'));
}

View File

@ -3,33 +3,28 @@
namespace App\Http\Controllers\Sales;
use App\Abstracts\Http\Controller;
use App\Exports\Sales\Invoices as Export;
use App\Exports\Document\Documents as Export;
use App\Http\Requests\Common\Import as ImportRequest;
use App\Http\Requests\Sale\Invoice as Request;
use App\Http\Requests\Sale\InvoiceAddItem as ItemRequest;
use App\Imports\Sales\Invoices as Import;
use App\Jobs\Sale\CreateInvoice;
use App\Jobs\Sale\DeleteInvoice;
use App\Jobs\Sale\DuplicateInvoice;
use App\Jobs\Sale\UpdateInvoice;
use App\Models\Banking\Account;
use App\Models\Common\Contact;
use App\Models\Common\Item;
use App\Models\Sale\Invoice;
use App\Models\Setting\Category;
use App\Models\Setting\Currency;
use App\Models\Setting\Tax;
use App\Http\Requests\Document\Document as Request;
use App\Imports\Document\Documents as Import;
use App\Jobs\Document\CreateDocument;
use App\Jobs\Document\DeleteDocument;
use App\Jobs\Document\DuplicateDocument;
use App\Jobs\Document\UpdateDocument;
use App\Models\Document\Document;
use App\Notifications\Sale\Invoice as Notification;
use App\Traits\Currencies;
use App\Traits\DateTime;
use App\Traits\Sales;
use App\Models\Setting\Currency;
use App\Traits\Documents;
use App\Utilities\Modules;
use File;
use Illuminate\Support\Facades\URL;
class Invoices extends Controller
{
use Currencies, DateTime, Sales;
use Documents;
/**
* @var string
*/
public $type = Document::INVOICE_TYPE;
/**
* Display a listing of the resource.
@ -38,7 +33,7 @@ class Invoices extends Controller
*/
public function index()
{
$invoices = Invoice::with('contact', 'transactions')->collect(['invoice_number'=> 'desc']);
$invoices = Document::invoice()->with('contact', 'transactions')->collect(['document_number'=> 'desc']);
return $this->response('sales.invoices.index', compact('invoices'));
}
@ -46,30 +41,14 @@ class Invoices extends Controller
/**
* Show the form for viewing the specified resource.
*
* @param Invoice $invoice
* @param Document $invoice
*
* @return Response
*/
public function show(Invoice $invoice)
public function show(Document $invoice)
{
$accounts = Account::enabled()->orderBy('name')->pluck('name', 'id');
$currencies = Currency::enabled()->orderBy('name')->pluck('name', 'code')->toArray();
$currency = Currency::where('code', $invoice->currency_code)->first();
$account_currency_code = Account::where('id', setting('default.account'))->pluck('currency_code')->first();
$customers = Contact::customer()->enabled()->orderBy('name')->pluck('name', 'id');
$categories = Category::income()->enabled()->orderBy('name')->pluck('name', 'id');
$payment_methods = Modules::getPaymentMethods();
$signed_url = URL::signedRoute('signed.invoices.show', [$invoice->id, 'company_id' => session('company_id')]);
$date_format = $this->getCompanyDateFormat();
// Get Invoice Totals
foreach ($invoice->totals_sorted as $invoice_total) {
$invoice->{$invoice_total->code} = $invoice_total->amount;
@ -83,7 +62,7 @@ class Invoices extends Controller
$invoice->grand_total = round($invoice->total - $invoice->paid, $currency->precision);
}
return view('sales.invoices.show', compact('invoice', 'accounts', 'currencies', 'currency', 'account_currency_code', 'customers', 'categories', 'payment_methods', 'signed_url', 'date_format'));
return view('sales.invoices.show', compact('invoice'));
}
/**
@ -93,21 +72,7 @@ class Invoices extends Controller
*/
public function create()
{
$customers = Contact::customer()->enabled()->orderBy('name')->take(setting('default.select_limit'))->pluck('name', 'id');
$currencies = Currency::enabled()->orderBy('name')->pluck('name', 'code')->toArray();
$currency = Currency::where('code', setting('default.currency'))->first();
$items = Item::enabled()->orderBy('name')->get();
$taxes = Tax::enabled()->orderBy('name')->get();
$categories = Category::income()->enabled()->orderBy('name')->take(setting('default.select_limit'))->pluck('name', 'id');
$number = $this->getNextInvoiceNumber();
return view('sales.invoices.create', compact('customers', 'currencies', 'currency', 'items', 'taxes', 'categories', 'number'));
return view('sales.invoices.create');
}
/**
@ -119,7 +84,7 @@ class Invoices extends Controller
*/
public function store(Request $request)
{
$response = $this->ajaxDispatch(new CreateInvoice($request));
$response = $this->ajaxDispatch(new CreateDocument($request));
if ($response['success']) {
$response['redirect'] = route('invoices.show', $response['data']->id);
@ -141,13 +106,13 @@ class Invoices extends Controller
/**
* Duplicate the specified resource.
*
* @param Invoice $invoice
* @param Document $invoice
*
* @return Response
*/
public function duplicate(Invoice $invoice)
public function duplicate(Document $invoice)
{
$clone = $this->dispatch(new DuplicateInvoice($invoice));
$clone = $this->dispatch(new DuplicateDocument($invoice));
$message = trans('messages.success.duplicated', ['type' => trans_choice('general.invoices', 1)]);
@ -166,7 +131,7 @@ class Invoices extends Controller
public function import(ImportRequest $request)
{
try {
\Excel::import(new Import(), $request->file('import'));
\Excel::import(new Import(Document::INVOICE_TYPE), $request->file('import'));
} catch (\Maatwebsite\Excel\Exceptions\SheetNotFoundException $e) {
flash($e->getMessage())->error()->important();
@ -183,38 +148,26 @@ class Invoices extends Controller
/**
* Show the form for editing the specified resource.
*
* @param Invoice $invoice
* @param Document $invoice
*
* @return Response
*/
public function edit(Invoice $invoice)
public function edit(Document $invoice)
{
$customers = Contact::customer()->enabled()->orderBy('name')->take(setting('default.select_limit'))->pluck('name', 'id');
$currencies = Currency::enabled()->orderBy('name')->pluck('name', 'code')->toArray();
$currency = Currency::where('code', $invoice->currency_code)->first();
$items = Item::enabled()->orderBy('name')->get();
$taxes = Tax::enabled()->orderBy('name')->get();
$categories = Category::income()->enabled()->orderBy('name')->take(setting('default.select_limit'))->pluck('name', 'id');
return view('sales.invoices.edit', compact('invoice', 'customers', 'currencies', 'currency', 'items', 'taxes', 'categories'));
return view('sales.invoices.edit', compact('invoice'));
}
/**
* Update the specified resource in storage.
*
* @param Invoice $invoice
* @param Request $request
* @param Document $invoice
* @param Request $request
*
* @return Response
*/
public function update(Invoice $invoice, Request $request)
public function update(Document $invoice, Request $request)
{
$response = $this->ajaxDispatch(new UpdateInvoice($invoice, $request));
$response = $this->ajaxDispatch(new UpdateDocument($invoice, $request));
if ($response['success']) {
$response['redirect'] = route('invoices.show', $response['data']->id);
@ -236,13 +189,13 @@ class Invoices extends Controller
/**
* Remove the specified resource from storage.
*
* @param Invoice $invoice
* @param Document $invoice
*
* @return Response
*/
public function destroy(Invoice $invoice)
public function destroy(Document $invoice)
{
$response = $this->ajaxDispatch(new DeleteInvoice($invoice));
$response = $this->ajaxDispatch(new DeleteDocument($invoice));
$response['redirect'] = route('invoices.index');
@ -266,19 +219,19 @@ class Invoices extends Controller
*/
public function export()
{
return \Excel::download(new Export(), \Str::filename(trans_choice('general.invoices', 2)) . '.xlsx');
return \Excel::download(new Export(null, Document::INVOICE_TYPE), \Str::filename(trans_choice('general.invoices', 2)) . '.xlsx');
}
/**
* Mark the invoice as sent.
*
* @param Invoice $invoice
* @param Document $invoice
*
* @return Response
*/
public function markSent(Invoice $invoice)
public function markSent(Document $invoice)
{
event(new \App\Events\Sale\InvoiceSent($invoice));
event(new \App\Events\Document\DocumentSent($invoice));
$message = trans('invoices.messages.marked_sent');
@ -290,13 +243,13 @@ class Invoices extends Controller
/**
* Mark the invoice as cancelled.
*
* @param Invoice $invoice
* @param Document $invoice
*
* @return Response
*/
public function markCancelled(Invoice $invoice)
public function markCancelled(Document $invoice)
{
event(new \App\Events\Sale\InvoiceCancelled($invoice));
event(new \App\Events\Document\DocumentCancelled($invoice));
$message = trans('invoices.messages.marked_cancelled');
@ -308,11 +261,11 @@ class Invoices extends Controller
/**
* Download the PDF file of invoice.
*
* @param Invoice $invoice
* @param Document $invoice
*
* @return Response
*/
public function emailInvoice(Invoice $invoice)
public function emailInvoice(Document $invoice)
{
if (empty($invoice->contact_email)) {
return redirect()->back();
@ -326,7 +279,7 @@ class Invoices extends Controller
$pdf = app('dompdf.wrapper');
$pdf->loadHTML($html);
$file_name = $this->getInvoiceFileName($invoice);
$file_name = $this->getDocumentFileName($invoice);
$file = storage_path('app/temp/' . $file_name);
@ -346,7 +299,7 @@ class Invoices extends Controller
unset($invoice->pdf_path);
unset($invoice->reconciled);
event(new \App\Events\Sale\InvoiceSent($invoice));
event(new \App\Events\Document\DocumentSent($invoice));
flash(trans('invoices.messages.email_sent'))->success();
@ -356,11 +309,11 @@ class Invoices extends Controller
/**
* Print the invoice.
*
* @param Invoice $invoice
* @param Document $invoice
*
* @return Response
*/
public function printInvoice(Invoice $invoice)
public function printInvoice(Document $invoice)
{
$invoice = $this->prepareInvoice($invoice);
@ -372,11 +325,11 @@ class Invoices extends Controller
/**
* Download the PDF file of invoice.
*
* @param Invoice $invoice
* @param Document $invoice
*
* @return Response
*/
public function pdfInvoice(Invoice $invoice)
public function pdfInvoice(Document $invoice)
{
$invoice = $this->prepareInvoice($invoice);
@ -390,7 +343,7 @@ class Invoices extends Controller
//$pdf->setPaper('A4', 'portrait');
$file_name = $this->getInvoiceFileName($invoice);
$file_name = $this->getDocumentFileName($invoice);
return $pdf->download($file_name);
}
@ -398,14 +351,14 @@ class Invoices extends Controller
/**
* Mark the invoice as paid.
*
* @param Invoice $invoice
* @param Document $invoice
*
* @return Response
*/
public function markPaid(Invoice $invoice)
public function markPaid(Document $invoice)
{
try {
event(new \App\Events\Sale\PaymentReceived($invoice));
event(new \App\Events\Document\PaymentReceived($invoice));
$message = trans('invoices.messages.marked_paid');
@ -419,38 +372,7 @@ class Invoices extends Controller
return redirect()->back();
}
public function addItem(ItemRequest $request)
{
$item_row = $request['item_row'];
$currency_code = $request['currency_code'];
$taxes = Tax::enabled()->orderBy('name')->get()->pluck('title', 'id');
$currency = Currency::where('code', $currency_code)->first();
if (empty($currency)) {
$currency = Currency::where('code', setting('default.currency'))->first();
}
if ($currency) {
// it should be integer for amount mask
$currency->precision = (int) $currency->precision;
}
$html = view('sales.invoices.item', compact('item_row', 'taxes', 'currency'))->render();
return response()->json([
'success' => true,
'error' => false,
'data' => [
'currency' => $currency
],
'message' => 'null',
'html' => $html,
]);
}
protected function prepareInvoice(Invoice $invoice)
protected function prepareInvoice(Document $invoice)
{
$paid = 0;
@ -468,9 +390,9 @@ class Invoices extends Controller
$invoice->paid = $paid;
$invoice->template_path = 'sales.invoices.print_' . setting('invoice.template' ,'default');
$invoice->template_path = 'sales.invoices.print_' . setting('invoice.template');
event(new \App\Events\Sale\InvoicePrinting($invoice));
event(new \App\Events\Document\DocumentPrinting($invoice));
return $invoice;
}

View File

@ -17,7 +17,7 @@ class DateFormat
public function handle($request, Closure $next)
{
if (($request->method() == 'POST') || ($request->method() == 'PATCH')) {
$fields = ['paid_at', 'due_at', 'billed_at', 'invoiced_at', 'started_at', 'ended_at'];
$fields = ['paid_at', 'due_at', 'issued_at', 'started_at', 'ended_at'];
foreach ($fields as $field) {
$date = $request->get($field);

View File

@ -17,8 +17,7 @@ class Money
{
if ($request->method() == 'POST' || $request->method() == 'PATCH') {
$amount = $request->get('amount');
$bill_number = $request->get('bill_number');
$invoice_number = $request->get('invoice_number');
$document_number = $request->get('document_number');
$sale_price = $request->get('sale_price');
$purchase_price = $request->get('purchase_price');
$opening_balance = $request->get('opening_balance');
@ -30,7 +29,7 @@ class Money
$request->request->set('amount', $amount);
}
if (isset($bill_number) || isset($invoice_number) || !empty($items)) {
if (isset($document_number) || !empty($items)) {
if (!empty($items)) {
foreach ($items as $key => $item) {
if (!isset($item['price'])) {

View File

@ -2,7 +2,7 @@
namespace App\Http\Middleware;
use App\Models\Sale\Invoice;
use App\Models\Document\Document;
use Closure;
class RedirectSignedIfAuthenticated
@ -27,7 +27,7 @@ class RedirectSignedIfAuthenticated
if ($request->segment(2) == 'invoices') {
$page = 'invoices.show';
$invoice = Invoice::find($request->segment(3));
$invoice = Document::find($request->segment(3));
$params = [$invoice->id];
}

View File

@ -1,11 +1,13 @@
<?php
namespace App\Http\Requests\Sale;
namespace App\Http\Requests\Document;
use App\Abstracts\Http\FormRequest;
use Date;
use App\Models\Document\Document as Model;
use App\Utilities\Date;
use Illuminate\Support\Str;
class Invoice extends FormRequest
class Document extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
@ -24,9 +26,13 @@ class Invoice extends FormRequest
*/
public function rules()
{
$type = $this->request->get('type', Model::INVOICE_TYPE);
$type = Str::replaceFirst('-', '_', $type);
// Check if store or update
if ($this->getMethod() == 'PATCH') {
$id = is_numeric($this->invoice) ? $this->invoice : $this->invoice->getAttribute('id');
$id = is_numeric($this->$type) ? $this->$type : $this->{$type}->getAttribute('id');
} else {
$id = null;
}
@ -41,15 +47,15 @@ class Invoice extends FormRequest
$company_id = $this->request->get('company_id');
return [
'invoice_number' => 'required|string|unique:invoices,NULL,' . $id . ',id,company_id,' . $company_id . ',deleted_at,NULL',
'type' => 'required|string',
'document_number' => 'required|string|unique:documents,NULL,' . $id . ',id,type,' . $type . ',company_id,' . $company_id . ',deleted_at,NULL',
'status' => 'required|string',
'invoiced_at' => 'required|date_format:Y-m-d H:i:s',
'issued_at' => 'required|date_format:Y-m-d H:i:s',
'due_at' => 'required|date_format:Y-m-d H:i:s',
'amount' => 'required',
'items.*.name' => 'required|string',
'items.*.quantity' => 'required',
'items.*.price' => 'required|amount',
'items.*.currency' => 'required|string|currency',
'currency_code' => 'required|string|currency',
'currency_rate' => 'required',
'contact_id' => 'required|integer',
@ -63,10 +69,10 @@ class Invoice extends FormRequest
{
if ($validator->errors()->count()) {
// Set date
$invoiced_at = Date::parse($this->request->get('invoiced_at'))->format('Y-m-d');
$issued_at = Date::parse($this->request->get('issued_at'))->format('Y-m-d');
$due_at = Date::parse($this->request->get('due_at'))->format('Y-m-d');
$this->request->set('invoiced_at', $invoiced_at);
$this->request->set('issued_at', $issued_at);
$this->request->set('due_at', $due_at);
}
}

View File

@ -1,10 +1,10 @@
<?php
namespace App\Http\Requests\Purchase;
namespace App\Http\Requests\Document;
use App\Abstracts\Http\FormRequest;
class BillAddItem extends FormRequest
class DocumentAddItem extends FormRequest
{
/**
* Determine if the user is authorized to make this request.

View File

@ -1,10 +1,10 @@
<?php
namespace App\Http\Requests\Sale;
namespace App\Http\Requests\Document;
use App\Abstracts\Http\FormRequest;
class InvoiceHistory extends FormRequest
class DocumentHistory extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
@ -24,7 +24,8 @@ class InvoiceHistory extends FormRequest
public function rules()
{
return [
'invoice_id' => 'required|integer',
'type' => 'required|string',
'document_id' => 'required|integer',
'status' => 'required|string',
'notify' => 'required|integer',
];

View File

@ -1,10 +1,10 @@
<?php
namespace App\Http\Requests\Sale;
namespace App\Http\Requests\Document;
use App\Abstracts\Http\FormRequest;
class InvoiceItem extends FormRequest
class DocumentItem extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
@ -24,7 +24,8 @@ class InvoiceItem extends FormRequest
public function rules()
{
return [
'invoice_id' => 'required|integer',
'type' => 'required|string',
'document_id' => 'required|integer',
'name' => 'required|string',
'quantity' => 'required|integer',
'price' => 'required',

View File

@ -1,10 +1,10 @@
<?php
namespace App\Http\Requests\Purchase;
namespace App\Http\Requests\Document;
use App\Abstracts\Http\FormRequest;
class BillItemTax extends FormRequest
class DocumentItemTax extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
@ -24,8 +24,9 @@ class BillItemTax extends FormRequest
public function rules()
{
return [
'bill_id' => 'required|integer',
'bill_item_id' => 'required|integer',
'type' => 'required|string',
'document_id' => 'required|integer',
'document_item_id' => 'required|integer',
'tax_id' => 'required|integer',
'name' => 'required|string',
'amount' => 'required',

View File

@ -1,10 +1,10 @@
<?php
namespace App\Http\Requests\Purchase;
namespace App\Http\Requests\Document;
use App\Abstracts\Http\FormRequest;
class BillTotal extends FormRequest
class DocumentTotal extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
@ -24,7 +24,8 @@ class BillTotal extends FormRequest
public function rules()
{
return [
'bill_id' => 'required|integer',
'type' => 'required|string',
'document_id' => 'required|integer',
'name' => 'required|string',
'amount' => 'required|amount',
'sort_order' => 'required|integer',

View File

@ -1,84 +0,0 @@
<?php
namespace App\Http\Requests\Purchase;
use App\Abstracts\Http\FormRequest;
use Date;
class Bill extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
// Check if store or update
if ($this->getMethod() == 'PATCH') {
$id = is_numeric($this->bill) ? $this->bill : $this->bill->getAttribute('id');
} else {
$id = null;
}
$attachment = 'nullable';
if ($this->request->get('attachment', null)) {
$attachment = 'mimes:' . config('filesystems.mimes') . '|between:0,' . config('filesystems.max_size') * 1024;
}
// Get company id
$company_id = $this->request->get('company_id');
return [
'bill_number' => 'required|string|unique:bills,NULL,' . $id . ',id,company_id,' . $company_id . ',deleted_at,NULL',
'status' => 'required|string',
'billed_at' => 'required|date_format:Y-m-d H:i:s',
'due_at' => 'required|date_format:Y-m-d H:i:s',
'amount' => 'required',
'items.*.name' => 'required|string',
'items.*.quantity' => 'required',
'items.*.price' => 'required|amount',
'items.*.currency' => 'required|string|currency',
'currency_code' => 'required|string|currency',
'currency_rate' => 'required',
'contact_id' => 'required|integer',
'contact_name' => 'required|string',
'category_id' => 'required|integer',
'attachment' => $attachment,
];
}
public function withValidator($validator)
{
if ($validator->errors()->count()) {
// Set date
$billed_at = Date::parse($this->request->get('billed_at'))->format('Y-m-d');
$due_at = Date::parse($this->request->get('due_at'))->format('Y-m-d');
$this->request->set('billed_at', $billed_at);
$this->request->set('due_at', $due_at);
}
}
public function messages()
{
return [
'items.*.name.required' => trans('validation.required', ['attribute' => mb_strtolower(trans('general.name'))]),
'items.*.quantity.required' => trans('validation.required', ['attribute' => mb_strtolower(trans('bills.quantity'))]),
'items.*.price.required' => trans('validation.required', ['attribute' => mb_strtolower(trans('bills.price'))]),
'items.*.currency.required' => trans('validation.custom.invalid_currency'),
'items.*.currency.string' => trans('validation.custom.invalid_currency'),
];
}
}

View File

@ -1,32 +0,0 @@
<?php
namespace App\Http\Requests\Purchase;
use App\Abstracts\Http\FormRequest;
class BillHistory extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'bill_id' => 'required|integer',
'status' => 'required|string',
'notify' => 'required|integer',
];
}
}

View File

@ -1,36 +0,0 @@
<?php
namespace App\Http\Requests\Purchase;
use App\Abstracts\Http\FormRequest;
class BillItem extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'bill_id' => 'required|integer',
'name' => 'required|string',
'quantity' => 'required|integer',
'price' => 'required',
'total' => 'required',
'tax' => 'required',
'tax_id' => 'required',
];
}
}

View File

@ -1,31 +0,0 @@
<?php
namespace App\Http\Requests\Sale;
use App\Abstracts\Http\FormRequest;
class InvoiceAddItem extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'item_row' => 'required|integer',
'currency_code' => 'required|string|currency',
];
}
}

View File

@ -1,34 +0,0 @@
<?php
namespace App\Http\Requests\Sale;
use App\Abstracts\Http\FormRequest;
class InvoiceItemTax extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'invoice_id' => 'required|integer',
'invoice_item_id' => 'required|integer',
'tax_id' => 'required|integer',
'name' => 'required|string',
'amount' => 'required',
];
}
}

View File

@ -1,33 +0,0 @@
<?php
namespace App\Http\Requests\Sale;
use App\Abstracts\Http\FormRequest;
class InvoiceTotal extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'invoice_id' => 'required|integer',
'name' => 'required|string',
'amount' => 'required|amount',
'sort_order' => 'required|integer',
];
}
}

Some files were not shown because too many files have changed in this diff Show More