From b635be6250d8552dea0be0c754851c093103942d Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Fri, 28 Jun 2024 10:42:44 +0530 Subject: [PATCH 01/62] project invoice terms --- .../Http/Controllers/InvoiceController.php | 23 +- .../Invoice/Resources/views/index.blade.php | 685 +++++++++--------- .../views/render/invoice-template.blade.php | 4 +- Modules/Invoice/Services/InvoiceService.php | 6 + ...21_103448_create_project_invoice_terms.php | 38 + Modules/Project/Entities/Project.php | 5 + .../Project/Entities/ProjectInvoiceTerm.php | 15 + .../Http/Controllers/ProjectController.php | 2 + .../Project/Resources/views/edit.blade.php | 107 ++- .../Project/Resources/views/show.blade.php | 6 +- .../subviews/create-project-details.blade.php | 2 +- .../subviews/edit-project-details.blade.php | 58 +- .../edit-project-financial-details.blade.php | 39 +- Modules/Project/Services/ProjectService.php | 40 + config/constants.php | 21 + config/snappy.php | 2 +- modules_statuses.json | 4 +- 17 files changed, 686 insertions(+), 371 deletions(-) create mode 100644 Modules/Project/Database/Migrations/2024_06_21_103448_create_project_invoice_terms.php create mode 100644 Modules/Project/Entities/ProjectInvoiceTerm.php diff --git a/Modules/Invoice/Http/Controllers/InvoiceController.php b/Modules/Invoice/Http/Controllers/InvoiceController.php index cbe4b69ec5..97337fe70f 100644 --- a/Modules/Invoice/Http/Controllers/InvoiceController.php +++ b/Modules/Invoice/Http/Controllers/InvoiceController.php @@ -27,16 +27,16 @@ public function __construct(InvoiceServiceContract $service) public function index(Request $request) { $invoiceStatus = $request->invoice_status ?? 'sent'; - $filters = $request->all(); - - if ($invoiceStatus == 'sent') { - unset($filters['invoice_status']); - $filters = $filters ?: $this->service->defaultFilters(); - } else { - $invoiceStatus = 'ready'; - $filters = $request->all(); + $filters = $request->except('invoice_status'); + + if ($invoiceStatus == 'scheduled') { + return view('invoice::index', [ + 'invoices' => $this->service->getScheduledInvoices($request), + 'invoiceStatus' => $invoiceStatus, + ]); } - + $invoiceStatus = ($invoiceStatus == 'sent') ? 'sent' : 'ready'; + return view('invoice::index', $this->service->index($filters, $invoiceStatus)); } @@ -222,4 +222,9 @@ public function createCustomInvoice() { return view('invoice::create-custom-invoice', $this->service->create()); } + + public function scheduledInvoicesIndex(Request $request) + { + return view('invoice::scheduled-invoice.index', $this->service->getScheduledInvoices($request)); + } } diff --git a/Modules/Invoice/Resources/views/index.blade.php b/Modules/Invoice/Resources/views/index.blade.php index 4596449e06..ab75499606 100644 --- a/Modules/Invoice/Resources/views/index.blade.php +++ b/Modules/Invoice/Resources/views/index.blade.php @@ -21,6 +21,13 @@ Sent +

Invoices

@@ -32,346 +39,374 @@ class="fa fa-plus mr-1">Add Invoice

- @if (request()->invoice_status == 'sent' || $invoiceStatus == 'sent') -
- @include('invoice::index-filters') -
- @endif - @error('invoice_email') -
- {{ $message }} -
- @enderror -
- Current Exchange rates ($1) :   ₹{{ $currencyService->getCurrentRatesInINR() }} -
- @if (request()->invoice_status == 'sent' || $invoiceStatus == 'sent') + + @if (request()->invoice_status !== 'scheduled' || $invoiceStatus !== 'scheduled') + @if (request()->invoice_status == 'sent' || $invoiceStatus == 'sent') +
+ @include('invoice::index-filters') +
+ @endif + @error('invoice_email') +
+ {{ $message }} +
+ @enderror
- Receivable amount (for current filters):   ₹{{ $totalReceivableAmount }} + Current Exchange rates ($1) :   ₹{{ $currencyService->getCurrentRatesInINR() }}
- @endif -
- @php - $month = now() - ->subMonth() - ->format('m'); - $year = now() - ->subMonth() - ->format('Y'); - $monthToSubtract = 1; - $quarter = now()->quarter; - @endphp - - - - - @if (request()->invoice_status == 'sent' || $invoiceStatus == 'sent') - - @endif - - @if (request()->invoice_status == 'sent' || $invoiceStatus == 'sent') - - @else - - - @endif - - @if (request()->invoice_status == 'sent' || $invoiceStatus == 'sent') - - @endif - @if (request()->invoice_status == 'sent' || $invoiceStatus == 'sent') - - - - - - @elseif (request()->invoice_status == 'ready') - - - - @endif - - - - @if ((request()->invoice_status == 'sent' || $invoiceStatus == 'sent') && $invoices->isNotEmpty()) - @foreach ($invoices as $invoice) - @php - $invoiceYear = $invoice->client->billingDetails->billing_date == 1 ? $invoice->sent_on->subMonth()->year : $invoice->sent_on->year; - $invoiceData = [ - 'projectName' => optional($invoice->project)->name ?: $invoice->client->name . 'Projects', - 'billingPersonName' => optional($invoice->client->billing_contact)->name, - 'billingPersonFirstName' => optional($invoice->client->billing_contact)->first_name, - 'billingPersonEmail' => optional($invoice->client->billing_contact)->email, - 'senderEmail' => config('invoice.mail.send-invoice.email'), - 'term' => $invoice->term, - 'year' => $invoiceYear, - 'emailSubject' => $invoiceReminderEmailSubject, - 'emailBody' => $invoiceReminderEmailBody, - 'invoiceId' => $invoice->id, - 'invoiceNumber' => $invoice->invoice_number, - 'invoiceAmount' => $invoice->invoiceAmount(), - 'bccEmails' => $invoice->client->bcc_emails, - 'ccEmails' => $invoice->client->cc_emails, - ]; - @endphp - - - - - - - @@ -271,7 +271,7 @@

- +

