diff --git a/app/Http/Controllers/Dashboard/Dashboard.php b/app/Http/Controllers/Dashboard/Dashboard.php index d170692e5..283c14703 100644 --- a/app/Http/Controllers/Dashboard/Dashboard.php +++ b/app/Http/Controllers/Dashboard/Dashboard.php @@ -18,6 +18,8 @@ class Dashboard extends Controller { use Currencies; + public $today; + /** * Display a listing of the resource. * @@ -25,8 +27,8 @@ class Dashboard extends Controller */ public function index() { - $td = Date::today(); - $month_days = $td->daysInMonth; + $this->today = Date::today(); + $month_days = $this->today->daysInMonth; /* * Cash Flow @@ -78,53 +80,16 @@ class Dashboard extends Controller $incomes = $expenses = array(); $incomes_amount = $expenses_amount = 0; - $open_invoice = $overdue_invoice = 0; - $open_bill = $overdue_bill = 0; - $invoice_paid_amount = $bill_paid_amount = 0; - - $today = $td->toDateString(); // Invoices - $invoices = Invoice::with('payments')->get(); - - foreach ($invoices as $invoice) { - $invoice_payments = 0; - - foreach ($invoice->payments as $payment) { - $invoice_payments += $payment->getConvertedAmount(); - } - - $invoice_paid_amount += $invoice_payments; - - // Check if it's open or overdue invoice - if ($invoice->due_at > $today) { - $open_invoice += $invoice->getConvertedAmount() - $invoice_payments; - } else { - $overdue_invoice += $invoice->getConvertedAmount() - $invoice_payments; - } - } + $invoices = Invoice::with('payments')->accrued()->get(); + list($invoice_paid_amount, $open_invoice, $overdue_invoice) = $this->getTotals($invoices, 'invoice'); $incomes_amount += $invoice_paid_amount; // Bills - $bills = Bill::with('payments')->get(); - - foreach ($bills as $bill) { - $bill_payments = 0; - - foreach ($bill->payments as $payment) { - $bill_payments += $payment->getConvertedAmount(); - } - - $bill_paid_amount += $bill_payments; - - // Check if it's open or overdue bill - if ($bill->due_at > $today) { - $open_bill += $bill->getConvertedAmount() - $bill_payments; - } else { - $overdue_bill += $bill->getConvertedAmount() - $bill_payments; - } - } + $bills = Bill::with('payments')->accrued()->get(); + list($bill_paid_amount, $open_bill, $overdue_bill) = $this->getTotals($bills, 'bill'); $expenses_amount += $bill_paid_amount; @@ -286,15 +251,15 @@ class Dashboard extends Controller * Latest Incomes */ - $latest_incomes = collect(InvoicePayment::latest()->take(5)->get()); - $latest_incomes = $latest_incomes->merge(Revenue::latest()->take(5)->get())->sortByDesc('paid_at'); + $latest_incomes = collect(Invoice::accrued()->latest()->take(10)->get()); + $latest_incomes = $latest_incomes->merge(Revenue::latest()->take(10)->get())->take(5)->sortByDesc('invoiced_at'); /* * Latest Expenses */ - $latest_expenses = collect(BillPayment::latest()->take(5)->get()); - $latest_expenses = $latest_expenses->merge(Payment::latest()->take(5)->get())->sortByDesc('paid_at'); + $latest_expenses = collect(Bill::accrued()->latest()->take(10)->get()); + $latest_expenses = $latest_expenses->merge(Payment::latest()->take(10)->get())->take(5)->sortByDesc('billed_at'); return view('dashboard.dashboard.index', compact( 'total_incomes', @@ -364,16 +329,16 @@ class Dashboard extends Controller $items_1 = $m1::whereBetween('paid_at', [$sub, $now])->get(); - $this->setTotals($totals, $items_1, $date_format); + $this->setCashFlowTotals($totals, $items_1, $date_format); $items_2 = $m2::whereBetween('paid_at', [$sub, $now])->get(); - $this->setTotals($totals, $items_2, $date_format); + $this->setCashFlowTotals($totals, $items_2, $date_format); return $totals; } - private function setTotals(&$totals, $items, $date_format) + private function setCashFlowTotals(&$totals, $items, $date_format) { foreach ($items as $item) { $i = Date::parse($item->paid_at)->format($date_format); @@ -382,6 +347,39 @@ class Dashboard extends Controller } } + private function getTotals($items, $type) + { + $paid = $open = $overdue = 0; + + $today = $this->today->toDateString(); + + foreach ($items as $item) { + $paid += $item->getConvertedAmount(); + + $code_field = $type . '_status_code'; + + if ($item->$code_field == 'paid') { + continue; + } + + $payments = 0; + if ($item->$code_field == 'partial') { + foreach ($item->payments as $payment) { + $payments += $payment->getConvertedAmount(); + } + } + + // Check if it's open or overdue invoice + if ($item->due_at > $today) { + $open += $item->getConvertedAmount() - $payments; + } else { + $overdue += $item->getConvertedAmount() - $payments; + } + } + + return array($paid, $open, $overdue); + } + private function getProfit($incomes, $expenses) { $profit = []; diff --git a/app/Http/Controllers/Expenses/Bills.php b/app/Http/Controllers/Expenses/Bills.php index e6ed086fa..bd196cd45 100644 --- a/app/Http/Controllers/Expenses/Bills.php +++ b/app/Http/Controllers/Expenses/Bills.php @@ -41,10 +41,10 @@ class Bills extends Controller $vendors = collect(Vendor::enabled()->pluck('name', 'id')) ->prepend(trans('general.all_type', ['type' => trans_choice('general.vendors', 2)]), ''); - $status = collect(BillStatus::all()->pluck('name', 'code')) + $statuses = collect(BillStatus::all()->pluck('name', 'code')) ->prepend(trans('general.all_type', ['type' => trans_choice('general.statuses', 2)]), ''); - return view('expenses.bills.index', compact('bills', 'vendors', 'status')); + return view('expenses.bills.index', compact('bills', 'vendors', 'statuses')); } /** @@ -81,133 +81,6 @@ class Bills extends Controller return view('expenses.bills.show', compact('bill', 'accounts', 'currencies', 'account_currency_code', 'vendors', 'categories', 'payment_methods')); } - /** - * Show the form for viewing the specified resource. - * - * @param int $bill_id - * - * @return Response - */ - public function printBill($bill_id) - { - $paid = 0; - - $bill = Bill::where('id', $bill_id)->first(); - - foreach ($bill->payments as $item) { - $item->default_currency_code = $bill->currency_code; - - $paid += $item->getDynamicConvertedAmount(); - } - - $bill->paid = $paid; - - return view('expenses.bills.bill', compact('bill')); - } - - /** - * Show the form for viewing the specified resource. - * - * @param int $bill_id - * - * @return Response - */ - public function pdfBill($bill_id) - { - $paid = 0; - - $bill = Bill::where('id', $bill_id)->first(); - - foreach ($bill->payments as $item) { - $item->default_currency_code = $bill->currency_code; - - $paid += $item->getDynamicConvertedAmount(); - } - - $bill->paid = $paid; - - $html = view('expenses.bills.bill', compact('bill'))->render(); - - $pdf = \App::make('dompdf.wrapper'); - $pdf->loadHTML($html); - - $file_name = 'bill_'.time().'.pdf'; - - return $pdf->download($file_name); - } - - /** - * Show the form for viewing the specified resource. - * - * @param PaymentRequest $request - * - * @return Response - */ - public function payment(PaymentRequest $request) - { - // Get currency object - $currency = Currency::where('code', $request['currency_code'])->first(); - - $request['currency_code'] = $currency->code; - $request['currency_rate'] = $currency->rate; - - // Upload attachment - $attachment_path = $this->getUploadedFilePath($request->file('attachment'), 'revenues'); - - if ($attachment_path) { - $request['attachment'] = $attachment_path; - } - - $bill = Bill::find($request['bill_id']); - - if ($request['currency_code'] == $bill->currency_code) { - if ($request['amount'] > $bill->amount) { - $message = trans('messages.error.added', ['type' => trans_choice('general.payment', 1)]); - - return response()->json($message); - } elseif ($request['amount'] == $bill->amount) { - $bill->bill_status_code = 'paid'; - } else { - $bill->bill_status_code = 'partial'; - } - } else { - $request_bill = new Bill(); - - $request_bill->amount = (float) $request['amount']; - $request_bill->currency_code = $currency->code; - $request_bill->currency_rate = $currency->rate; - - $amount = $request_bill->getConvertedAmount(); - - if ($amount > $bill->amount) { - $message = trans('messages.error.added', ['type' => trans_choice('general.payment', 1)]); - - return response()->json($message); - } elseif ($amount == $bill->amount) { - $bill->bill_status_code = 'paid'; - } else { - $bill->bill_status_code = 'partial'; - } - } - - $bill->save(); - - $bill_payment = BillPayment::create($request->input()); - - $request['status_code'] = $bill->bill_status_code; - $request['notify'] = 0; - - $desc_date = Date::parse($request['paid_at'])->format($this->getCompanyDateFormat()); - $desc_amount = money((float) $request['amount'], $request['currency_code'], true)->format(); - $request['description'] = $desc_date . ' ' . $desc_amount; - - BillHistory::create($request->input()); - - $message = trans('messages.success.added', ['type' => trans_choice('general.revenues', 1)]); - - return response()->json($message); - } - /** * Show the form for creating a new resource. * @@ -250,7 +123,7 @@ class Bills extends Controller $request['currency_code'] = $currency->code; $request['currency_rate'] = $currency->rate; - $request['bill_status_code'] = 'new'; + $request['bill_status_code'] = 'draft'; $request['amount'] = 0; @@ -429,8 +302,6 @@ class Bills extends Controller $request['currency_code'] = $currency->code; $request['currency_rate'] = $currency->rate; - $request['bill_status_code'] = 'updated'; - $request['amount'] = 0; // Upload attachment @@ -587,6 +458,151 @@ class Bills extends Controller return redirect('expenses/bills'); } + /** + * Mark the invoice as sent. + * + * @param int $invoice_id + * + * @return Response + */ + public function markReceived($bill_id) + { + $bill = Bill::find($bill_id); + $bill->bill_status_code = 'received'; + $bill->save(); + + flash(trans('bills.marked_received'))->success(); + + return redirect()->back(); + } + + /** + * Show the form for viewing the specified resource. + * + * @param int $bill_id + * + * @return Response + */ + public function printBill($bill_id) + { + $paid = 0; + + $bill = Bill::where('id', $bill_id)->first(); + + foreach ($bill->payments as $item) { + $item->default_currency_code = $bill->currency_code; + + $paid += $item->getDynamicConvertedAmount(); + } + + $bill->paid = $paid; + + return view('expenses.bills.bill', compact('bill')); + } + + /** + * Show the form for viewing the specified resource. + * + * @param int $bill_id + * + * @return Response + */ + public function pdfBill($bill_id) + { + $paid = 0; + + $bill = Bill::where('id', $bill_id)->first(); + + foreach ($bill->payments as $item) { + $item->default_currency_code = $bill->currency_code; + + $paid += $item->getDynamicConvertedAmount(); + } + + $bill->paid = $paid; + + $html = view('expenses.bills.bill', compact('bill'))->render(); + + $pdf = \App::make('dompdf.wrapper'); + $pdf->loadHTML($html); + + $file_name = 'bill_'.time().'.pdf'; + + return $pdf->download($file_name); + } + + /** + * Show the form for viewing the specified resource. + * + * @param PaymentRequest $request + * + * @return Response + */ + public function payment(PaymentRequest $request) + { + // Get currency object + $currency = Currency::where('code', $request['currency_code'])->first(); + + $request['currency_code'] = $currency->code; + $request['currency_rate'] = $currency->rate; + + // Upload attachment + $attachment_path = $this->getUploadedFilePath($request->file('attachment'), 'revenues'); + + if ($attachment_path) { + $request['attachment'] = $attachment_path; + } + + $bill = Bill::find($request['bill_id']); + + if ($request['currency_code'] == $bill->currency_code) { + if ($request['amount'] > $bill->amount) { + $message = trans('messages.error.added', ['type' => trans_choice('general.payment', 1)]); + + return response()->json($message); + } elseif ($request['amount'] == $bill->amount) { + $bill->bill_status_code = 'paid'; + } else { + $bill->bill_status_code = 'partial'; + } + } else { + $request_bill = new Bill(); + + $request_bill->amount = (float) $request['amount']; + $request_bill->currency_code = $currency->code; + $request_bill->currency_rate = $currency->rate; + + $amount = $request_bill->getConvertedAmount(); + + if ($amount > $bill->amount) { + $message = trans('messages.error.added', ['type' => trans_choice('general.payment', 1)]); + + return response()->json($message); + } elseif ($amount == $bill->amount) { + $bill->bill_status_code = 'paid'; + } else { + $bill->bill_status_code = 'partial'; + } + } + + $bill->save(); + + $bill_payment = BillPayment::create($request->input()); + + $request['status_code'] = $bill->bill_status_code; + $request['notify'] = 0; + + $desc_date = Date::parse($request['paid_at'])->format($this->getCompanyDateFormat()); + $desc_amount = money((float) $request['amount'], $request['currency_code'], true)->format(); + $request['description'] = $desc_date . ' ' . $desc_amount; + + BillHistory::create($request->input()); + + $message = trans('messages.success.added', ['type' => trans_choice('general.revenues', 1)]); + + return response()->json($message); + } + /** * Remove the specified resource from storage. * diff --git a/app/Http/Controllers/Incomes/Invoices.php b/app/Http/Controllers/Incomes/Invoices.php index 3936b6389..b5adc5160 100644 --- a/app/Http/Controllers/Incomes/Invoices.php +++ b/app/Http/Controllers/Incomes/Invoices.php @@ -82,141 +82,6 @@ class Invoices extends Controller return view('incomes.invoices.show', compact('invoice', 'accounts', 'currencies', 'account_currency_code', 'customers', 'categories', 'payment_methods')); } - /** - * Show the form for viewing the specified resource. - * - * @param int $invoice_id - * - * @return Response - */ - public function printInvoice($invoice_id) - { - $paid = 0; - - $invoice = Invoice::where('id', $invoice_id)->first(); - - foreach ($invoice->payments as $item) { - $item->default_currency_code = $invoice->currency_code; - - $paid += $item->getDynamicConvertedAmount(); - } - - $invoice->paid = $paid; - - $invoice->template_path = 'incomes.invoices.invoice'; - - event(new InvoicePrinting($invoice)); - - return view($invoice->template_path, compact('invoice')); - } - - /** - * Show the form for viewing the specified resource. - * - * @param int $invoice_id - * - * @return Response - */ - public function pdfInvoice($invoice_id) - { - $paid = 0; - - $invoice = Invoice::where('id', $invoice_id)->first(); - - foreach ($invoice->payments as $item) { - $item->default_currency_code = $invoice->currency_code; - - $paid += $item->getDynamicConvertedAmount(); - } - - $invoice->paid = $paid; - - $invoice->template_path = 'incomes.invoices.invoice'; - - event(new InvoicePrinting($invoice)); - - $html = view($invoice->template_path, compact('invoice'))->render(); - - $pdf = \App::make('dompdf.wrapper'); - $pdf->loadHTML($html); - - $file_name = 'invoice_'.time().'.pdf'; - - return $pdf->download($file_name); - } - - /** - * Show the form for viewing the specified resource. - * - * @param PaymentRequest $request - * - * @return Response - */ - public function payment(PaymentRequest $request) - { - // Get currency object - $currency = Currency::where('code', $request['currency_code'])->first(); - - $request['currency_code'] = $currency->code; - $request['currency_rate'] = $currency->rate; - - // Upload attachment - $attachment_path = $this->getUploadedFilePath($request->file('attachment'), 'revenues'); - - if ($attachment_path) { - $request['attachment'] = $attachment_path; - } - - $invoice = Invoice::find($request['invoice_id']); - - if ($request['currency_code'] == $invoice->currency_code) { - if ($request['amount'] > $invoice->amount) { - $message = trans('messages.error.added', ['type' => trans_choice('general.payment', 1)]); - - return response()->json($message); - } elseif ($request['amount'] == $invoice->amount) { - $invoice->invoice_status_code = 'paid'; - } else { - $invoice->invoice_status_code = 'partial'; - } - } else { - $request_invoice = new Invoice(); - - $request_invoice->amount = (float) $request['amount']; - $request_invoice->currency_code = $currency->code; - $request_invoice->currency_rate = $currency->rate; - - $amount = $request_invoice->getConvertedAmount(); - - if ($amount > $invoice->amount) { - $message = trans('messages.error.added', ['type' => trans_choice('general.payment', 1)]); - - return response()->json($message); - } elseif ($amount == $invoice->amount) { - $invoice->invoice_status_code = 'paid'; - } else { - $invoice->invoice_status_code = 'partial'; - } - } - - $invoice->save(); - - $invoice_payment = InvoicePayment::create($request->input()); - - $request['status_code'] = $invoice->invoice_status_code; - $request['notify'] = 0; - - $desc_date = Date::parse($request['paid_at'])->format($this->getCompanyDateFormat()); - $desc_amount = money((float) $request['amount'], $request['currency_code'], true)->format(); - $request['description'] = $desc_date . ' ' . $desc_amount; - - InvoiceHistory::create($request->input()); - - $message = trans('messages.success.added', ['type' => trans_choice('general.revenues', 1)]); - - return response()->json($message); - } - /** * Show the form for creating a new resource. * @@ -411,8 +276,6 @@ class Invoices extends Controller $request['currency_code'] = $currency->code; $request['currency_rate'] = $currency->rate; - $request['invoice_status_code'] = 'draft'; - // Upload attachment $attachment_path = $this->getUploadedFilePath($request->file('attachment'), 'invoices'); @@ -527,6 +390,195 @@ class Invoices extends Controller return redirect('incomes/invoices'); } + /** + * Mark the invoice as sent. + * + * @param int $invoice_id + * + * @return Response + */ + public function markSent($invoice_id) + { + $invoice = Invoice::find($invoice_id); + $invoice->invoice_status_code = 'sent'; + $invoice->save(); + + flash(trans('invoices.messages.marked_sent'))->success(); + + return redirect()->back(); + } + + /** + * Mark the invoice as paid. + * + * @param int $invoice_id + * + * @return Response + */ + public function payInvoice($invoice_id) + { + $invoice = Invoice::find($invoice_id); + + $paid = 0; + foreach ($invoice->payments as $item) { + $item->default_currency_code = $invoice->currency_code; + + $paid += $item->getDynamicConvertedAmount(); + } + + $amount = $invoice->amount - $paid; + + $request = new PaymentRequest(); + + $request['company_id'] = $invoice->company_id; + $request['invoice_id'] = $invoice->id; + $request['account_id'] = setting('general.default_account'); + $request['payment_method'] = setting('general.default_payment_method'); + $request['currency_code'] = $invoice->currency_code; + $request['amount'] = $amount; + $request['paid_at'] = Date::now(); + $request['_token'] = csrf_token(); + + $this->payment($request); + + return redirect()->back(); + } + + /** + * Print the invoice. + * + * @param int $invoice_id + * + * @return Response + */ + public function printInvoice($invoice_id) + { + $paid = 0; + + $invoice = Invoice::find($invoice_id); + + foreach ($invoice->payments as $item) { + $item->default_currency_code = $invoice->currency_code; + + $paid += $item->getDynamicConvertedAmount(); + } + + $invoice->paid = $paid; + + $invoice->template_path = 'incomes.invoices.invoice'; + + event(new InvoicePrinting($invoice)); + + return view($invoice->template_path, compact('invoice')); + } + + /** + * Download the PDF file of invoice. + * + * @param int $invoice_id + * + * @return Response + */ + public function pdfInvoice($invoice_id) + { + $paid = 0; + + $invoice = Invoice::find($invoice_id); + + foreach ($invoice->payments as $item) { + $item->default_currency_code = $invoice->currency_code; + + $paid += $item->getDynamicConvertedAmount(); + } + + $invoice->paid = $paid; + + $invoice->template_path = 'incomes.invoices.invoice'; + + event(new InvoicePrinting($invoice)); + + $html = view($invoice->template_path, compact('invoice'))->render(); + + $pdf = \App::make('dompdf.wrapper'); + $pdf->loadHTML($html); + + $file_name = 'invoice_'.time().'.pdf'; + + return $pdf->download($file_name); + } + + /** + * Add payment to the invoice. + * + * @param PaymentRequest $request + * + * @return Response + */ + public function payment(PaymentRequest $request) + { + // Get currency object + $currency = Currency::where('code', $request['currency_code'])->first(); + + $request['currency_code'] = $currency->code; + $request['currency_rate'] = $currency->rate; + + // Upload attachment + $attachment_path = $this->getUploadedFilePath($request->file('attachment'), 'invoices'); + + if ($attachment_path) { + $request['attachment'] = $attachment_path; + } + + $invoice = Invoice::find($request['invoice_id']); + + if ($request['currency_code'] == $invoice->currency_code) { + if ($request['amount'] > $invoice->amount) { + $message = trans('messages.error.added', ['type' => trans_choice('general.payment', 1)]); + + return response()->json($message); + } elseif ($request['amount'] == $invoice->amount) { + $invoice->invoice_status_code = 'paid'; + } else { + $invoice->invoice_status_code = 'partial'; + } + } else { + $request_invoice = new Invoice(); + + $request_invoice->amount = (float) $request['amount']; + $request_invoice->currency_code = $currency->code; + $request_invoice->currency_rate = $currency->rate; + + $amount = $request_invoice->getConvertedAmount(); + + if ($amount > $invoice->amount) { + $message = trans('messages.error.added', ['type' => trans_choice('general.payment', 1)]); + + return response()->json($message); + } elseif ($amount == $invoice->amount) { + $invoice->invoice_status_code = 'paid'; + } else { + $invoice->invoice_status_code = 'partial'; + } + } + + $invoice->save(); + + $invoice_payment = InvoicePayment::create($request->input()); + + $request['status_code'] = $invoice->invoice_status_code; + $request['notify'] = 0; + + $desc_date = Date::parse($request['paid_at'])->format($this->getCompanyDateFormat()); + $desc_amount = money((float) $request['amount'], $request['currency_code'], true)->format(); + $request['description'] = $desc_date . ' ' . $desc_amount; + + InvoiceHistory::create($request->input()); + + $message = trans('messages.success.added', ['type' => trans_choice('general.revenues', 1)]); + + return response()->json($message); + } + /** * Remove the specified resource from storage. * diff --git a/app/Http/Controllers/Reports/ExpenseSummary.php b/app/Http/Controllers/Reports/ExpenseSummary.php index 4a94ea857..0b1b33129 100644 --- a/app/Http/Controllers/Reports/ExpenseSummary.php +++ b/app/Http/Controllers/Reports/ExpenseSummary.php @@ -70,23 +70,23 @@ class ExpenseSummary extends Controller // Bills switch ($status) { - case 'all': - $bills = Bill::getMonthsOfYear('billed_at'); - $this->setAmount($expenses_graph, $totals, $expenses, $bills, 'bill', 'billed_at'); + case 'paid': + $bills = BillPayment::monthsOfYear('paid_at')->get(); + $this->setAmount($expenses_graph, $totals, $expenses, $bills, 'bill', 'paid_at'); break; case 'upcoming': - $bills = Bill::getMonthsOfYear('due_at'); + $bills = Bill::accrued()->monthsOfYear('due_at')->get(); $this->setAmount($expenses_graph, $totals, $expenses, $bills, 'bill', 'due_at'); break; default: - $bills = BillPayment::getMonthsOfYear('paid_at'); - $this->setAmount($expenses_graph, $totals, $expenses, $bills, 'bill', 'paid_at'); + $bills = Bill::accrued()->monthsOfYear('billed_at')->get(); + $this->setAmount($expenses_graph, $totals, $expenses, $bills, 'bill', 'billed_at'); break; } // Payments if ($status != 'upcoming') { - $payments = Payment::getMonthsOfYear('paid_at'); + $payments = Payment::monthsOfYear('paid_at')->get(); $this->setAmount($expenses_graph, $totals, $expenses, $payments, 'payment', 'paid_at'); } diff --git a/app/Http/Controllers/Reports/IncomeExpenseSummary.php b/app/Http/Controllers/Reports/IncomeExpenseSummary.php index 83ed62eb4..291a6737d 100644 --- a/app/Http/Controllers/Reports/IncomeExpenseSummary.php +++ b/app/Http/Controllers/Reports/IncomeExpenseSummary.php @@ -98,45 +98,45 @@ class IncomeExpenseSummary extends Controller // Invoices switch ($status) { - case 'all': - $invoices = Invoice::getMonthsOfYear('invoiced_at'); - $this->setAmount($compares_graph, $totals, $compares, $invoices, 'invoice', 'invoiced_at'); + case 'paid': + $invoices = InvoicePayment::monthsOfYear('paid_at')->get(); + $this->setAmount($compares_graph, $totals, $compares, $invoices, 'invoice', 'paid_at'); break; case 'upcoming': - $invoices = Invoice::getMonthsOfYear('due_at'); + $invoices = Invoice::accrued()->monthsOfYear('due_at')->get(); $this->setAmount($compares_graph, $totals, $compares, $invoices, 'invoice', 'due_at'); break; default: - $invoices = InvoicePayment::getMonthsOfYear('paid_at'); - $this->setAmount($compares_graph, $totals, $compares, $invoices, 'invoice', 'paid_at'); + $invoices = Invoice::accrued()->monthsOfYear('invoiced_at')->get(); + $this->setAmount($compares_graph, $totals, $compares, $invoices, 'invoice', 'invoiced_at'); break; } // Revenues if ($status != 'upcoming') { - $revenues = Revenue::getMonthsOfYear('paid_at'); + $revenues = Revenue::monthsOfYear('paid_at')->get(); $this->setAmount($compares_graph, $totals, $compares, $revenues, 'revenue', 'paid_at'); } // Bills switch ($status) { - case 'all': - $bills = Bill::getMonthsOfYear('billed_at'); - $this->setAmount($compares_graph, $totals, $compares, $bills, 'bill', 'billed_at'); + case 'paid': + $bills = BillPayment::monthsOfYear('paid_at')->get(); + $this->setAmount($compares_graph, $totals, $compares, $bills, 'bill', 'paid_at'); break; case 'upcoming': - $bills = Bill::getMonthsOfYear('due_at'); + $bills = Bill::accrued()->monthsOfYear('due_at')->get(); $this->setAmount($compares_graph, $totals, $compares, $bills, 'bill', 'due_at'); break; default: - $bills = BillPayment::getMonthsOfYear('paid_at'); - $this->setAmount($compares_graph, $totals, $compares, $bills, 'bill', 'paid_at'); + $bills = Bill::accrued()->monthsOfYear('billed_at')->get(); + $this->setAmount($compares_graph, $totals, $compares, $bills, 'bill', 'billed_at'); break; } // Payments if ($status != 'upcoming') { - $payments = Payment::getMonthsOfYear('paid_at'); + $payments = Payment::monthsOfYear('paid_at')->get(); $this->setAmount($compares_graph, $totals, $compares, $payments, 'payment', 'paid_at'); } diff --git a/app/Http/Controllers/Reports/IncomeSummary.php b/app/Http/Controllers/Reports/IncomeSummary.php index d46377c96..6dad8537a 100644 --- a/app/Http/Controllers/Reports/IncomeSummary.php +++ b/app/Http/Controllers/Reports/IncomeSummary.php @@ -70,23 +70,23 @@ class IncomeSummary extends Controller // Invoices switch ($status) { - case 'all': - $invoices = Invoice::getMonthsOfYear('invoiced_at'); - $this->setAmount($incomes_graph, $totals, $incomes, $invoices, 'invoice', 'invoiced_at'); + case 'paid': + $invoices = InvoicePayment::monthsOfYear('paid_at')->get(); + $this->setAmount($incomes_graph, $totals, $incomes, $invoices, 'invoice', 'paid_at'); break; case 'upcoming': - $invoices = Invoice::getMonthsOfYear('due_at'); + $invoices = Invoice::accrued()->monthsOfYear('due_at')->get(); $this->setAmount($incomes_graph, $totals, $incomes, $invoices, 'invoice', 'due_at'); break; default: - $invoices = InvoicePayment::getMonthsOfYear('paid_at'); - $this->setAmount($incomes_graph, $totals, $incomes, $invoices, 'invoice', 'paid_at'); + $invoices = Invoice::accrued()->monthsOfYear('invoiced_at')->get(); + $this->setAmount($incomes_graph, $totals, $incomes, $invoices, 'invoice', 'invoiced_at'); break; } // Revenues if ($status != 'upcoming') { - $revenues = Revenue::getMonthsOfYear('paid_at'); + $revenues = Revenue::monthsOfYear('paid_at')->get(); $this->setAmount($incomes_graph, $totals, $incomes, $revenues, 'revenue', 'paid_at'); } diff --git a/app/Listeners/Updates/Version108.php b/app/Listeners/Updates/Version108.php index 4e4f47fea..bde164478 100644 --- a/app/Listeners/Updates/Version108.php +++ b/app/Listeners/Updates/Version108.php @@ -3,6 +3,9 @@ namespace App\Listeners\Updates; use App\Events\UpdateFinished; +use App\Models\Company\Company; +use App\Models\Expense\Bill; +use App\Models\Expense\BillStatus; class Version108 extends Listener { @@ -23,6 +26,13 @@ class Version108 extends Listener return; } + $this->updateSettings(); + $this->updateBills(); + } + + private function updateSettings() + { + // Set new invoice settings setting(['general.invoice_number_prefix' => setting('general.invoice_prefix', 'INV-')]); setting(['general.invoice_number_digit' => setting('general.invoice_digit', '5')]); setting(['general.invoice_number_next' => setting('general.invoice_start', '1')]); @@ -33,4 +43,48 @@ class Version108 extends Listener setting()->save(); } + + private function updateBills() + { + // Create new bill statuses + $companies = Company::all(); + + foreach ($companies as $company) { + $rows = [ + [ + 'company_id' => $company->id, + 'name' => trans('bills.status.draft'), + 'code' => 'draft', + ], + [ + 'company_id' => $company->id, + 'name' => trans('bills.status.received'), + 'code' => 'received', + ], + ]; + + foreach ($rows as $row) { + BillStatus::create($row); + } + } + + $bills = Bill::all(); + + foreach ($bills as $bill) { + if (($bill->bill_status_code != 'new') || ($bill->bill_status_code != 'updated')) { + continue; + } + + $bill->bill_status_code = 'draft'; + $bill->save(); + } + + $new = BillStatus::where('code', 'new'); + $new->delete(); + $new->forceDelete(); + + $updated = BillStatus::where('code', 'updated'); + $updated->delete(); + $updated->forceDelete(); + } } diff --git a/app/Models/Expense/Bill.php b/app/Models/Expense/Bill.php index 4d5bb1603..ea726b525 100644 --- a/app/Models/Expense/Bill.php +++ b/app/Models/Expense/Bill.php @@ -79,6 +79,21 @@ class Bill extends Model return $this->hasMany('App\Models\Expense\BillHistory'); } + public function scopeDue($query, $date) + { + return $query->where('due_at', '=', $date); + } + + public function scopeLatest($query) + { + return $query->orderBy('paid_at', 'desc'); + } + + public function scopeAccrued($query) + { + return $query->where('bill_status_code', '!=', 'new'); + } + /** * Convert amount to double. * @@ -100,9 +115,4 @@ class Bill extends Model { $this->attributes['currency_rate'] = (double) $value; } - - public function scopeDue($query, $date) - { - return $query->where('due_at', '=', $date); - } } diff --git a/app/Models/Income/Invoice.php b/app/Models/Income/Invoice.php index 425e3d0c5..28765ce0b 100644 --- a/app/Models/Income/Invoice.php +++ b/app/Models/Income/Invoice.php @@ -84,6 +84,21 @@ class Invoice extends Model return $this->hasMany('App\Models\Income\InvoiceHistory'); } + public function scopeDue($query, $date) + { + return $query->where('due_at', '=', $date); + } + + public function scopeLatest($query) + { + return $query->orderBy('paid_at', 'desc'); + } + + public function scopeAccrued($query) + { + return $query->where('invoice_status_code', '!=', 'draft'); + } + /** * Convert amount to double. * @@ -105,9 +120,4 @@ class Invoice extends Model { $this->attributes['currency_rate'] = (double) $value; } - - public function scopeDue($query, $date) - { - return $query->where('due_at', '=', $date); - } } diff --git a/app/Traits/DateTime.php b/app/Traits/DateTime.php index a22716b5c..974fffeef 100644 --- a/app/Traits/DateTime.php +++ b/app/Traits/DateTime.php @@ -23,7 +23,7 @@ trait DateTime return str_replace(' ', $date_separator, $date_format); } - public static function getMonthsOfYear($field) + public function scopeMonthsOfYear($query, $field) { $year = request('year'); @@ -35,7 +35,7 @@ trait DateTime $start = Date::parse($year . '-01-01')->format('Y-m-d'); $end = Date::parse($year . '-12-31')->format('Y-m-d'); - return static::whereBetween($field, [$start, $end])->get(); + return $query->whereBetween($field, [$start, $end]); } public function getTimezones() diff --git a/database/seeds/BillStatuses.php b/database/seeds/BillStatuses.php index 7d7580aa7..bbd92950b 100644 --- a/database/seeds/BillStatuses.php +++ b/database/seeds/BillStatuses.php @@ -30,13 +30,13 @@ class BillStatuses extends Seeder $rows = [ [ 'company_id' => $company_id, - 'name' => trans('bills.status.new'), - 'code' => 'new', + 'name' => trans('bills.status.draft'), + 'code' => 'draft', ], [ 'company_id' => $company_id, - 'name' => trans('bills.status.updated'), - 'code' => 'updated', + 'name' => trans('bills.status.received'), + 'code' => 'received', ], [ 'company_id' => $company_id, diff --git a/resources/lang/en-GB/bills.php b/resources/lang/en-GB/bills.php index 7a2ffca89..407cfc8e5 100644 --- a/resources/lang/en-GB/bills.php +++ b/resources/lang/en-GB/bills.php @@ -23,14 +23,19 @@ return [ 'histories' => 'Histories', 'payments' => 'Payments', 'add_payment' => 'Add Payment', + 'mark_received' => 'Mark Received', 'download_pdf' => 'Download PDF', 'send_mail' => 'Send Email', 'status' => [ - 'new' => 'New', - 'updated' => 'Updated', + 'draft' => 'Draft', + 'received' => 'Received', 'partial' => 'Partial', 'paid' => 'Paid', ], + 'messages' => [ + 'received' => 'Bill marked as received successfully!', + ], + ]; diff --git a/resources/lang/en-GB/general.php b/resources/lang/en-GB/general.php index 7e37296b5..0e1a74067 100644 --- a/resources/lang/en-GB/general.php +++ b/resources/lang/en-GB/general.php @@ -91,6 +91,7 @@ return [ 'upcoming' => 'Upcoming', 'created' => 'Created', 'id' => 'ID', + 'more_actions' => 'More Actions', 'title' => [ 'new' => 'New :type', diff --git a/resources/lang/en-GB/invoices.php b/resources/lang/en-GB/invoices.php index 790fe22c0..b1f0f7a55 100644 --- a/resources/lang/en-GB/invoices.php +++ b/resources/lang/en-GB/invoices.php @@ -22,6 +22,8 @@ return [ 'histories' => 'Histories', 'payments' => 'Payments', 'add_payment' => 'Add Payment', + 'mark_paid' => 'Mark Paid', + 'mark_sent' => 'Mark Sent', 'download_pdf' => 'Download PDF', 'send_mail' => 'Send Email', @@ -34,4 +36,8 @@ return [ 'paid' => 'Paid', ], + 'messages' => [ + 'marked_sent' => 'Invoice marked as sent successfully!', + ], + ]; diff --git a/resources/views/expenses/bills/index.blade.php b/resources/views/expenses/bills/index.blade.php index 9f49639f3..10d0df512 100644 --- a/resources/views/expenses/bills/index.blade.php +++ b/resources/views/expenses/bills/index.blade.php @@ -17,7 +17,7 @@ {!! Form::text('search', request('search'), ['class' => 'form-control input-filter input-sm', 'placeholder' => trans('general.search_placeholder')]) !!} {!! Form::select('vendor', $vendors, request('vendor'), ['class' => 'form-control input-filter input-sm']) !!} - {!! Form::select('status', $status, request('status'), ['class' => 'form-control input-filter input-sm']) !!} + {!! Form::select('status', $statuses, request('status'), ['class' => 'form-control input-filter input-sm']) !!} {!! Form::button('  ' . trans('general.filter'), ['type' => 'submit', 'class' => 'btn btn-sm btn-default btn-filter']) !!}
diff --git a/resources/views/expenses/bills/show.blade.php b/resources/views/expenses/bills/show.blade.php index 8d2d51484..d744f571f 100644 --- a/resources/views/expenses/bills/show.blade.php +++ b/resources/views/expenses/bills/show.blade.php @@ -150,12 +150,21 @@   {{ trans('general.print') }} - - +
+ + +
diff --git a/resources/views/incomes/invoices/show.blade.php b/resources/views/incomes/invoices/show.blade.php index ff558f823..8525818cf 100644 --- a/resources/views/incomes/invoices/show.blade.php +++ b/resources/views/incomes/invoices/show.blade.php @@ -150,15 +150,26 @@   {{ trans('general.print') }} - - - +
+ + +
diff --git a/resources/views/reports/expense_summary/index.blade.php b/resources/views/reports/expense_summary/index.blade.php index 4705ee773..3de9eb97b 100644 --- a/resources/views/reports/expense_summary/index.blade.php +++ b/resources/views/reports/expense_summary/index.blade.php @@ -7,8 +7,8 @@
{!! Form::open(['url' => 'reports/expense-summary', 'role' => 'form', 'method' => 'GET']) !!} diff --git a/resources/views/reports/income_expense_summary/index.blade.php b/resources/views/reports/income_expense_summary/index.blade.php index 990566461..e644febef 100644 --- a/resources/views/reports/income_expense_summary/index.blade.php +++ b/resources/views/reports/income_expense_summary/index.blade.php @@ -7,8 +7,8 @@
{!! Form::open(['url' => 'reports/income-expense-summary', 'role' => 'form', 'method' => 'GET']) !!} diff --git a/resources/views/reports/income_summary/index.blade.php b/resources/views/reports/income_summary/index.blade.php index b75f269b7..7569c7dd9 100644 --- a/resources/views/reports/income_summary/index.blade.php +++ b/resources/views/reports/income_summary/index.blade.php @@ -7,8 +7,8 @@
{!! Form::open(['url' => 'reports/income-summary', 'role' => 'form', 'method' => 'GET']) !!} diff --git a/routes/web.php b/routes/web.php index c35523e72..3491b1fb0 100644 --- a/routes/web.php +++ b/routes/web.php @@ -44,6 +44,8 @@ Route::group(['middleware' => 'language'], function () { Route::group(['prefix' => 'incomes'], function () { Route::get('customers/currency', 'Incomes\Customers@currency'); Route::resource('customers', 'Incomes\Customers'); + Route::get('invoices/{id}/sent', 'Incomes\Invoices@markSent'); + Route::get('invoices/{id}/pay', 'Incomes\Invoices@payInvoice'); Route::get('invoices/{id}/print', 'Incomes\Invoices@printInvoice'); Route::get('invoices/{id}/pdf', 'Incomes\Invoices@pdfInvoice'); Route::post('invoices/payment', 'Incomes\Invoices@payment'); @@ -54,6 +56,7 @@ Route::group(['middleware' => 'language'], function () { Route::group(['prefix' => 'expenses'], function () { Route::resource('payments', 'Expenses\Payments'); + Route::get('bills/{id}/received', 'Expenses\Bills@markReceived'); Route::get('bills/{id}/print', 'Expenses\Bills@printBill'); Route::get('bills/{id}/pdf', 'Expenses\Bills@pdfBill'); Route::post('bills/payment', 'Expenses\Bills@payment');