Merge pull request 'development' (#115) from development into main
Some checks failed
Deploy / deploy (push) Failing after 15s
Some checks failed
Deploy / deploy (push) Failing after 15s
Reviewed-on: #115
This commit is contained in:
commit
44ec2068c3
25
.dockerignore
Normal file
25
.dockerignore
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
# .dockerignore
|
||||||
|
/deploy/docker-compose.yml
|
||||||
|
/deploy/Dockerfile
|
||||||
|
/.phpunit.cache
|
||||||
|
/node_modules
|
||||||
|
/public/build
|
||||||
|
/public/hot
|
||||||
|
/public/storage
|
||||||
|
/public/bucket
|
||||||
|
/storage/*.key
|
||||||
|
/vendor
|
||||||
|
.env
|
||||||
|
.env.example
|
||||||
|
.env.backup
|
||||||
|
.env.production
|
||||||
|
.phpunit.result.cache
|
||||||
|
Homestead.json
|
||||||
|
Homestead.yaml
|
||||||
|
auth.json
|
||||||
|
npm-debug.log
|
||||||
|
yarn-error.log
|
||||||
|
/.fleet
|
||||||
|
/.idea
|
||||||
|
/.vscode
|
||||||
|
.git
|
@ -54,7 +54,7 @@ public static function table(Table $table): Table
|
|||||||
TextColumn::make('balance')
|
TextColumn::make('balance')
|
||||||
->getStateUsing(fn (Customer $customer) => $customer->calculateBalance())
|
->getStateUsing(fn (Customer $customer) => $customer->calculateBalance())
|
||||||
->money()
|
->money()
|
||||||
->hidden(! auth()->user()->is_admin),
|
->hidden(! auth()->user()->is_admin ?? false),
|
||||||
])
|
])
|
||||||
->filters([
|
->filters([
|
||||||
//
|
//
|
||||||
|
@ -15,7 +15,9 @@ protected function getHeaderActions(): array
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
Actions\CreateAction::make()
|
Actions\CreateAction::make()
|
||||||
->icon(IconEnum::NEW->value),
|
->modal()
|
||||||
|
->icon(IconEnum::NEW->value)
|
||||||
|
->successRedirectUrl(fn ($record) => CustomerResource::getUrl('edit', ['record' => $record->id])),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,11 @@
|
|||||||
namespace App\Filament\Admin\Resources;
|
namespace App\Filament\Admin\Resources;
|
||||||
|
|
||||||
use App\Enums\IconEnum;
|
use App\Enums\IconEnum;
|
||||||
|
use App\Enums\InvoiceStatus;
|
||||||
use App\Filament\Admin\Resources\InvoiceReportResource\RelationManagers\InvoicesRelationManager;
|
use App\Filament\Admin\Resources\InvoiceReportResource\RelationManagers\InvoicesRelationManager;
|
||||||
use App\Models\InvoiceReport;
|
use App\Models\InvoiceReport;
|
||||||
use Filament\Forms\Components\DatePicker;
|
use Filament\Forms\Components\DatePicker;
|
||||||
|
use Filament\Forms\Components\Group;
|
||||||
use Filament\Forms\Components\Placeholder;
|
use Filament\Forms\Components\Placeholder;
|
||||||
use Filament\Forms\Components\Section;
|
use Filament\Forms\Components\Section;
|
||||||
use Filament\Forms\Components\Select;
|
use Filament\Forms\Components\Select;
|
||||||
@ -32,28 +34,34 @@ public static function form(Form $form): Form
|
|||||||
return $form
|
return $form
|
||||||
->schema([
|
->schema([
|
||||||
Section::make([
|
Section::make([
|
||||||
|
Group::make([
|
||||||
Select::make('customer_id')
|
Select::make('customer_id')
|
||||||
->relationship('customer', 'company_name')
|
->relationship('customer', 'company_name')
|
||||||
->preload()
|
->preload()
|
||||||
->required()
|
->required()
|
||||||
|
->columnSpanFull()
|
||||||
->searchable(),
|
->searchable(),
|
||||||
ToggleButtons::make('filter_paid')
|
|
||||||
->boolean()
|
ToggleButtons::make('payment_types')
|
||||||
->required()
|
->required()
|
||||||
->default(false)
|
->options(InvoiceStatus::class)
|
||||||
->colors([
|
->multiple()
|
||||||
'true' => 'info',
|
->columnSpanFull()
|
||||||
'false' => 'info',
|
|
||||||
])
|
|
||||||
->inline(),
|
->inline(),
|
||||||
|
|
||||||
DatePicker::make('date_start')
|
DatePicker::make('date_start')
|
||||||
->required(),
|
->required()
|
||||||
|
->columnSpan(1),
|
||||||
|
|
||||||
DatePicker::make('date_end')
|
DatePicker::make('date_end')
|
||||||
->required()
|
->required()
|
||||||
->default(today()),
|
->default(today())
|
||||||
|
->columnSpan(1),
|
||||||
|
])->columnSpan(fn (?InvoiceReport $record) => $record === null ? 5 : 3)
|
||||||
|
->columns(2),
|
||||||
])
|
])
|
||||||
->columns(2)
|
->columns(5)
|
||||||
->columnSpan(2),
|
->columnSpan(fn ($record) => $record === null ? 3 : 2),
|
||||||
|
|
||||||
Section::make([
|
Section::make([
|
||||||
Placeholder::make('created_at')
|
Placeholder::make('created_at')
|
||||||
@ -115,7 +123,7 @@ public static function getPages(): array
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'index' => \App\Filament\Admin\Resources\InvoiceReportResource\Pages\ListInvoiceReports::route('/'),
|
'index' => \App\Filament\Admin\Resources\InvoiceReportResource\Pages\ListInvoiceReports::route('/'),
|
||||||
'create' => \App\Filament\Admin\Resources\InvoiceReportResource\Pages\CreateInvoiceReport::route('/create'),
|
// 'create' => \App\Filament\Admin\Resources\InvoiceReportResource\Pages\CreateInvoiceReport::route('/create'),
|
||||||
'view' => \App\Filament\Admin\Resources\InvoiceReportResource\Pages\ViewInvoiceReport::route('/{record}'),
|
'view' => \App\Filament\Admin\Resources\InvoiceReportResource\Pages\ViewInvoiceReport::route('/{record}'),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,6 @@
|
|||||||
|
|
||||||
namespace App\Filament\Admin\Resources\InvoiceReportResource\Pages;
|
namespace App\Filament\Admin\Resources\InvoiceReportResource\Pages;
|
||||||
|
|
||||||
use App\Filament\Admin\Resources\InvoiceReportResource;
|
|
||||||
use Filament\Resources\Pages\CreateRecord;
|
use Filament\Resources\Pages\CreateRecord;
|
||||||
|
|
||||||
class CreateInvoiceReport extends CreateRecord
|
class CreateInvoiceReport extends CreateRecord {}
|
||||||
{
|
|
||||||
protected static string $resource = InvoiceReportResource::class;
|
|
||||||
}
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
namespace App\Filament\Admin\Resources\InvoiceReportResource\Pages;
|
namespace App\Filament\Admin\Resources\InvoiceReportResource\Pages;
|
||||||
|
|
||||||
use App\Enums\IconEnum;
|
use App\Enums\IconEnum;
|
||||||
|
use App\Enums\InvoiceStatus;
|
||||||
use App\Filament\Admin\Resources\InvoiceReportResource;
|
use App\Filament\Admin\Resources\InvoiceReportResource;
|
||||||
use Filament\Actions;
|
use Filament\Actions;
|
||||||
use Filament\Resources\Pages\ListRecords;
|
use Filament\Resources\Pages\ListRecords;
|
||||||
@ -17,7 +18,31 @@ protected function getHeaderActions(): array
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
Actions\CreateAction::make()
|
Actions\CreateAction::make()
|
||||||
->icon(IconEnum::NEW->value),
|
->modalWidth('xl')
|
||||||
|
->icon(IconEnum::NEW->value)
|
||||||
|
->mutateFormDataUsing(function ($data) {
|
||||||
|
/* Initialize all payment statues to false,
|
||||||
|
map selected payment types to corresponding status,
|
||||||
|
assign filtered statuses to specific keys */
|
||||||
|
|
||||||
|
$paymentTypes = array_fill_keys(array_map(fn ($status) => $status->name, InvoiceStatus::cases()), false);
|
||||||
|
|
||||||
|
if (! empty($data['payment_types'])) {
|
||||||
|
foreach ($data['payment_types'] as $type) {
|
||||||
|
$statusName = InvoiceStatus::from($type)->name;
|
||||||
|
$paymentTypes[$statusName] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($paymentTypes as $status => $value) {
|
||||||
|
$data['with_'.strtolower($status)] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($data['payment_types']);
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
})
|
||||||
|
->successRedirectUrl(fn ($record) => InvoiceReportResource::getUrl('view', ['record' => $record->id])),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Filament\Admin\Resources\InvoiceReportResource\Pages;
|
namespace App\Filament\Admin\Resources\InvoiceReportResource\Pages;
|
||||||
|
|
||||||
|
use App\Enums\InvoiceStatus;
|
||||||
use App\Filament\Admin\Resources\InvoiceReportResource;
|
use App\Filament\Admin\Resources\InvoiceReportResource;
|
||||||
use App\Models\InvoiceReport;
|
use App\Models\InvoiceReport;
|
||||||
use Filament\Actions\Action;
|
use Filament\Actions\Action;
|
||||||
@ -19,6 +20,19 @@ public function getTitle(): string|Htmlable
|
|||||||
return parent::getTitle().' '.$this->record->internal_id;
|
return parent::getTitle().' '.$this->record->internal_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function mutateFormDataBeforeFill(array $data): array
|
||||||
|
{
|
||||||
|
foreach (InvoiceStatus::cases() as $case) {
|
||||||
|
$name = 'with_'.strtolower($case->name);
|
||||||
|
|
||||||
|
if ($data[$name]) {
|
||||||
|
$data['payment_types'][] = $case->value ?? null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
protected function getHeaderActions(): array
|
protected function getHeaderActions(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
use Filament\Forms\Components\Section;
|
use Filament\Forms\Components\Section;
|
||||||
use Filament\Forms\Components\Select;
|
use Filament\Forms\Components\Select;
|
||||||
use Filament\Forms\Components\Split;
|
use Filament\Forms\Components\Split;
|
||||||
|
use Filament\Forms\Components\Toggle;
|
||||||
use Filament\Forms\Components\ToggleButtons;
|
use Filament\Forms\Components\ToggleButtons;
|
||||||
use Filament\Forms\Form;
|
use Filament\Forms\Form;
|
||||||
use Filament\Notifications\Notification;
|
use Filament\Notifications\Notification;
|
||||||
@ -47,6 +48,8 @@ public static function form(Form $form): Form
|
|||||||
Group::make()
|
Group::make()
|
||||||
->schema([
|
->schema([
|
||||||
Section::make([
|
Section::make([
|
||||||
|
Group::make([
|
||||||
|
|
||||||
Select::make('customer_id')
|
Select::make('customer_id')
|
||||||
->required()
|
->required()
|
||||||
->label('Customer')
|
->label('Customer')
|
||||||
@ -61,51 +64,37 @@ public static function form(Form $form): Form
|
|||||||
->required()
|
->required()
|
||||||
->default(today()),
|
->default(today()),
|
||||||
DatePicker::make('due_date'),
|
DatePicker::make('due_date'),
|
||||||
])
|
])->columnSpan(2),
|
||||||
->columnSpan(2),
|
|
||||||
|
|
||||||
Grid::make(3)
|
|
||||||
->schema([
|
|
||||||
ToggleButtons::make('has_gst')
|
|
||||||
->label('GST')
|
|
||||||
->boolean('On', 'Off')
|
|
||||||
->default(true)
|
|
||||||
// ->inline()
|
|
||||||
->colors([
|
|
||||||
'true' => 'info',
|
|
||||||
'false' => 'info',
|
|
||||||
]),
|
|
||||||
|
|
||||||
ToggleButtons::make('has_pst')
|
|
||||||
->label('PST')
|
|
||||||
->boolean('On', 'Off')
|
|
||||||
->default(false)
|
|
||||||
// ->inline()
|
|
||||||
->colors([
|
|
||||||
'true' => 'info',
|
|
||||||
'false' => 'info',
|
|
||||||
]),
|
|
||||||
|
|
||||||
ToggleButtons::make('has_hst')
|
|
||||||
->label('HST')
|
|
||||||
->boolean('On', 'Off')
|
|
||||||
->default(false)
|
|
||||||
->colors([
|
|
||||||
'true' => 'info',
|
|
||||||
'false' => 'info',
|
|
||||||
]),
|
|
||||||
])->columnSpan(1),
|
|
||||||
|
|
||||||
ToggleButtons::make('status')
|
ToggleButtons::make('status')
|
||||||
->options(InvoiceStatus::class)
|
->options(InvoiceStatus::class)
|
||||||
->required()
|
->required()
|
||||||
->inline()
|
->inline()
|
||||||
->default(InvoiceStatus::UNPAID)
|
->default(InvoiceStatus::UNPAID)
|
||||||
->columnSpan(1),
|
->columnSpan(2),
|
||||||
|
|
||||||
|
Grid::make(3)
|
||||||
|
->schema([
|
||||||
|
Toggle::make('has_gst')
|
||||||
|
->label('GST')
|
||||||
|
->inline(false)
|
||||||
|
->default(true),
|
||||||
|
|
||||||
|
Toggle::make('has_pst')
|
||||||
|
->label('PST')
|
||||||
|
->inline(false)
|
||||||
|
->default(false),
|
||||||
|
|
||||||
|
Toggle::make('has_hst')
|
||||||
|
->label('HST')
|
||||||
|
->inline(false)
|
||||||
|
->default(false),
|
||||||
|
]),
|
||||||
|
|
||||||
|
])->columnSpan(fn (?Invoice $record) => $record === null ? 2 : 1),
|
||||||
])
|
])
|
||||||
->columns(2)
|
->columns(2)
|
||||||
->columnSpan(2),
|
->columnSpan(fn (?Invoice $record) => $record === null ? 3 : 2),
|
||||||
|
|
||||||
Section::make()
|
Section::make()
|
||||||
->schema([
|
->schema([
|
||||||
@ -334,7 +323,7 @@ public static function getPages(): array
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'index' => \App\Filament\Admin\Resources\InvoiceResource\Pages\ListInvoices::route('/'),
|
'index' => \App\Filament\Admin\Resources\InvoiceResource\Pages\ListInvoices::route('/'),
|
||||||
'create' => \App\Filament\Admin\Resources\InvoiceResource\Pages\CreateInvoice::route('/create'),
|
// 'create' => \App\Filament\Admin\Resources\InvoiceResource\Pages\CreateInvoice::route('/create'),
|
||||||
'edit' => \App\Filament\Admin\Resources\InvoiceResource\Pages\EditInvoice::route('/{record}/edit'),
|
'edit' => \App\Filament\Admin\Resources\InvoiceResource\Pages\EditInvoice::route('/{record}/edit'),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,10 @@ protected function getHeaderActions(): array
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
Actions\CreateAction::make()
|
Actions\CreateAction::make()
|
||||||
->icon(IconEnum::NEW->value),
|
->modal()
|
||||||
|
->modalWidth('lg')
|
||||||
|
->icon(IconEnum::NEW->value)
|
||||||
|
->successRedirectUrl(fn ($record) => InvoiceResource::getUrl('edit', ['record' => $record->id])),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -459,12 +459,6 @@ public static function table(Table $table): Table
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getRelations(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getPages(): array
|
public static function getPages(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
@ -74,7 +74,7 @@ public function getTabs(): array
|
|||||||
'ready_for_invoice' => Tab::make()
|
'ready_for_invoice' => Tab::make()
|
||||||
->query(fn ($query) => $query->where('status', OrderStatus::READY_FOR_INVOICE))
|
->query(fn ($query) => $query->where('status', OrderStatus::READY_FOR_INVOICE))
|
||||||
->icon(OrderStatus::READY_FOR_INVOICE->getIcon())
|
->icon(OrderStatus::READY_FOR_INVOICE->getIcon())
|
||||||
->badge(fn () => $this->getBadgeCount(fn ($query) => $query->where('status', OrderStatus::READY_FOR_INVOICE)))
|
->badge(fn () => Order::query()->where('status', OrderStatus::READY_FOR_INVOICE)->count())
|
||||||
->badgeColor(OrderStatus::READY_FOR_INVOICE->getColor()),
|
->badgeColor(OrderStatus::READY_FOR_INVOICE->getColor()),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
use App\Filament\Admin\Resources\PaymentResource\RelationManagers\InvoicesRelationManager;
|
use App\Filament\Admin\Resources\PaymentResource\RelationManagers\InvoicesRelationManager;
|
||||||
use App\Models\Payment;
|
use App\Models\Payment;
|
||||||
use Filament\Forms\Components\DatePicker;
|
use Filament\Forms\Components\DatePicker;
|
||||||
|
use Filament\Forms\Components\Group;
|
||||||
|
use Filament\Forms\Components\Placeholder;
|
||||||
use Filament\Forms\Components\Section;
|
use Filament\Forms\Components\Section;
|
||||||
use Filament\Forms\Components\Select;
|
use Filament\Forms\Components\Select;
|
||||||
use Filament\Forms\Components\Textarea;
|
use Filament\Forms\Components\Textarea;
|
||||||
@ -32,9 +34,7 @@ public static function form(Form $form): Form
|
|||||||
return $form
|
return $form
|
||||||
->schema([
|
->schema([
|
||||||
Section::make([
|
Section::make([
|
||||||
DatePicker::make('date')
|
Group::make([
|
||||||
->default(today())
|
|
||||||
->columnSpan(2),
|
|
||||||
|
|
||||||
Select::make('customer_id')
|
Select::make('customer_id')
|
||||||
->relationship('customer', 'company_name')
|
->relationship('customer', 'company_name')
|
||||||
@ -42,7 +42,7 @@ public static function form(Form $form): Form
|
|||||||
->searchable()
|
->searchable()
|
||||||
->hidden(fn ($livewire) => $livewire::class === ListInvoices::class)
|
->hidden(fn ($livewire) => $livewire::class === ListInvoices::class)
|
||||||
->preload()
|
->preload()
|
||||||
->columnSpan(2),
|
->columnSpanFull(),
|
||||||
|
|
||||||
TextInput::make('amount')
|
TextInput::make('amount')
|
||||||
->required()
|
->required()
|
||||||
@ -50,14 +50,22 @@ public static function form(Form $form): Form
|
|||||||
->rules('numeric')
|
->rules('numeric')
|
||||||
->minValue(0)
|
->minValue(0)
|
||||||
->maxValue(99999999)
|
->maxValue(99999999)
|
||||||
->columnSpan(1),
|
|
||||||
|
|
||||||
TextInput::make('check_number')
|
|
||||||
->columnSpan(3),
|
->columnSpan(3),
|
||||||
|
|
||||||
Textarea::make('notes')
|
TextInput::make('check_number')
|
||||||
|
->columnSpan(6),
|
||||||
|
|
||||||
|
DatePicker::make('date')
|
||||||
|
->default(today())
|
||||||
->columnSpan(4),
|
->columnSpan(4),
|
||||||
])->columns(4),
|
|
||||||
|
Placeholder::make('break_2')->columnSpan(3)->hiddenLabel(),
|
||||||
|
|
||||||
|
Textarea::make('notes')
|
||||||
|
->columnSpanFull(),
|
||||||
|
])->columnSpan(fn (?Payment $record) => $record === null ? 9 : 3)
|
||||||
|
->columns(9),
|
||||||
|
])->columns(9),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,9 @@ protected function getHeaderActions(): array
|
|||||||
}),*/
|
}),*/
|
||||||
|
|
||||||
Actions\CreateAction::make()
|
Actions\CreateAction::make()
|
||||||
->icon(IconEnum::NEW->value),
|
->modalWidth('lg')
|
||||||
|
->icon(IconEnum::NEW->value)
|
||||||
|
->successRedirectUrl(fn ($record) => PaymentResource::getUrl('edit', ['record' => $record->id])),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
use App\Models\Quote;
|
use App\Models\Quote;
|
||||||
use Filament\Forms\Components\DatePicker;
|
use Filament\Forms\Components\DatePicker;
|
||||||
use Filament\Forms\Components\Grid;
|
use Filament\Forms\Components\Grid;
|
||||||
|
use Filament\Forms\Components\Group;
|
||||||
use Filament\Forms\Components\Placeholder;
|
use Filament\Forms\Components\Placeholder;
|
||||||
use Filament\Forms\Components\Section;
|
use Filament\Forms\Components\Section;
|
||||||
use Filament\Forms\Components\Select;
|
use Filament\Forms\Components\Select;
|
||||||
@ -36,6 +37,8 @@ public static function form(Form $form): Form
|
|||||||
Grid::make(3)
|
Grid::make(3)
|
||||||
->schema([
|
->schema([
|
||||||
Section::make([
|
Section::make([
|
||||||
|
Group::make([
|
||||||
|
|
||||||
Select::make('customer_id')
|
Select::make('customer_id')
|
||||||
->required()
|
->required()
|
||||||
->label('Customer')
|
->label('Customer')
|
||||||
@ -51,6 +54,7 @@ public static function form(Form $form): Form
|
|||||||
TextArea::make('notes')
|
TextArea::make('notes')
|
||||||
->rows(3)
|
->rows(3)
|
||||||
->columnSpan(2),
|
->columnSpan(2),
|
||||||
|
]),
|
||||||
])
|
])
|
||||||
->columns(2)
|
->columns(2)
|
||||||
->columnSpan(fn (?Quote $record) => $record === null ? 3 : 2)
|
->columnSpan(fn (?Quote $record) => $record === null ? 3 : 2)
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
use App\Enums\IconEnum;
|
use App\Enums\IconEnum;
|
||||||
use App\Filament\Admin\Resources\TaxRateResource\Pages;
|
use App\Filament\Admin\Resources\TaxRateResource\Pages;
|
||||||
use App\Models\TaxRate;
|
use App\Models\TaxRate;
|
||||||
use Filament\Forms\Components\Placeholder;
|
|
||||||
use Filament\Forms\Components\Section;
|
use Filament\Forms\Components\Section;
|
||||||
use Filament\Forms\Components\TextInput;
|
use Filament\Forms\Components\TextInput;
|
||||||
use Filament\Forms\Form;
|
use Filament\Forms\Form;
|
||||||
@ -36,24 +35,8 @@ public static function form(Form $form): Form
|
|||||||
->label('Value in percentage')
|
->label('Value in percentage')
|
||||||
->numeric()
|
->numeric()
|
||||||
->prefix('%'),
|
->prefix('%'),
|
||||||
])
|
]),
|
||||||
->columns(1)
|
]);
|
||||||
->columnSpan(2),
|
|
||||||
|
|
||||||
Section::make()
|
|
||||||
->schema([
|
|
||||||
Placeholder::make('created_at')
|
|
||||||
->label('Created')
|
|
||||||
->content(fn (TaxRate $record): ?string => $record->created_at?->diffForHumans()),
|
|
||||||
|
|
||||||
Placeholder::make('updated_at')
|
|
||||||
->label('Last modified')
|
|
||||||
->content(fn (TaxRate $record): ?string => $record->updated_at?->diffForHumans()),
|
|
||||||
])
|
|
||||||
->columnSpan(1)
|
|
||||||
->hidden(fn (?TaxRate $record) => $record === null)
|
|
||||||
->extraAttributes(['class' => 'h-full']),
|
|
||||||
])->columns(3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function table(Table $table): Table
|
public static function table(Table $table): Table
|
||||||
@ -70,7 +53,8 @@ public static function table(Table $table): Table
|
|||||||
//
|
//
|
||||||
])
|
])
|
||||||
->actions([
|
->actions([
|
||||||
Tables\Actions\EditAction::make(),
|
Tables\Actions\EditAction::make()
|
||||||
|
->modalWidth('xs'),
|
||||||
])
|
])
|
||||||
->bulkActions([
|
->bulkActions([
|
||||||
Tables\Actions\BulkActionGroup::make([
|
Tables\Actions\BulkActionGroup::make([
|
||||||
|
@ -15,7 +15,9 @@ protected function getHeaderActions(): array
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
Actions\CreateAction::make()
|
Actions\CreateAction::make()
|
||||||
->icon(IconEnum::NEW->value),
|
->modalWidth('xs')
|
||||||
|
->icon(IconEnum::NEW->value)
|
||||||
|
->createAnother(false),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
use App\Enums\IconEnum;
|
use App\Enums\IconEnum;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Filament\Forms\Components\Grid;
|
|
||||||
use Filament\Forms\Components\Section;
|
use Filament\Forms\Components\Section;
|
||||||
use Filament\Forms\Components\Select;
|
use Filament\Forms\Components\Select;
|
||||||
use Filament\Forms\Components\TextInput;
|
use Filament\Forms\Components\TextInput;
|
||||||
@ -36,10 +35,8 @@ public static function form(Form $form): Form
|
|||||||
->autocomplete('new-username')
|
->autocomplete('new-username')
|
||||||
->unique()
|
->unique()
|
||||||
->required()
|
->required()
|
||||||
->columnSpan(1),
|
->columnSpanFull(),
|
||||||
|
|
||||||
Grid::make(2)
|
|
||||||
->schema([
|
|
||||||
TextInput::make('password')
|
TextInput::make('password')
|
||||||
->password()
|
->password()
|
||||||
->autocomplete('new-password')
|
->autocomplete('new-password')
|
||||||
@ -54,14 +51,13 @@ public static function form(Form $form): Form
|
|||||||
->same('password')
|
->same('password')
|
||||||
->dehydrated(false)
|
->dehydrated(false)
|
||||||
->required(fn (string $operation) => $operation === 'create'),
|
->required(fn (string $operation) => $operation === 'create'),
|
||||||
])
|
|
||||||
->columnSpan(2),
|
|
||||||
]),
|
]),
|
||||||
|
|
||||||
Section::make('Permissions')
|
Section::make('Permissions')
|
||||||
->description('Administrators can access financial information and change settings.')
|
->description('Administrators can access invoices and settings')
|
||||||
->schema([
|
->schema([
|
||||||
Toggle::make('is_admin')
|
Toggle::make('is_admin')
|
||||||
|
->columnSpanFull()
|
||||||
->label('User is an administrator')
|
->label('User is an administrator')
|
||||||
->reactive()
|
->reactive()
|
||||||
->afterStateUpdated(fn ($state, callable $set) => $set('customer_id', null))
|
->afterStateUpdated(fn ($state, callable $set) => $set('customer_id', null))
|
||||||
@ -70,7 +66,7 @@ public static function form(Form $form): Form
|
|||||||
->columns(2),
|
->columns(2),
|
||||||
|
|
||||||
Section::make('Customer Login')
|
Section::make('Customer Login')
|
||||||
->description('If this account is for a customer, select them here.')
|
->description('If this account is for a customer, select them here')
|
||||||
->schema([
|
->schema([
|
||||||
|
|
||||||
Select::make('customer_id')
|
Select::make('customer_id')
|
||||||
@ -102,7 +98,9 @@ public static function table(Table $table): Table
|
|||||||
//
|
//
|
||||||
])
|
])
|
||||||
->actions([
|
->actions([
|
||||||
Tables\Actions\EditAction::make()->modal(),
|
Tables\Actions\EditAction::make()
|
||||||
|
->modalWidth('md')
|
||||||
|
->modal(),
|
||||||
])
|
])
|
||||||
->defaultSort('customer_id', 'asc');
|
->defaultSort('customer_id', 'asc');
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ protected function getHeaderActions(): array
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
Actions\CreateAction::make()
|
Actions\CreateAction::make()
|
||||||
|
->modalWidth('md')
|
||||||
->icon(IconEnum::NEW->value)
|
->icon(IconEnum::NEW->value)
|
||||||
->modal(),
|
->modal(),
|
||||||
];
|
];
|
||||||
|
@ -1,43 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Livewire;
|
|
||||||
|
|
||||||
use App\Enums\OrderStatus;
|
|
||||||
use App\Enums\OrderType;
|
|
||||||
use App\Models\Customer;
|
|
||||||
use Illuminate\Contracts\View\View;
|
|
||||||
use Illuminate\Database\Eloquent\Collection;
|
|
||||||
use Illuminate\Support\Carbon;
|
|
||||||
use Livewire\Component;
|
|
||||||
|
|
||||||
class CreateOrder extends Component
|
|
||||||
{
|
|
||||||
public Collection $customers;
|
|
||||||
|
|
||||||
public string $selectedCustomer;
|
|
||||||
|
|
||||||
public $contacts;
|
|
||||||
|
|
||||||
public function mount(Collection $customers): void
|
|
||||||
{
|
|
||||||
$this->customers = $customers;
|
|
||||||
$this->contacts = $customers->first()->contacts;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getContacts(): void
|
|
||||||
{
|
|
||||||
$this->contacts = Customer::find($this->selectedCustomer)->contacts;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function render(): View
|
|
||||||
{
|
|
||||||
return view('livewire.create-order', [
|
|
||||||
'contacts' => $this->contacts,
|
|
||||||
'order_types' => OrderType::cases(),
|
|
||||||
'order_status' => OrderStatus::cases(),
|
|
||||||
'customers' => $this->customers,
|
|
||||||
'today' => Carbon::today()->format('Y-m-d'),
|
|
||||||
'due_default' => Carbon::today()->addDay(10)->format('Y-m-d'),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Livewire;
|
|
||||||
|
|
||||||
use App\Models\Customer;
|
|
||||||
use Illuminate\Support\Collection;
|
|
||||||
use Livewire\Component;
|
|
||||||
|
|
||||||
class CustomerAndContactSelect extends Component
|
|
||||||
{
|
|
||||||
public Collection $customers;
|
|
||||||
|
|
||||||
public Collection $contacts;
|
|
||||||
|
|
||||||
public string $selectedCustomer;
|
|
||||||
|
|
||||||
public function mount(Collection $customers)
|
|
||||||
{
|
|
||||||
$this->customers = $customers;
|
|
||||||
|
|
||||||
if (isset($this->selectedCustomer)) {
|
|
||||||
$this->contacts = Customer::find($this->selectedCustomer)->contacts;
|
|
||||||
} else {
|
|
||||||
$this->contacts = $customers->first()->contacts;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public function updateContactList()
|
|
||||||
{
|
|
||||||
$this->contacts = Customer::find($this->selectedCustomer)->contacts;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function render()
|
|
||||||
{
|
|
||||||
return view('livewire.customer-and-contact-select', [
|
|
||||||
'customers' => $this->customers,
|
|
||||||
'contacts' => $this->contacts,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,172 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Livewire;
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
use Illuminate\Contracts\View\Factory;
|
|
||||||
use Illuminate\Foundation\Application;
|
|
||||||
use Illuminate\Support\Collection;
|
|
||||||
use Illuminate\View\View;
|
|
||||||
use Livewire\Component;
|
|
||||||
|
|
||||||
class OrderProductsCreate extends Component
|
|
||||||
{
|
|
||||||
/** @var Collection<string, int> */
|
|
||||||
public Collection $productInputs;
|
|
||||||
|
|
||||||
/** @var Collection<string, int> */
|
|
||||||
public Collection $serviceInputs;
|
|
||||||
|
|
||||||
/** @var array<int> */
|
|
||||||
public array $sizes = [];
|
|
||||||
|
|
||||||
/** @var array<int> */
|
|
||||||
public array $totals = [];
|
|
||||||
|
|
||||||
/** @var array<int> */
|
|
||||||
public array $units = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array<int>
|
|
||||||
*/
|
|
||||||
public array $prices = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array<int>
|
|
||||||
*/
|
|
||||||
public array $priceTotals = [];
|
|
||||||
|
|
||||||
public int $totalQuantity = 0;
|
|
||||||
|
|
||||||
public string $totalPrice = '$0.00';
|
|
||||||
|
|
||||||
public function updated(): void
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
foreach ($this->sizes as $index => $size) {
|
|
||||||
$this->totals[$index] = array_sum($size);
|
|
||||||
}
|
|
||||||
} catch (Exception $e) {
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
foreach ($this->units as $index => $unit) {
|
|
||||||
$this->priceTotals[$index] = $unit * $this->prices[$index];
|
|
||||||
}
|
|
||||||
} catch (Exception $e) {
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->totalQuantity = array_sum($this->totals);
|
|
||||||
|
|
||||||
$this->totalPrice = '$'.number_format(round(array_sum($this->priceTotals), 2), 2);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public function addProductInput(): void
|
|
||||||
{
|
|
||||||
$index = $this->productInputs->count();
|
|
||||||
$this->productInputs->push([
|
|
||||||
$index => [
|
|
||||||
'sku' => '',
|
|
||||||
'product_name' => '',
|
|
||||||
'product_color' => '',
|
|
||||||
'size_xs' => '',
|
|
||||||
'size_s' => '',
|
|
||||||
'size_m' => '',
|
|
||||||
'size_l' => '',
|
|
||||||
'size_xl' => '',
|
|
||||||
'size_2xl' => '',
|
|
||||||
'size_3xl' => '',
|
|
||||||
'size_osfa' => '',
|
|
||||||
'product_total' => '',
|
|
||||||
],
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function determineAddProductRow(int $index): void
|
|
||||||
{
|
|
||||||
if ($index == $this->productInputs->count() - 1) {
|
|
||||||
$this->addProductInput();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function determineAddServiceProductRow(int $index): void
|
|
||||||
{
|
|
||||||
if ($index == $this->serviceInputs->count() - 1) {
|
|
||||||
$this->addServiceInput();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function removeProductInput(int $key): void
|
|
||||||
{
|
|
||||||
if ($this->productInputs->count() > 1) {
|
|
||||||
$this->productInputs->pull($key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function addServiceInput(): void
|
|
||||||
{
|
|
||||||
$this->serviceInputs->push([
|
|
||||||
$this->serviceInputs->count() => [
|
|
||||||
'service_name' => '',
|
|
||||||
'product_name' => '',
|
|
||||||
'product_color' => '',
|
|
||||||
'logo_name' => '',
|
|
||||||
'setup_number' => '',
|
|
||||||
'service_width' => '',
|
|
||||||
'service_height' => '',
|
|
||||||
'service_setup_unit' => '',
|
|
||||||
'service_setup_price' => '',
|
|
||||||
'service_total' => '',
|
|
||||||
],
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function removeServiceInput(int $key): void
|
|
||||||
{
|
|
||||||
if ($this->serviceInputs->count() > 1) {
|
|
||||||
$this->serviceInputs->pull($key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function mount(): void
|
|
||||||
{
|
|
||||||
$this->fill([
|
|
||||||
'productInputs' => collect([
|
|
||||||
[
|
|
||||||
'sku' => '',
|
|
||||||
'product_name' => '',
|
|
||||||
'product_color' => '',
|
|
||||||
'size_xs' => '',
|
|
||||||
'size_s' => '',
|
|
||||||
'size_m' => '',
|
|
||||||
'size_l' => '',
|
|
||||||
'size_xl' => '',
|
|
||||||
'size_2xl' => '',
|
|
||||||
'size_3xl' => '',
|
|
||||||
'size_osfa' => '',
|
|
||||||
'product_total' => '0',
|
|
||||||
],
|
|
||||||
]),
|
|
||||||
'serviceInputs' => collect([
|
|
||||||
[
|
|
||||||
'sku' => '',
|
|
||||||
'product_name' => '',
|
|
||||||
'product_color' => '',
|
|
||||||
'logo_name' => '',
|
|
||||||
'setup_number' => '',
|
|
||||||
'service_width' => '',
|
|
||||||
'service_height' => '',
|
|
||||||
'service_setup_unit' => '',
|
|
||||||
'service_setup_price' => '',
|
|
||||||
'service_total' => '',
|
|
||||||
],
|
|
||||||
]),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function render(): \Illuminate\Contracts\View\View|Factory|Application|View
|
|
||||||
{
|
|
||||||
return view('livewire.order-products-create');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,64 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Livewire;
|
|
||||||
|
|
||||||
use App\Models\Order;
|
|
||||||
use Illuminate\Contracts\View\Factory;
|
|
||||||
use Illuminate\Foundation\Application;
|
|
||||||
use Illuminate\Support\Carbon;
|
|
||||||
use Illuminate\View\View;
|
|
||||||
use Livewire\Component;
|
|
||||||
use Livewire\WithPagination;
|
|
||||||
|
|
||||||
class OrdersTable extends Component
|
|
||||||
{
|
|
||||||
use WithPagination;
|
|
||||||
|
|
||||||
protected string $paginationTheme = 'bootstrap';
|
|
||||||
|
|
||||||
public bool $showCustomerColumn;
|
|
||||||
|
|
||||||
public string $orderType = 'active';
|
|
||||||
|
|
||||||
public string $search = '';
|
|
||||||
|
|
||||||
public string $title = '';
|
|
||||||
|
|
||||||
public string $customer_id = '';
|
|
||||||
|
|
||||||
public Carbon $today;
|
|
||||||
|
|
||||||
public function mount(bool $showCustomerColumn, string $orderType, string $title, ?string $customer_id = null): void
|
|
||||||
{
|
|
||||||
$this->today = Carbon::today();
|
|
||||||
$this->showCustomerColumn = $showCustomerColumn;
|
|
||||||
$this->orderType = $orderType;
|
|
||||||
$this->title = $title;
|
|
||||||
$this->customer_id = $customer_id ?? '';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function render(): \Illuminate\Contracts\View\View|Factory|Application|View
|
|
||||||
{
|
|
||||||
return view('livewire.orders-table', [
|
|
||||||
'orders' => Order::with('customer')
|
|
||||||
->when($this->customer_id != null, fn ($q) => $q->where('customer_id', $this->customer_id))
|
|
||||||
->when($this->orderType === 'active', fn ($q) => $q->active())
|
|
||||||
->when($this->orderType === 'invoiced', fn ($q) => $q->invoiced())
|
|
||||||
->when($this->orderType === 'finished', fn ($q) => $q->finished())
|
|
||||||
->when($this->search !== '', function ($query) {
|
|
||||||
$query->whereHas('customer', function ($query) {
|
|
||||||
$query->where('company_name', 'like', '%'.$this->search.'%');
|
|
||||||
})->orWhere('customer_po', 'like', '%'.$this->search.'%')
|
|
||||||
->orWhere('internal_po', 'like', '%'.$this->search.'%')
|
|
||||||
->orWhere('order_date', 'like', '%'.$this->search.'%')
|
|
||||||
->orWhere('due_date', 'like', '%'.$this->search.'%')
|
|
||||||
->orWhere('status', 'like', '%'.$this->search.'%');
|
|
||||||
})
|
|
||||||
->orderByDesc('rush')
|
|
||||||
->orderBy('due_date')
|
|
||||||
->paginate(15)
|
|
||||||
->withQueryString(),
|
|
||||||
'today' => $this->today,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
@ -56,8 +56,12 @@ class Invoice extends Model
|
|||||||
'total' => 'float',
|
'total' => 'float',
|
||||||
];
|
];
|
||||||
|
|
||||||
public function scopeSearchByBalance(Builder $query, float $amount): Builder
|
public function scopeSearchByBalance(Builder $query, $amount): Builder
|
||||||
{
|
{
|
||||||
|
if (! is_numeric($amount)) {
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
return $query->whereRaw('total - (SELECT IFNULL(SUM(applied_amount), 0)
|
return $query->whereRaw('total - (SELECT IFNULL(SUM(applied_amount), 0)
|
||||||
FROM payments
|
FROM payments
|
||||||
INNER JOIN invoice_payment
|
INNER JOIN invoice_payment
|
||||||
|
@ -17,8 +17,11 @@ class InvoiceReport extends Model
|
|||||||
'customer_id',
|
'customer_id',
|
||||||
'date_start',
|
'date_start',
|
||||||
'date_end',
|
'date_end',
|
||||||
'filter_paid',
|
|
||||||
'subtotal',
|
'subtotal',
|
||||||
|
'with_unpaid',
|
||||||
|
'with_partially_paid',
|
||||||
|
'with_paid',
|
||||||
|
'with_void',
|
||||||
'pst',
|
'pst',
|
||||||
'gst',
|
'gst',
|
||||||
];
|
];
|
||||||
@ -42,10 +45,10 @@ public static function boot(): void
|
|||||||
|
|
||||||
$invoices = Invoice::whereBetween('date', [$model->date_start, $model->date_end])
|
$invoices = Invoice::whereBetween('date', [$model->date_start, $model->date_end])
|
||||||
->where('customer_id', $model->customer_id)
|
->where('customer_id', $model->customer_id)
|
||||||
->when($model->filter_paid, function ($query) {
|
->when(! $model->with_unpaid, fn ($query) => $query->whereNot('status', InvoiceStatus::UNPAID))
|
||||||
$query->where('status', InvoiceStatus::UNPAID)
|
->when(! $model->with_partially_paid, fn ($query) => $query->whereNot('status', InvoiceStatus::PARTIALLY_PAID))
|
||||||
->orWhere('status', InvoiceStatus::PARTIALLY_PAID);
|
->when(! $model->with_paid, fn ($query) => $query->whereNot('status', InvoiceStatus::PAID))
|
||||||
});
|
->when(! $model->with_void, fn ($query) => $query->whereNot('status', InvoiceStatus::VOID));
|
||||||
|
|
||||||
$model->invoices()->sync($invoices->pluck('id')->toArray());
|
$model->invoices()->sync($invoices->pluck('id')->toArray());
|
||||||
|
|
||||||
|
@ -14,11 +14,11 @@
|
|||||||
"laravel/tinker": "^2.9",
|
"laravel/tinker": "^2.9",
|
||||||
"livewire/livewire": "^3.5",
|
"livewire/livewire": "^3.5",
|
||||||
"mallardduck/blade-lucide-icons": "^1.23",
|
"mallardduck/blade-lucide-icons": "^1.23",
|
||||||
"spatie/laravel-pdf": "^1.5"
|
"spatie/laravel-pdf": "^1.5",
|
||||||
|
"fakerphp/faker": "^1.23"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"barryvdh/laravel-ide-helper": "^3.5",
|
"barryvdh/laravel-ide-helper": "^3.5",
|
||||||
"fakerphp/faker": "^1.23",
|
|
||||||
"larastan/larastan": "^2.0",
|
"larastan/larastan": "^2.0",
|
||||||
"laravel/pint": "^1.17",
|
"laravel/pint": "^1.17",
|
||||||
"laravel/sail": "^1.26",
|
"laravel/sail": "^1.26",
|
||||||
|
1121
composer.lock
generated
1121
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@ -15,6 +15,18 @@
|
|||||||
|
|
||||||
'name' => env('APP_NAME', 'Laravel'),
|
'name' => env('APP_NAME', 'Laravel'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Application Version
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This value is the version of your application. This value is used when
|
||||||
|
| the framework needs to place the application's version in a notification
|
||||||
|
| or any other location as required by the application or its packages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
'version' => '1.0.0',
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Application Environment
|
| Application Environment
|
||||||
|
@ -17,7 +17,10 @@ public function definition(): array
|
|||||||
'customer_id' => Customer::all()->shuffle()->first()->id,
|
'customer_id' => Customer::all()->shuffle()->first()->id,
|
||||||
'date_start' => Carbon::now()->subYear(),
|
'date_start' => Carbon::now()->subYear(),
|
||||||
'date_end' => Carbon::now(),
|
'date_end' => Carbon::now(),
|
||||||
'filter_paid' => $this->faker->boolean(40),
|
'with_unpaid' => $this->faker->boolean(40),
|
||||||
|
'with_partially_paid' => $this->faker->boolean(40),
|
||||||
|
'with_paid' => $this->faker->boolean(40),
|
||||||
|
'with_void' => $this->faker->boolean(40),
|
||||||
'created_at' => Carbon::now(),
|
'created_at' => Carbon::now(),
|
||||||
'updated_at' => Carbon::now(),
|
'updated_at' => Carbon::now(),
|
||||||
];
|
];
|
||||||
|
@ -11,16 +11,16 @@ public function up(): void
|
|||||||
Schema::create('invoice_reports', function (Blueprint $table) {
|
Schema::create('invoice_reports', function (Blueprint $table) {
|
||||||
$table->id();
|
$table->id();
|
||||||
$table->string('internal_id')->nullable();
|
$table->string('internal_id')->nullable();
|
||||||
|
|
||||||
$table->foreignId('customer_id')->constrained();
|
$table->foreignId('customer_id')->constrained();
|
||||||
|
|
||||||
$table->date('date_start');
|
$table->date('date_start');
|
||||||
$table->date('date_end');
|
$table->date('date_end');
|
||||||
$table->boolean('filter_paid');
|
$table->boolean('with_unpaid')->default(false);
|
||||||
|
$table->boolean('with_partially_paid')->default(false);
|
||||||
|
$table->boolean('with_paid')->default(false);
|
||||||
|
$table->boolean('with_void')->default(false);
|
||||||
$table->float('subtotal', 2)->default(0);
|
$table->float('subtotal', 2)->default(0);
|
||||||
$table->float('pst', 2)->default(0);
|
$table->float('pst', 2)->default(0);
|
||||||
$table->float('gst', 2)->default(0);
|
$table->float('gst', 2)->default(0);
|
||||||
// $table->float('total', 2)->default(0);
|
|
||||||
|
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
});
|
});
|
||||||
|
91
deploy/Dockerfile
Normal file
91
deploy/Dockerfile
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
# deploy/Dockerfile
|
||||||
|
|
||||||
|
# stage 1: build stage
|
||||||
|
FROM php:8.3-fpm-alpine as build
|
||||||
|
|
||||||
|
# installing system dependencies and php extensions
|
||||||
|
RUN apk add --no-cache \
|
||||||
|
zip \
|
||||||
|
libzip-dev \
|
||||||
|
freetype \
|
||||||
|
libjpeg-turbo \
|
||||||
|
libpng \
|
||||||
|
freetype-dev \
|
||||||
|
libjpeg-turbo-dev \
|
||||||
|
libpng-dev \
|
||||||
|
nodejs \
|
||||||
|
npm \
|
||||||
|
icu-dev \
|
||||||
|
&& docker-php-ext-configure intl \
|
||||||
|
&& docker-php-ext-install intl \
|
||||||
|
&& docker-php-ext-configure zip \
|
||||||
|
&& docker-php-ext-install zip pdo pdo_mysql \
|
||||||
|
&& docker-php-ext-configure gd --with-freetype=/usr/include/ --with-jpeg=/usr/include/ \
|
||||||
|
&& docker-php-ext-install -j$(nproc) gd \
|
||||||
|
&& docker-php-ext-enable gd
|
||||||
|
|
||||||
|
# install composer
|
||||||
|
COPY --from=composer:2.7.6 /usr/bin/composer /usr/bin/composer
|
||||||
|
|
||||||
|
WORKDIR /var/www/html
|
||||||
|
|
||||||
|
# copy necessary files and change permissions
|
||||||
|
COPY . .
|
||||||
|
RUN chown -R www-data:www-data /var/www/html \
|
||||||
|
&& chmod -R 775 /var/www/html/storage \
|
||||||
|
&& chmod -R 775 /var/www/html/bootstrap/cache
|
||||||
|
|
||||||
|
# install php and node.js dependencies
|
||||||
|
RUN composer install --no-dev --prefer-dist \
|
||||||
|
&& npm install \
|
||||||
|
&& npm run build
|
||||||
|
|
||||||
|
RUN chown -R www-data:www-data /var/www/html/vendor \
|
||||||
|
&& chmod -R 775 /var/www/html/vendor
|
||||||
|
|
||||||
|
# stage 2: production stage
|
||||||
|
FROM php:8.3-fpm-alpine
|
||||||
|
|
||||||
|
# install nginx
|
||||||
|
RUN apk add --no-cache \
|
||||||
|
zip \
|
||||||
|
libzip-dev \
|
||||||
|
freetype \
|
||||||
|
libjpeg-turbo \
|
||||||
|
libpng \
|
||||||
|
freetype-dev \
|
||||||
|
libjpeg-turbo-dev \
|
||||||
|
libpng-dev \
|
||||||
|
oniguruma-dev \
|
||||||
|
gettext-dev \
|
||||||
|
freetype-dev \
|
||||||
|
nginx \
|
||||||
|
icu-dev \
|
||||||
|
&& docker-php-ext-configure zip intl \
|
||||||
|
&& docker-php-ext-install zip pdo pdo_mysql intl \
|
||||||
|
&& docker-php-ext-enable intl \
|
||||||
|
&& docker-php-ext-configure gd --with-freetype=/usr/include/ --with-jpeg=/usr/include/ \
|
||||||
|
&& docker-php-ext-install -j$(nproc) gd \
|
||||||
|
&& docker-php-ext-enable gd \
|
||||||
|
&& docker-php-ext-install bcmath \
|
||||||
|
&& docker-php-ext-enable bcmath \
|
||||||
|
&& docker-php-ext-install exif \
|
||||||
|
&& docker-php-ext-enable exif \
|
||||||
|
&& docker-php-ext-install gettext \
|
||||||
|
&& docker-php-ext-enable gettext \
|
||||||
|
&& docker-php-ext-install opcache \
|
||||||
|
&& docker-php-ext-enable opcache \
|
||||||
|
&& rm -rf /var/cache/apk/*
|
||||||
|
|
||||||
|
# copy files from the build stage
|
||||||
|
COPY --from=build /var/www/html /var/www/html
|
||||||
|
COPY ./deploy/nginx.conf /etc/nginx/http.d/default.conf
|
||||||
|
COPY ./deploy/php.ini "$PHP_INI_DIR/conf.d/app.ini"
|
||||||
|
|
||||||
|
WORKDIR /var/www/html
|
||||||
|
|
||||||
|
# add all folders where files are being stored that require persistence. if needed, otherwise remove this line.
|
||||||
|
VOLUME ["/var/www/html/storage/app"]
|
||||||
|
|
||||||
|
CMD ["sh", "-c", "nginx && php-fpm"]
|
||||||
|
|
63
deploy/docker-compose.yml
Normal file
63
deploy/docker-compose.yml
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
# deploy/docker-compose.yml
|
||||||
|
|
||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
laravel:
|
||||||
|
restart: unless-stopped
|
||||||
|
container_name: sewtopnotch.com
|
||||||
|
build:
|
||||||
|
context: ../
|
||||||
|
dockerfile: ./deploy/Dockerfile
|
||||||
|
# allocate as many volumes as necessary, if needed.
|
||||||
|
volumes:
|
||||||
|
- ../storage/app:/var/www/html/storage/app
|
||||||
|
environment:
|
||||||
|
APP_NAME: ${APP_NAME}
|
||||||
|
APP_ENV: ${APP_ENV}
|
||||||
|
APP_DEBUG: ${APP_DEBUG}
|
||||||
|
APP_KEY: ${APP_KEY}
|
||||||
|
APP_VERSION: ${APP_VERSION}
|
||||||
|
APP_URL: ${APP_URL}
|
||||||
|
DB_CONNECTION: mysql
|
||||||
|
DB_HOST: database
|
||||||
|
DB_PORT: 3306
|
||||||
|
DB_DATABASE: ${DB_DATABASE}
|
||||||
|
DB_USERNAME: ${DB_USERNAME}
|
||||||
|
DB_PASSWORD: ${DB_PASSWORD}
|
||||||
|
MAIL_MAILER: ${MAIL_MAILER}
|
||||||
|
MAIL_HOST: ${MAIL_HOST}
|
||||||
|
MAIL_PORT: ${MAIL_PORT}
|
||||||
|
MAIL_USERNAME: ${MAIL_USERNAME}
|
||||||
|
MAIL_PASSWORD: ${MAIL_PASSWORD}
|
||||||
|
MAIL_ENCRYPTION: ${MAIL_ENCRYPTION}
|
||||||
|
MAIL_FROM_ADDRESS: ${MAIL_FROM_ADDRESS}
|
||||||
|
MAIL_FROM_NAME: ${MAIL_FROM_NAME}
|
||||||
|
ports:
|
||||||
|
- "8080:80"
|
||||||
|
networks:
|
||||||
|
- n-laravel
|
||||||
|
depends_on:
|
||||||
|
- database
|
||||||
|
|
||||||
|
database:
|
||||||
|
restart: unless-stopped
|
||||||
|
image: mariadb:lts-jammy
|
||||||
|
volumes:
|
||||||
|
- v-database:/var/lib/mysql
|
||||||
|
environment:
|
||||||
|
MARIADB_DATABASE: ${DB_DATABASE}
|
||||||
|
MARIADB_USER: ${DB_USERNAME}
|
||||||
|
MARIADB_PASSWORD: ${DB_PASSWORD}
|
||||||
|
MARIADB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
|
||||||
|
networks:
|
||||||
|
- n-laravel
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
v-database:
|
||||||
|
|
||||||
|
|
||||||
|
networks:
|
||||||
|
n-laravel:
|
||||||
|
driver: bridge
|
||||||
|
|
35
deploy/nginx.conf
Normal file
35
deploy/nginx.conf
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
# deploy/nginx.conf
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80 default_server;
|
||||||
|
listen [::]:80 default_server;
|
||||||
|
|
||||||
|
root /var/www/html/public;
|
||||||
|
client_max_body_size 10M;
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN";
|
||||||
|
add_header X-Content-Type-Options "nosniff";
|
||||||
|
|
||||||
|
index index.php;
|
||||||
|
|
||||||
|
charset utf-8;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.php?$query_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
location = /favicon.ico {
|
||||||
|
access_log off; log_not_found off;
|
||||||
|
}
|
||||||
|
location = /robots.txt {
|
||||||
|
access_log off; log_not_found off;
|
||||||
|
}
|
||||||
|
|
||||||
|
error_page 404 /index.php;
|
||||||
|
|
||||||
|
location ~ \.php$ {
|
||||||
|
fastcgi_pass 127.0.0.1:9000;
|
||||||
|
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
|
||||||
|
include fastcgi_params;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
0
deploy/php.ini
Normal file
0
deploy/php.ini
Normal file
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
|||||||
function i({state:a,splitKeys:n}){return{newTag:"",state:a,createTag:function(){if(this.newTag=this.newTag.trim(),this.newTag!==""){if(this.state.includes(this.newTag)){this.newTag="";return}this.state.push(this.newTag),this.newTag=""}},deleteTag:function(t){this.state=this.state.filter(e=>e!==t)},reorderTags:function(t){let e=this.state.splice(t.oldIndex,1)[0];this.state.splice(t.newIndex,0,e),this.state=[...this.state]},input:{["x-on:blur"]:"createTag()",["x-model"]:"newTag",["x-on:keydown"](t){["Enter",...n].includes(t.key)&&(t.preventDefault(),t.stopPropagation(),this.createTag())},["x-on:paste"](){this.$nextTick(()=>{if(n.length===0){this.createTag();return}let t=n.map(e=>e.replace(/[/\-\\^$*+?.()|[\]{}]/g,"\\$&")).join("|");this.newTag.split(new RegExp(t,"g")).forEach(e=>{this.newTag=e,this.createTag()})})}}}}export{i as default};
|
function i({state:a,splitKeys:n}){return{newTag:"",state:a,createTag:function(){if(this.newTag=this.newTag.trim(),this.newTag!==""){if(this.state.includes(this.newTag)){this.newTag="";return}this.state.push(this.newTag),this.newTag=""}},deleteTag:function(t){this.state=this.state.filter(e=>e!==t)},reorderTags:function(t){let e=this.state.splice(t.oldIndex,1)[0];this.state.splice(t.newIndex,0,e),this.state=[...this.state]},input:{"x-on:blur":"createTag()","x-model":"newTag","x-on:keydown"(t){["Enter",...n].includes(t.key)&&(t.preventDefault(),t.stopPropagation(),this.createTag())},"x-on:paste"(){this.$nextTick(()=>{if(n.length===0){this.createTag();return}let t=n.map(e=>e.replace(/[/\-\\^$*+?.()|[\]{}]/g,"\\$&")).join("|");this.newTag.split(new RegExp(t,"g")).forEach(e=>{this.newTag=e,this.createTag()})})}}}}export{i as default};
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user