{{ $project->type }}
diff --git a/Modules/Project/Resources/views/subviews/create-project-details.blade.php b/Modules/Project/Resources/views/subviews/create-project-details.blade.php index ba306377fe..fdc91834ba 100644 --- a/Modules/Project/Resources/views/subviews/create-project-details.blade.php +++ b/Modules/Project/Resources/views/subviews/create-project-details.blade.php @@ -35,7 +35,7 @@
- + ` @foreach (config('project.type') as $key => $project_type) @@ -70,7 +70,9 @@ class="badge badge-primary p-1 ml-2 text-light {{ $project->effort_sheet_url ? '
- + + + @@ -137,6 +143,50 @@ class="badge badge-primary p-1 ml-2 text-light {{ $project->effort_sheet_url ? ' value="{{ old('total_estimated_hours', $project->total_estimated_hours) }}">
+
+ +
+
+
+ S. No. +
+
+ Invoice Date +
+
+ Amount +
+
+
+ + +
+
@{{ index + 1 }}
+
+
+ +
+
+ +
+ {{ optional($project->client->country)->currency }} +
+
+
+ +
+
+
+ @if($project->status == 'active') + + + Schedule An Invoice + Add Another + + @endif +
+
+
@if ($project->is_amc == 1) AMC: diff --git a/Modules/Project/Resources/views/subviews/edit-project-financial-details.blade.php b/Modules/Project/Resources/views/subviews/edit-project-financial-details.blade.php index 14b8e38379..a9bbee79ea 100644 --- a/Modules/Project/Resources/views/subviews/edit-project-financial-details.blade.php +++ b/Modules/Project/Resources/views/subviews/edit-project-financial-details.blade.php @@ -30,7 +30,44 @@ class="input-group-text">{{ optional($project->client->country)->currency }}
-
+ {{--
+ +
+
+ S. No. +
+
+ Invoice Date +
+
+ Amount +
+
+
+ + +
+
+
+
+ +
+
+ +
+ {{ optional($project->client->country)->currency }} +
+
+
+ +
+
+
--}} + + @if($project->status == 'active') + Add More + @endif + - {{--
- -
-
- S. No. -
-
- Invoice Date -
-
- Amount -
-
-
- - -
-
-
-
- -
-
- -
- {{ optional($project->client->country)->currency }} -
-
-
- -
-
-
--}} - @if($project->status == 'active') Add More @endif diff --git a/config/snappy.php b/config/snappy.php index 69047fa145..4eedb5a021 100644 --- a/config/snappy.php +++ b/config/snappy.php @@ -34,7 +34,7 @@ 'pdf' => [ 'enabled' => true, - 'binary' => env('PDF_BINARY', '/usr/local/bin/wkhtmltopdf'), + 'binary' => env('PDF_BINARY'), 'timeout' => false, 'options' => [ 'page-size' => 'B4', From 853bc3010d217fe6b07f646d2ee63d6af4a36554 Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Fri, 28 Jun 2024 11:37:16 +0530 Subject: [PATCH 06/62] synced with main --- Modules/Invoice/Http/Controllers/InvoiceController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Invoice/Http/Controllers/InvoiceController.php b/Modules/Invoice/Http/Controllers/InvoiceController.php index cc8b43aa3c..1eeefb1107 100644 --- a/Modules/Invoice/Http/Controllers/InvoiceController.php +++ b/Modules/Invoice/Http/Controllers/InvoiceController.php @@ -34,7 +34,7 @@ public function index(Request $request) 'invoices' => $this->service->getScheduledInvoices($request), 'invoiceStatus' => $invoiceStatus, ]); - }else if ($invoiceStatus == 'sent') { + } else if ($invoiceStatus == 'sent') { unset($filters['invoice_status']); $filters = $filters ?: $this->service->defaultFilters(); } else { From 9cb897fdfb0dda180fe37a5e77609ee33c9efc7f Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Fri, 28 Jun 2024 11:38:32 +0530 Subject: [PATCH 07/62] synced with main --- Modules/Invoice/Http/Controllers/InvoiceController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Invoice/Http/Controllers/InvoiceController.php b/Modules/Invoice/Http/Controllers/InvoiceController.php index 1eeefb1107..d9964c6409 100644 --- a/Modules/Invoice/Http/Controllers/InvoiceController.php +++ b/Modules/Invoice/Http/Controllers/InvoiceController.php @@ -34,7 +34,7 @@ public function index(Request $request) 'invoices' => $this->service->getScheduledInvoices($request), 'invoiceStatus' => $invoiceStatus, ]); - } else if ($invoiceStatus == 'sent') { + } elseif ($invoiceStatus == 'sent') { unset($filters['invoice_status']); $filters = $filters ?: $this->service->defaultFilters(); } else { From d1ee044f82c96b05de23c3232dde862eee14653d Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Fri, 28 Jun 2024 11:43:12 +0530 Subject: [PATCH 08/62] synced with main --- ...21_103448_create_project_invoice_terms.php | 2 +- .../Project/Resources/views/edit.blade.php | 29 ++++++++++--------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/Modules/Project/Database/Migrations/2024_06_21_103448_create_project_invoice_terms.php b/Modules/Project/Database/Migrations/2024_06_21_103448_create_project_invoice_terms.php index cb4f3c0a4d..c493c6015b 100644 --- a/Modules/Project/Database/Migrations/2024_06_21_103448_create_project_invoice_terms.php +++ b/Modules/Project/Database/Migrations/2024_06_21_103448_create_project_invoice_terms.php @@ -1,7 +1,7 @@ Date: Fri, 28 Jun 2024 11:52:53 +0530 Subject: [PATCH 09/62] synced with main --- Modules/Project/Services/ProjectService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Project/Services/ProjectService.php b/Modules/Project/Services/ProjectService.php index bbdad8a495..8207de5354 100644 --- a/Modules/Project/Services/ProjectService.php +++ b/Modules/Project/Services/ProjectService.php @@ -448,7 +448,7 @@ private function updateProjectDetails($data, $project) $project->is_ready_to_renew ? $project->tag('get-renewed') : $project->untag('get-renewed'); - $invoiceTerms = $data['invoiceTerms']; + $invoiceTerms = $data['invoiceTerms'] ?? []; $this->updateInvoiceTerms($invoiceTerms, $project); return $isProjectUpdated; From f18f09b03d6999f2473f6a82a7017ab0a935567d Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Fri, 28 Jun 2024 12:21:15 +0530 Subject: [PATCH 10/62] synced with main --- .../Http/Controllers/InvoiceController.php | 15 ++++++--------- Modules/Invoice/Services/InvoiceService.php | 16 +++++++++++----- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/Modules/Invoice/Http/Controllers/InvoiceController.php b/Modules/Invoice/Http/Controllers/InvoiceController.php index d9964c6409..518e9c69ab 100644 --- a/Modules/Invoice/Http/Controllers/InvoiceController.php +++ b/Modules/Invoice/Http/Controllers/InvoiceController.php @@ -29,16 +29,13 @@ public function index(Request $request) $invoiceStatus = $request->invoice_status ?? 'sent'; $filters = $request->all(); - if ($invoiceStatus == 'scheduled') { - return view('invoice::index', [ - 'invoices' => $this->service->getScheduledInvoices($request), - 'invoiceStatus' => $invoiceStatus, - ]); - } elseif ($invoiceStatus == 'sent') { + if ($invoiceStatus == 'sent') { + $filters = $request->all(); unset($filters['invoice_status']); - $filters = $filters ?: $this->service->defaultFilters(); - } else { - $invoiceStatus = 'ready'; + if (empty($filters)) { + $filters = $this->service->defaultFilters(); + } + } elseif ($invoiceStatus == 'ready') { $filters = $request->all(); } diff --git a/Modules/Invoice/Services/InvoiceService.php b/Modules/Invoice/Services/InvoiceService.php index 895c624feb..129d26302d 100644 --- a/Modules/Invoice/Services/InvoiceService.php +++ b/Modules/Invoice/Services/InvoiceService.php @@ -38,16 +38,22 @@ public function index($filters = [], $invoiceStatus = 'sent') 'year' => $filters['year'] ?? null, 'status' => $filters['status'] ?? null, ]; + + $invoices = []; + $clientsReadyToSendInvoicesData = []; + $projectsReadyToSendInvoicesData = []; + $totalReceivableAmount = 0.00; + if ($invoiceStatus == 'sent') { $invoices = Invoice::query()->with('client', 'client.contactPersons', 'client.billingDetails')->applyFilters($filters)->leftjoin('clients', 'invoices.client_id', '=', 'clients.id') ->select('invoices.*', 'clients.name') ->where('clients.is_billable', true) ->orderBy('name', 'asc')->orderBy('sent_on', 'desc') ->get(); - $clientsReadyToSendInvoicesData = []; - $projectsReadyToSendInvoicesData = []; + $totalReceivableAmount = $this->getTotalReceivableAmountInINR($invoices); + } elseif ($invoiceStatus == 'scheduled') { + $invoices = $this->getScheduledInvoices(); } else { - $invoices = []; $clientsReadyToSendInvoicesData = Client::status('active')->billable()->invoiceReadyToSend()->orderBy('name')->get(); $projectsReadyToSendInvoicesData = Project::billable()->whereHas('meta', function ($query) { return $query->where([ @@ -61,7 +67,7 @@ public function index($filters = [], $invoiceStatus = 'sent') 'invoices' => $invoices, 'clients' => $this->getClientsForInvoice(), 'currencyService' => $this->currencyService(), - 'totalReceivableAmount' => $this->getTotalReceivableAmountInINR($invoices), + 'totalReceivableAmount' => $totalReceivableAmount, 'filters' => $filters, 'invoiceStatus' => $invoiceStatus, 'clientsReadyToSendInvoicesData' => $clientsReadyToSendInvoicesData, @@ -770,7 +776,7 @@ public function storeLedgerAccountData(array $data) LedgerAccount::destroy($ledgerAccountsIdToDelete); } - public function getScheduledInvoices($request) + public function getScheduledInvoices() { return ProjectInvoiceTerm::with('project')->get(); } From a11a171523d48ebaaef13b8fe47e2e4f6100f3c4 Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Fri, 28 Jun 2024 12:22:11 +0530 Subject: [PATCH 11/62] synced with main --- Modules/Invoice/Http/Controllers/InvoiceController.php | 1 - 1 file changed, 1 deletion(-) diff --git a/Modules/Invoice/Http/Controllers/InvoiceController.php b/Modules/Invoice/Http/Controllers/InvoiceController.php index 518e9c69ab..07879feee5 100644 --- a/Modules/Invoice/Http/Controllers/InvoiceController.php +++ b/Modules/Invoice/Http/Controllers/InvoiceController.php @@ -30,7 +30,6 @@ public function index(Request $request) $filters = $request->all(); if ($invoiceStatus == 'sent') { - $filters = $request->all(); unset($filters['invoice_status']); if (empty($filters)) { $filters = $this->service->defaultFilters(); From eeb1c0e345bde1abdceeaece41b8247050764c33 Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Fri, 28 Jun 2024 12:23:18 +0530 Subject: [PATCH 12/62] synced with main --- Modules/Invoice/Http/Controllers/InvoiceController.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Modules/Invoice/Http/Controllers/InvoiceController.php b/Modules/Invoice/Http/Controllers/InvoiceController.php index 07879feee5..e0b6e4582b 100644 --- a/Modules/Invoice/Http/Controllers/InvoiceController.php +++ b/Modules/Invoice/Http/Controllers/InvoiceController.php @@ -31,9 +31,7 @@ public function index(Request $request) if ($invoiceStatus == 'sent') { unset($filters['invoice_status']); - if (empty($filters)) { - $filters = $this->service->defaultFilters(); - } + $filters = $this->service->defaultFilters(); } elseif ($invoiceStatus == 'ready') { $filters = $request->all(); } From 33d695693cc70bde599323f37631c686087f73d5 Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Fri, 28 Jun 2024 12:23:46 +0530 Subject: [PATCH 13/62] synced with main --- Modules/Invoice/Http/Controllers/InvoiceController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Invoice/Http/Controllers/InvoiceController.php b/Modules/Invoice/Http/Controllers/InvoiceController.php index e0b6e4582b..831da4548c 100644 --- a/Modules/Invoice/Http/Controllers/InvoiceController.php +++ b/Modules/Invoice/Http/Controllers/InvoiceController.php @@ -31,7 +31,7 @@ public function index(Request $request) if ($invoiceStatus == 'sent') { unset($filters['invoice_status']); - $filters = $this->service->defaultFilters(); + $filters = $filters ?: $this->service->defaultFilters(); } elseif ($invoiceStatus == 'ready') { $filters = $request->all(); } From 7a4330f26c78c7d1d3ca0d79ee2c869b309d88de Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Fri, 28 Jun 2024 12:25:05 +0530 Subject: [PATCH 14/62] synced with main --- .../views/subviews/edit-project-financial-details.blade.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Modules/Project/Resources/views/subviews/edit-project-financial-details.blade.php b/Modules/Project/Resources/views/subviews/edit-project-financial-details.blade.php index 5c93db9c84..14b8e38379 100644 --- a/Modules/Project/Resources/views/subviews/edit-project-financial-details.blade.php +++ b/Modules/Project/Resources/views/subviews/edit-project-financial-details.blade.php @@ -30,10 +30,7 @@ class="input-group-text">{{ optional($project->client->country)->currency }} - @if($project->status == 'active') - Add More - @endif - +
+ + - @foreach ($invoices as $invoice) + @foreach ($invoices as $index => $invoice) + {{$invoice->delivery_report}} + + - + @endforeach
ClientProjectInvoice NumberRatesBillable HoursAmount ( + taxes)Deviation - -   - - Sent onDue onPaid onStatusEmailEffortSheetPreview InvoiceAction
{{ $loop->iteration }}{{ $invoice->client->name }}{{ optional($invoice->project)->name ?: $invoice->client->name . ' Projects' }}{{ $invoice->invoice_number }} - - {{ $invoice->invoiceAmount() }}
-
- - @if ($invoice->invoiceAmountDifference() > 0) - {{ $invoice->invoiceAmountDifference() }} - @elseif ($invoice->invoiceAmountDifference() < 0) - - {{ $invoice->invoiceAmountDifference() }} + @if (request()->invoice_status == 'sent' || $invoiceStatus == 'sent') +
+ Receivable amount (for current filters):   ₹{{ $totalReceivableAmount }} +
+ @endif +
+ @php + $month = now() + ->subMonth() + ->format('m'); + $year = now() + ->subMonth() + ->format('Y'); + $monthToSubtract = 1; + $quarter = now()->quarter; + @endphp + + + + + @if (request()->invoice_status == 'sent' || $invoiceStatus == 'sent') + + @endif + + @if (request()->invoice_status == 'sent' || $invoiceStatus == 'sent') + + @else + + + @endif + + @if (request()->invoice_status == 'sent' || $invoiceStatus == 'sent') + + @endif + @if (request()->invoice_status == 'sent' || $invoiceStatus == 'sent') + + + + + + @elseif (request()->invoice_status == 'ready') + + + + @endif + + + + @if ((request()->invoice_status == 'sent' || $invoiceStatus == 'sent') && $invoices->isNotEmpty()) + @foreach ($invoices as $invoice) + @php + $invoiceYear = $invoice->client->billingDetails->billing_date == 1 ? $invoice->sent_on->subMonth()->year : $invoice->sent_on->year; + $invoiceData = [ + 'projectName' => optional($invoice->project)->name ?: $invoice->client->name . 'Projects', + 'billingPersonName' => optional($invoice->client->billing_contact)->name, + 'billingPersonFirstName' => optional($invoice->client->billing_contact)->first_name, + 'billingPersonEmail' => optional($invoice->client->billing_contact)->email, + 'senderEmail' => config('invoice.mail.send-invoice.email'), + 'term' => $invoice->term, + 'year' => $invoiceYear, + 'emailSubject' => $invoiceReminderEmailSubject, + 'emailBody' => $invoiceReminderEmailBody, + 'invoiceId' => $invoice->id, + 'invoiceNumber' => $invoice->invoice_number, + 'invoiceAmount' => $invoice->invoiceAmount(), + 'bccEmails' => $invoice->client->bcc_emails, + 'ccEmails' => $invoice->client->cc_emails, + ]; + @endphp + + + + + + + + + + + + + - - - - - - + + + @endforeach + @elseif( + (request()->invoice_status == 'ready' || $invoiceStatus == 'ready') && + $clientsReadyToSendInvoicesData->isNotEmpty()) + + - @endforeach - @elseif( - (request()->invoice_status == 'ready' || $invoiceStatus == 'ready') && - $clientsReadyToSendInvoicesData->isNotEmpty()) - - - - @php - $index = 0; - @endphp - @foreach ($clientsReadyToSendInvoicesData as $client) - @if ($client->getClientLevelProjectsBillableHoursForInvoice() == 0) - @continue - @endif @php - $index++; - $currencySymbol = config('constants.currency.' . $client->currency . '.symbol'); - if ($client->hasCustomInvoiceTemplate()) { - $amount = $currencySymbol . ($client->getResourceBasedTotalAmount() + $client->getClientProjectsTotalLedgerAmount($quarter)); - } else { - $amount = $currencySymbol . $client->getTotalPayableAmountForTerm($monthToSubtract, $client->clientLevelBillingProjects); - } - $billingStartMonth = $client->getMonthStartDateAttribute($monthToSubtract)->format('M'); - $billingEndMonth = $client->getMonthEndDateAttribute($monthToSubtract)->format('M'); - $billingEndMonthYear = $client->getMonthEndDateAttribute($monthToSubtract)->format('Y'); - $monthName = $client->getMonthEndDateAttribute($monthToSubtract)->format('F'); - $termText = $billingStartMonth; - if (optional($client->billingDetails)->billing_frequency == config('client.billing-frequency.quarterly.id')) { - $termText = today() - ->startOfQuarter() - ->format('M'); - $billingStartMonth = today() - ->startOfQuarter() - ->addQuarter() - ->format('M'); - $billingEndMonth = today() - ->endOfQuarter() - ->format('M'); - } - $invoiceData = [ - 'projectName' => $client->name . ' Projects', - 'billingPersonName' => optional($client->billing_contact)->name, - 'billingPersonFirstName' => optional($client->billing_contact)->first_name, - 'billingPersonEmail' => optional($client->billing_contact)->email, - 'senderEmail' => config('invoice.mail.send-invoice.email'), - 'invoiceNumber' => $client->next_invoice_number, - 'totalAmount' => $amount, - 'year' => $billingEndMonthYear, - 'term' => $billingStartMonth != $billingEndMonth ? $termText . ' - ' . $billingEndMonth : $monthName, - 'emailSubject' => $sendInvoiceEmailSubject, - 'emailBody' => $sendInvoiceEmailBody, - 'clientId' => $client->id, - 'projectId' => null, - 'bccEmails' => $client->bcc_emails, - 'ccEmails' => $client->cc_emails, - ]; + $index = 0; @endphp - - - - - - - - - - - @endforeach - @if ($index == 0) - - - - @endif - - - - @php - $index = 0; - @endphp - @foreach ($projectsReadyToSendInvoicesData as $project) - @if ($project->getBillableHoursForMonth($monthToSubtract) == 0) - @continue + @foreach ($clientsReadyToSendInvoicesData as $client) + @if ($client->getClientLevelProjectsBillableHoursForInvoice() == 0) + @continue + @endif + @php + $index++; + $currencySymbol = config('constants.currency.' . $client->currency . '.symbol'); + if ($client->hasCustomInvoiceTemplate()) { + $amount = $currencySymbol . ($client->getResourceBasedTotalAmount() + $client->getClientProjectsTotalLedgerAmount($quarter)); + } else { + $amount = $currencySymbol . $client->getTotalPayableAmountForTerm($monthToSubtract, $client->clientLevelBillingProjects); + } + $billingStartMonth = $client->getMonthStartDateAttribute($monthToSubtract)->format('M'); + $billingEndMonth = $client->getMonthEndDateAttribute($monthToSubtract)->format('M'); + $billingEndMonthYear = $client->getMonthEndDateAttribute($monthToSubtract)->format('Y'); + $monthName = $client->getMonthEndDateAttribute($monthToSubtract)->format('F'); + $termText = $billingStartMonth; + if (optional($client->billingDetails)->billing_frequency == config('client.billing-frequency.quarterly.id')) { + $termText = today() + ->startOfQuarter() + ->format('M'); + $billingStartMonth = today() + ->startOfQuarter() + ->addQuarter() + ->format('M'); + $billingEndMonth = today() + ->endOfQuarter() + ->format('M'); + } + $invoiceData = [ + 'projectName' => $client->name . ' Projects', + 'billingPersonName' => optional($client->billing_contact)->name, + 'billingPersonFirstName' => optional($client->billing_contact)->first_name, + 'billingPersonEmail' => optional($client->billing_contact)->email, + 'senderEmail' => config('invoice.mail.send-invoice.email'), + 'invoiceNumber' => $client->next_invoice_number, + 'totalAmount' => $amount, + 'year' => $billingEndMonthYear, + 'term' => $billingStartMonth != $billingEndMonth ? $termText . ' - ' . $billingEndMonth : $monthName, + 'emailSubject' => $sendInvoiceEmailSubject, + 'emailBody' => $sendInvoiceEmailBody, + 'clientId' => $client->id, + 'projectId' => null, + 'bccEmails' => $client->bcc_emails, + 'ccEmails' => $client->cc_emails, + ]; + @endphp + + + + + + + + + + + @endforeach + @if ($index == 0) + + + @endif + + + @php - $index++; - - $currencySymbol = config('constants.currency.' . $project->client->currency . '.symbol'); - if ($project->hasCustomInvoiceTemplate()) { - $amount = $currencySymbol . $project->getTotalLedgerAmount($quarter); - } elseif (optional($project->client->billingDetails)->service_rate_term == config('client.service-rate-terms.per_resource.slug')) { - $amount = $currencySymbol . $project->getResourceBillableAmount(); - } else { - $amount = $currencySymbol . $project->getTotalPayableAmountForTerm($monthToSubtract); - } - $billingStartMonth = $project->client->getMonthStartDateAttribute($monthToSubtract)->format('M'); - $billingEndMonth = $project->client->getMonthEndDateAttribute($monthToSubtract)->format('M'); - $billingEndMonthYear = $project->client->getMonthEndDateAttribute($monthToSubtract)->format('Y'); - $monthName = $project->client->getMonthEndDateAttribute($monthToSubtract)->format('F'); - $termText = $billingStartMonth; - if (optional($project->client->billingDetails)->billing_frequency == config('client.billing-frequency.quarterly.id')) { - $termText = today() - ->startOfQuarter() - ->format('M'); - $billingStartMonth = $termText = today() - ->startOfQuarter() - ->format('M'); - $billingEndMonth = $termText = today() - ->endOfQuarter() - ->format('M'); - } - $invoiceData = [ - 'projectName' => $project->name, - 'billingPersonName' => optional($project->client->billing_contact)->name, - 'billingPersonFirstName' => optional($project->client->billing_contact)->first_name, - 'billingPersonEmail' => optional($project->client->billing_contact)->email, - 'senderEmail' => config('invoice.mail.send-invoice.email'), - 'invoiceNumber' => str_replace('-', '', $project->next_invoice_number), - 'totalAmount' => $amount, - 'year' => $billingEndMonthYear, - 'term' => $billingStartMonth != $billingEndMonth ? $termText . ' - ' . $billingEndMonth : $monthName, - 'emailSubject' => $sendInvoiceEmailSubject, - 'emailBody' => $sendInvoiceEmailBody, - 'projectId' => $project->id, - 'clientId' => null, - 'bccEmails' => $project->client->bcc_emails, - 'ccEmails' => $project->client->cc_emails, - ]; + $index = 0; @endphp + @foreach ($projectsReadyToSendInvoicesData as $project) + @if ($project->getBillableHoursForMonth($monthToSubtract) == 0) + @continue + @endif + @php + $index++; + + $currencySymbol = config('constants.currency.' . $project->client->currency . '.symbol'); + if ($project->hasCustomInvoiceTemplate()) { + $amount = $currencySymbol . $project->getTotalLedgerAmount($quarter); + } elseif (optional($project->client->billingDetails)->service_rate_term == config('client.service-rate-terms.per_resource.slug')) { + $amount = $currencySymbol . $project->getResourceBillableAmount(); + } else { + $amount = $currencySymbol . $project->getTotalPayableAmountForTerm($monthToSubtract); + } + $billingStartMonth = $project->client->getMonthStartDateAttribute($monthToSubtract)->format('M'); + $billingEndMonth = $project->client->getMonthEndDateAttribute($monthToSubtract)->format('M'); + $billingEndMonthYear = $project->client->getMonthEndDateAttribute($monthToSubtract)->format('Y'); + $monthName = $project->client->getMonthEndDateAttribute($monthToSubtract)->format('F'); + $termText = $billingStartMonth; + if (optional($project->client->billingDetails)->billing_frequency == config('client.billing-frequency.quarterly.id')) { + $termText = today() + ->startOfQuarter() + ->format('M'); + $billingStartMonth = $termText = today() + ->startOfQuarter() + ->format('M'); + $billingEndMonth = $termText = today() + ->endOfQuarter() + ->format('M'); + } + $invoiceData = [ + 'projectName' => $project->name, + 'billingPersonName' => optional($project->client->billing_contact)->name, + 'billingPersonFirstName' => optional($project->client->billing_contact)->first_name, + 'billingPersonEmail' => optional($project->client->billing_contact)->email, + 'senderEmail' => config('invoice.mail.send-invoice.email'), + 'invoiceNumber' => str_replace('-', '', $project->next_invoice_number), + 'totalAmount' => $amount, + 'year' => $billingEndMonthYear, + 'term' => $billingStartMonth != $billingEndMonth ? $termText . ' - ' . $billingEndMonth : $monthName, + 'emailSubject' => $sendInvoiceEmailSubject, + 'emailBody' => $sendInvoiceEmailBody, + 'projectId' => $project->id, + 'clientId' => null, + 'bccEmails' => $project->client->bcc_emails, + 'ccEmails' => $project->client->cc_emails, + ]; + @endphp + + + + + + + + + + + @endforeach + @if ($index == 0) + + + + @endif + @else - - - - - - - - - - @endforeach - @if ($index == 0) - - + @endif - @else - - - - @endif - + +
ClientProjectInvoice NumberRatesBillable HoursAmount ( + taxes)Deviation + +   + + Sent onDue onPaid onStatusEmailEffortSheetPreview InvoiceAction
{{ $loop->iteration }}{{ $invoice->client->name }}{{ optional($invoice->project)->name ?: $invoice->client->name . ' Projects' }}{{ $invoice->invoice_number }} + + {{ $invoice->invoiceAmount() }}
+
+ + @if ($invoice->invoiceAmountDifference() > 0) + {{ $invoice->invoiceAmountDifference() }} + @elseif ($invoice->invoiceAmountDifference() < 0) + + {{ $invoice->invoiceAmountDifference() }} + @endif + + + {{ $invoice->sent_on->format(config('invoice.default-date-format')) }} + {{ $invoice->receivable_date->format(config('invoice.default-date-format')) }} + + {{ $invoice->payment_at ? $invoice->payment_at->format(config('invoice.default-date-format')) : '' }} + + {{ $invoice->shouldHighlighted() ? __('Overdue') : $invoice->status }} + + @if ($invoice->reminder_mail_count) +
{{ __('Reminder Sent') }}
+ @elseif($invoice->shouldHighlighted()) +
{{ __('Reminder') }}
+ @else +
-
@endif - -
- {{ $invoice->sent_on->format(config('invoice.default-date-format')) }} - {{ $invoice->receivable_date->format(config('invoice.default-date-format')) }} - - {{ $invoice->payment_at ? $invoice->payment_at->format(config('invoice.default-date-format')) : '' }} - - {{ $invoice->shouldHighlighted() ? __('Overdue') : $invoice->status }} - - @if ($invoice->reminder_mail_count) -
{{ __('Reminder Sent') }}
- @elseif($invoice->shouldHighlighted()) -
{{ __('Reminder') }}
- @else -
-
- @endif -
{{ __('Client Level Billing Projects') }}
{{ __('Client Level Billing Projects') }}
{{ $index }} - {{ $client->name . ' Projects' }} - {{ config('constants.currency.' . $client->currency . '.symbol') . '' . $client->billingDetails->service_rates . config('client.service-rate-terms.' . optional($client->billingDetails)->service_rate_term . '.short-label') }} - - @if (optional($client->billingDetails)->service_rate_term == config('client.service-rate-terms.per_resource.slug')) - {{ __('-') }} - @else - {{ $client->getClientLevelProjectsBillableHoursForInvoice() }} - {{-- --}} - @endif - {{ $amount }} {{ __('Link') }} - -
- @csrf - - -
-
-
{{ __('View Mail') }}
-
No invoices available
{{ __('Project Level Billing Projects') }}
{{ $index }} + {{ $client->name . ' Projects' }} + {{ config('constants.currency.' . $client->currency . '.symbol') . '' . $client->billingDetails->service_rates . config('client.service-rate-terms.' . optional($client->billingDetails)->service_rate_term . '.short-label') }} + + @if (optional($client->billingDetails)->service_rate_term == config('client.service-rate-terms.per_resource.slug')) + {{ __('-') }} + @else + {{ $client->getClientLevelProjectsBillableHoursForInvoice() }} + {{-- --}} + @endif + {{ $amount }} {{ __('Link') }} + +
+ @csrf + + +
+
+
{{ __('View Mail') }}
+
No invoices available
{{ __('Project Level Billing Projects') }}
{{ $index }} + {{ $project->name }} + {{ config('constants.currency.' . $project->client->currency . '.symbol') . '' . $project->client->billingDetails->service_rates . config('client.service-rate-terms.' . optional($project->client->billingDetails)->service_rate_term . '.short-label') }} + + @if (optional($project->client->billingDetails)->service_rate_term == + config('client.service-rate-terms.per_resource.slug')) + {{ __('-') }} + @else + {{ $project->getBillableHoursForMonth($monthToSubtract) }} + @endif + {{ $amount }} {{ __('Link') }} + +
+ @csrf + + +
+
+
{{ __('View Mail') }}
+
No invoices available
{{ $index }} - {{ $project->name }} - {{ config('constants.currency.' . $project->client->currency . '.symbol') . '' . $project->client->billingDetails->service_rates . config('client.service-rate-terms.' . optional($project->client->billingDetails)->service_rate_term . '.short-label') }} - - @if (optional($project->client->billingDetails)->service_rate_term == - config('client.service-rate-terms.per_resource.slug')) - {{ __('-') }} - @else - {{ $project->getBillableHoursForMonth($monthToSubtract) }} - @endif - {{ $amount }} {{ __('Link') }} - -
- @csrf - - -
-
-
{{ __('View Mail') }}
-
No invoices availableNo invoices available
No invoices available
+
+ @foreach ($clientsReadyToSendInvoicesData as $client) + @include('invoice::subviews.invoice-report.invoice-details-modal', [ + 'modalId' => 'InvoiceDetailsForClient' . $client->id, + 'teamMembers' => $client->teamMembersEffortData($monthToSubtract), + ]) + @endforeach + @else + + + + + + + + + + @foreach ($invoices as $invoice) + + + + + + + @endforeach
ProjectInvoice DateAmountStatus
{{ $invoice->project->name }}{{ $invoice->invoice_date }}{{ $invoice->amount }} +
status.class") }}"> + {{config("constants.finance.scheduled-invoice.status.$invoice->status.title")}} +
+
- - @foreach ($clientsReadyToSendInvoicesData as $client) - @include('invoice::subviews.invoice-report.invoice-details-modal', [ - 'modalId' => 'InvoiceDetailsForClient' . $client->id, - 'teamMembers' => $client->teamMembersEffortData($monthToSubtract), - ]) - @endforeach + @endif @if (request()->invoice_status == 'ready' || $invoiceStatus == 'ready') @include('invoice::modals.invoice-email-preview') @endif - @include('invoice::modals.invoice-reminder') + @if (request()->invoice_status !== 'scheduled' || $invoiceStatus !== 'scheduled') + @include('invoice::modals.invoice-reminder') + @endif @endsection diff --git a/Modules/Invoice/Resources/views/render/invoice-template.blade.php b/Modules/Invoice/Resources/views/render/invoice-template.blade.php index 3ab02fe525..2ef74ad3e2 100644 --- a/Modules/Invoice/Resources/views/render/invoice-template.blade.php +++ b/Modules/Invoice/Resources/views/render/invoice-template.blade.php @@ -412,7 +412,7 @@ @endif @else @if (optional($client->billingDetails)->service_rate_term == config('client.service-rate-terms.per_resource.slug')) - {{ $currencySymbol . $project->getResourceBillableAmount() }} + {{ $currencySymbol . $project->getResourceBillableAmount() }} @else {{ $currencySymbol . $project->getTotalPayableAmountForTerm($monthsToSubtract, $periodStartDate, $periodEndDate) }} @endif @@ -483,7 +483,7 @@ @if (optional($client->billingDetails)->service_rate_term == config('client.service-rate-terms.per_resource.slug')) {{ '' }} @else - {{ $currencySymbol . $client->getTotalPayableAmountForTerm($monthsToSubtract, $projects, $periodStartDate, $periodEndDate) }} + {{ $currencySymbol . $client->getTotalPayabl eAmountForTerm($monthsToSubtract, $projects, $periodStartDate, $periodEndDate) }} @endif @else @if (optional($client->billingDetails)->service_rate_term == config('client.service-rate-terms.per_resource.slug')) diff --git a/Modules/Invoice/Services/InvoiceService.php b/Modules/Invoice/Services/InvoiceService.php index 5d1c4a7b56..c04454104d 100644 --- a/Modules/Invoice/Services/InvoiceService.php +++ b/Modules/Invoice/Services/InvoiceService.php @@ -22,6 +22,7 @@ use Modules\Invoice\Entities\Invoice; use Modules\Invoice\Entities\LedgerAccount; use Modules\Invoice\Exports\MonthlyGSTTaxReportExport; +use Modules\Project\Entities\ProjectInvoiceTerm; use Modules\Invoice\Exports\TaxReportExport; use Modules\Invoice\Exports\YearlyInvoiceReportExport; use Modules\Invoice\Notifications\GoogleChat\SendPaymentReceivedNotification; @@ -919,4 +920,9 @@ private function formatYearlyInvoicesReportForInternationalClientExport($invoice ]; }); } + + public function getScheduledInvoices($request) + { + return ProjectInvoiceTerm::with('project')->get();; + } } diff --git a/Modules/Project/Database/Migrations/2024_06_21_103448_create_project_invoice_terms.php b/Modules/Project/Database/Migrations/2024_06_21_103448_create_project_invoice_terms.php new file mode 100644 index 0000000000..3e5c28a76a --- /dev/null +++ b/Modules/Project/Database/Migrations/2024_06_21_103448_create_project_invoice_terms.php @@ -0,0 +1,38 @@ +id(); + $table->unsignedBigInteger('project_id'); + $table->date('invoice_date')->nullable(); + $table->decimal('amount', 10, 2)->nullable(); + $table->string('status')->nullable()->default('yet-to-be-created'); + $table->timestamps(); + + $table->foreign('project_id')->references('id')->on('projects')->onDelete('cascade'); + $table->index('project_id'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('project_invoice_terms'); + } +} diff --git a/Modules/Project/Entities/Project.php b/Modules/Project/Entities/Project.php index 8cccbcd4c4..fc327a259f 100644 --- a/Modules/Project/Entities/Project.php +++ b/Modules/Project/Entities/Project.php @@ -53,6 +53,11 @@ public function repositories() return $this->hasMany(ProjectRepository::class); } + public function invoiceTerms() + { + return $this->hasMany(ProjectInvoiceTerm::class); + } + public function resourceRequirement() { return $this->hasMany(ProjectResourceRequirement::class); diff --git a/Modules/Project/Entities/ProjectInvoiceTerm.php b/Modules/Project/Entities/ProjectInvoiceTerm.php new file mode 100644 index 0000000000..eeeb3f6fdc --- /dev/null +++ b/Modules/Project/Entities/ProjectInvoiceTerm.php @@ -0,0 +1,15 @@ +belongsTo(Project::class); + } +} diff --git a/Modules/Project/Http/Controllers/ProjectController.php b/Modules/Project/Http/Controllers/ProjectController.php index e13190f206..205823453f 100644 --- a/Modules/Project/Http/Controllers/ProjectController.php +++ b/Modules/Project/Http/Controllers/ProjectController.php @@ -147,6 +147,7 @@ public function edit(Project $project) $designationKeys = array_keys($designations); $contractData = $this->getContractData($project); $contractName = $contractData['contractName']; + $invoiceTerms = $this->service->getInvoiceTerms($project); return view('project::edit', [ 'project' => $project, @@ -158,6 +159,7 @@ public function edit(Project $project) 'workingDaysInMonth' => $this->service->getWorkingDays($project), 'designationKeys' => $designationKeys, 'contractName' => $contractName, + 'invoiceTerms' => $invoiceTerms, ]); } diff --git a/Modules/Project/Resources/views/edit.blade.php b/Modules/Project/Resources/views/edit.blade.php index 11f5934220..c694cae480 100644 --- a/Modules/Project/Resources/views/edit.blade.php +++ b/Modules/Project/Resources/views/edit.blade.php @@ -83,7 +83,8 @@ class="text-theme-body text-decoration-none mb-2 mb-xl-4 d-inline-flex align-ite projectRepositories: @json($projectRepositories), workingDaysInMonth: @json($workingDaysInMonth), users: @json($teamMembers->sortBy('name')->values()), - designations: @json($designations) + designations: @json($designations), + invoiceTerms: @json($invoiceTerms) } }, @@ -114,7 +115,6 @@ class="text-theme-body text-decoration-none mb-2 mb-xl-4 d-inline-flex align-ite daily_expected_effort: 0, weekly_expected_effort: 0, monthly_expected_effort: 0, - } } }, @@ -169,6 +169,16 @@ class="text-theme-body text-decoration-none mb-2 mb-xl-4 d-inline-flex align-ite addNewProjectRepository() { this.projectRepositories.push(this.defaultProjectRepository()); }, + addNewProjectInvoiceTerm() { + this.invoiceTerms.push({ + id: new Date().getTime(), + invoice_date: new Date().getTime(), + amount: '' + }); + }, + removeProjectInvoiceTerm(index) { + this.invoiceTerms.splice(index, 1); + }, removeProjectTeamMember(index) { this.projectTeamMembers.splice(index, 1); @@ -182,54 +192,103 @@ class="text-theme-body text-decoration-none mb-2 mb-xl-4 d-inline-flex align-ite this.projectTeamMembers[index]['pivot']['started_on'] = newDate; }, - - updatedDailyExpectedEffort($event, index, numberOfDays) { value = $event.target.value; - maximumExpectedEfforts = 12 + maximumExpectedEfforts = 12; if (numberOfDays == 5) { - maximumExpectedEfforts = 60 + maximumExpectedEfforts = 60; } else if (numberOfDays == this.workingDaysInMonth) { - maximumExpectedEfforts = 276 + maximumExpectedEfforts = 276; } if (value > maximumExpectedEfforts) { - if(! confirm('are you sure you want to enter more than ' + maximumExpectedEfforts + ' hours in expected effort?')) { - $event.target.value = value.slice(0, -1) - return + if (!confirm('Are you sure you want to enter more than ' + maximumExpectedEfforts + ' hours in expected effort?')) { + $event.target.value = value.slice(0, -1); + return; } } if (numberOfDays == 5) { - this.projectTeamMembers[index]['pivot']['daily_expected_effort'] = value/5; + this.projectTeamMembers[index]['pivot']['daily_expected_effort'] = value / 5; this.projectTeamMembers[index]['pivot']['weekly_expected_effort'] = value; - this.projectTeamMembers[index]['pivot']['monthly_expected_effort'] = (value/5) * this.workingDaysInMonth; + this.projectTeamMembers[index]['pivot']['monthly_expected_effort'] = (value / 5) * this.workingDaysInMonth; } else if (numberOfDays == this.workingDaysInMonth) { - this.projectTeamMembers[index]['pivot']['daily_expected_effort'] = value/numberOfDays; - this.projectTeamMembers[index]['pivot']['weekly_expected_effort'] = (value/numberOfDays) * 5; + this.projectTeamMembers[index]['pivot']['daily_expected_effort'] = value / numberOfDays; + this.projectTeamMembers[index]['pivot']['weekly_expected_effort'] = (value / numberOfDays) * 5; this.projectTeamMembers[index]['pivot']['monthly_expected_effort'] = value; } else { this.projectTeamMembers[index]['pivot']['daily_expected_effort'] = value; this.projectTeamMembers[index]['pivot']['weekly_expected_effort'] = value * 5; this.projectTeamMembers[index]['pivot']['monthly_expected_effort'] = value * this.workingDaysInMonth; } - - this.projectTeamMembers[index]['pivot']['daily_expected_effort'] = value/numberOfDays; - this.$forceUpdate() + this.$forceUpdate(); + }, + + handleFileUpload(event) { + const fileInput = event.target; + this.toggleSections(fileInput.files.length > 0); + }, + + toggleSectionsByContracts() { + const hasContracts = this.project.project_contracts.length > 0; + this.toggleSections(hasContracts); + }, + + handleBillingCycle(event) { + const projectType = event.target.value; + this.toggleSectionsByProjectType(projectType); + }, + + toggleSections(condition) { + const linkDiv = document.getElementById('client-financial-detail-link'); + const invoiceTermDiv = document.getElementById('invoice-terms-section'); + + if (condition) { + if (this.projectType === 'monthly-billing') { + linkDiv.classList.remove('d-none'); + invoiceTermDiv.classList.add('d-none'); + } else if (this.projectType === 'fixed-budget') { + linkDiv.classList.add('d-none'); + invoiceTermDiv.classList.remove('d-none'); + } + } else { + linkDiv.classList.add('d-none'); + invoiceTermDiv.classList.add('d-none'); + } + }, + + toggleSectionsByProjectType(projectType) { + const linkDiv = document.getElementById('client-financial-detail-link'); + const invoiceTermDiv = document.getElementById('invoice-terms-section'); + + if (projectType === 'monthly-billing') { + linkDiv.classList.remove('d-none'); + invoiceTermDiv.classList.add('d-none'); + } else if (projectType === 'fixed-budget') { + linkDiv.classList.add('d-none'); + invoiceTermDiv.classList.remove('d-none'); + } else { + linkDiv.classList.add('d-none'); + invoiceTermDiv.classList.add('d-none'); + } } }, - filters: { - toDate: function(timestamp) { - if (timestamp == null) { - return timestamp; + filters: { + toDate(timestamp) { + if (!timestamp) { + return timestamp; } - return timestamp.substring(0,10); + return timestamp.substring(0, 10); } }, - mounted() {}, + mounted() { + document.getElementById('contract_file').addEventListener('change', this.handleFileUpload); + document.getElementById('project_type').addEventListener('change', this.handleBillingCycle); + this.toggleSectionsByContracts(); + } }); -@endsection +@endsection \ No newline at end of file diff --git a/Modules/Project/Resources/views/show.blade.php b/Modules/Project/Resources/views/show.blade.php index d54c4da754..77fbd16643 100644 --- a/Modules/Project/Resources/views/show.blade.php +++ b/Modules/Project/Resources/views/show.blade.php @@ -81,11 +81,11 @@
- + - + {{$teamMember->user->name}} Project Invoice Date AmountConfirmed By CLientSrvice Delivery Report Status
{{ $invoice->project->name }} {{ $invoice->invoice_date }} {{ $invoice->amount }} -
status.class") }}"> - {{config("constants.finance.scheduled-invoice.status.$invoice->status.title")}} + @if ($invoice->confirmation_required) + {{ $invoice->is_confirmed == 0 ? "NO" : "YES" }} + @else + Not required + @endif +
+ + {{ basename($invoice->delivery_report) }} + + +
status.class") }}"> + {{ config("constants.finance.scheduled-invoice.status.$invoice->status.title") }}
@endif diff --git a/Modules/Project/Database/Migrations/2024_06_21_103448_create_project_invoice_terms.php b/Modules/Project/Database/Migrations/2024_06_21_103448_create_project_invoice_terms.php index c493c6015b..b543edf9e0 100644 --- a/Modules/Project/Database/Migrations/2024_06_21_103448_create_project_invoice_terms.php +++ b/Modules/Project/Database/Migrations/2024_06_21_103448_create_project_invoice_terms.php @@ -19,6 +19,9 @@ public function up() $table->date('invoice_date')->nullable(); $table->decimal('amount', 10, 2)->nullable(); $table->string('status')->nullable(); + $table->boolean('confirmation_required')->nullable(); + $table->boolean('is_confirmed')->nullable(); + $table->string('delivery_report')->nullable(); $table->timestamps(); $table->foreign('project_id')->references('id')->on('projects')->onDelete('cascade'); diff --git a/Modules/Project/Entities/ProjectInvoiceTerm.php b/Modules/Project/Entities/ProjectInvoiceTerm.php index e00bcc0e85..c298c2a703 100644 --- a/Modules/Project/Entities/ProjectInvoiceTerm.php +++ b/Modules/Project/Entities/ProjectInvoiceTerm.php @@ -6,7 +6,7 @@ class ProjectInvoiceTerm extends Model { - protected $fillable = ['project_id', 'invoice_date', 'status', 'amount']; + protected $fillable = ['project_id', 'invoice_date', 'status', 'confirmation_required', 'amount', 'is_confirmed', 'delivery_report']; public function project() { diff --git a/Modules/Project/Http/Controllers/ProjectController.php b/Modules/Project/Http/Controllers/ProjectController.php index 205823453f..0ed331a6c0 100644 --- a/Modules/Project/Http/Controllers/ProjectController.php +++ b/Modules/Project/Http/Controllers/ProjectController.php @@ -212,4 +212,9 @@ private function getContractData(Project $project) 'contractName' => $contractName, ]; } + + public function showDeliveryReport($invoiceId) + { + return $this->service->showDeliveryReport($invoiceId); + } } diff --git a/Modules/Project/Resources/views/edit.blade.php b/Modules/Project/Resources/views/edit.blade.php index 1815a33bb1..0df430f3ff 100644 --- a/Modules/Project/Resources/views/edit.blade.php +++ b/Modules/Project/Resources/views/edit.blade.php @@ -115,9 +115,20 @@ class="text-theme-body text-decoration-none mb-2 mb-xl-4 d-inline-flex align-ite daily_expected_effort: 0, weekly_expected_effort: 0, monthly_expected_effort: 0, + delivery_report:null, } } }, + defaultProjectInvoiceTerm() { + return { + id: new Date().getTime(), + invoice_date: new Date().getTime(), + amount: '', + confirmation_required: 0, + is_confirmed: 0, + deliveryReport: '', + } + }, defaultProjectRepository() { return { id: new Date().getTime(), @@ -170,11 +181,7 @@ class="text-theme-body text-decoration-none mb-2 mb-xl-4 d-inline-flex align-ite this.projectRepositories.push(this.defaultProjectRepository()); }, addNewProjectInvoiceTerm() { - this.invoiceTerms.push({ - id: new Date().getTime(), - invoice_date: new Date().getTime(), - amount: '' - }); + this.invoiceTerms.push(this.defaultProjectInvoiceTerm()); }, removeProjectInvoiceTerm(index) { this.invoiceTerms.splice(index, 1); diff --git a/Modules/Project/Resources/views/subviews/edit-project-details.blade.php b/Modules/Project/Resources/views/subviews/edit-project-details.blade.php index 83fdac8852..719c696c6c 100644 --- a/Modules/Project/Resources/views/subviews/edit-project-details.blade.php +++ b/Modules/Project/Resources/views/subviews/edit-project-details.blade.php @@ -70,8 +70,9 @@ class="badge badge-primary p-1 ml-2 text-light {{ $project->effort_sheet_url ? '
- - + + +
-
-
- S. No. -
-
- Invoice Date -
-
- Amount -
-
-
+
@{{ index + 1 }}
-
- -
-
- -
- {{ optional($project->client->country)->currency }} +
+
+
+ + +
+
+ +
+ +
+ {{ optional($project->client->country)->currency }} +
+
+
+
+ + +
+
+ + +
-
-
- +
+
+
+ +
+
+ + +
+ File: {{ $project->name }}_invoice_term_@{{ index + 1 }} +
+
+
+
+
+ +
+
diff --git a/Modules/Project/Routes/web.php b/Modules/Project/Routes/web.php index 79c151a686..f7b226f7b5 100644 --- a/Modules/Project/Routes/web.php +++ b/Modules/Project/Routes/web.php @@ -18,6 +18,7 @@ Route::get('/create', 'ProjectController@create')->name('project.create'); Route::post('/', 'ProjectController@store')->name('project.store'); Route::post('/{project}/update', 'ProjectController@update')->name('project.update'); + Route::get('/delivery-report/{invoice}', 'ProjectController@showDeliveryReport')->name('delivery-report.show'); Route::get('/contract/pdf/{contract}', 'ProjectController@showPdf')->name('pdf.show'); Route::delete('client/{project}/edit', 'ProjectController@destroy')->name('project.destroy'); Route::post('/project-fte-export', 'ProjectController@projectFTEExport')->name('project.fte.export'); diff --git a/Modules/Project/Services/ProjectService.php b/Modules/Project/Services/ProjectService.php index 8207de5354..e039b61374 100644 --- a/Modules/Project/Services/ProjectService.php +++ b/Modules/Project/Services/ProjectService.php @@ -499,34 +499,74 @@ private function updateInvoiceTerms($invoiceTerms, $project) { if (empty($invoiceTerms)) { $project->invoiceTerms()->delete(); - return; } - + $existingTerms = $project->invoiceTerms()->get()->keyBy('id'); - + $termIds = []; - foreach ($invoiceTerms as $term) { + foreach ($invoiceTerms as $index => $term) { $termId = $term['id'] ?? null; - + if ($termId && isset($existingTerms[$termId])) { $existingTerm = $existingTerms[$termId]; - $existingTerm->invoice_date = $term['invoice_date']; - $existingTerm->amount = $term['amount']; - $existingTerm->save(); + $filePath = $existingTerm->delivery_report; + if (isset($data['delivery_report'])) { + $filePath = $this->saveOrUpdateDeliveryReport($term, $project, $index); + } + + $existingTerm->update([ + 'invoice_date' => $term['invoice_date'], + 'amount' => $term['amount'], + 'confirmation_required' => $term['confirmation_required'], + 'is_confirmed' => $term['is_confirmed'] ?? $existingTerm->is_confirmed, + 'delivery_report' => $filePath, + ]); + $termIds[] = $termId; } else { - $newTerm = ProjectInvoiceTerm::create([ + $filePath = $this->saveOrUpdateDeliveryReport($term, $project, $index); + $newTerm = $project->invoiceTerms()->create([ 'project_id' => $project->id, 'invoice_date' => $term['invoice_date'], 'status' => 'yet-to-be-created', 'amount' => $term['amount'], + 'confirmation_required' => $term['confirmation_required'], + 'is_confirmed' => $term['is_confirmed'] ?? false, + 'delivery_report' => $filePath, ]); + $termIds[] = $newTerm->id; } } + $project->invoiceTerms()->whereNotIn('id', $termIds)->delete(); } + + public function saveOrUpdateDeliveryReport($data, $project, $index) + { + if ($data['delivery_report'] ?? null) { + $file = $data['delivery_report']; + $folder = '/delivery_report/' . date('Y') . '/' . date('m'); + $originalName = $file->getClientOriginalName(); + $extension = $file->getClientOriginalExtension(); + $fileName = $project->name . '_' . $index + 1 . '.' . $extension; + return Storage::putFileAs($folder, $file, $fileName); + } + } + + public function showDeliveryReport($invoiceId) + { + + $invoiceTerm = ProjectInvoiceTerm::where('id', $invoiceId)->first(); + $filePath = storage_path('app/' . $invoiceTerm->delivery_report); + $content = file_get_contents($filePath); + $deliveryReport = pathinfo($invoiceTerm->delivery_report)['filename']; + return response($content)->withHeaders([ + 'content-type' => mime_content_type($filePath), + 'deliveryReport' => $deliveryReport, + ]); + } private function updateProjectRepositories($data, $project) { From 8bd9a93958d2aa9945f6344c507fe1b04a72e757 Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Mon, 1 Jul 2024 16:37:11 +0530 Subject: [PATCH 17/62] synced with main --- .../Invoice/Resources/views/index.blade.php | 3 +- .../Project/Resources/views/edit.blade.php | 6 ++++ .../subviews/edit-project-details.blade.php | 28 ++++++++++--------- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/Modules/Invoice/Resources/views/index.blade.php b/Modules/Invoice/Resources/views/index.blade.php index 8c16cc2e2d..5e7e1657f5 100644 --- a/Modules/Invoice/Resources/views/index.blade.php +++ b/Modules/Invoice/Resources/views/index.blade.php @@ -402,9 +402,8 @@ class="{{ $invoice->shouldHighlighted() ? 'font-weight-bold text-danger' : '' }} Not required @endif - {{$invoice->delivery_report}} - + {{ basename($invoice->delivery_report) }} diff --git a/Modules/Project/Resources/views/edit.blade.php b/Modules/Project/Resources/views/edit.blade.php index 0df430f3ff..8e2868fb1f 100644 --- a/Modules/Project/Resources/views/edit.blade.php +++ b/Modules/Project/Resources/views/edit.blade.php @@ -280,6 +280,12 @@ class="text-theme-body text-decoration-none mb-2 mb-xl-4 d-inline-flex align-ite linkDiv.classList.add('d-none'); invoiceTermDiv.classList.add('d-none'); } + }, + getFileName(filePath) { + return filePath.split('\\').pop().split('/').pop(); + }, + getDeliveryReportUrl(invoiceTermId) { + return `{{ route('delivery-report.show', ':id') }}`.replace(':id', invoiceTermId); } }, diff --git a/Modules/Project/Resources/views/subviews/edit-project-details.blade.php b/Modules/Project/Resources/views/subviews/edit-project-details.blade.php index 719c696c6c..210a9d1917 100644 --- a/Modules/Project/Resources/views/subviews/edit-project-details.blade.php +++ b/Modules/Project/Resources/views/subviews/edit-project-details.blade.php @@ -149,35 +149,35 @@ class="badge badge-primary p-1 ml-2 text-light {{ $project->effort_sheet_url ? '
- +
@{{ index + 1 }}
- - + +
- +
- +
{{ optional($project->client->country)->currency }}
- -
- - @@ -186,17 +186,19 @@ class="badge badge-primary p-1 ml-2 text-light {{ $project->effort_sheet_url ? '
- +
- +
- File: {{ $project->name }}_invoice_term_@{{ index + 1 }} + + @{{ getFileName(invoiceTerm.delivery_report) }} +
-
+
i
From 1dceff73e565f9a48e8fcc50f6eed2584e9d0428 Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Mon, 1 Jul 2024 17:10:10 +0530 Subject: [PATCH 18/62] synced with main --- .../views/subviews/edit-project-details.blade.php | 14 +++++++------- Modules/Project/Services/ProjectService.php | 3 ++- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/Modules/Project/Resources/views/subviews/edit-project-details.blade.php b/Modules/Project/Resources/views/subviews/edit-project-details.blade.php index 210a9d1917..1bf51e51bd 100644 --- a/Modules/Project/Resources/views/subviews/edit-project-details.blade.php +++ b/Modules/Project/Resources/views/subviews/edit-project-details.blade.php @@ -149,7 +149,7 @@ class="badge badge-primary p-1 ml-2 text-light {{ $project->effort_sheet_url ? '
- +
@{{ index + 1 }}
@@ -157,12 +157,12 @@ class="badge badge-primary p-1 ml-2 text-light {{ $project->effort_sheet_url ? '
- +
- +
{{ optional($project->client->country)->currency }}
@@ -170,14 +170,14 @@ class="badge badge-primary p-1 ml-2 text-light {{ $project->effort_sheet_url ? '
-
- @@ -189,7 +189,7 @@ class="badge badge-primary p-1 ml-2 text-light {{ $project->effort_sheet_url ? '
-
i +
diff --git a/Modules/Project/Services/ProjectService.php b/Modules/Project/Services/ProjectService.php index e039b61374..301d4a0270 100644 --- a/Modules/Project/Services/ProjectService.php +++ b/Modules/Project/Services/ProjectService.php @@ -511,7 +511,8 @@ private function updateInvoiceTerms($invoiceTerms, $project) if ($termId && isset($existingTerms[$termId])) { $existingTerm = $existingTerms[$termId]; $filePath = $existingTerm->delivery_report; - if (isset($data['delivery_report'])) { + + if (isset($term['delivery_report'])) { $filePath = $this->saveOrUpdateDeliveryReport($term, $project, $index); } From 67a08ddd4cdf6538ec20499149a8a8cce71cb85b Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Mon, 1 Jul 2024 19:57:34 +0530 Subject: [PATCH 19/62] synced with main --- .../Invoice/Resources/views/index.blade.php | 20 ++++++----- Modules/Invoice/Services/InvoiceService.php | 35 +++++++++++++++++-- .../Project/Entities/ProjectInvoiceTerm.php | 1 + config/constants.php | 5 +++ 4 files changed, 50 insertions(+), 11 deletions(-) diff --git a/Modules/Invoice/Resources/views/index.blade.php b/Modules/Invoice/Resources/views/index.blade.php index 5e7e1657f5..1baac78751 100644 --- a/Modules/Invoice/Resources/views/index.blade.php +++ b/Modules/Invoice/Resources/views/index.blade.php @@ -392,24 +392,26 @@ class="{{ $invoice->shouldHighlighted() ? 'font-weight-bold text-danger' : '' }} @foreach ($invoices as $index => $invoice) -
{{ $invoice->project->name }} - {{ $invoice->invoice_date }} - {{ $invoice->amount }} + {{-- @dd($invoices) --}} + + {{ $invoice['project'] }} + {{ $invoice['invoice_date'] }} + {{ $invoice['amount'] }} - @if ($invoice->confirmation_required) - {{ $invoice->is_confirmed == 0 ? "NO" : "YES" }} + @if ($invoice['confirmation_required']) + {{ $invoice['is_confirmed'] == 0 ? "NO" : "YES" }} @else Not required @endif - - {{ basename($invoice->delivery_report) }} + + {{ basename($invoice['delivery_report']) }} -
status.class") }}"> - {{ config("constants.finance.scheduled-invoice.status.$invoice->status.title") }} +
+ {{ config('constants.finance.scheduled-invoice.status.' . $invoice['status'] . '.title') }}
diff --git a/Modules/Invoice/Services/InvoiceService.php b/Modules/Invoice/Services/InvoiceService.php index 129d26302d..8bae8549e3 100644 --- a/Modules/Invoice/Services/InvoiceService.php +++ b/Modules/Invoice/Services/InvoiceService.php @@ -26,6 +26,7 @@ use Modules\Invoice\Exports\YearlyInvoiceReportExport; use Modules\Invoice\Notifications\GoogleChat\SendPaymentReceivedNotification; use Modules\Project\Entities\Project; +use Illuminate\Support\Facades\DB; use Modules\Project\Entities\ProjectInvoiceTerm; class InvoiceService implements InvoiceServiceContract @@ -778,9 +779,39 @@ public function storeLedgerAccountData(array $data) public function getScheduledInvoices() { - return ProjectInvoiceTerm::with('project')->get(); + return ProjectInvoiceTerm::with(['project' => function ($query) { + $query->with(['invoices' => function ($query) { + $query->select('id', 'project_id', 'sent_on', 'status'); + }])->select('id', 'name'); + }]) + ->get(['id', 'amount', 'invoice_date', 'confirmation_required', 'delivery_report', 'is_confirmed', 'status', 'project_id']) + ->map(function ($term) { + $project = $term->project; + $termDate = Carbon::parse($term->invoice_date)->toDateString(); + + $invoice = $project->invoices->first(function ($invoice) use ($termDate) { + return Carbon::parse($invoice->sent_on)->toDateString() == $termDate; + }); + + $status = $invoice ? $invoice->status : $term->status; + if ($termDate < Carbon::now()->toDateString()) { + $status = "overdue"; + } + + return [ + 'amount' => $term->amount, + 'id' => $term->id, + 'invoice_date' => $term->invoice_date, + 'confirmation_required' => $term->confirmation_required, + 'delivery_report' => $term->delivery_report, + 'is_confirmed' => $term->is_confirmed, + 'project_id' => $project->id, + 'project' => $project->name, + 'status' => $status, + ]; + }); } - + private function setInvoiceNumber($invoice, $sent_date) { $invoice->invoice_number = $this->getInvoiceNumber($invoice->client_id, $invoice->project_id, $sent_date, $invoice->billing_level); diff --git a/Modules/Project/Entities/ProjectInvoiceTerm.php b/Modules/Project/Entities/ProjectInvoiceTerm.php index c298c2a703..0f37b30c58 100644 --- a/Modules/Project/Entities/ProjectInvoiceTerm.php +++ b/Modules/Project/Entities/ProjectInvoiceTerm.php @@ -3,6 +3,7 @@ namespace Modules\Project\Entities; use Illuminate\Database\Eloquent\Model; +use Modules\Invoice\Entities\Invoice; class ProjectInvoiceTerm extends Model { diff --git a/config/constants.php b/config/constants.php index e1c27b4f43..6403ecb6f9 100644 --- a/config/constants.php +++ b/config/constants.php @@ -184,6 +184,11 @@ 'title' => 'Paid', 'class' => 'badge badge-success', ], + 'overdue' => [ + 'label' => 'overdue', + 'title' => 'Over Due', + 'class' => 'badge badge-danger', + ], ], 'email-duration-in-days' => 5, 'email'=> 'finance@coloredcow.com', From 70b705456ff5c14f6f4744f03dd277b249aeb19d Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Tue, 2 Jul 2024 09:51:57 +0530 Subject: [PATCH 20/62] synced with main --- .../subviews/edit-project-details.blade.php | 93 +++++++++---------- 1 file changed, 46 insertions(+), 47 deletions(-) diff --git a/Modules/Project/Resources/views/subviews/edit-project-details.blade.php b/Modules/Project/Resources/views/subviews/edit-project-details.blade.php index 1bf51e51bd..941c980f97 100644 --- a/Modules/Project/Resources/views/subviews/edit-project-details.blade.php +++ b/Modules/Project/Resources/views/subviews/edit-project-details.blade.php @@ -147,62 +147,61 @@ class="badge badge-primary p-1 ml-2 text-light {{ $project->effort_sheet_url ? '
-
+
-
-
@{{ index + 1 }}
-
-
-
-
- - -
-
- -
- -
- {{ optional($project->client->country)->currency }} +
+
+
+
+ + +
+
+ +
+ +
+ {{ optional($project->client->country)->currency }} +
-
-
- - -
-
- - -
-
-
-
-
- +
+ +
-
- - - +
+
+
+ +
+
+
+ + +
+
+
+
+
-
- -
-
From c87c2d9f7a6d046d6bacaf7c2aafdab686c60762 Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Tue, 2 Jul 2024 10:56:15 +0530 Subject: [PATCH 21/62] synced with main --- .../Console/SendUpcomingInvoiceReminder.php | 37 +++++++++++ .../Emails/SendInvoiceReminderMail.php | 40 ++++++++++++ .../Providers/InvoiceServiceProvider.php | 1 + .../Invoice/Resources/views/index.blade.php | 18 ++--- .../mail/upcoming-invoice-list.blade.php | 36 ++++++++++ Modules/Invoice/Services/InvoiceService.php | 65 ++++++++++--------- app/Console/Kernel.php | 1 + 7 files changed, 160 insertions(+), 38 deletions(-) create mode 100644 Modules/Invoice/Console/SendUpcomingInvoiceReminder.php create mode 100644 Modules/Invoice/Emails/SendInvoiceReminderMail.php create mode 100644 Modules/Invoice/Resources/views/mail/upcoming-invoice-list.blade.php diff --git a/Modules/Invoice/Console/SendUpcomingInvoiceReminder.php b/Modules/Invoice/Console/SendUpcomingInvoiceReminder.php new file mode 100644 index 0000000000..170a0b9035 --- /dev/null +++ b/Modules/Invoice/Console/SendUpcomingInvoiceReminder.php @@ -0,0 +1,37 @@ +getScheduledInvoicesForMail(); + Mail::send(new SendInvoiceReminderMail($upcomingInvoices)); + } +} diff --git a/Modules/Invoice/Emails/SendInvoiceReminderMail.php b/Modules/Invoice/Emails/SendInvoiceReminderMail.php new file mode 100644 index 0000000000..a639ec9e56 --- /dev/null +++ b/Modules/Invoice/Emails/SendInvoiceReminderMail.php @@ -0,0 +1,40 @@ +upcomingInvoices = $upcomingInvoices; + } + + /** + * Build the message. + * + * @return $this + */ + public function build() + { + return $this + ->to('finance@coloredcow.com') + ->from('abhishek.negi@coloredcow.in') + ->subject('List of upcoming invoices.') + ->view('invoice::mail.upcoming-invoice-list') + ->with(['upcomingInvoices' => $this->upcomingInvoices]); + } +} diff --git a/Modules/Invoice/Providers/InvoiceServiceProvider.php b/Modules/Invoice/Providers/InvoiceServiceProvider.php index 781edb159e..d3b20278a0 100644 --- a/Modules/Invoice/Providers/InvoiceServiceProvider.php +++ b/Modules/Invoice/Providers/InvoiceServiceProvider.php @@ -138,6 +138,7 @@ protected function registerCommands() $this->commands([ \Modules\Invoice\Console\SendUnpaidInvoiceList::class, \Modules\Invoice\Console\FixInvoiceAmountsCommand::class, + \Modules\Invoice\Console\SendUpcomingInvoiceReminder::class, ]); } diff --git a/Modules/Invoice/Resources/views/index.blade.php b/Modules/Invoice/Resources/views/index.blade.php index 1baac78751..b4b1a72398 100644 --- a/Modules/Invoice/Resources/views/index.blade.php +++ b/Modules/Invoice/Resources/views/index.blade.php @@ -392,11 +392,9 @@ class="{{ $invoice->shouldHighlighted() ? 'font-weight-bold text-danger' : '' }} @foreach ($invoices as $index => $invoice) - {{-- @dd($invoices) --}} - - {{ $invoice['project'] }} + {{ $invoice['project']->name }} {{ $invoice['invoice_date'] }} - {{ $invoice['amount'] }} + {{ $invoice['amount'] }} {{$invoice['client']->country->currency_symbol}} @if ($invoice['confirmation_required']) {{ $invoice['is_confirmed'] == 0 ? "NO" : "YES" }} @@ -405,10 +403,14 @@ class="{{ $invoice->shouldHighlighted() ? 'font-weight-bold text-danger' : '' }} @endif - - {{ basename($invoice['delivery_report']) }} - - + @if ($invoice['delivery_report']) + + {{ basename($invoice['delivery_report']) }} + + @else + Not Uploaded Yet. + @endif +
{{ config('constants.finance.scheduled-invoice.status.' . $invoice['status'] . '.title') }} diff --git a/Modules/Invoice/Resources/views/mail/upcoming-invoice-list.blade.php b/Modules/Invoice/Resources/views/mail/upcoming-invoice-list.blade.php new file mode 100644 index 0000000000..07044ff64f --- /dev/null +++ b/Modules/Invoice/Resources/views/mail/upcoming-invoice-list.blade.php @@ -0,0 +1,36 @@ +
+

Hello Finance Team!

+

Please find a list of pending invoices.

+ {{--

Total unpaid invoices: {{ $upcomingInvoices->count() }}

--}} + +
+ + + + + + + + @foreach($upcomingInvoices as $index => $invoice) + + + + + + @endforeach + +
Project nameInvoice DateDelivery Report
{{$invoice->project->name}}{{ $invoice->invoice_date}} + @if ($invoice['delivery_report']) + + {{ basename($invoice['delivery_report']) }} + + @else + Not Uploaded Yet. + @endif +
+
+ +

You can see more details here.

+ + Please reach out in case you want to made some changes in this email. +
diff --git a/Modules/Invoice/Services/InvoiceService.php b/Modules/Invoice/Services/InvoiceService.php index 8bae8549e3..9477fadd17 100644 --- a/Modules/Invoice/Services/InvoiceService.php +++ b/Modules/Invoice/Services/InvoiceService.php @@ -779,39 +779,44 @@ public function storeLedgerAccountData(array $data) public function getScheduledInvoices() { - return ProjectInvoiceTerm::with(['project' => function ($query) { - $query->with(['invoices' => function ($query) { + return ProjectInvoiceTerm::with(['project.client', 'project.invoices' => function ($query) { $query->select('id', 'project_id', 'sent_on', 'status'); - }])->select('id', 'name'); - }]) - ->get(['id', 'amount', 'invoice_date', 'confirmation_required', 'delivery_report', 'is_confirmed', 'status', 'project_id']) - ->map(function ($term) { - $project = $term->project; - $termDate = Carbon::parse($term->invoice_date)->toDateString(); - - $invoice = $project->invoices->first(function ($invoice) use ($termDate) { - return Carbon::parse($invoice->sent_on)->toDateString() == $termDate; + }]) + ->select('id', 'amount', 'invoice_date', 'confirmation_required', 'delivery_report', 'is_confirmed', 'status', 'project_id') + ->get() + ->map(function ($term) { + $project = $term->project; + $client = $project->client; + $termDate = Carbon::parse($term->invoice_date)->toDateString(); + + $invoice = $project->invoices->first(function ($invoice) use ($termDate) { + return Carbon::parse($invoice->sent_on)->toDateString() == $termDate; + }); + + $status = $invoice ? $invoice->status : $term->status; + if ($termDate < Carbon::now()->toDateString()) { + $status = "overdue"; + } + + return [ + 'amount' => $term->amount, + 'id' => $term->id, + 'invoice_date' => $term->invoice_date, + 'confirmation_required' => $term->confirmation_required, + 'delivery_report' => $term->delivery_report, + 'is_confirmed' => $term->is_confirmed, + 'project' => $project, + 'client' => $client ? $client : null, + 'status' => $status, + ]; }); - - $status = $invoice ? $invoice->status : $term->status; - if ($termDate < Carbon::now()->toDateString()) { - $status = "overdue"; - } - - return [ - 'amount' => $term->amount, - 'id' => $term->id, - 'invoice_date' => $term->invoice_date, - 'confirmation_required' => $term->confirmation_required, - 'delivery_report' => $term->delivery_report, - 'is_confirmed' => $term->is_confirmed, - 'project_id' => $project->id, - 'project' => $project->name, - 'status' => $status, - ]; - }); } - + + public function getScheduledInvoicesForMail(){ + + return ProjectInvoiceTerm::where('invoice_date', '<=', Carbon::now()->addDays(config('constants.finance.scheduled-invoice.email-duration-in-days'))) ->with('project') ->get(); + } + private function setInvoiceNumber($invoice, $sent_date) { $invoice->invoice_number = $this->getInvoiceNumber($invoice->client_id, $invoice->project_id, $sent_date, $invoice->billing_level); diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index b4a9658609..199b089a88 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -55,6 +55,7 @@ protected function schedule(Schedule $schedule) $schedule->command('mapping-of-jobs-and-hr-rounds'); $schedule->command('project:fixed-budget-project'); $schedule->command('invoice:send-unpaid-invoice-list')->weekly()->mondays()->at('09:00'); + $schedule->command('invoice:send-upcoming-invoice-list')->dailyAt('11:00'); $schedule->command('project:zero-effort-in-project')->weekly()->mondays()->at('09:00'); $schedule->command('project:ended-project')->dailyAt('09:00'); $schedule->command('project:zero-expected-hours-in-project')->weekly()->tuesdays()->at('11:00'); From 14afb4aa628d15e124cdc61e1b480348b0ecb921 Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Tue, 2 Jul 2024 11:02:26 +0530 Subject: [PATCH 22/62] synced with main --- Modules/Invoice/Emails/SendInvoiceReminderMail.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/Invoice/Emails/SendInvoiceReminderMail.php b/Modules/Invoice/Emails/SendInvoiceReminderMail.php index a639ec9e56..403b4b30bd 100644 --- a/Modules/Invoice/Emails/SendInvoiceReminderMail.php +++ b/Modules/Invoice/Emails/SendInvoiceReminderMail.php @@ -31,8 +31,8 @@ public function __construct(Collection $upcomingInvoices) public function build() { return $this - ->to('finance@coloredcow.com') - ->from('abhishek.negi@coloredcow.in') + ->to(config('constants.finance.scheduled-invoice.email')) + ->from(config('mail.from.address'), config('mail.from.name')) ->subject('List of upcoming invoices.') ->view('invoice::mail.upcoming-invoice-list') ->with(['upcomingInvoices' => $this->upcomingInvoices]); From ded6e1009d6b05963082be9e46dc56b589ca68de Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Tue, 2 Jul 2024 11:04:51 +0530 Subject: [PATCH 23/62] synced with main --- Modules/Invoice/Emails/SendInvoiceReminderMail.php | 11 +++++------ Modules/Project/Resources/views/edit.blade.php | 1 - 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/Modules/Invoice/Emails/SendInvoiceReminderMail.php b/Modules/Invoice/Emails/SendInvoiceReminderMail.php index 403b4b30bd..269b65e4a3 100644 --- a/Modules/Invoice/Emails/SendInvoiceReminderMail.php +++ b/Modules/Invoice/Emails/SendInvoiceReminderMail.php @@ -30,11 +30,10 @@ public function __construct(Collection $upcomingInvoices) */ public function build() { - return $this - ->to(config('constants.finance.scheduled-invoice.email')) - ->from(config('mail.from.address'), config('mail.from.name')) - ->subject('List of upcoming invoices.') - ->view('invoice::mail.upcoming-invoice-list') - ->with(['upcomingInvoices' => $this->upcomingInvoices]); + return $this->to(config('constants.finance.scheduled-invoice.email')) + ->from(config('mail.from.address'), config('mail.from.name')) + ->subject('List of upcoming invoices.') + ->view('invoice::mail.upcoming-invoice-list') + ->with(['upcomingInvoices' => $this->upcomingInvoices]); } } diff --git a/Modules/Project/Resources/views/edit.blade.php b/Modules/Project/Resources/views/edit.blade.php index 8e2868fb1f..70feb21386 100644 --- a/Modules/Project/Resources/views/edit.blade.php +++ b/Modules/Project/Resources/views/edit.blade.php @@ -115,7 +115,6 @@ class="text-theme-body text-decoration-none mb-2 mb-xl-4 d-inline-flex align-ite daily_expected_effort: 0, weekly_expected_effort: 0, monthly_expected_effort: 0, - delivery_report:null, } } }, From f3d6da9cfc548a4cb4ba17855d109172b3be7f9f Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Tue, 2 Jul 2024 11:06:44 +0530 Subject: [PATCH 24/62] synced with main --- Modules/Invoice/Services/InvoiceService.php | 7 ++++--- Modules/Project/Services/ProjectService.php | 1 - 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Modules/Invoice/Services/InvoiceService.php b/Modules/Invoice/Services/InvoiceService.php index 9477fadd17..656eb23945 100644 --- a/Modules/Invoice/Services/InvoiceService.php +++ b/Modules/Invoice/Services/InvoiceService.php @@ -780,8 +780,8 @@ public function storeLedgerAccountData(array $data) public function getScheduledInvoices() { return ProjectInvoiceTerm::with(['project.client', 'project.invoices' => function ($query) { - $query->select('id', 'project_id', 'sent_on', 'status'); - }]) + $query->select('id', 'project_id', 'sent_on', 'status'); + }]) ->select('id', 'amount', 'invoice_date', 'confirmation_required', 'delivery_report', 'is_confirmed', 'status', 'project_id') ->get() ->map(function ($term) { @@ -812,7 +812,8 @@ public function getScheduledInvoices() }); } - public function getScheduledInvoicesForMail(){ + public function getScheduledInvoicesForMail() + { return ProjectInvoiceTerm::where('invoice_date', '<=', Carbon::now()->addDays(config('constants.finance.scheduled-invoice.email-duration-in-days'))) ->with('project') ->get(); } diff --git a/Modules/Project/Services/ProjectService.php b/Modules/Project/Services/ProjectService.php index 301d4a0270..83ddc1183e 100644 --- a/Modules/Project/Services/ProjectService.php +++ b/Modules/Project/Services/ProjectService.php @@ -558,7 +558,6 @@ public function saveOrUpdateDeliveryReport($data, $project, $index) public function showDeliveryReport($invoiceId) { - $invoiceTerm = ProjectInvoiceTerm::where('id', $invoiceId)->first(); $filePath = storage_path('app/' . $invoiceTerm->delivery_report); $content = file_get_contents($filePath); From cbf9cc6b7f26910b46ceef74729193f5bc6a0ce0 Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Tue, 2 Jul 2024 11:07:35 +0530 Subject: [PATCH 25/62] CI checks --- Modules/Invoice/Services/InvoiceService.php | 1 - 1 file changed, 1 deletion(-) diff --git a/Modules/Invoice/Services/InvoiceService.php b/Modules/Invoice/Services/InvoiceService.php index 656eb23945..ebb149738e 100644 --- a/Modules/Invoice/Services/InvoiceService.php +++ b/Modules/Invoice/Services/InvoiceService.php @@ -814,7 +814,6 @@ public function getScheduledInvoices() public function getScheduledInvoicesForMail() { - return ProjectInvoiceTerm::where('invoice_date', '<=', Carbon::now()->addDays(config('constants.finance.scheduled-invoice.email-duration-in-days'))) ->with('project') ->get(); } From 4f72cd0dac1646820a1b1dddc6648e9b516aa145 Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Tue, 2 Jul 2024 11:17:24 +0530 Subject: [PATCH 26/62] CI checks --- .../Console/SendUpcomingInvoiceReminder.php | 2 +- .../Emails/SendInvoiceReminderMail.php | 2 +- Modules/Invoice/Services/InvoiceService.php | 4 +- .../Project/Entities/ProjectInvoiceTerm.php | 1 - .../Http/Controllers/ProjectController.php | 9 +-- Modules/Project/Services/ProjectService.php | 63 ++++++++++--------- 6 files changed, 42 insertions(+), 39 deletions(-) diff --git a/Modules/Invoice/Console/SendUpcomingInvoiceReminder.php b/Modules/Invoice/Console/SendUpcomingInvoiceReminder.php index 170a0b9035..3e39809de0 100644 --- a/Modules/Invoice/Console/SendUpcomingInvoiceReminder.php +++ b/Modules/Invoice/Console/SendUpcomingInvoiceReminder.php @@ -4,8 +4,8 @@ use Illuminate\Console\Command; use Illuminate\Support\Facades\Mail; -use Modules\Invoice\Services\InvoiceService; use Modules\Invoice\Emails\SendInvoiceReminderMail; +use Modules\Invoice\Services\InvoiceService; class SendUpcomingInvoiceReminder extends Command { diff --git a/Modules/Invoice/Emails/SendInvoiceReminderMail.php b/Modules/Invoice/Emails/SendInvoiceReminderMail.php index 269b65e4a3..f3cc2500cb 100644 --- a/Modules/Invoice/Emails/SendInvoiceReminderMail.php +++ b/Modules/Invoice/Emails/SendInvoiceReminderMail.php @@ -31,7 +31,7 @@ public function __construct(Collection $upcomingInvoices) public function build() { return $this->to(config('constants.finance.scheduled-invoice.email')) - ->from(config('mail.from.address'), config('mail.from.name')) + ->from('abhishek.negi@coloredcow.in') ->subject('List of upcoming invoices.') ->view('invoice::mail.upcoming-invoice-list') ->with(['upcomingInvoices' => $this->upcomingInvoices]); diff --git a/Modules/Invoice/Services/InvoiceService.php b/Modules/Invoice/Services/InvoiceService.php index ebb149738e..3788adf4fc 100644 --- a/Modules/Invoice/Services/InvoiceService.php +++ b/Modules/Invoice/Services/InvoiceService.php @@ -795,7 +795,7 @@ public function getScheduledInvoices() $status = $invoice ? $invoice->status : $term->status; if ($termDate < Carbon::now()->toDateString()) { - $status = "overdue"; + $status = 'overdue'; } return [ @@ -814,7 +814,7 @@ public function getScheduledInvoices() public function getScheduledInvoicesForMail() { - return ProjectInvoiceTerm::where('invoice_date', '<=', Carbon::now()->addDays(config('constants.finance.scheduled-invoice.email-duration-in-days'))) ->with('project') ->get(); + return ProjectInvoiceTerm::where('invoice_date', '<=', Carbon::now()->addDays(config('constants.finance.scheduled-invoice.email-duration-in-days')))->with('project')->get(); } private function setInvoiceNumber($invoice, $sent_date) diff --git a/Modules/Project/Entities/ProjectInvoiceTerm.php b/Modules/Project/Entities/ProjectInvoiceTerm.php index 0f37b30c58..c298c2a703 100644 --- a/Modules/Project/Entities/ProjectInvoiceTerm.php +++ b/Modules/Project/Entities/ProjectInvoiceTerm.php @@ -3,7 +3,6 @@ namespace Modules\Project\Entities; use Illuminate\Database\Eloquent\Model; -use Modules\Invoice\Entities\Invoice; class ProjectInvoiceTerm extends Model { diff --git a/Modules/Project/Http/Controllers/ProjectController.php b/Modules/Project/Http/Controllers/ProjectController.php index 0ed331a6c0..a8b5f7cd1e 100644 --- a/Modules/Project/Http/Controllers/ProjectController.php +++ b/Modules/Project/Http/Controllers/ProjectController.php @@ -199,6 +199,11 @@ public function projectResource() 'jobName' => $jobName, ]); } + + public function showDeliveryReport($invoiceId) + { + return $this->service->showDeliveryReport($invoiceId); + } // storing Contract related data here private function getContractData(Project $project) { @@ -213,8 +218,4 @@ private function getContractData(Project $project) ]; } - public function showDeliveryReport($invoiceId) - { - return $this->service->showDeliveryReport($invoiceId); - } } diff --git a/Modules/Project/Services/ProjectService.php b/Modules/Project/Services/ProjectService.php index 83ddc1183e..f1b871d5dd 100644 --- a/Modules/Project/Services/ProjectService.php +++ b/Modules/Project/Services/ProjectService.php @@ -389,6 +389,32 @@ public function getInvoiceTerms($project) return $invoiceTerms; } + public function saveOrUpdateDeliveryReport($data, $project, $index) + { + if ($data['delivery_report'] ?? null) { + $file = $data['delivery_report']; + $folder = '/delivery_report/' . date('Y') . '/' . date('m'); + $originalName = $file->getClientOriginalName(); + $extension = $file->getClientOriginalExtension(); + $fileName = $project->name . '_' . $index + 1 . '.' . $extension; + + return Storage::putFileAs($folder, $file, $fileName); + } + } + + public function showDeliveryReport($invoiceId) + { + $invoiceTerm = ProjectInvoiceTerm::where('id', $invoiceId)->first(); + $filePath = storage_path('app/' . $invoiceTerm->delivery_report); + $content = file_get_contents($filePath); + $deliveryReport = pathinfo($invoiceTerm->delivery_report)['filename']; + + return response($content)->withHeaders([ + 'content-type' => mime_content_type($filePath), + 'deliveryReport' => $deliveryReport, + ]); + } + private function getListTabCounts($filters, $showAllProjects, $userId) { $counts = [ @@ -499,11 +525,12 @@ private function updateInvoiceTerms($invoiceTerms, $project) { if (empty($invoiceTerms)) { $project->invoiceTerms()->delete(); + return; } - + $existingTerms = $project->invoiceTerms()->get()->keyBy('id'); - + $termIds = []; foreach ($invoiceTerms as $index => $term) { $termId = $term['id'] ?? null; @@ -511,11 +538,11 @@ private function updateInvoiceTerms($invoiceTerms, $project) if ($termId && isset($existingTerms[$termId])) { $existingTerm = $existingTerms[$termId]; $filePath = $existingTerm->delivery_report; - + if (isset($term['delivery_report'])) { $filePath = $this->saveOrUpdateDeliveryReport($term, $project, $index); } - + $existingTerm->update([ 'invoice_date' => $term['invoice_date'], 'amount' => $term['amount'], @@ -523,7 +550,7 @@ private function updateInvoiceTerms($invoiceTerms, $project) 'is_confirmed' => $term['is_confirmed'] ?? $existingTerm->is_confirmed, 'delivery_report' => $filePath, ]); - + $termIds[] = $termId; } else { $filePath = $this->saveOrUpdateDeliveryReport($term, $project, $index); @@ -536,37 +563,13 @@ private function updateInvoiceTerms($invoiceTerms, $project) 'is_confirmed' => $term['is_confirmed'] ?? false, 'delivery_report' => $filePath, ]); - + $termIds[] = $newTerm->id; } } $project->invoiceTerms()->whereNotIn('id', $termIds)->delete(); } - - public function saveOrUpdateDeliveryReport($data, $project, $index) - { - if ($data['delivery_report'] ?? null) { - $file = $data['delivery_report']; - $folder = '/delivery_report/' . date('Y') . '/' . date('m'); - $originalName = $file->getClientOriginalName(); - $extension = $file->getClientOriginalExtension(); - $fileName = $project->name . '_' . $index + 1 . '.' . $extension; - return Storage::putFileAs($folder, $file, $fileName); - } - } - - public function showDeliveryReport($invoiceId) - { - $invoiceTerm = ProjectInvoiceTerm::where('id', $invoiceId)->first(); - $filePath = storage_path('app/' . $invoiceTerm->delivery_report); - $content = file_get_contents($filePath); - $deliveryReport = pathinfo($invoiceTerm->delivery_report)['filename']; - return response($content)->withHeaders([ - 'content-type' => mime_content_type($filePath), - 'deliveryReport' => $deliveryReport, - ]); - } private function updateProjectRepositories($data, $project) { From e5305720c383d386ecc2446040389b7182e278e5 Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Tue, 2 Jul 2024 11:18:34 +0530 Subject: [PATCH 27/62] CI checks --- Modules/Project/Http/Controllers/ProjectController.php | 1 - 1 file changed, 1 deletion(-) diff --git a/Modules/Project/Http/Controllers/ProjectController.php b/Modules/Project/Http/Controllers/ProjectController.php index a8b5f7cd1e..d2919909fe 100644 --- a/Modules/Project/Http/Controllers/ProjectController.php +++ b/Modules/Project/Http/Controllers/ProjectController.php @@ -217,5 +217,4 @@ private function getContractData(Project $project) 'contractName' => $contractName, ]; } - } From 01e8740c06f18aec3106c5a82fa663ea55b33b89 Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Tue, 2 Jul 2024 11:21:45 +0530 Subject: [PATCH 28/62] CI checks --- Modules/Project/Services/ProjectService.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Modules/Project/Services/ProjectService.php b/Modules/Project/Services/ProjectService.php index f1b871d5dd..a3bf66fe37 100644 --- a/Modules/Project/Services/ProjectService.php +++ b/Modules/Project/Services/ProjectService.php @@ -397,7 +397,7 @@ public function saveOrUpdateDeliveryReport($data, $project, $index) $originalName = $file->getClientOriginalName(); $extension = $file->getClientOriginalExtension(); $fileName = $project->name . '_' . $index + 1 . '.' . $extension; - + return Storage::putFileAs($folder, $file, $fileName); } } @@ -408,7 +408,7 @@ public function showDeliveryReport($invoiceId) $filePath = storage_path('app/' . $invoiceTerm->delivery_report); $content = file_get_contents($filePath); $deliveryReport = pathinfo($invoiceTerm->delivery_report)['filename']; - + return response($content)->withHeaders([ 'content-type' => mime_content_type($filePath), 'deliveryReport' => $deliveryReport, @@ -534,7 +534,7 @@ private function updateInvoiceTerms($invoiceTerms, $project) $termIds = []; foreach ($invoiceTerms as $index => $term) { $termId = $term['id'] ?? null; - + if ($termId && isset($existingTerms[$termId])) { $existingTerm = $existingTerms[$termId]; $filePath = $existingTerm->delivery_report; @@ -567,7 +567,7 @@ private function updateInvoiceTerms($invoiceTerms, $project) $termIds[] = $newTerm->id; } } - + $project->invoiceTerms()->whereNotIn('id', $termIds)->delete(); } From 23595206db715b34df65a38df5be87cc0588e3cf Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Tue, 2 Jul 2024 11:24:46 +0530 Subject: [PATCH 29/62] CI checks --- Modules/Invoice/Services/InvoiceService.php | 1 - 1 file changed, 1 deletion(-) diff --git a/Modules/Invoice/Services/InvoiceService.php b/Modules/Invoice/Services/InvoiceService.php index 3788adf4fc..d9998012ff 100644 --- a/Modules/Invoice/Services/InvoiceService.php +++ b/Modules/Invoice/Services/InvoiceService.php @@ -26,7 +26,6 @@ use Modules\Invoice\Exports\YearlyInvoiceReportExport; use Modules\Invoice\Notifications\GoogleChat\SendPaymentReceivedNotification; use Modules\Project\Entities\Project; -use Illuminate\Support\Facades\DB; use Modules\Project\Entities\ProjectInvoiceTerm; class InvoiceService implements InvoiceServiceContract From 5f1711a0c2704c4685d6cea52c65442fc75dce52 Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Tue, 2 Jul 2024 16:56:15 +0530 Subject: [PATCH 30/62] CI checks --- .../Invoice/Resources/views/index.blade.php | 84 ++++++++++--------- .../mail/upcoming-invoice-list.blade.php | 20 ++--- Modules/Invoice/Services/InvoiceService.php | 37 +++++--- ...21_103448_create_project_invoice_terms.php | 5 +- .../Project/Entities/ProjectInvoiceTerm.php | 2 +- .../Project/Resources/views/edit.blade.php | 5 +- .../subviews/edit-project-details.blade.php | 42 +++++----- Modules/Project/Services/ProjectService.php | 10 ++- 8 files changed, 115 insertions(+), 90 deletions(-) diff --git a/Modules/Invoice/Resources/views/index.blade.php b/Modules/Invoice/Resources/views/index.blade.php index b4b1a72398..56c24721c0 100644 --- a/Modules/Invoice/Resources/views/index.blade.php +++ b/Modules/Invoice/Resources/views/index.blade.php @@ -379,46 +379,54 @@ class="{{ $invoice->shouldHighlighted() ? 'font-weight-bold text-danger' : '' }} ]) @endforeach @else - - +
+ + + + + + + + + + + @if (!$invoices->isEmpty()) + @foreach ($invoices as $index => $invoice) + @php + $invoiceTerm = $invoice['invoiceTerm'] + @endphp + + + + + + + + @endforeach + @else - - - - - - + - - @foreach ($invoices as $index => $invoice) - - - - - - - - - @endforeach -
ProjectInvoice DateAmountService Delivery ReportStatus
{{ $invoice['project']->name }}{{ $invoiceTerm->invoice_date }}{{ $invoiceTerm->amount }} {{ $invoice['client']->country->currency_symbol }} + @if ($invoiceTerm->report_required) + @if ($invoiceTerm->delivery_report) + + {{ basename($invoiceTerm->delivery_report) }} + + @else + Not Uploaded Yet. + @endif + @else + Not Required. + @endif + +
+ {{ config('constants.finance.scheduled-invoice.status.' . $invoice['status'] . '.title') }} +
+
ProjectInvoice DateAmountConfirmed By CLientSrvice Delivery ReportStatusNo Scheduled Invoices To Show
{{ $invoice['project']->name }}{{ $invoice['invoice_date'] }}{{ $invoice['amount'] }} {{$invoice['client']->country->currency_symbol}} - @if ($invoice['confirmation_required']) - {{ $invoice['is_confirmed'] == 0 ? "NO" : "YES" }} - @else - Not required - @endif - - @if ($invoice['delivery_report']) - - {{ basename($invoice['delivery_report']) }} - - @else - Not Uploaded Yet. - @endif - -
- {{ config('constants.finance.scheduled-invoice.status.' . $invoice['status'] . '.title') }} -
-
+ @endif + + + @endif
@if (request()->invoice_status == 'ready' || $invoiceStatus == 'ready') diff --git a/Modules/Invoice/Resources/views/mail/upcoming-invoice-list.blade.php b/Modules/Invoice/Resources/views/mail/upcoming-invoice-list.blade.php index 07044ff64f..cda5c899aa 100644 --- a/Modules/Invoice/Resources/views/mail/upcoming-invoice-list.blade.php +++ b/Modules/Invoice/Resources/views/mail/upcoming-invoice-list.blade.php @@ -1,27 +1,27 @@

Hello Finance Team!

-

Please find a list of pending invoices.

- {{--

Total unpaid invoices: {{ $upcomingInvoices->count() }}

--}} +

Please find a list of scheduled invoices.

+

Total upcoming invoices: {{ $upcomingInvoices->count() }}

- - - + + + @foreach($upcomingInvoices as $index => $invoice) - - - - + + + diff --git a/Modules/Invoice/Services/InvoiceService.php b/Modules/Invoice/Services/InvoiceService.php index d9998012ff..07a5072102 100644 --- a/Modules/Invoice/Services/InvoiceService.php +++ b/Modules/Invoice/Services/InvoiceService.php @@ -167,6 +167,7 @@ public function store($data) $invoice = Invoice::create($data); $this->saveInvoiceFile($invoice, $data['invoice_file']); $this->setInvoiceNumber($invoice, $data['sent_on']); + $this->updateScheduledInvoice($invoice); return $invoice; } @@ -192,6 +193,7 @@ public function update($data, $invoice) $this->saveInvoiceFile($invoice, $data['invoice_file']); $this->setInvoiceNumber($invoice, $data['sent_on']); } + $this->updateScheduledInvoice($invoice); return $invoice; } @@ -776,12 +778,27 @@ public function storeLedgerAccountData(array $data) LedgerAccount::destroy($ledgerAccountsIdToDelete); } + public function updateScheduledInvoice($invoice) + { + $project = $invoice->project; + if (!$project) { + return; + } + + $invoiceSentOn = Carbon::parse($invoice->sent_on)->toDateString(); + $invoiceStatus = $invoice->status; + + foreach ($project->invoiceTerms as $scheduledInvoice) { + if (Carbon::parse($scheduledInvoice->invoice_date)->toDateString() === $invoiceSentOn) { + $scheduledInvoice->update(['status' => $invoiceStatus]); + } + } + } + public function getScheduledInvoices() { - return ProjectInvoiceTerm::with(['project.client', 'project.invoices' => function ($query) { - $query->select('id', 'project_id', 'sent_on', 'status'); - }]) - ->select('id', 'amount', 'invoice_date', 'confirmation_required', 'delivery_report', 'is_confirmed', 'status', 'project_id') + return ProjectInvoiceTerm::with(['project.client', 'project.invoices']) + ->whereNotIn('status', ['sent', 'paid']) ->get() ->map(function ($term) { $project = $term->project; @@ -793,24 +810,20 @@ public function getScheduledInvoices() }); $status = $invoice ? $invoice->status : $term->status; + if ($termDate < Carbon::now()->toDateString()) { $status = 'overdue'; } return [ - 'amount' => $term->amount, - 'id' => $term->id, - 'invoice_date' => $term->invoice_date, - 'confirmation_required' => $term->confirmation_required, - 'delivery_report' => $term->delivery_report, - 'is_confirmed' => $term->is_confirmed, + 'invoiceTerm' => $term, 'project' => $project, - 'client' => $client ? $client : null, + 'client' => $client, 'status' => $status, ]; }); } - + public function getScheduledInvoicesForMail() { return ProjectInvoiceTerm::where('invoice_date', '<=', Carbon::now()->addDays(config('constants.finance.scheduled-invoice.email-duration-in-days')))->with('project')->get(); diff --git a/Modules/Project/Database/Migrations/2024_06_21_103448_create_project_invoice_terms.php b/Modules/Project/Database/Migrations/2024_06_21_103448_create_project_invoice_terms.php index b543edf9e0..b538be0617 100644 --- a/Modules/Project/Database/Migrations/2024_06_21_103448_create_project_invoice_terms.php +++ b/Modules/Project/Database/Migrations/2024_06_21_103448_create_project_invoice_terms.php @@ -19,8 +19,9 @@ public function up() $table->date('invoice_date')->nullable(); $table->decimal('amount', 10, 2)->nullable(); $table->string('status')->nullable(); - $table->boolean('confirmation_required')->nullable(); - $table->boolean('is_confirmed')->nullable(); + $table->boolean('client_acceptance_required')->nullable(); + $table->boolean('is_accepted')->nullable(); + $table->boolean('report_required')->nullable(); $table->string('delivery_report')->nullable(); $table->timestamps(); diff --git a/Modules/Project/Entities/ProjectInvoiceTerm.php b/Modules/Project/Entities/ProjectInvoiceTerm.php index c298c2a703..ff0eed460d 100644 --- a/Modules/Project/Entities/ProjectInvoiceTerm.php +++ b/Modules/Project/Entities/ProjectInvoiceTerm.php @@ -6,7 +6,7 @@ class ProjectInvoiceTerm extends Model { - protected $fillable = ['project_id', 'invoice_date', 'status', 'confirmation_required', 'amount', 'is_confirmed', 'delivery_report']; + protected $fillable = ['project_id', 'invoice_date', 'status', 'client_acceptance_required', 'amount', 'is_accepted', 'report_required', 'delivery_report']; public function project() { diff --git a/Modules/Project/Resources/views/edit.blade.php b/Modules/Project/Resources/views/edit.blade.php index 70feb21386..cff35a7893 100644 --- a/Modules/Project/Resources/views/edit.blade.php +++ b/Modules/Project/Resources/views/edit.blade.php @@ -123,8 +123,9 @@ class="text-theme-body text-decoration-none mb-2 mb-xl-4 d-inline-flex align-ite id: new Date().getTime(), invoice_date: new Date().getTime(), amount: '', - confirmation_required: 0, - is_confirmed: 0, + client_acceptance_required: 0, + report_required: 0, + is_accepted: 0, deliveryReport: '', } }, diff --git a/Modules/Project/Resources/views/subviews/edit-project-details.blade.php b/Modules/Project/Resources/views/subviews/edit-project-details.blade.php index 941c980f97..6a0e0a5c81 100644 --- a/Modules/Project/Resources/views/subviews/edit-project-details.blade.php +++ b/Modules/Project/Resources/views/subviews/edit-project-details.blade.php @@ -153,11 +153,27 @@ class="badge badge-primary p-1 ml-2 text-light {{ $project->effort_sheet_url ? '
-
+
+ + +
+
+ + +
+
+
+ + +
+
+
+
+
-
+
@@ -166,22 +182,13 @@ class="badge badge-primary p-1 ml-2 text-light {{ $project->effort_sheet_url ? '
-
- - -
-
-
-
-
+
diff --git a/Modules/Project/Services/ProjectService.php b/Modules/Project/Services/ProjectService.php index a3bf66fe37..53bc8a0a23 100644 --- a/Modules/Project/Services/ProjectService.php +++ b/Modules/Project/Services/ProjectService.php @@ -546,8 +546,9 @@ private function updateInvoiceTerms($invoiceTerms, $project) $existingTerm->update([ 'invoice_date' => $term['invoice_date'], 'amount' => $term['amount'], - 'confirmation_required' => $term['confirmation_required'], - 'is_confirmed' => $term['is_confirmed'] ?? $existingTerm->is_confirmed, + 'report_required' => $term['report_required'] ?? $existingTerm->report_required, + 'client_acceptance_required' => $term['client_acceptance_required'] ?? $existingTerm->client_acceptance_required, + 'is_accepted' => $term['is_accepted'] ?? $existingTerm->is_accepted, 'delivery_report' => $filePath, ]); @@ -559,8 +560,9 @@ private function updateInvoiceTerms($invoiceTerms, $project) 'invoice_date' => $term['invoice_date'], 'status' => 'yet-to-be-created', 'amount' => $term['amount'], - 'confirmation_required' => $term['confirmation_required'], - 'is_confirmed' => $term['is_confirmed'] ?? false, + 'report_required' => $term['report_required'] ?? false, + 'client_acceptance_required' => $term['client_acceptance_required'] ?? false, + 'is_accepted' => $term['is_accepted'] ?? false, 'delivery_report' => $filePath, ]); From e413d0cc97787978f103048c2922263fbaf51de3 Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Tue, 2 Jul 2024 16:57:16 +0530 Subject: [PATCH 31/62] CI checks --- Modules/Invoice/Services/InvoiceService.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/Invoice/Services/InvoiceService.php b/Modules/Invoice/Services/InvoiceService.php index 07a5072102..bd7877255a 100644 --- a/Modules/Invoice/Services/InvoiceService.php +++ b/Modules/Invoice/Services/InvoiceService.php @@ -793,7 +793,7 @@ public function updateScheduledInvoice($invoice) $scheduledInvoice->update(['status' => $invoiceStatus]); } } - } + } public function getScheduledInvoices() { @@ -810,7 +810,7 @@ public function getScheduledInvoices() }); $status = $invoice ? $invoice->status : $term->status; - + if ($termDate < Carbon::now()->toDateString()) { $status = 'overdue'; } @@ -823,7 +823,7 @@ public function getScheduledInvoices() ]; }); } - + public function getScheduledInvoicesForMail() { return ProjectInvoiceTerm::where('invoice_date', '<=', Carbon::now()->addDays(config('constants.finance.scheduled-invoice.email-duration-in-days')))->with('project')->get(); From 5d2f969e57e2835e357489ba9b7db11b7221b432 Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Tue, 2 Jul 2024 20:19:26 +0530 Subject: [PATCH 32/62] CI checks --- .../Emails/SendInvoiceReminderMail.php | 4 +- .../mail/upcoming-invoice-list.blade.php | 55 ++++++++++++++----- Modules/Invoice/Services/InvoiceService.php | 5 +- .../Console/DeliveryReportReminder.php | 39 +++++++++++++ .../Emails/DeliveryReportReminderMail.php | 37 +++++++++++++ .../mail/delivery-report-reminder.blade.php | 46 ++++++++++++++++ Modules/Project/Services/ProjectService.php | 33 +++++++++++ app/Console/Kernel.php | 3 + 8 files changed, 205 insertions(+), 17 deletions(-) create mode 100644 Modules/Project/Console/DeliveryReportReminder.php create mode 100644 Modules/Project/Emails/DeliveryReportReminderMail.php create mode 100644 Modules/Project/Resources/views/mail/delivery-report-reminder.blade.php diff --git a/Modules/Invoice/Emails/SendInvoiceReminderMail.php b/Modules/Invoice/Emails/SendInvoiceReminderMail.php index f3cc2500cb..48fb577b89 100644 --- a/Modules/Invoice/Emails/SendInvoiceReminderMail.php +++ b/Modules/Invoice/Emails/SendInvoiceReminderMail.php @@ -31,8 +31,8 @@ public function __construct(Collection $upcomingInvoices) public function build() { return $this->to(config('constants.finance.scheduled-invoice.email')) - ->from('abhishek.negi@coloredcow.in') - ->subject('List of upcoming invoices.') + ->from(config('mail.from.address')) + ->subject('Upcoming Scheduled Invoices Notification') ->view('invoice::mail.upcoming-invoice-list') ->with(['upcomingInvoices' => $this->upcomingInvoices]); } diff --git a/Modules/Invoice/Resources/views/mail/upcoming-invoice-list.blade.php b/Modules/Invoice/Resources/views/mail/upcoming-invoice-list.blade.php index cda5c899aa..503bfb1aa9 100644 --- a/Modules/Invoice/Resources/views/mail/upcoming-invoice-list.blade.php +++ b/Modules/Invoice/Resources/views/mail/upcoming-invoice-list.blade.php @@ -1,27 +1,54 @@
+

Hello Finance Team!

Please find a list of scheduled invoices.

Total upcoming invoices: {{ $upcomingInvoices->count() }}

-
Project nameInvoice DateDelivery ReportProject nameInvoice DateDelivery Report
{{$invoice->project->name}}{{ $invoice->invoice_date}} +
{{$invoice->project->name}}{{ $invoice->invoice_date}} @if ($invoice['delivery_report']) {{ basename($invoice['delivery_report']) }} @else - Not Uploaded Yet. + Not Uploaded Yet. @endif
+
- - - + + + + + @foreach($upcomingInvoices as $index => $invoice) - - - - + + + @@ -30,7 +57,7 @@
Project nameInvoice DateDelivery Report
Project NameInvoice DateDelivery Report
{{$invoice->project->name}}{{ $invoice->invoice_date}} - @if ($invoice['delivery_report']) - - {{ basename($invoice['delivery_report']) }} +
{{ $invoice->project->name }}{{ \Carbon\Carbon::parse($invoice->invoice_date)->format('d-m-Y') }} + @if ($invoice->delivery_report) + + {{ basename($invoice->delivery_report) }} @else - Not Uploaded Yet. + Not Uploaded Yet. @endif
-

You can see more details here.

+

You can see more details here.

- Please reach out in case you want to made some changes in this email. +

Please reach out in case you want to make some changes to this email.

diff --git a/Modules/Invoice/Services/InvoiceService.php b/Modules/Invoice/Services/InvoiceService.php index bd7877255a..6f9b6e3ca2 100644 --- a/Modules/Invoice/Services/InvoiceService.php +++ b/Modules/Invoice/Services/InvoiceService.php @@ -826,7 +826,10 @@ public function getScheduledInvoices() public function getScheduledInvoicesForMail() { - return ProjectInvoiceTerm::where('invoice_date', '<=', Carbon::now()->addDays(config('constants.finance.scheduled-invoice.email-duration-in-days')))->with('project')->get(); + return ProjectInvoiceTerm::where('invoice_date', '<=', Carbon::now()->addDays(config('constants.finance.scheduled-invoice.email-duration-in-days'))) + ->whereNotIn('status', ['sent', 'paid']) + ->with('project') + ->get(); } private function setInvoiceNumber($invoice, $sent_date) diff --git a/Modules/Project/Console/DeliveryReportReminder.php b/Modules/Project/Console/DeliveryReportReminder.php new file mode 100644 index 0000000000..d5d48c958d --- /dev/null +++ b/Modules/Project/Console/DeliveryReportReminder.php @@ -0,0 +1,39 @@ +getPendingDeliveryReportInvoices(); + foreach ($keyAccountManagers as $keyAccountManager) { + Mail::send(new DeliveryReportReminderMail($keyAccountManager)); + } + } +} diff --git a/Modules/Project/Emails/DeliveryReportReminderMail.php b/Modules/Project/Emails/DeliveryReportReminderMail.php new file mode 100644 index 0000000000..dcca0186f3 --- /dev/null +++ b/Modules/Project/Emails/DeliveryReportReminderMail.php @@ -0,0 +1,37 @@ +keyAccountManager = $keyAccountManager; + } + + /** + * Build the message. + * + * @return $this + */ + public function build() + { + return $this->subject('Action Required: Missing Delivery Reports for Scheduled Invoices') + ->from(config('mail.from.address')) + ->to($this->keyAccountManager->email) + ->view('project::mail.delivery-report-reminder'); + } +} diff --git a/Modules/Project/Resources/views/mail/delivery-report-reminder.blade.php b/Modules/Project/Resources/views/mail/delivery-report-reminder.blade.php new file mode 100644 index 0000000000..011147de6a --- /dev/null +++ b/Modules/Project/Resources/views/mail/delivery-report-reminder.blade.php @@ -0,0 +1,46 @@ +
+ +

Hi, {{ $keyAccountManager->name }}

+

Hope you are doing well.

+

There are some scheduled invoices that are missing delivery reports. Please take action to provide the necessary reports so that the finance team can proceed with the invoice generation process.

+ + + + + + + + + + @foreach ($keyAccountManager->invoiceTerms as $invoiceTerm) + + + + + + @endforeach + +
Project NameInvoice DateAmount
+ {{ $invoiceTerm->project->name }} + {{ \Carbon\Carbon::parse($invoiceTerm->invoice_date)->format('d-m-Y') }}{{ $invoiceTerm->amount }}
+
+ +
+

Thanks,

+

ColoredCow Portal

+
diff --git a/Modules/Project/Services/ProjectService.php b/Modules/Project/Services/ProjectService.php index 53bc8a0a23..4a24af426a 100644 --- a/Modules/Project/Services/ProjectService.php +++ b/Modules/Project/Services/ProjectService.php @@ -488,6 +488,39 @@ private function updateProjectFinancialDetails($data, $project) ); } + public function getPendingDeliveryReportInvoices() + { + $currentDate = Carbon::now(); + $futureDate = $currentDate->copy()->addDays(config('constants.finance.scheduled-invoice.email-duration-in-days')); + + $groupedInvoices = ProjectInvoiceTerm::where('invoice_date', '<=', $futureDate) + ->where('report_required', true) + ->where('delivery_report', null) + ->whereNotIn('status', ['sent', 'paid']) + ->whereMonth('invoice_date', $currentDate->month) + ->with('project') + ->get() + ->groupBy('project_id'); + + $keyAccountManagersDetails = []; + + foreach ($groupedInvoices as $projectId => $invoiceTerms) { + $project = $invoiceTerms->first()->project; + $user = $project->client->keyAccountManager; + if ($user) { + if (!isset($keyAccountManagersDetails[$user->id])) { + $keyAccountManagersDetails[$user->id] = new \stdClass(); + $keyAccountManagersDetails[$user->id]->invoiceTerms = collect(); + $keyAccountManagersDetails[$user->id]->email = $user->email; + $keyAccountManagersDetails[$user->id]->name = $user->name; + } + $keyAccountManagersDetails[$user->id]->invoiceTerms = $keyAccountManagersDetails[$user->id]->invoiceTerms->merge($invoiceTerms); + } + } + + return $keyAccountManagersDetails; + } + private function updateProjectTeamMembers($data, $project) { $projectTeamMembers = $project->getTeamMembers; diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 199b089a88..305387c010 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -7,6 +7,7 @@ use Modules\HR\Console\JobExpiredEmailToHr; use Modules\Invoice\Console\SeedLoanInstallmentForMonth; use Modules\Project\Console\EndedProject; +use Modules\Project\Console\DeliveryReportReminder; use Modules\Project\Console\FixedBudgetProject; use Modules\Project\Console\GoogleChat\NotificationToProjectTeamMembersToUpdateEffortOnGoogleChat; use Modules\Project\Console\SendEffortSummaryCommand; @@ -27,6 +28,7 @@ class Kernel extends ConsoleKernel ZeroEffortInProject::class, ZeroExpectedHourInProject::class, EndedProject::class, + DeliveryReportReminder::class, FixedBudgetProject::class, NotificationToProjectTeamMembersToUpdateEffortOnGoogleChat::class, JobExpiredEmailToHr::class, @@ -54,6 +56,7 @@ protected function schedule(Schedule $schedule) $schedule->command('hr:send-job-expired-email-to-hr')->dailyAt('11:00'); $schedule->command('mapping-of-jobs-and-hr-rounds'); $schedule->command('project:fixed-budget-project'); + $schedule->command('project:send-pending-delivery-report-reminder')->dailyAt('11:00'); $schedule->command('invoice:send-unpaid-invoice-list')->weekly()->mondays()->at('09:00'); $schedule->command('invoice:send-upcoming-invoice-list')->dailyAt('11:00'); $schedule->command('project:zero-effort-in-project')->weekly()->mondays()->at('09:00'); From 45a6ce144fa27b7be5d5e5ff3d34132b08e66511 Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Tue, 2 Jul 2024 20:24:49 +0530 Subject: [PATCH 33/62] CI checks --- Modules/Invoice/Services/InvoiceService.php | 2 +- .../Console/DeliveryReportReminder.php | 2 +- Modules/Project/Services/ProjectService.php | 68 +++++++++---------- app/Console/Kernel.php | 2 +- 4 files changed, 37 insertions(+), 37 deletions(-) diff --git a/Modules/Invoice/Services/InvoiceService.php b/Modules/Invoice/Services/InvoiceService.php index 6f9b6e3ca2..102175f546 100644 --- a/Modules/Invoice/Services/InvoiceService.php +++ b/Modules/Invoice/Services/InvoiceService.php @@ -781,7 +781,7 @@ public function storeLedgerAccountData(array $data) public function updateScheduledInvoice($invoice) { $project = $invoice->project; - if (!$project) { + if ( !$project) { return; } diff --git a/Modules/Project/Console/DeliveryReportReminder.php b/Modules/Project/Console/DeliveryReportReminder.php index d5d48c958d..faa2798b6c 100644 --- a/Modules/Project/Console/DeliveryReportReminder.php +++ b/Modules/Project/Console/DeliveryReportReminder.php @@ -4,8 +4,8 @@ use Illuminate\Console\Command; use Illuminate\Support\Facades\Mail; -use Modules\Project\Services\ProjectService; use Modules\Project\Emails\DeliveryReportReminderMail; +use Modules\Project\Services\ProjectService; class DeliveryReportReminder extends Command { diff --git a/Modules/Project/Services/ProjectService.php b/Modules/Project/Services/ProjectService.php index 4a24af426a..13b35059dc 100644 --- a/Modules/Project/Services/ProjectService.php +++ b/Modules/Project/Services/ProjectService.php @@ -415,6 +415,39 @@ public function showDeliveryReport($invoiceId) ]); } + public function getPendingDeliveryReportInvoices() + { + $currentDate = Carbon::now(); + $futureDate = $currentDate->copy()->addDays(config('constants.finance.scheduled-invoice.email-duration-in-days')); + + $groupedInvoices = ProjectInvoiceTerm::where('invoice_date', '<=', $futureDate) + ->where('report_required', true) + ->where('delivery_report', null) + ->whereNotIn('status', ['sent', 'paid']) + ->whereMonth('invoice_date', $currentDate->month) + ->with('project') + ->get() + ->groupBy('project_id'); + + $keyAccountManagersDetails = []; + + foreach ($groupedInvoices as $projectId => $invoiceTerms) { + $project = $invoiceTerms->first()->project; + $user = $project->client->keyAccountManager; + if ($user) { + if (!isset($keyAccountManagersDetails[$user->id])) { + $keyAccountManagersDetails[$user->id] = new \stdClass(); + $keyAccountManagersDetails[$user->id]->invoiceTerms = collect(); + $keyAccountManagersDetails[$user->id]->email = $user->email; + $keyAccountManagersDetails[$user->id]->name = $user->name; + } + $keyAccountManagersDetails[$user->id]->invoiceTerms = $keyAccountManagersDetails[$user->id]->invoiceTerms->merge($invoiceTerms); + } + } + + return $keyAccountManagersDetails; + } + private function getListTabCounts($filters, $showAllProjects, $userId) { $counts = [ @@ -488,39 +521,6 @@ private function updateProjectFinancialDetails($data, $project) ); } - public function getPendingDeliveryReportInvoices() - { - $currentDate = Carbon::now(); - $futureDate = $currentDate->copy()->addDays(config('constants.finance.scheduled-invoice.email-duration-in-days')); - - $groupedInvoices = ProjectInvoiceTerm::where('invoice_date', '<=', $futureDate) - ->where('report_required', true) - ->where('delivery_report', null) - ->whereNotIn('status', ['sent', 'paid']) - ->whereMonth('invoice_date', $currentDate->month) - ->with('project') - ->get() - ->groupBy('project_id'); - - $keyAccountManagersDetails = []; - - foreach ($groupedInvoices as $projectId => $invoiceTerms) { - $project = $invoiceTerms->first()->project; - $user = $project->client->keyAccountManager; - if ($user) { - if (!isset($keyAccountManagersDetails[$user->id])) { - $keyAccountManagersDetails[$user->id] = new \stdClass(); - $keyAccountManagersDetails[$user->id]->invoiceTerms = collect(); - $keyAccountManagersDetails[$user->id]->email = $user->email; - $keyAccountManagersDetails[$user->id]->name = $user->name; - } - $keyAccountManagersDetails[$user->id]->invoiceTerms = $keyAccountManagersDetails[$user->id]->invoiceTerms->merge($invoiceTerms); - } - } - - return $keyAccountManagersDetails; - } - private function updateProjectTeamMembers($data, $project) { $projectTeamMembers = $project->getTeamMembers; @@ -580,7 +580,7 @@ private function updateInvoiceTerms($invoiceTerms, $project) 'invoice_date' => $term['invoice_date'], 'amount' => $term['amount'], 'report_required' => $term['report_required'] ?? $existingTerm->report_required, - 'client_acceptance_required' => $term['client_acceptance_required'] ?? $existingTerm->client_acceptance_required, + 'client_acceptance_required' => $term['client_acceptance_required'] ?? $existingTerm->client_acceptance_required, 'is_accepted' => $term['is_accepted'] ?? $existingTerm->is_accepted, 'delivery_report' => $filePath, ]); diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 305387c010..8c88bee30e 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -7,8 +7,8 @@ use Modules\HR\Console\JobExpiredEmailToHr; use Modules\Invoice\Console\SeedLoanInstallmentForMonth; use Modules\Project\Console\EndedProject; -use Modules\Project\Console\DeliveryReportReminder; use Modules\Project\Console\FixedBudgetProject; +use Modules\Project\Console\DeliveryReportReminder; use Modules\Project\Console\GoogleChat\NotificationToProjectTeamMembersToUpdateEffortOnGoogleChat; use Modules\Project\Console\SendEffortSummaryCommand; use Modules\Project\Console\SyncEffortsheet; From 955409096f6af539fdd53d54fcafe75bc23fa97d Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Tue, 2 Jul 2024 20:25:37 +0530 Subject: [PATCH 34/62] CI checks --- Modules/Invoice/Services/InvoiceService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Invoice/Services/InvoiceService.php b/Modules/Invoice/Services/InvoiceService.php index 102175f546..6f9b6e3ca2 100644 --- a/Modules/Invoice/Services/InvoiceService.php +++ b/Modules/Invoice/Services/InvoiceService.php @@ -781,7 +781,7 @@ public function storeLedgerAccountData(array $data) public function updateScheduledInvoice($invoice) { $project = $invoice->project; - if ( !$project) { + if (!$project) { return; } From 6be349ebc5794b013f3ea04f1e0b83895c3e7a03 Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Tue, 2 Jul 2024 20:29:42 +0530 Subject: [PATCH 35/62] CI checks --- Modules/Invoice/Services/InvoiceService.php | 2 +- Modules/Project/Services/ProjectService.php | 2 +- app/Console/Kernel.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/Invoice/Services/InvoiceService.php b/Modules/Invoice/Services/InvoiceService.php index 6f9b6e3ca2..c90764dac7 100644 --- a/Modules/Invoice/Services/InvoiceService.php +++ b/Modules/Invoice/Services/InvoiceService.php @@ -781,7 +781,7 @@ public function storeLedgerAccountData(array $data) public function updateScheduledInvoice($invoice) { $project = $invoice->project; - if (!$project) { + if (! $project) { return; } diff --git a/Modules/Project/Services/ProjectService.php b/Modules/Project/Services/ProjectService.php index 13b35059dc..46cd329343 100644 --- a/Modules/Project/Services/ProjectService.php +++ b/Modules/Project/Services/ProjectService.php @@ -435,7 +435,7 @@ public function getPendingDeliveryReportInvoices() $project = $invoiceTerms->first()->project; $user = $project->client->keyAccountManager; if ($user) { - if (!isset($keyAccountManagersDetails[$user->id])) { + if (! isset($keyAccountManagersDetails[$user->id])) { $keyAccountManagersDetails[$user->id] = new \stdClass(); $keyAccountManagersDetails[$user->id]->invoiceTerms = collect(); $keyAccountManagersDetails[$user->id]->email = $user->email; diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 8c88bee30e..6f1a16a06f 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -6,9 +6,9 @@ use Illuminate\Foundation\Console\Kernel as ConsoleKernel; use Modules\HR\Console\JobExpiredEmailToHr; use Modules\Invoice\Console\SeedLoanInstallmentForMonth; +use Modules\Project\Console\DeliveryReportReminder; use Modules\Project\Console\EndedProject; use Modules\Project\Console\FixedBudgetProject; -use Modules\Project\Console\DeliveryReportReminder; use Modules\Project\Console\GoogleChat\NotificationToProjectTeamMembersToUpdateEffortOnGoogleChat; use Modules\Project\Console\SendEffortSummaryCommand; use Modules\Project\Console\SyncEffortsheet; From aad1d6de5b5aaf9ebe9110524ce6a4d41dee4ccc Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Tue, 2 Jul 2024 20:36:29 +0530 Subject: [PATCH 36/62] CI checks --- Modules/Project/Services/ProjectService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Project/Services/ProjectService.php b/Modules/Project/Services/ProjectService.php index 46cd329343..d27a3c3f3c 100644 --- a/Modules/Project/Services/ProjectService.php +++ b/Modules/Project/Services/ProjectService.php @@ -424,7 +424,7 @@ public function getPendingDeliveryReportInvoices() ->where('report_required', true) ->where('delivery_report', null) ->whereNotIn('status', ['sent', 'paid']) - ->whereMonth('invoice_date', $currentDate->month) + ->whereMonth('invoice_date', '=', $currentDate->month) // Adjusted line ->with('project') ->get() ->groupBy('project_id'); From c5f7876de2a555241990f93f15a5bb6892b3ee32 Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Tue, 2 Jul 2024 20:36:53 +0530 Subject: [PATCH 37/62] CI checks --- Modules/Project/Services/ProjectService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Project/Services/ProjectService.php b/Modules/Project/Services/ProjectService.php index d27a3c3f3c..039088e0ff 100644 --- a/Modules/Project/Services/ProjectService.php +++ b/Modules/Project/Services/ProjectService.php @@ -424,7 +424,7 @@ public function getPendingDeliveryReportInvoices() ->where('report_required', true) ->where('delivery_report', null) ->whereNotIn('status', ['sent', 'paid']) - ->whereMonth('invoice_date', '=', $currentDate->month) // Adjusted line + ->whereMonth('invoice_date', '=', $currentDate->month) ->with('project') ->get() ->groupBy('project_id'); From 82853942e7bcfc5662b47d92c5953b3893b6980b Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Tue, 2 Jul 2024 20:48:57 +0530 Subject: [PATCH 38/62] CI checks --- Modules/Project/Services/ProjectService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Project/Services/ProjectService.php b/Modules/Project/Services/ProjectService.php index 039088e0ff..46cd329343 100644 --- a/Modules/Project/Services/ProjectService.php +++ b/Modules/Project/Services/ProjectService.php @@ -424,7 +424,7 @@ public function getPendingDeliveryReportInvoices() ->where('report_required', true) ->where('delivery_report', null) ->whereNotIn('status', ['sent', 'paid']) - ->whereMonth('invoice_date', '=', $currentDate->month) + ->whereMonth('invoice_date', $currentDate->month) ->with('project') ->get() ->groupBy('project_id'); From 1faff04ec61844c33a1d966f7fa4a0d18cd3ab0e Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Tue, 2 Jul 2024 20:57:15 +0530 Subject: [PATCH 39/62] CI checks --- Modules/Project/Services/ProjectService.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Modules/Project/Services/ProjectService.php b/Modules/Project/Services/ProjectService.php index 46cd329343..7bad730d58 100644 --- a/Modules/Project/Services/ProjectService.php +++ b/Modules/Project/Services/ProjectService.php @@ -418,13 +418,14 @@ public function showDeliveryReport($invoiceId) public function getPendingDeliveryReportInvoices() { $currentDate = Carbon::now(); + $monthString = str_pad($currentDate->month, 2, '0', STR_PAD_LEFT); $futureDate = $currentDate->copy()->addDays(config('constants.finance.scheduled-invoice.email-duration-in-days')); $groupedInvoices = ProjectInvoiceTerm::where('invoice_date', '<=', $futureDate) ->where('report_required', true) ->where('delivery_report', null) ->whereNotIn('status', ['sent', 'paid']) - ->whereMonth('invoice_date', $currentDate->month) + ->whereMonth('invoice_date', $monthString) ->with('project') ->get() ->groupBy('project_id'); From 8778a4e44df367031810e6677232fa442b4657a7 Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Tue, 2 Jul 2024 21:02:22 +0530 Subject: [PATCH 40/62] CI checks --- Modules/Project/Services/ProjectService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Project/Services/ProjectService.php b/Modules/Project/Services/ProjectService.php index 7bad730d58..4d21228040 100644 --- a/Modules/Project/Services/ProjectService.php +++ b/Modules/Project/Services/ProjectService.php @@ -418,7 +418,7 @@ public function showDeliveryReport($invoiceId) public function getPendingDeliveryReportInvoices() { $currentDate = Carbon::now(); - $monthString = str_pad($currentDate->month, 2, '0', STR_PAD_LEFT); + $monthString = strval($currentDate->month); $futureDate = $currentDate->copy()->addDays(config('constants.finance.scheduled-invoice.email-duration-in-days')); $groupedInvoices = ProjectInvoiceTerm::where('invoice_date', '<=', $futureDate) From 7743074b20e7b52a4f842b2e961d09b5d5734f58 Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Tue, 2 Jul 2024 21:08:15 +0530 Subject: [PATCH 41/62] CI checks --- Modules/Project/Services/ProjectService.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Modules/Project/Services/ProjectService.php b/Modules/Project/Services/ProjectService.php index 4d21228040..fa666b6e07 100644 --- a/Modules/Project/Services/ProjectService.php +++ b/Modules/Project/Services/ProjectService.php @@ -418,14 +418,13 @@ public function showDeliveryReport($invoiceId) public function getPendingDeliveryReportInvoices() { $currentDate = Carbon::now(); - $monthString = strval($currentDate->month); $futureDate = $currentDate->copy()->addDays(config('constants.finance.scheduled-invoice.email-duration-in-days')); $groupedInvoices = ProjectInvoiceTerm::where('invoice_date', '<=', $futureDate) ->where('report_required', true) ->where('delivery_report', null) ->whereNotIn('status', ['sent', 'paid']) - ->whereMonth('invoice_date', $monthString) + ->whereMonth('invoice_date', strval($currentDate->month)) ->with('project') ->get() ->groupBy('project_id'); From c23d68b8806a8117544dc92eed824efccd12daf1 Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Wed, 3 Jul 2024 09:57:11 +0530 Subject: [PATCH 42/62] CI checks --- Modules/Invoice/Services/InvoiceService.php | 4 +++- .../Emails/DeliveryReportReminderMail.php | 2 +- .../mail/delivery-report-reminder.blade.php | 14 +++++------ Modules/Project/Services/ProjectService.php | 23 +++++++++++-------- config/constants.php | 3 ++- 5 files changed, 27 insertions(+), 19 deletions(-) diff --git a/Modules/Invoice/Services/InvoiceService.php b/Modules/Invoice/Services/InvoiceService.php index c90764dac7..960226929f 100644 --- a/Modules/Invoice/Services/InvoiceService.php +++ b/Modules/Invoice/Services/InvoiceService.php @@ -826,8 +826,10 @@ public function getScheduledInvoices() public function getScheduledInvoicesForMail() { - return ProjectInvoiceTerm::where('invoice_date', '<=', Carbon::now()->addDays(config('constants.finance.scheduled-invoice.email-duration-in-days'))) + $currentDate = Carbon::now(); + return ProjectInvoiceTerm::where('invoice_date', '<=', Carbon::now()->addDays(config('constants.finance.scheduled-invoice.finance-team-invoice-reminder-days'))) ->whereNotIn('status', ['sent', 'paid']) + ->whereMonth('invoice_date', strval($currentDate->month)) ->with('project') ->get(); } diff --git a/Modules/Project/Emails/DeliveryReportReminderMail.php b/Modules/Project/Emails/DeliveryReportReminderMail.php index dcca0186f3..25dfc333c4 100644 --- a/Modules/Project/Emails/DeliveryReportReminderMail.php +++ b/Modules/Project/Emails/DeliveryReportReminderMail.php @@ -30,7 +30,7 @@ public function __construct($keyAccountManager) public function build() { return $this->subject('Action Required: Missing Delivery Reports for Scheduled Invoices') - ->from(config('mail.from.address')) + ->from('abhishek.negi@coloredcow.in') ->to($this->keyAccountManager->email) ->view('project::mail.delivery-report-reminder'); } diff --git a/Modules/Project/Resources/views/mail/delivery-report-reminder.blade.php b/Modules/Project/Resources/views/mail/delivery-report-reminder.blade.php index 011147de6a..c3a75a7af3 100644 --- a/Modules/Project/Resources/views/mail/delivery-report-reminder.blade.php +++ b/Modules/Project/Resources/views/mail/delivery-report-reminder.blade.php @@ -28,13 +28,13 @@ @foreach ($keyAccountManager->invoiceTerms as $invoiceTerm) - - - {{ $invoiceTerm->project->name }} - - {{ \Carbon\Carbon::parse($invoiceTerm->invoice_date)->format('d-m-Y') }} - {{ $invoiceTerm->amount }} - + + + {{ $invoiceTerm->project->name }} + + {{ \Carbon\Carbon::parse($invoiceTerm->invoice_date)->format('d-m-Y') }} + {{ $invoiceTerm->amount }} {{$invoiceTerm->project->client->currency_symbol}} + @endforeach diff --git a/Modules/Project/Services/ProjectService.php b/Modules/Project/Services/ProjectService.php index fa666b6e07..1495a21a3d 100644 --- a/Modules/Project/Services/ProjectService.php +++ b/Modules/Project/Services/ProjectService.php @@ -418,7 +418,7 @@ public function showDeliveryReport($invoiceId) public function getPendingDeliveryReportInvoices() { $currentDate = Carbon::now(); - $futureDate = $currentDate->copy()->addDays(config('constants.finance.scheduled-invoice.email-duration-in-days')); + $futureDate = $currentDate->copy()->addDays(config('constants.finance.scheduled-invoice.delivery-report-reminder-days')); $groupedInvoices = ProjectInvoiceTerm::where('invoice_date', '<=', $futureDate) ->where('report_required', true) @@ -431,19 +431,24 @@ public function getPendingDeliveryReportInvoices() $keyAccountManagersDetails = []; - foreach ($groupedInvoices as $projectId => $invoiceTerms) { + $groupedInvoices->each(function ($invoiceTerms, $projectId) use (&$keyAccountManagersDetails) { $project = $invoiceTerms->first()->project; $user = $project->client->keyAccountManager; + if ($user) { - if (! isset($keyAccountManagersDetails[$user->id])) { - $keyAccountManagersDetails[$user->id] = new \stdClass(); - $keyAccountManagersDetails[$user->id]->invoiceTerms = collect(); - $keyAccountManagersDetails[$user->id]->email = $user->email; - $keyAccountManagersDetails[$user->id]->name = $user->name; + $userId = $user->id; + + if (! isset($keyAccountManagersDetails[$userId])) { + $keyAccountManagersDetails[$userId] = (object) [ + 'invoiceTerms' => collect(), + 'email' => $user->email, + 'name' => $user->name, + ]; } - $keyAccountManagersDetails[$user->id]->invoiceTerms = $keyAccountManagersDetails[$user->id]->invoiceTerms->merge($invoiceTerms); + + $keyAccountManagersDetails[$userId]->invoiceTerms = $keyAccountManagersDetails[$userId]->invoiceTerms->merge($invoiceTerms); } - } + }); return $keyAccountManagersDetails; } diff --git a/config/constants.php b/config/constants.php index 6403ecb6f9..29242d4041 100644 --- a/config/constants.php +++ b/config/constants.php @@ -190,7 +190,8 @@ 'class' => 'badge badge-danger', ], ], - 'email-duration-in-days' => 5, + 'delivery-report-reminder-days' => 7, + 'finance-team-invoice-reminder-days' => 5, 'email'=> 'finance@coloredcow.com', ], 'gst' => '18', From c1b1fd43424e289dada8acfbd072373e13d53fdd Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Wed, 3 Jul 2024 09:58:25 +0530 Subject: [PATCH 43/62] CI checks --- Modules/Project/Emails/DeliveryReportReminderMail.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Project/Emails/DeliveryReportReminderMail.php b/Modules/Project/Emails/DeliveryReportReminderMail.php index 25dfc333c4..dcca0186f3 100644 --- a/Modules/Project/Emails/DeliveryReportReminderMail.php +++ b/Modules/Project/Emails/DeliveryReportReminderMail.php @@ -30,7 +30,7 @@ public function __construct($keyAccountManager) public function build() { return $this->subject('Action Required: Missing Delivery Reports for Scheduled Invoices') - ->from('abhishek.negi@coloredcow.in') + ->from(config('mail.from.address')) ->to($this->keyAccountManager->email) ->view('project::mail.delivery-report-reminder'); } From 02ada5aef6dc782478681d8a15490a1e14727fbe Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Wed, 3 Jul 2024 09:59:11 +0530 Subject: [PATCH 44/62] CI checks --- Modules/Project/Services/ProjectService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Project/Services/ProjectService.php b/Modules/Project/Services/ProjectService.php index 1495a21a3d..6200663fc1 100644 --- a/Modules/Project/Services/ProjectService.php +++ b/Modules/Project/Services/ProjectService.php @@ -448,7 +448,7 @@ public function getPendingDeliveryReportInvoices() $keyAccountManagersDetails[$userId]->invoiceTerms = $keyAccountManagersDetails[$userId]->invoiceTerms->merge($invoiceTerms); } - }); + }); return $keyAccountManagersDetails; } From e3f15ed4b26d028e5b5f78a64e0ad0f6d5c2334d Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Wed, 3 Jul 2024 10:10:33 +0530 Subject: [PATCH 45/62] CI checks --- Modules/Invoice/Services/InvoiceService.php | 1 + 1 file changed, 1 insertion(+) diff --git a/Modules/Invoice/Services/InvoiceService.php b/Modules/Invoice/Services/InvoiceService.php index 960226929f..9ad19878e7 100644 --- a/Modules/Invoice/Services/InvoiceService.php +++ b/Modules/Invoice/Services/InvoiceService.php @@ -827,6 +827,7 @@ public function getScheduledInvoices() public function getScheduledInvoicesForMail() { $currentDate = Carbon::now(); + return ProjectInvoiceTerm::where('invoice_date', '<=', Carbon::now()->addDays(config('constants.finance.scheduled-invoice.finance-team-invoice-reminder-days'))) ->whereNotIn('status', ['sent', 'paid']) ->whereMonth('invoice_date', strval($currentDate->month)) From 35bfac8ee47fc83f4d0554764041d2564da8646f Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Wed, 3 Jul 2024 11:32:10 +0530 Subject: [PATCH 46/62] CI checks --- .../subviews/edit-project-details.blade.php | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/Modules/Project/Resources/views/subviews/edit-project-details.blade.php b/Modules/Project/Resources/views/subviews/edit-project-details.blade.php index 6a0e0a5c81..3db478f02c 100644 --- a/Modules/Project/Resources/views/subviews/edit-project-details.blade.php +++ b/Modules/Project/Resources/views/subviews/edit-project-details.blade.php @@ -171,12 +171,12 @@ class="badge badge-primary p-1 ml-2 text-light {{ $project->effort_sheet_url ? '
- +
- +
{{ optional($project->client->country)->currency }}
@@ -195,12 +195,22 @@ class="badge badge-primary p-1 ml-2 text-light {{ $project->effort_sheet_url ? '
+
+
+
+
+
+
+ + + +
+ Invoice has been proceeded for this term. +
+

-
- -
From 86180daea17be67b9e9ee55a5e6076c77bb0b7f5 Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Thu, 4 Jul 2024 10:18:43 +0530 Subject: [PATCH 47/62] CI checks --- .../Invoice/Resources/views/index.blade.php | 19 +++++------ Modules/Invoice/Services/InvoiceService.php | 33 +++++------------- ...21_103448_create_project_invoice_terms.php | 5 ++- .../Project/Entities/ProjectInvoiceTerm.php | 20 ++++++++++- .../Project/Resources/views/edit.blade.php | 8 ++++- .../subviews/edit-project-details.blade.php | 34 +++++++++++++++---- Modules/Project/Services/ProjectService.php | 21 ++++++++++-- app/Models/Comment.php | 1 + 8 files changed, 93 insertions(+), 48 deletions(-) diff --git a/Modules/Invoice/Resources/views/index.blade.php b/Modules/Invoice/Resources/views/index.blade.php index 56c24721c0..083b9ea82c 100644 --- a/Modules/Invoice/Resources/views/index.blade.php +++ b/Modules/Invoice/Resources/views/index.blade.php @@ -392,18 +392,15 @@ class="{{ $invoice->shouldHighlighted() ? 'font-weight-bold text-danger' : '' }} @if (!$invoices->isEmpty()) @foreach ($invoices as $index => $invoice) - @php - $invoiceTerm = $invoice['invoiceTerm'] - @endphp {{ $invoice['project']->name }} - {{ $invoiceTerm->invoice_date }} - {{ $invoiceTerm->amount }} {{ $invoice['client']->country->currency_symbol }} + {{ $invoice->invoice_date }} + {{ $invoice->amount }} {{ $invoice->project->client->country->currency_symbol }} - @if ($invoiceTerm->report_required) - @if ($invoiceTerm->delivery_report) - - {{ basename($invoiceTerm->delivery_report) }} + @if ($invoice->report_required) + @if ($invoice->delivery_report) + + {{ basename($invoice->delivery_report) }} @else Not Uploaded Yet. @@ -413,8 +410,8 @@ class="{{ $invoice->shouldHighlighted() ? 'font-weight-bold text-danger' : '' }} @endif -
- {{ config('constants.finance.scheduled-invoice.status.' . $invoice['status'] . '.title') }} +
+ {{ config('constants.finance.scheduled-invoice.status.' . $invoice->currentStatus. '.title') }}
diff --git a/Modules/Invoice/Services/InvoiceService.php b/Modules/Invoice/Services/InvoiceService.php index 9ad19878e7..108eb64b2e 100644 --- a/Modules/Invoice/Services/InvoiceService.php +++ b/Modules/Invoice/Services/InvoiceService.php @@ -787,41 +787,24 @@ public function updateScheduledInvoice($invoice) $invoiceSentOn = Carbon::parse($invoice->sent_on)->toDateString(); $invoiceStatus = $invoice->status; + $invoiceId = $invoice->id; + foreach ($project->invoiceTerms as $scheduledInvoice) { if (Carbon::parse($scheduledInvoice->invoice_date)->toDateString() === $invoiceSentOn) { - $scheduledInvoice->update(['status' => $invoiceStatus]); + $scheduledInvoice->update([ + 'status' => $invoiceStatus, + 'invoice_id' => $invoiceId + ]); } } } public function getScheduledInvoices() { - return ProjectInvoiceTerm::with(['project.client', 'project.invoices']) + return ProjectInvoiceTerm::with('project') ->whereNotIn('status', ['sent', 'paid']) - ->get() - ->map(function ($term) { - $project = $term->project; - $client = $project->client; - $termDate = Carbon::parse($term->invoice_date)->toDateString(); - - $invoice = $project->invoices->first(function ($invoice) use ($termDate) { - return Carbon::parse($invoice->sent_on)->toDateString() == $termDate; - }); - - $status = $invoice ? $invoice->status : $term->status; - - if ($termDate < Carbon::now()->toDateString()) { - $status = 'overdue'; - } - - return [ - 'invoiceTerm' => $term, - 'project' => $project, - 'client' => $client, - 'status' => $status, - ]; - }); + ->get(); } public function getScheduledInvoicesForMail() diff --git a/Modules/Project/Database/Migrations/2024_06_21_103448_create_project_invoice_terms.php b/Modules/Project/Database/Migrations/2024_06_21_103448_create_project_invoice_terms.php index b538be0617..9bd35663a7 100644 --- a/Modules/Project/Database/Migrations/2024_06_21_103448_create_project_invoice_terms.php +++ b/Modules/Project/Database/Migrations/2024_06_21_103448_create_project_invoice_terms.php @@ -16,6 +16,7 @@ public function up() Schema::create('project_invoice_terms', function (Blueprint $table) { $table->id(); $table->unsignedBigInteger('project_id'); + $table->unsignedBigInteger('invoice_id')->nullable(); $table->date('invoice_date')->nullable(); $table->decimal('amount', 10, 2)->nullable(); $table->string('status')->nullable(); @@ -24,9 +25,11 @@ public function up() $table->boolean('report_required')->nullable(); $table->string('delivery_report')->nullable(); $table->timestamps(); - + $table->foreign('project_id')->references('id')->on('projects')->onDelete('cascade'); + $table->foreign('invoice_id')->references('id')->on('invoices')->onDelete('cascade'); $table->index('project_id'); + $table->index('invoice_id'); }); } diff --git a/Modules/Project/Entities/ProjectInvoiceTerm.php b/Modules/Project/Entities/ProjectInvoiceTerm.php index ff0eed460d..df753923f8 100644 --- a/Modules/Project/Entities/ProjectInvoiceTerm.php +++ b/Modules/Project/Entities/ProjectInvoiceTerm.php @@ -2,14 +2,32 @@ namespace Modules\Project\Entities; +use App\Models\Comment; +use Carbon\Carbon; +use Modules\Invoice\Entities\Invoice; use Illuminate\Database\Eloquent\Model; class ProjectInvoiceTerm extends Model { - protected $fillable = ['project_id', 'invoice_date', 'status', 'client_acceptance_required', 'amount', 'is_accepted', 'report_required', 'delivery_report']; + protected $fillable = ['project_id','invoice_id', 'invoice_date', 'status', 'client_acceptance_required', 'amount', 'is_accepted', 'report_required', 'delivery_report']; public function project() { return $this->belongsTo(Project::class); } + + public function getCurrentStatusAttribute() + { + return Carbon::now() > $this->invoice_date ? 'overdue' : $this->status; + } + + public function invoice() + { + return $this->belongsTo(Invoice::class); + } + + public function comments() + { + return $this->morphMany(Comment::class, 'commentable'); + } } diff --git a/Modules/Project/Resources/views/edit.blade.php b/Modules/Project/Resources/views/edit.blade.php index cff35a7893..381464f857 100644 --- a/Modules/Project/Resources/views/edit.blade.php +++ b/Modules/Project/Resources/views/edit.blade.php @@ -126,7 +126,8 @@ class="text-theme-body text-decoration-none mb-2 mb-xl-4 d-inline-flex align-ite client_acceptance_required: 0, report_required: 0, is_accepted: 0, - deliveryReport: '', + delivery_report: '', + comment:'' } }, defaultProjectRepository() { @@ -286,6 +287,11 @@ class="text-theme-body text-decoration-none mb-2 mb-xl-4 d-inline-flex align-ite }, getDeliveryReportUrl(invoiceTermId) { return `{{ route('delivery-report.show', ':id') }}`.replace(':id', invoiceTermId); + }, + toggleOverDue(index){ + const invoiceDate = new Date(this.invoiceTerms[index].invoice_date); + const currentDate = new Date(); + return invoiceDate <= currentDate; } }, diff --git a/Modules/Project/Resources/views/subviews/edit-project-details.blade.php b/Modules/Project/Resources/views/subviews/edit-project-details.blade.php index 3db478f02c..b89c9d1346 100644 --- a/Modules/Project/Resources/views/subviews/edit-project-details.blade.php +++ b/Modules/Project/Resources/views/subviews/edit-project-details.blade.php @@ -149,7 +149,7 @@ class="badge badge-primary p-1 ml-2 text-light {{ $project->effort_sheet_url ? '
- +
@@ -188,16 +188,36 @@ class="badge badge-primary p-1 ml-2 text-light {{ $project->effort_sheet_url ? '
- - -
-
-
+
+
+
+
+ +
+
@{{ comment.body }}
+
+ {{ "- " }}@{{ comment.user.name }} (@{{ comment.created_at }}) +
+
+
+
+ + +
+
+ +
@@ -208,7 +228,7 @@ class="badge badge-primary p-1 ml-2 text-light {{ $project->effort_sheet_url ? '
Invoice has been proceeded for this term.
-
+

diff --git a/Modules/Project/Services/ProjectService.php b/Modules/Project/Services/ProjectService.php index 6200663fc1..c96935549d 100644 --- a/Modules/Project/Services/ProjectService.php +++ b/Modules/Project/Services/ProjectService.php @@ -2,6 +2,7 @@ namespace Modules\Project\Services; +use App\Models\Comment; use Carbon\Carbon; use Carbon\CarbonPeriod; use Illuminate\Support\Arr; @@ -384,7 +385,7 @@ public function getProjectApprovedPipelineHour($project) public function getInvoiceTerms($project) { - $invoiceTerms = ProjectInvoiceTerm::where('project_id', $project->id)->get(); + $invoiceTerms = ProjectInvoiceTerm::where('project_id', $project->id)->with('comments')->get(); return $invoiceTerms; } @@ -589,7 +590,9 @@ private function updateInvoiceTerms($invoiceTerms, $project) 'is_accepted' => $term['is_accepted'] ?? $existingTerm->is_accepted, 'delivery_report' => $filePath, ]); - + if(isset($term['comment'])){ + $this->addCommentOnInvoiceTerm($term, $existingTerm); + } $termIds[] = $termId; } else { $filePath = $this->saveOrUpdateDeliveryReport($term, $project, $index); @@ -611,6 +614,20 @@ private function updateInvoiceTerms($invoiceTerms, $project) $project->invoiceTerms()->whereNotIn('id', $termIds)->delete(); } + public function addCommentOnInvoiceTerm ($term, $existingTerm) + { + if($term['comment']){ + $comment = Comment::create([ + 'user_id' => auth()->id(), + 'body' => $term['comment'], + 'commentable_id' => $existingTerm->id, + 'commentable_type' => ProjectInvoiceTerm::class, + ]); + $existingTerm->comments()->save($comment); + } + return; + } + private function updateProjectRepositories($data, $project) { if (! isset($data['url'])) { diff --git a/app/Models/Comment.php b/app/Models/Comment.php index 13414a29f7..d602d0d1cc 100644 --- a/app/Models/Comment.php +++ b/app/Models/Comment.php @@ -9,6 +9,7 @@ class Comment extends Model { protected $casts = [ 'created_at' => 'datetime: D d M @ h:i', + 'updated_at' => 'datetime: D d M @ h:i', ]; protected $with = ['user']; From 2470c02bdea2ce513fb25646a0f0a0499b51410d Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Thu, 4 Jul 2024 10:22:02 +0530 Subject: [PATCH 48/62] CI checks --- Modules/Project/Entities/ProjectInvoiceTerm.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Project/Entities/ProjectInvoiceTerm.php b/Modules/Project/Entities/ProjectInvoiceTerm.php index df753923f8..fcd87e5942 100644 --- a/Modules/Project/Entities/ProjectInvoiceTerm.php +++ b/Modules/Project/Entities/ProjectInvoiceTerm.php @@ -16,7 +16,7 @@ public function project() return $this->belongsTo(Project::class); } - public function getCurrentStatusAttribute() + public function getCurrentStatusAttribute() { return Carbon::now() > $this->invoice_date ? 'overdue' : $this->status; } From ddf5345a9de065d9401edba6f4f37cdfbbf985ed Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Thu, 4 Jul 2024 10:23:08 +0530 Subject: [PATCH 49/62] CI checks --- Modules/Project/Services/ProjectService.php | 1 + 1 file changed, 1 insertion(+) diff --git a/Modules/Project/Services/ProjectService.php b/Modules/Project/Services/ProjectService.php index 1e1431652e..e375091f8d 100644 --- a/Modules/Project/Services/ProjectService.php +++ b/Modules/Project/Services/ProjectService.php @@ -454,6 +454,7 @@ public function getPendingDeliveryReportInvoices() }); return $keyAccountManagersDetails; + } public function getProjectStages(Project $project) { From e8586b6e043002b1bd9ae04b419b5a07fcc9e25a Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Thu, 4 Jul 2024 10:24:16 +0530 Subject: [PATCH 50/62] CI checks --- Modules/Project/Services/ProjectService.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Modules/Project/Services/ProjectService.php b/Modules/Project/Services/ProjectService.php index e375091f8d..ad122cb994 100644 --- a/Modules/Project/Services/ProjectService.php +++ b/Modules/Project/Services/ProjectService.php @@ -670,7 +670,8 @@ private function updateInvoiceTerms($invoiceTerms, $project) 'is_accepted' => $term['is_accepted'] ?? $existingTerm->is_accepted, 'delivery_report' => $filePath, ]); - if(isset($term['comment'])){ + + if (isset($term['comment'])){ $this->addCommentOnInvoiceTerm($term, $existingTerm); } $termIds[] = $termId; @@ -694,9 +695,9 @@ private function updateInvoiceTerms($invoiceTerms, $project) $project->invoiceTerms()->whereNotIn('id', $termIds)->delete(); } - public function addCommentOnInvoiceTerm ($term, $existingTerm) + public function addCommentOnInvoiceTerm($term, $existingTerm) { - if($term['comment']){ + if ($term['comment']){ $comment = Comment::create([ 'user_id' => auth()->id(), 'body' => $term['comment'], From d53fb869a6db68953751ab74f411670d672f472d Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Thu, 4 Jul 2024 10:24:54 +0530 Subject: [PATCH 51/62] CI checks --- Modules/Project/Services/ProjectService.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/Project/Services/ProjectService.php b/Modules/Project/Services/ProjectService.php index ad122cb994..017b2771f0 100644 --- a/Modules/Project/Services/ProjectService.php +++ b/Modules/Project/Services/ProjectService.php @@ -671,7 +671,7 @@ private function updateInvoiceTerms($invoiceTerms, $project) 'delivery_report' => $filePath, ]); - if (isset($term['comment'])){ + if (isset($term['comment'])) { $this->addCommentOnInvoiceTerm($term, $existingTerm); } $termIds[] = $termId; @@ -697,7 +697,7 @@ private function updateInvoiceTerms($invoiceTerms, $project) public function addCommentOnInvoiceTerm($term, $existingTerm) { - if ($term['comment']){ + if ($term['comment']) { $comment = Comment::create([ 'user_id' => auth()->id(), 'body' => $term['comment'], From 30c1c3a92189db6dd7dd4b3677a91393d227be42 Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Thu, 4 Jul 2024 13:58:48 +0530 Subject: [PATCH 52/62] CI checks --- .../Project/Entities/ProjectInvoiceTerm.php | 10 +- .../Project/Resources/views/edit.blade.php | 24 +++- .../subviews/edit-project-details.blade.php | 99 +--------------- .../edit-project-inoice-terms.blade.php | 106 ++++++++++++++++++ Modules/Project/Services/ProjectService.php | 28 ++--- 5 files changed, 148 insertions(+), 119 deletions(-) create mode 100644 Modules/Project/Resources/views/subviews/edit-project-inoice-terms.blade.php diff --git a/Modules/Project/Entities/ProjectInvoiceTerm.php b/Modules/Project/Entities/ProjectInvoiceTerm.php index fcd87e5942..73cd6d11a1 100644 --- a/Modules/Project/Entities/ProjectInvoiceTerm.php +++ b/Modules/Project/Entities/ProjectInvoiceTerm.php @@ -9,7 +9,11 @@ class ProjectInvoiceTerm extends Model { - protected $fillable = ['project_id','invoice_id', 'invoice_date', 'status', 'client_acceptance_required', 'amount', 'is_accepted', 'report_required', 'delivery_report']; + protected $fillable = [ + 'project_id', 'invoice_id', 'invoice_date', 'status', + 'client_acceptance_required', 'amount', 'is_accepted', + 'report_required', 'delivery_report' + ]; public function project() { @@ -26,8 +30,8 @@ public function invoice() return $this->belongsTo(Invoice::class); } - public function comments() + public function comment() { - return $this->morphMany(Comment::class, 'commentable'); + return $this->morphOne(Comment::class, 'commentable'); } } diff --git a/Modules/Project/Resources/views/edit.blade.php b/Modules/Project/Resources/views/edit.blade.php index 381464f857..d3d56637aa 100644 --- a/Modules/Project/Resources/views/edit.blade.php +++ b/Modules/Project/Resources/views/edit.blade.php @@ -120,14 +120,19 @@ class="text-theme-body text-decoration-none mb-2 mb-xl-4 d-inline-flex align-ite }, defaultProjectInvoiceTerm() { return { - id: new Date().getTime(), + id: 'New', invoice_date: new Date().getTime(), amount: '', + status: 'yet-to-be-created', client_acceptance_required: 0, report_required: 0, is_accepted: 0, delivery_report: '', - comment:'' + comment:{ + id: new Date().getTime(), + body: '', + user: null + } } }, defaultProjectRepository() { @@ -288,10 +293,19 @@ class="text-theme-body text-decoration-none mb-2 mb-xl-4 d-inline-flex align-ite getDeliveryReportUrl(invoiceTermId) { return `{{ route('delivery-report.show', ':id') }}`.replace(':id', invoiceTermId); }, - toggleOverDue(index){ - const invoiceDate = new Date(this.invoiceTerms[index].invoice_date); + toggleDelayInput(index){ + const invoiceTerm = this.invoiceTerms[index] + const invoiceDate = new Date(invoiceTerm.invoice_date); const currentDate = new Date(); - return invoiceDate <= currentDate; + return invoiceDate <= currentDate && invoiceTerm.status === 'yet-to-be-created' && invoiceTerm.id !== 'New'; + }, + toggleDelayReason(index){ + const invoiceTermComment= this.invoiceTerms[index].comment + return invoiceTermComment && invoiceTermComment.body !== ""; + }, + formatDate(dateString) { + const options = { year: 'numeric', month: '2-digit', day: '2-digit' }; + return new Date(dateString).toISOString().slice(0, 10); } }, diff --git a/Modules/Project/Resources/views/subviews/edit-project-details.blade.php b/Modules/Project/Resources/views/subviews/edit-project-details.blade.php index b89c9d1346..8ebdceb5ba 100644 --- a/Modules/Project/Resources/views/subviews/edit-project-details.blade.php +++ b/Modules/Project/Resources/views/subviews/edit-project-details.blade.php @@ -146,104 +146,7 @@ class="badge badge-primary p-1 ml-2 text-light {{ $project->effort_sheet_url ? '
-
-
- - -
-
-
-
- - -
-
- - -
-
-
- - -
-
-
-
-
- - -
-
- -
- -
- {{ optional($project->client->country)->currency }} -
-
-
-
-
- -
- -
-
-
-
- -
-
@{{ comment.body }}
-
- {{ "- " }}@{{ comment.user.name }} (@{{ comment.created_at }}) -
-
-
-
- - -
-
- -
-
- -
-
- - - -
- Invoice has been proceeded for this term. -
-
-
-
-
-
-
-
- @if($project->status == 'active') - - - Schedule An Invoice - Add Another - - @endif -
-
+ @include('project::subviews.edit-project-inoice-terms')
@if ($project->is_amc == 1) diff --git a/Modules/Project/Resources/views/subviews/edit-project-inoice-terms.blade.php b/Modules/Project/Resources/views/subviews/edit-project-inoice-terms.blade.php new file mode 100644 index 0000000000..22e64873b8 --- /dev/null +++ b/Modules/Project/Resources/views/subviews/edit-project-inoice-terms.blade.php @@ -0,0 +1,106 @@ +
+
+ + + +
+
+
+
+ + +
+
+ + +
+
+
+ + +
+
+
+
+
+ + +
+
+ +
+ +
+ {{ optional($project->client->country)->currency }} +
+
+
+
+
+ +
+ +
+
+
+
+ + +
+
+
+
+
+
+ {{'Last updated at ' }} @{{formatDate(invoiceTerm.updated_at)}} +
+
+ {{_('Reaseon for delay')}} +
+
@{{ invoiceTerm.comment?.body }}
+
+ {{ "- " }} @{{invoiceTerm.comment?.user.name}} (@{{invoiceTerm.comment?.created_at}}) +
+
+
+
+
+
+
+
+ +
+
+ + + +
+ Invoice has been proceeded for this term. +
+
+
+
+
+
+
+
+ @if($project->status == 'active') + + + Schedule An Invoice + Add Another + + @endif +
+
\ No newline at end of file diff --git a/Modules/Project/Services/ProjectService.php b/Modules/Project/Services/ProjectService.php index 017b2771f0..95354b63d6 100644 --- a/Modules/Project/Services/ProjectService.php +++ b/Modules/Project/Services/ProjectService.php @@ -387,7 +387,7 @@ public function getProjectApprovedPipelineHour($project) public function getInvoiceTerms($project) { - $invoiceTerms = ProjectInvoiceTerm::where('project_id', $project->id)->with('comments')->get(); + $invoiceTerms = ProjectInvoiceTerm::where('project_id', $project->id)->with('comment')->get(); return $invoiceTerms; } @@ -649,10 +649,11 @@ private function updateInvoiceTerms($invoiceTerms, $project) } $existingTerms = $project->invoiceTerms()->get()->keyBy('id'); - + $termIds = []; foreach ($invoiceTerms as $index => $term) { $termId = $term['id'] ?? null; + $invoice = $project->invoices()->where('sent_on', $term['invoice_date'])->first(); if ($termId && isset($existingTerms[$termId])) { $existingTerm = $existingTerms[$termId]; @@ -671,16 +672,14 @@ private function updateInvoiceTerms($invoiceTerms, $project) 'delivery_report' => $filePath, ]); - if (isset($term['comment'])) { $this->addCommentOnInvoiceTerm($term, $existingTerm); - } $termIds[] = $termId; } else { $filePath = $this->saveOrUpdateDeliveryReport($term, $project, $index); $newTerm = $project->invoiceTerms()->create([ 'project_id' => $project->id, 'invoice_date' => $term['invoice_date'], - 'status' => 'yet-to-be-created', + 'status' => $invoice ? $invoice->status: $term['status'], 'amount' => $term['amount'], 'report_required' => $term['report_required'] ?? false, 'client_acceptance_required' => $term['client_acceptance_required'] ?? false, @@ -697,14 +696,17 @@ private function updateInvoiceTerms($invoiceTerms, $project) public function addCommentOnInvoiceTerm($term, $existingTerm) { - if ($term['comment']) { - $comment = Comment::create([ - 'user_id' => auth()->id(), - 'body' => $term['comment'], - 'commentable_id' => $existingTerm->id, - 'commentable_type' => ProjectInvoiceTerm::class, - ]); - $existingTerm->comments()->save($comment); + if (isset($term['comment'])) { + Comment::updateOrCreate( + [ + 'user_id' => auth()->id(), + 'commentable_id' => $existingTerm->id, + 'commentable_type' => ProjectInvoiceTerm::class, + ], + [ + 'body' => $term['comment']['body'], + ] + ); } return; } From cafb2514632639a0d2dc201df983a99185c34586 Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Thu, 4 Jul 2024 13:59:36 +0530 Subject: [PATCH 53/62] CI checks --- Modules/Project/Services/ProjectService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Project/Services/ProjectService.php b/Modules/Project/Services/ProjectService.php index 95354b63d6..b4624c8279 100644 --- a/Modules/Project/Services/ProjectService.php +++ b/Modules/Project/Services/ProjectService.php @@ -672,7 +672,7 @@ private function updateInvoiceTerms($invoiceTerms, $project) 'delivery_report' => $filePath, ]); - $this->addCommentOnInvoiceTerm($term, $existingTerm); + $this->addCommentOnInvoiceTerm($term, $existingTerm); $termIds[] = $termId; } else { $filePath = $this->saveOrUpdateDeliveryReport($term, $project, $index); From dede36a9f3f9d44c021aa5018eed391e304e64ca Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Thu, 4 Jul 2024 14:16:48 +0530 Subject: [PATCH 54/62] CI checks --- Modules/Invoice/Services/InvoiceService.php | 3 +- ...21_103448_create_project_invoice_terms.php | 2 +- .../Project/Entities/ProjectInvoiceTerm.php | 2 +- .../Http/Controllers/ProjectController.php | 1 - Modules/Project/Services/ProjectService.php | 38 +++++++++---------- 5 files changed, 22 insertions(+), 24 deletions(-) diff --git a/Modules/Invoice/Services/InvoiceService.php b/Modules/Invoice/Services/InvoiceService.php index 108eb64b2e..f67605e0c9 100644 --- a/Modules/Invoice/Services/InvoiceService.php +++ b/Modules/Invoice/Services/InvoiceService.php @@ -789,12 +789,11 @@ public function updateScheduledInvoice($invoice) $invoiceStatus = $invoice->status; $invoiceId = $invoice->id; - foreach ($project->invoiceTerms as $scheduledInvoice) { if (Carbon::parse($scheduledInvoice->invoice_date)->toDateString() === $invoiceSentOn) { $scheduledInvoice->update([ 'status' => $invoiceStatus, - 'invoice_id' => $invoiceId + 'invoice_id' => $invoiceId, ]); } } diff --git a/Modules/Project/Database/Migrations/2024_06_21_103448_create_project_invoice_terms.php b/Modules/Project/Database/Migrations/2024_06_21_103448_create_project_invoice_terms.php index 9bd35663a7..989ed22536 100644 --- a/Modules/Project/Database/Migrations/2024_06_21_103448_create_project_invoice_terms.php +++ b/Modules/Project/Database/Migrations/2024_06_21_103448_create_project_invoice_terms.php @@ -25,7 +25,7 @@ public function up() $table->boolean('report_required')->nullable(); $table->string('delivery_report')->nullable(); $table->timestamps(); - + $table->foreign('project_id')->references('id')->on('projects')->onDelete('cascade'); $table->foreign('invoice_id')->references('id')->on('invoices')->onDelete('cascade'); $table->index('project_id'); diff --git a/Modules/Project/Entities/ProjectInvoiceTerm.php b/Modules/Project/Entities/ProjectInvoiceTerm.php index 73cd6d11a1..40091ac649 100644 --- a/Modules/Project/Entities/ProjectInvoiceTerm.php +++ b/Modules/Project/Entities/ProjectInvoiceTerm.php @@ -12,7 +12,7 @@ class ProjectInvoiceTerm extends Model protected $fillable = [ 'project_id', 'invoice_id', 'invoice_date', 'status', 'client_acceptance_required', 'amount', 'is_accepted', - 'report_required', 'delivery_report' + 'report_required', 'delivery_report', ]; public function project() diff --git a/Modules/Project/Http/Controllers/ProjectController.php b/Modules/Project/Http/Controllers/ProjectController.php index 3a8a4c4077..71954afa6f 100644 --- a/Modules/Project/Http/Controllers/ProjectController.php +++ b/Modules/Project/Http/Controllers/ProjectController.php @@ -204,7 +204,6 @@ public function projectResource() ]); } - public function showDeliveryReport($invoiceId) { return $this->service->showDeliveryReport($invoiceId); diff --git a/Modules/Project/Services/ProjectService.php b/Modules/Project/Services/ProjectService.php index b4624c8279..36428838f3 100644 --- a/Modules/Project/Services/ProjectService.php +++ b/Modules/Project/Services/ProjectService.php @@ -504,6 +504,23 @@ public function createProjectStageList(string $stageName) ); } + public function addCommentOnInvoiceTerm($term, $existingTerm) + { + if (isset($term['comment'])) { + Comment::updateOrCreate( + [ + 'user_id' => auth()->id(), + 'commentable_id' => $existingTerm->id, + 'commentable_type' => ProjectInvoiceTerm::class, + ], + [ + 'body' => $term['comment']['body'], + ] + ); + } + return; + } + private function prepareStageData(array $stage): array { $startDate = null; @@ -649,7 +666,7 @@ private function updateInvoiceTerms($invoiceTerms, $project) } $existingTerms = $project->invoiceTerms()->get()->keyBy('id'); - + $termIds = []; foreach ($invoiceTerms as $index => $term) { $termId = $term['id'] ?? null; @@ -679,7 +696,7 @@ private function updateInvoiceTerms($invoiceTerms, $project) $newTerm = $project->invoiceTerms()->create([ 'project_id' => $project->id, 'invoice_date' => $term['invoice_date'], - 'status' => $invoice ? $invoice->status: $term['status'], + 'status' => $invoice ? $invoice->status : $term['status'], 'amount' => $term['amount'], 'report_required' => $term['report_required'] ?? false, 'client_acceptance_required' => $term['client_acceptance_required'] ?? false, @@ -694,23 +711,6 @@ private function updateInvoiceTerms($invoiceTerms, $project) $project->invoiceTerms()->whereNotIn('id', $termIds)->delete(); } - public function addCommentOnInvoiceTerm($term, $existingTerm) - { - if (isset($term['comment'])) { - Comment::updateOrCreate( - [ - 'user_id' => auth()->id(), - 'commentable_id' => $existingTerm->id, - 'commentable_type' => ProjectInvoiceTerm::class, - ], - [ - 'body' => $term['comment']['body'], - ] - ); - } - return; - } - private function updateProjectRepositories($data, $project) { if (! isset($data['url'])) { From 3aa83c45da669a5a6bb3965abc9aa04f4b2b7204 Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Thu, 4 Jul 2024 14:20:42 +0530 Subject: [PATCH 55/62] CI checks --- Modules/Project/Entities/ProjectInvoiceTerm.php | 2 +- Modules/Project/Services/ProjectService.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/Project/Entities/ProjectInvoiceTerm.php b/Modules/Project/Entities/ProjectInvoiceTerm.php index 40091ac649..fa9b1b0b2e 100644 --- a/Modules/Project/Entities/ProjectInvoiceTerm.php +++ b/Modules/Project/Entities/ProjectInvoiceTerm.php @@ -4,8 +4,8 @@ use App\Models\Comment; use Carbon\Carbon; -use Modules\Invoice\Entities\Invoice; use Illuminate\Database\Eloquent\Model; +use Modules\Invoice\Entities\Invoice; class ProjectInvoiceTerm extends Model { diff --git a/Modules/Project/Services/ProjectService.php b/Modules/Project/Services/ProjectService.php index 36428838f3..86dfc6db97 100644 --- a/Modules/Project/Services/ProjectService.php +++ b/Modules/Project/Services/ProjectService.php @@ -518,7 +518,7 @@ public function addCommentOnInvoiceTerm($term, $existingTerm) ] ); } - return; + } private function prepareStageData(array $stage): array From 04ded8fef8b03ce3bc9a823ee9907f77f338926a Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Thu, 4 Jul 2024 14:28:21 +0530 Subject: [PATCH 56/62] CI checks --- Modules/Project/Services/ProjectService.php | 1 - 1 file changed, 1 deletion(-) diff --git a/Modules/Project/Services/ProjectService.php b/Modules/Project/Services/ProjectService.php index 86dfc6db97..8d6e21e55c 100644 --- a/Modules/Project/Services/ProjectService.php +++ b/Modules/Project/Services/ProjectService.php @@ -518,7 +518,6 @@ public function addCommentOnInvoiceTerm($term, $existingTerm) ] ); } - } private function prepareStageData(array $stage): array From f79cac6735339d667568ab05cd792a514a9948d3 Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Thu, 4 Jul 2024 19:55:43 +0530 Subject: [PATCH 57/62] CI checks --- .../Project/Resources/views/edit.blade.php | 13 ++++----- .../edit-project-inoice-terms.blade.php | 29 ++++++++++--------- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/Modules/Project/Resources/views/edit.blade.php b/Modules/Project/Resources/views/edit.blade.php index d3d56637aa..9f33eaf6ee 100644 --- a/Modules/Project/Resources/views/edit.blade.php +++ b/Modules/Project/Resources/views/edit.blade.php @@ -128,7 +128,8 @@ class="text-theme-body text-decoration-none mb-2 mb-xl-4 d-inline-flex align-ite report_required: 0, is_accepted: 0, delivery_report: '', - comment:{ + date_change: false, + comment: { id: new Date().getTime(), body: '', user: null @@ -293,19 +294,17 @@ class="text-theme-body text-decoration-none mb-2 mb-xl-4 d-inline-flex align-ite getDeliveryReportUrl(invoiceTermId) { return `{{ route('delivery-report.show', ':id') }}`.replace(':id', invoiceTermId); }, - toggleDelayInput(index){ - const invoiceTerm = this.invoiceTerms[index] - const invoiceDate = new Date(invoiceTerm.invoice_date); - const currentDate = new Date(); - return invoiceDate <= currentDate && invoiceTerm.status === 'yet-to-be-created' && invoiceTerm.id !== 'New'; - }, toggleDelayReason(index){ const invoiceTermComment= this.invoiceTerms[index].comment + console.log(this.invoiceTerms[index].invoice_date, index); return invoiceTermComment && invoiceTermComment.body !== ""; }, formatDate(dateString) { const options = { year: 'numeric', month: '2-digit', day: '2-digit' }; return new Date(dateString).toISOString().slice(0, 10); + }, + isDateChange(index) { + this.$set(this.invoiceTerms[index], 'date_change', true); } }, diff --git a/Modules/Project/Resources/views/subviews/edit-project-inoice-terms.blade.php b/Modules/Project/Resources/views/subviews/edit-project-inoice-terms.blade.php index 22e64873b8..55355abd02 100644 --- a/Modules/Project/Resources/views/subviews/edit-project-inoice-terms.blade.php +++ b/Modules/Project/Resources/views/subviews/edit-project-inoice-terms.blade.php @@ -6,25 +6,28 @@
-
- - +
+ +
-
- - +
+ +
-
- - +
+ +
-
+
- +
@@ -50,7 +53,7 @@
-
+
-
@@ -79,6 +71,14 @@ class="form-control"
+
+ + +
From 079050d1fbb5bd9dc100b1275d898a181f75854d Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Fri, 5 Jul 2024 10:31:23 +0530 Subject: [PATCH 60/62] CI checks --- .../views/subviews/edit-project-inoice-terms.blade.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/Project/Resources/views/subviews/edit-project-inoice-terms.blade.php b/Modules/Project/Resources/views/subviews/edit-project-inoice-terms.blade.php index 6393197720..214eaae26a 100644 --- a/Modules/Project/Resources/views/subviews/edit-project-inoice-terms.blade.php +++ b/Modules/Project/Resources/views/subviews/edit-project-inoice-terms.blade.php @@ -61,7 +61,7 @@ {{'Last updated on ' }} @{{formatDate(invoiceTerm.updated_at)}}
- {{_('Reaseon for delay')}} + {{_('Reaseon for rescheduling')}}
@{{ invoiceTerm.comment?.body }}
@@ -72,11 +72,11 @@
- +
From 7aa9b1ff9ab871ff293f4de1d68d4c1a66dd5ce8 Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Fri, 5 Jul 2024 12:59:00 +0530 Subject: [PATCH 61/62] CI checks --- .../edit-project-inoice-terms.blade.php | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/Modules/Project/Resources/views/subviews/edit-project-inoice-terms.blade.php b/Modules/Project/Resources/views/subviews/edit-project-inoice-terms.blade.php index 214eaae26a..6153cab4d1 100644 --- a/Modules/Project/Resources/views/subviews/edit-project-inoice-terms.blade.php +++ b/Modules/Project/Resources/views/subviews/edit-project-inoice-terms.blade.php @@ -52,10 +52,21 @@
-
-
+
+
+ + +
+
-
+ +
{{'Last updated on ' }} @{{formatDate(invoiceTerm.updated_at)}} @@ -71,14 +82,6 @@
-
- - -
From 9817e1bdf7f8769f931070efdcd6875d51313d31 Mon Sep 17 00:00:00 2001 From: AbhishekNegi25 Date: Fri, 5 Jul 2024 13:57:36 +0530 Subject: [PATCH 62/62] CI checks --- config/constants.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/constants.php b/config/constants.php index 29242d4041..68aea4e7ad 100644 --- a/config/constants.php +++ b/config/constants.php @@ -190,8 +190,8 @@ 'class' => 'badge badge-danger', ], ], - 'delivery-report-reminder-days' => 7, - 'finance-team-invoice-reminder-days' => 5, + 'delivery-report-reminder-days' => 5, + 'finance-team-invoice-reminder-days' => 3, 'email'=> 'finance@coloredcow.com', ], 'gst' => '18',