mirror of
https://github.com/crater-invoice/crater.git
synced 2025-10-27 11:41:09 -04:00
add overdue
This commit is contained in:
@ -41,11 +41,12 @@ class CheckInvoiceStatus extends Command
|
||||
{
|
||||
$date = Carbon::now();
|
||||
$invoices = Invoice::whereNotIn('status', [Invoice::STATUS_COMPLETED, Invoice::STATUS_DRAFT])
|
||||
->where('overdue', false)
|
||||
->whereDate('due_date', '<', $date)
|
||||
->get();
|
||||
|
||||
foreach ($invoices as $invoice) {
|
||||
$invoice->status = Invoice::STATUS_OVERDUE;
|
||||
$invoice->overdue = true;
|
||||
printf("Invoice %s is OVERDUE \n", $invoice->invoice_number);
|
||||
$invoice->save();
|
||||
}
|
||||
|
||||
@ -51,6 +51,7 @@ class InvoiceResource extends JsonResource
|
||||
'formatted_invoice_date' => $this->formattedInvoiceDate,
|
||||
'formatted_due_date' => $this->formattedDueDate,
|
||||
'payment_module_enabled' => $this->payment_module_enabled,
|
||||
'overdue' => $this->overdue,
|
||||
'items' => $this->when($this->items()->exists(), function () {
|
||||
return InvoiceItemResource::collection($this->items);
|
||||
}),
|
||||
|
||||
@ -55,6 +55,7 @@ class InvoiceResource extends JsonResource
|
||||
'payment_module_enabled' => $this->payment_module_enabled,
|
||||
'sales_tax_type' => $this->sales_tax_type,
|
||||
'sales_tax_address_type' => $this->sales_tax_address_type,
|
||||
'overdue' => $this->overdue,
|
||||
'items' => $this->when($this->items()->exists(), function () {
|
||||
return InvoiceItemResource::collection($this->items);
|
||||
}),
|
||||
|
||||
@ -28,10 +28,8 @@ class Invoice extends Model implements HasMedia
|
||||
public const STATUS_DRAFT = 'DRAFT';
|
||||
public const STATUS_SENT = 'SENT';
|
||||
public const STATUS_VIEWED = 'VIEWED';
|
||||
public const STATUS_OVERDUE = 'OVERDUE';
|
||||
public const STATUS_COMPLETED = 'COMPLETED';
|
||||
|
||||
public const STATUS_DUE = 'DUE';
|
||||
public const STATUS_UNPAID = 'UNPAID';
|
||||
public const STATUS_PARTIALLY_PAID = 'PARTIALLY_PAID';
|
||||
public const STATUS_PAID = 'PAID';
|
||||
@ -138,7 +136,6 @@ class Invoice extends Model implements HasMedia
|
||||
self::STATUS_DRAFT,
|
||||
self::STATUS_SENT,
|
||||
self::STATUS_VIEWED,
|
||||
self::STATUS_OVERDUE,
|
||||
self::STATUS_COMPLETED,
|
||||
];
|
||||
|
||||
@ -155,9 +152,7 @@ class Invoice extends Model implements HasMedia
|
||||
|
||||
public function getPreviousStatus()
|
||||
{
|
||||
if ($this->due_date < Carbon::now()) {
|
||||
return self::STATUS_OVERDUE;
|
||||
} elseif ($this->viewed) {
|
||||
if ($this->viewed) {
|
||||
return self::STATUS_VIEWED;
|
||||
} elseif ($this->sent) {
|
||||
return self::STATUS_SENT;
|
||||
@ -254,7 +249,7 @@ class Invoice extends Model implements HasMedia
|
||||
$filters->get('status') == self::STATUS_PAID
|
||||
) {
|
||||
$query->wherePaidStatus($filters->get('status'));
|
||||
} elseif ($filters->get('status') == self::STATUS_DUE) {
|
||||
} elseif ($filters->get('status') == 'DUE') {
|
||||
$query->whereDueStatus($filters->get('status'));
|
||||
} else {
|
||||
$query->whereStatus($filters->get('status'));
|
||||
@ -692,6 +687,7 @@ class Invoice extends Model implements HasMedia
|
||||
if ($amount == 0) {
|
||||
$this->status = Invoice::STATUS_COMPLETED;
|
||||
$this->paid_status = Invoice::STATUS_PAID;
|
||||
$this->overdue = false;
|
||||
} elseif ($amount == $this->total) {
|
||||
$this->status = $this->getPreviousStatus();
|
||||
$this->paid_status = Invoice::STATUS_UNPAID;
|
||||
|
||||
@ -37,15 +37,6 @@ class InvoiceFactory extends Factory
|
||||
});
|
||||
}
|
||||
|
||||
public function overdue()
|
||||
{
|
||||
return $this->state(function (array $attributes) {
|
||||
return [
|
||||
'status' => Invoice::STATUS_OVERDUE,
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
public function completed()
|
||||
{
|
||||
return $this->state(function (array $attributes) {
|
||||
@ -55,15 +46,6 @@ class InvoiceFactory extends Factory
|
||||
});
|
||||
}
|
||||
|
||||
public function due()
|
||||
{
|
||||
return $this->state(function (array $attributes) {
|
||||
return [
|
||||
'status' => Invoice::STATUS_DUE,
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
public function unpaid()
|
||||
{
|
||||
return $this->state(function (array $attributes) {
|
||||
|
||||
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddOverdueToInvoicesTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('invoices', function (Blueprint $table) {
|
||||
$table->boolean('overdue')->default(false);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('invoices', function (Blueprint $table) {
|
||||
$table->dropForeign(['overdue']);
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -237,6 +237,14 @@
|
||||
:currency="row.data.currency"
|
||||
/>
|
||||
|
||||
<BasePaidStatusBadge
|
||||
v-if="row.data.overdue"
|
||||
status="OVERDUE"
|
||||
class="px-1 py-0.5 ml-2"
|
||||
>
|
||||
{{ $t('invoices.overdue') }}
|
||||
</BasePaidStatusBadge>
|
||||
|
||||
<BasePaidStatusBadge
|
||||
:status="row.data.paid_status"
|
||||
class="px-1 py-0.5 ml-2"
|
||||
@ -284,7 +292,7 @@ const showFilters = ref(false)
|
||||
const status = ref([
|
||||
{
|
||||
label: 'Status',
|
||||
options: ['DRAFT', 'DUE', 'SENT', 'VIEWED', 'OVERDUE', 'COMPLETED'],
|
||||
options: ['DRAFT', 'DUE', 'SENT', 'VIEWED', 'COMPLETED'],
|
||||
},
|
||||
{
|
||||
label: 'Paid Status',
|
||||
@ -527,10 +535,6 @@ function setActiveTab(val) {
|
||||
activeTab.value = t('invoices.viewed')
|
||||
break
|
||||
|
||||
case 'OVERDUE':
|
||||
activeTab.value = t('invoices.overdue')
|
||||
break
|
||||
|
||||
default:
|
||||
activeTab.value = t('general.all')
|
||||
break
|
||||
|
||||
@ -267,9 +267,7 @@ onSearched = debounce(onSearched, 500)
|
||||
>
|
||||
<BaseButton
|
||||
v-if="
|
||||
invoiceData.status === 'SENT' ||
|
||||
invoiceData.status === 'OVERDUE' ||
|
||||
invoiceData.status === 'VIEWED'
|
||||
invoiceData.status === 'SENT' || invoiceData.status === 'VIEWED'
|
||||
"
|
||||
variant="primary"
|
||||
>
|
||||
|
||||
@ -29,6 +29,8 @@ export default {
|
||||
return ' bg-yellow-500 bg-opacity-25 text-yellow-900 uppercase font-normal text-center '
|
||||
case 'PARTIALLY_PAID':
|
||||
return 'bg-blue-400 bg-opacity-25 text-blue-900 uppercase font-normal text-center'
|
||||
case 'OVERDUE':
|
||||
return 'bg-red-300 bg-opacity-50 px-2 py-1 text-sm text-red-900 uppercase font-normal text-center'
|
||||
default:
|
||||
return 'bg-gray-500 bg-opacity-25 text-gray-900 uppercase font-normal text-center'
|
||||
}
|
||||
|
||||
@ -160,7 +160,7 @@ const route = useRoute()
|
||||
const table = ref(null)
|
||||
let isFetchingInitialData = ref(true)
|
||||
let showFilters = ref(false)
|
||||
const status = ref(['DRAFT', 'DUE', 'SENT', 'VIEWED', 'OVERDUE', 'COMPLETED'])
|
||||
const status = ref(['DRAFT', 'DUE', 'SENT', 'VIEWED', 'COMPLETED'])
|
||||
const filters = reactive({
|
||||
status: '',
|
||||
from_date: '',
|
||||
|
||||
@ -209,11 +209,6 @@ export default {
|
||||
bgColor: '#C9E3EC',
|
||||
color: '#2c5282',
|
||||
}
|
||||
case 'OVERDUE':
|
||||
return {
|
||||
bgColor: '#FED7D7',
|
||||
color: '#c53030',
|
||||
}
|
||||
case 'COMPLETED':
|
||||
return {
|
||||
bgColor: '#D5EED0',
|
||||
@ -256,8 +251,6 @@ export default {
|
||||
return global.t('estimates.expired')
|
||||
case 'PARTIALLY PAID':
|
||||
return global.t('estimates.partially_paid')
|
||||
case 'OVERDUE':
|
||||
return global.t('invoices.overdue')
|
||||
case 'COMPLETED':
|
||||
return global.t('invoices.completed')
|
||||
case 'DUE':
|
||||
|
||||
Reference in New Issue
Block a user