<?php

namespace App\Http\Controllers\Accounts\Incomes;

use File;
use Image;
use App\Traits\Incomes;
use App\Traits\Uploads;
use App\Traits\DateTime;
use App\Traits\Currencies;
use App\Utilities\Modules;
use Illuminate\Support\Str;
use App\Classes\DepositType;
use Illuminate\Http\Request;
use App\Events\InvoiceCreated;
use App\Events\InvoiceUpdated;
use App\Events\InvoicePrinting;
use App\Models\Accounts\Item\Item;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Mail;
use App\Models\Accounts\Charthistory;
use App\Models\Accounts\Common\Media;
use App\Models\Accounts\Income\Terms;
use App\Models\Accounts\Income\Invoice;
use Illuminate\Support\Facades\Session;
use App\Models\Accounts\Banking\Account;
use App\Models\Accounts\Income\Customer;
use App\Models\Accounts\Setting\Category;
use App\Models\Accounts\Setting\Currency;
use App\Models\Timesheets\TimesheetWeekly;
use App\Models\Accounts\CharthistoryParent;
use App\Models\Accounts\Income\InvoiceItem;
use App\Models\Accounts\Income\InvoiceTotal;
use App\Models\Accounts\Income\InvoiceStatus;
use App\Models\Accounts\Income\InvoiceHistory;
use App\Models\Accounts\Income\InvoicePayment;
use App\Models\Accounts\Income\CreditMemoModel;
use App\Models\Accounts\Income\InvoiceDiscount;
use App\Models\Accounts\Income\InvoiceCustomers;
use App\Models\Accounts\Income\InvoiceTimesheet;
use App\Models\Accounts\Accounting\Chartofaccounts;
use App\Http\Requests\Income\InvoicePayment as PaymentRequest;
use App\Notifications\Income\Invoice as Notification;
use App\Notifications\Item\Item as ItemNotification;

class InvoiceController extends Controller
{
    use DateTime, Currencies, Incomes, Uploads;
    
    public function index(Invoice $invoice)
    {        
        $date = new \DateTime();
        $overdue_date = $date->format('Y-m-d H:i:s');
        $date->modify('-30 Days');
        $formatted_date = $date->format('Y-m-d H:i:s');

        $invoices = Invoice::with(['customer', 'status', 'items', 'payments', 'histories','payments_total'])->orderBy('created_at','desc')->get(); 

        if(request('page')){ 
            return view('accounts.incomes.invoices.ajaxrender',compact('invoices'));
        };
  
        $status = collect(InvoiceStatus::all()->pluck('name', 'code'))
            ->prepend(trans('general.all_type', ['type' => trans_choice('general.statuses', 2)]), '');
            $paid = 0;

        // For Graphs

        $unpaid_amount=Invoice::where('invoice_status_code','=','draft')->sum('amount');

        $overdue_amount=Invoice::whereIn('invoice_status_code',['draft','partial'])->where('due_at','<=',$overdue_date)->sum('amount');

        $paid_amount = Invoice::sum('amount');

        $invoice_amount = $paid_amount;


        $payments_amount = InvoicePayment::sum('amount');
        if($paid_amount > $payments_amount){

        $paid_notdeposited = $paid_amount - $payments_amount;
        }else{
            $paid_notdeposited = $payments_amount-$paid_amount;
        }

        foreach ($invoice->payments as $item) {
            $item->default_currency_code = $invoice->currency_code;

            $paid += $item->getDynamicConvertedAmount();
        }

        $invoice->paid = $paid;
        
        return view('accounts.incomes.invoices.index', compact('invoices', 'status', 'invoice','unpaid_amount','paid_amount','payments_amount','overdue_amount','paid_notdeposited','invoice_amount'));
    }

    public function create($id='')
    {     
        $elements = Customer::select('name', 'id','parent_id')->get()->toArray();

        $customers = app('App\Http\Controllers\Accounts\Incomes\CustomerController')->bulidCustomer($elements);

        $currencies = Currency::pluck('name', 'code');

        $elements = Item::whereEnabled(1)->select('id','name','subitem')->get()->toArray();

        $items  = $this->bulidItems($elements);

        $terms = Terms::pluck('name','id');

        $number = $this->getNextInvoiceNumber();

        $customer_id = isset($id)?$id:0;

        return view('accounts.incomes.invoices.create',compact('customers', 'currencies', 'items', 'number','terms','customer_id'));
    }

    function bulidItems(array $elements, $parentId = NULL) {
        $child = array();
    
        foreach ($elements as $element) {
            if ($element['subitem'] == $parentId) {

                $children = $this->bulidItems($elements, $element['id']);

                    if (!empty($children) > 0 ) {
                        $element['children'] = $children;
                    }

                $child[] = $element;
            }
        }
        return $child;
    }

    public function store(Request $request)
    {
        // dd($request->all());
        // Update next invoice number
        // $this->increaseNextInvoiceNumber();
        
        // Get customer object
        $customer = Customer::find($request['customer_id']);
        $customer_parent = app('App\Http\Controllers\Accounts\Incomes\Customers')->parent_customer_id($customer->id);
        $customer_parent_list = explode(',', $customer_parent->original['parent_id_string']); 

        $request['customer_name_with_parent'] = $customer_parent->original['full_name'];
        $request['customer_name'] = $customer->name;
        $request['customer_email'] = $customer->customer_email;
        $request['customer_tax_number'] = $customer->tax_number;
        $request['customer_phone'] = $customer->phone;
        $request['customer_address'] = $customer->address; 

        
        $date = $this->date_format_change_unique($request->invoiced_at, $request->due_at);
        $request['invoiced_at'] = date("Y-m-d", strtotime($date[0]));
        $request['due_at'] =  date("Y-m-d", strtotime($date[1]));

        // Get currency object
        $currency = Currency::where('code', 'USD')->first();

        $request['currency_code'] = $currency->code;
        $request['currency_rate'] = $currency->rate;

        $request['invoice_status_code'] = 'draft';

        $request['amount'] = 0;

        $invoice = Invoice::create($request->input());

        /* For Multi Customers List Save */
        foreach ($customer_parent_list as $key => $parent_list) {
            if($parent_list){
                $invoice_customer['company_id'] = session('company_id');
                $invoice_customer['invoice_id'] = $invoice->id;
                $invoice_customer['customer_id'] = $parent_list;
                InvoiceCustomers::create($invoice_customer); 
            }
        }

        $invoice_customer['company_id'] = session('company_id');
        $invoice_customer['invoice_id'] = $invoice->id;
        $invoice_customer['customer_id'] = $request['customer_id'];

        InvoiceCustomers::create($invoice_customer);
        // Upload attachment
        if ($request->file('attachment')) {
            $media = $this->getMedia($request->file('attachment'), 'invoices');

            $invoice->attachMedia($media, 'attachment');
        }

        $sub_total = 0;

        $invoice_item = [];
        $invoice_item['company_id'] = session('company_id');
        $invoice_item['invoice_id'] = $invoice->id;
        
        //Set Chart History.
        $chart_history = [];
        $chart_history['company_id'] = session('company_id');
        $chart_history['transaction_id'] = $invoice->id;
        $chart_history['transaction_type'] = 'Invoice';
        $chart_history['number'] = $invoice->invoice_number;
        $chart_history['currency_code'] = $currency->code;
        $chart_history['name'] = $customer->name;
        $chart_history['transaction_date'] = date("Y-m-d", strtotime($date[0]));

        if ($request['item']) {
            foreach ($request['item'] as $item) {
                $item_sku = '';
                if (!empty($item['item_id'])) {
                    $item_object = Item::find($item['item_id']);
                    $chart_object = Chartofaccounts::find($item['chartid']);
                }

                $invoice_item['item_id'] = $item['item_id'];
                $invoice_item['company_id'] = session('company_id');
                $invoice_item['name'] = Str::limit($item['name'], 180, '');
                $invoice_item['sku'] = $item_sku;
                $invoice_item['quantity'] = $item['quantity'];
                $invoice_item['description'] = isset($item['description'])?$item['description']:Str::limit($item['name'], 180, '');
                $invoice_item['price'] = $item['price'];
                $invoice_item['chartid'] = $item['chartid'];
                $invoice_item['total'] = $item['price'] * $item['quantity'];

                InvoiceItem::create($invoice_item);

                // Set Chart History.
                $chart_history['amount_type'] = DepositType::find($item['chartid'],'credit');
                $chart_history['chartofaccount_id'] = $item['chartid'];
                $chart_history['account_type_id'] = $chart_object['account_type_id'];
                $chart_history['detail_type'] = $chart_object['detail_type'];
                $chart_history['amount'] = $item['price'] * $item['quantity'];
                $chart_history['description'] = $invoice_item['description'] = isset($item['description'])?$item['description']:Str::limit($item['name'], 180, '');

                $chart_history_id = Charthistory::create($chart_history);

                $chartparents = app('App\Http\Controllers\Accounts\Accounting\Accounting')->parent_chartaccount_id($item['chartid']);

                CharthistoryParent::charthistoryparentsave($chart_history_id->id,$chartparents->original['parent_id_string'],$item['chartid']);

                // Calculate totals
                $sub_total += $invoice_item['total'];
            }
        }

        $request['amount'] = $sub_total;

        //History For Account Receiveble
        $chart =  Chartofaccounts::where('name','=','Accounts Receivable')->first();
        $chart_receivable = [];
        $chart_receivable['company_id'] = session('company_id');
        $chart_receivable['transaction_id'] = $invoice->id;
        $chart_receivable['transaction_type'] = 'Invoice';
        $chart_receivable['number'] = $invoice->invoice_number;
        $chart_receivable['currency_code'] = $currency->code;
        $chart_receivable['name'] = $customer->name;
        $chart_receivable['amount_type'] =  DepositType::find($item['chartid'],'debit');
        $chart_receivable['chartofaccount_id'] = $chart->id;
        $chart_receivable['account_type_id'] = $chart->account_type_id;
        $chart_receivable['detail_type'] = $chart->detail_type;
        $chart_receivable['amount'] = $sub_total;
        $chart_receivable['description'] = $request->notes;
        $chart_receivable['transaction_date'] = date("Y-m-d", strtotime($date[0]));

        $chart_receivable_id = Charthistory::create($chart_receivable);


        $chartparents = app('App\Http\Controllers\Accounts\Accounting\Accounting')->parent_chartaccount_id($chart->id);

        CharthistoryParent::charthistoryparentsave($chart_receivable_id->id,$chartparents->original['parent_id_string'],$chart->id);



        $invoice->update($request->input());

        // Add invoice totals
        $this->addTotals($invoice, $request, $sub_total);

        // Add invoice history
        InvoiceHistory::create([
            'company_id' => session('company_id'),
            'invoice_id' => $invoice->id,
            'status_code' => 'draft',
            'notify' => 0,
            'description' => trans('messages.success.added', ['type' => $invoice->invoice_number]),
        ]);


        /* Check Time Sheet Data and approved Hours*/

        if($request->approved_days_array){
            
            foreach($request->approved_days_array as $days){
                $day = explode("," ,$days);
                foreach($day as $key => $value){
                    $timesheet = explode("_",$value);
                // echo count($timesheet);
                    if(count($timesheet) > 1){
                        if(count($timesheet) == 2){ 
                        TimesheetWeekly::where('id',$timesheet[1])->update(["approved_days->$timesheet[0]"=>'approved']);
                            $invoice_timesheet = new InvoiceTimesheet();
                            $invoice_timesheet->invoice_id = $invoice->id;
                            $invoice_timesheet->timesheet_id = $timesheet[1];
                            $invoice_timesheet->day = $timesheet[0].'_WH';
                            $invoice_timesheet->company_id = session('company_id');
                            $invoice_timesheet->save();
                        }else{
                        TimesheetWeekly::where('id',$timesheet[2])->update(["approved_daysot->$timesheet[0]".'ot'=>'approved']);
                            $invoice_timesheet = new InvoiceTimesheet();
                            $invoice_timesheet->invoice_id = $invoice->id;
                            $invoice_timesheet->timesheet_id = $timesheet[2];
                            $invoice_timesheet->day = $timesheet[0].'_OT';
                            $invoice_timesheet->company_id = session('company_id');
                            $invoice_timesheet->save();
                        }
                    }
                }
            }
        }
        
        // Fire the event to make it extendible
        event(new InvoiceCreated($invoice));

        // Check For Credit Memo Balanse Is Any.

        $credit_memo_values = CreditMemoModel::where('customer_id',$request['customer_id'])->where('remaining_balance', '!=', '0')->get();

        if($credit_memo_values){
            $invoice_amount = $request['amount']; 
            foreach ($credit_memo_values as $key => $value) {
                $amount = $value->total;
                if($invoice_amount != 0){
                    $amount =  $value->remaining_balance;
                    if ($amount >= $invoice_amount) {
                        $invoice->invoice_status_code = 'paid';
                        $paid_amount = $invoice_amount;
                        $amount = $amount - $invoice_amount;
                        $invoice_amount = '0';
                    } else if($amount <= $invoice_amount){
                        $invoice->invoice_status_code = 'partial';
                        $paid_amount = $amount;
                        $amount = '0';
                        $invoice_amount = $invoice_amount - $amount;
                    }else {
                        $invoice->invoice_status_code = 'partial';
                        $paid_amount = $invoice_amount;
                        $amount  = '0';
                        $invoice_amount = '0';
                    }
                    $invoice->save();

                    $invoice_payment = new InvoicePayment;
                    $invoice_payment->paid_at = $request['invoiced_at'];
                    $invoice_payment->customer_id = $request['customer_id'];
                    $invoice_payment->company_id = $invoice->company_id;
                    $invoice_payment->currency_code = 'USD';
                    $invoice_payment->amount = $paid_amount;
                    $invoice_payment->invoice_id = $invoice->id;
                    $invoice_payment->save();

                    $invoice_history = new InvoiceHistory;
                    $invoice_history->company_id = session('company_id');
                    $invoice_history->invoice_id = $invoice->id;
                    $invoice_history->status_code = $invoice->invoice_status_code;
                    $invoice_history->notify = '0';
                    $invoice_history->description = '$' .$sub_total .' Credit Memo';
                    $invoice_history->save();
                    
                    $credit_memo = CreditMemoModel::find($value->id);

                    if($amount!= '0'){
                    $credit_memo->status = 'uncleared';
                    $credit_memo->remaining_balance = $amount;
                    }else{
                        $credit_memo->status = 'closed';
                        $credit_memo->remaining_balance = '0';
                    }
                    $credit_memo->update();

                    //History For Account Receiveble
                    $chart =  Chartofaccounts::where('name','=','Accounts Receivable')->first();
                    $chart_history = [];
                    $chart_history['company_id'] = session('company_id');
                    $chart_history['transaction_id'] = $credit_memo->id;
                    $chart_history['transaction_type'] = 'Credit Memo';
                    $chart_history['currency_code'] = 'USD';
                    $chart_history['amount_type'] = 'sub';
                    $chart_history['name'] = $invoice->customer_name_with_parent;
                    $chart_history['number'] = $invoice->invoice_number;
                    $chart_history['chartofaccount_id'] = $chart->id;
                    $chart_history['account_type_id'] = $chart->account_type_id;
                    $chart_history['detail_type'] = $chart->detail_type;
                    $chart_history['amount'] = $paid_amount;
                    $chart_history['description'] = 'Credit Memo';

                    $chart_receivable_id = Charthistory::create($chart_history);

                    $chartparents = app('App\Http\Controllers\Accounts\Accounting\Accounting')->parent_chartaccount_id($chart->id);

                    CharthistoryParent::charthistoryparentsave($chart_receivable_id->id,$chartparents->original['parent_id_string'],$chart->id);
                }
            }
        }

        $message = trans('messages.success.added', ['type' => trans_choice('general.invoices', 1)]);

        Session::flash('success',$message);

        return redirect('incomes/invoices/' . $invoice->id);
    }   

    protected function addTotals($invoice, $request, $sub_total)
    {
        $sort_order = 1;

        // Added invoice total sub total
        InvoiceTotal::create([
            'company_id' => session('company_id'),
            'invoice_id' => $invoice->id,
            'code' => 'sub_total',
            'name' => 'invoices.sub_total',
            'amount' => $sub_total,
            'sort_order' => $sort_order,
        ]);

        $sort_order++;


        // Added invoice total total
        InvoiceTotal::create([
            'company_id' => session('company_id'),
            'invoice_id' => $invoice->id,
            'code' => 'total',
            'name' => 'invoices.total',
            'amount' => $sub_total,
            'sort_order' => $sort_order,
        ]);
    }

    public function show(Invoice $invoice)
    {
        $paid = 0;

        foreach ($invoice->payments as $item) {
            $item->default_currency_code = $invoice->currency_code;

            $paid += $item->getDynamicConvertedAmount();
        }

        $invoice->paid = $paid;

        $accounts = Account::whereEnabled(1)->get()->pluck('name_number', 'id');

        $currencies = Currency::whereEnabled(1)->pluck('name', 'code')->toArray();

        $account_currency_code = Account::where('id', setting('general.default_account'))->pluck('currency_code')->first();

        $customers = Customer::whereEnabled(1)->pluck('name', 'id');

        $categories = Category::whereEnabled(1)->type('income')->pluck('name', 'id');

        $payment_methods = Modules::getPaymentMethods();

        return view('accounts.incomes.invoices.show', compact('invoice', 'accounts', 'currencies', 'account_currency_code', 'customers', 'categories', 'payment_methods'));
    }

    public function receivepayment(Request $request, $id, $invoice_id)
    {
        $customer = Customer::find($id);
        $customer_parent = app('App\Http\Controllers\Accounts\Incomes\Customers')->parent_customer_id($customer->id);

        $payment_methods = Modules::getPaymentMethods();

        $accounts = Account::whereEnabled(1)->get()->pluck('name_number', 'id');
        $invoice = Invoice::find($invoice_id);

        $payments_lists = Invoice::with('status','payments_total','payments','histories')->where('customer_id',$id)->where('invoice_status_code' ,'!=','paid')->orderBy('due_at','asc')->get();
        
        return view('accounts.incomes.invoices.payment',compact('customer','payment_methods','accounts','payments_lists','invoice','customer_parent','invoice_id'));
    }

    public function customerpayment(PaymentRequest $request)
    {        
        // dd($request->all());
        // Get currency object
        $currency = Currency::where('code', $request['currency_code'])->first();

        $request['currency_code'] = $currency->code;
        $request['currency_rate'] = $currency->rate;
        $date = $this->date_format_change_unique($request->paid_at);
        $request['paid_at'] =  date("Y-m-d", strtotime($date[0]));  

        //Set Chart History.
        $chart_object = Chartofaccounts::find($request->account_chart_id);
        $chart_history = [];
        $chart_history['company_id'] =  session('company_id');
        $chart_history['chartofaccount_id'] = $request->account_chart_id;
        $chart_history['transaction_type'] = 'Invoice (Payment)';
        $chart_history['currency_code'] = $currency->code;
        $chart_history['account_type_id'] = $chart_object['account_type_id'];
        $chart_history['detail_type'] = $chart_object['detail_type'];
        $chart_history['transaction_date'] = date("Y-m-d", strtotime($date[0]));        
 
        foreach ($request['invoice_id'] as $key => $value) {
            if($request['amount'][$key] != 0){
                $invoice = Invoice::find($value);  
                $request['customer_id'] = $invoice->customer_id;  
                $discounted = 0;
                if($invoice->discounts()->count()){
                    $discounted += $invoice->discounts()->paid();;
                }
                $total_amount = $invoice->amount + $discounted;

                $request_amount = (double) $request['amount'][$key];
                $discount = (double) $request['discount'][$key];

                $amount = $request_amount + $discount;
                $bank_amount = $request_amount;

                if ($invoice->discounts()->count()) {
                    $total_amount -= $invoice->discounts()->paid();
                }
               
                if ($invoice->payments()->count()) {
                    $total_amount -= $invoice->payments()->paid();
                } 

                 
                if ($amount > $total_amount) {
                $message = trans('messages.error.over_payment');
                 
                Session::flash('error',$message);
                return redirect()->back();
                } elseif ($amount == $total_amount) {
                    $invoice->invoice_status_code = 'paid';
                } else {
                    $invoice->invoice_status_code = 'partial';
                }
                $invoice->save();
                if($request['discount'][$key] != 0){
                    $discount = new InvoiceDiscount;
                    $discount->invoice_id = $invoice->id;
                    $discount->account = $request['discount_account'][$key];
                    $discount->amount = $request['discount'][$key];
                    $discount->save();

                    $cchart =  Chartofaccounts::where('name','=','Accounts Receivable')->first();
                    $chart_recvble = [];
                    $chart_recvble['company_id'] = session('company_id');
                    $chart_recvble['transaction_id'] = $discount->id;
                    $chart_recvble['transaction_type'] = 'Invoice (Discount)';
                    $chart_recvble['number'] = $invoice->invoice_number;
                    $chart_recvble['currency_code'] = 'USD';
                    $chart_recvble['name'] = $invoice->customer_name;
                    $chart_recvble['amount_type'] = DepositType::find($cchart->id,'credit');
                    $chart_recvble['chartofaccount_id'] = $cchart->id;
                    $chart_recvble['account_type_id'] = $cchart->account_type_id;
                    $chart_recvble['detail_type'] = $cchart->detail_type;
                    $chart_recvble['amount'] = $request['discount'][$key];
                    $chart_recvble['description'] = $request['notes'];

                    $chart_receivable_id = Charthistory::create($chart_recvble);

                    $chartparents = app('App\Http\Controllers\Accounts\Accounting\Accounting')->parent_chartaccount_id($cchart->id);

                    CharthistoryParent::charthistoryparentsave($chart_receivable_id->id,$chartparents->original['parent_id_string'],$cchart->id);
                
                    // Set Chart History.
                    $chtobj = Chartofaccounts::find($request['discount_account'][$key]);
                    $chthist = [];
                    $chthist['company_id'] =  session('company_id');
                    $chthist['chartofaccount_id'] = $request['discount_account'][$key];
                    $chthist['transaction_type'] = 'Invoice (Discount)';
                    $chthist['currency_code'] = $currency->code;
                    $chthist['account_type_id'] = $chtobj['account_type_id'];
                    $chthist['detail_type'] = $chtobj['detail_type'];
                    $chthist['amount_type'] = DepositType::find($request['discount_account'][$key],'debit');
                    $chthist['transaction_id'] = $discount->id;
                    $chthist['name'] = $invoice->customer_name;
                    $chthist['number'] = $invoice->invoice_number;
                    $chthist['amount'] = $request['discount'][$key];
                    $chthist['description'] = '';
                    $chthist['transaction_date'] = date("Y-m-d", strtotime($date[0]));

                    $chthist = Charthistory::create($chthist);

                    $chartparents = app('App\Http\Controllers\Accounts\Accounting\Accounting')->parent_chartaccount_id($request['discount_account'][$key]);

                    CharthistoryParent::charthistoryparentsave($chthist->id,$chartparents->original['parent_id_string'],$request['discount_account'][$key]);                   
                }

                $invoice_payment = new InvoicePayment;
                $invoice_payment->paid_at = $request->paid_at;
                $invoice_payment->customer_id = $request['customer_id'];
                $invoice_payment->company_id = $invoice->company_id;
                $invoice_payment->payment_method = $request->payment_method;
                $invoice_payment->account_id = $request->account_id;
                $invoice_payment->currency_code = $request->currency_code;
                $invoice_payment->amount = $request_amount;
                $invoice_payment->invoice_id = $value;
                $invoice_payment->currency_rate = $request['currency_rate'];
                $invoice_payment->description = $request['notes'];
                $invoice_payment->reference = $request['reference'];
                $invoice_payment->save();
                
                // Set Chart History.
                $chart_history['amount_type'] = DepositType::find($request->account_chart_id,'debit');
                $chart_history['transaction_id'] = $invoice_payment->id;
                $chart_history['name'] = $invoice->customer_name;
                $chart_history['number'] = $invoice->invoice_number;
                $chart_history['amount'] = $bank_amount;
                $chart_history['description'] = $request->notes;
                $chart_history['transaction_date'] = date("Y-m-d", strtotime($date[0]));

                $chart_history_id = Charthistory::create($chart_history);

                $chartparents = app('App\Http\Controllers\Accounts\Accounting\Accounting')->parent_chartaccount_id($request->account_chart_id);

                CharthistoryParent::charthistoryparentsave($chart_history_id->id,$chartparents->original['parent_id_string'],$request->account_chart_id);

                //Histort For Account Receiveble
                $chart =  Chartofaccounts::where('name','=','Accounts Receivable')->first();
                $chart_receivable = [];
                $chart_receivable['company_id'] = session('company_id');
                $chart_receivable['transaction_id'] = $invoice_payment->id;
                $chart_receivable['transaction_type'] = 'Invoice (Payment)';
                $chart_receivable['number'] = $invoice->invoice_number;
                $chart_receivable['currency_code'] = $currency->code;
                $chart_receivable['name'] = $invoice->customer_name;
                $chart_receivable['amount_type'] = DepositType::find($chart->id,'credit');
                $chart_receivable['chartofaccount_id'] = $chart->id;
                $chart_receivable['account_type_id'] = $chart->account_type_id;
                $chart_receivable['detail_type'] = $chart->detail_type;
                $chart_receivable['amount'] = $request_amount;
                $chart_receivable['description'] = $request->notes;
                $chart_receivable['transaction_date'] = date("Y-m-d", strtotime($date[0]));

                $chart_receivable_id = Charthistory::create($chart_receivable);

                $chartparents = app('App\Http\Controllers\Accounts\Accounting\Accounting')->parent_chartaccount_id($chart->id);

                CharthistoryParent::charthistoryparentsave($chart_receivable_id->id,$chartparents->original['parent_id_string'],$chart->id);

                // Upload attachment
                if ($request->file('attachment')) {
                    $media = $this->getMedia($request->file('attachment'), 'invoices');

                    $invoice_payment->attachMedia($media, 'attachment');
                }

                $request['status_code'] = $invoice->invoice_status_code;
                $request['notify'] = 0;

                $desc_amount = money((float) $amount, (string) $request['currency_code'], true)->format();

                $request['description'] = $desc_amount . ' ' . trans_choice('general.payments', 1);
                $request['invoice_id'] = $value;
                
                $invoice_history = new InvoiceHistory;
                $invoice_history->company_id = session('company_id');
                $invoice_history->invoice_id = $value;
                $invoice_history->status_code = $request['status_code'];
                $invoice_history->notify = $request['notify'];
                $invoice_history->description = $request['description'];
                $invoice_history->save();

             $message = trans('messages.success.added', ['type' => trans_choice('general.payments', 1)]);
            }
        } 
        Session::flash('success',$message);
        return redirect('incomes/invoices');
    }

    public function edit(Invoice $invoice)
    {
       // $customers = Customer::enabled()->pluck('name', 'id');

        $elements = Customer::whereEnabled(1)->select('name', 'id','parent_id')->get()->toArray();

        $customers = app('App\Http\Controllers\Accounts\Incomes\Customers')->bulidCustomer($elements);

        //$items = Item::enabled()->pluck('name', 'id');

        $elements = Item::select('id','name','subitem')->get()->toArray();

        $items  = $this->bulidItems($elements);

        $terms = Terms::pluck('name','id');
        
        return view('accounts.incomes.invoices.edit', compact('invoice', 'customers', 'items','terms'));
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  Invoice  $invoice
     * @param  Request  $request
     *
     * @return Response
     */
    public function update(Invoice $invoice, Request $request)
    {
        
        // Get customer object
        $customer = Customer::find($request['customer_id']);

        $customer_parent = app('App\Http\Controllers\Accounts\Incomes\Customers')->parent_customer_id($customer->id);
        $customer_parent_list = explode(',', $customer_parent->original['parent_id_string']); 

        $request['customer_name_with_parent'] = $customer_parent->original['full_name'];

        $request['customer_name'] = $customer->name;
        $request['customer_email'] = $customer->email;
        $request['customer_tax_number'] = $customer->tax_number;
        $request['customer_phone'] = $customer->phone;
        $request['customer_address'] = $customer->address;
        $date = $this->date_format_change_unique($request->invoiced_at, $request->due_at);
        $request['invoiced_at'] = date("Y-m-d", strtotime($date[0]));
        $request['due_at'] =  date("Y-m-d", strtotime($date[1]));
        // Get currency object
        $currency = Currency::where('code', $request['currency_code'])->first();

        $request['currency_code'] = $currency->code;
        $request['currency_rate'] = $currency->rate;

        $sub_total = 0;

        $invoice_item = [];
        $invoice_item['company_id'] = $request['company_id'];
        $invoice_item['invoice_id'] = $invoice->id;

        if ($request['item']) {
            InvoiceItem::where('invoice_id', $invoice->id)->delete();
            Charthistory::where('transaction_id',$invoice->id)->whereIn('transaction_type', ['Invoice (Payment)','Invoice'])->delete();

            $chart_history = [];
            $chart_history['company_id'] = session('company_id');
            $chart_history['transaction_id'] = $invoice->id;
            $chart_history['transaction_type'] = 'Invoice';
            $chart_history['number'] = $invoice->invoice_number;
            $chart_history['currency_code'] = $currency->code;
            $chart_history['name'] = $customer->name;
            $chart_history['transaction_date'] = date("Y-m-d", strtotime($date[0]));
            

            foreach ($request['item'] as $item) {
                $item_sku = '';

                if (!empty($item['item_id'])) {
                    $item_object = Item::find($item['item_id']);
                    $chart_object = Chartofaccounts::find($item_object->income_account);

                    $item_sku = $item_object->sku;
                }


                $invoice_item['item_id'] = $item['item_id'];
                $invoice_item['name'] = Str::limit($item['name'], 180, '');
                $invoice_item['sku'] = $item_sku;
                $invoice_item['quantity'] = $item['quantity'];
                $invoice_item['description'] = $invoice_item['description'] = isset($item['description'])?$item['description']:Str::limit($item['name'], 180, '');
                $invoice_item['price'] = $item['price'];
                $invoice_item['total'] = $item['price'] * $item['quantity'];

                $sub_total += $invoice_item['total'];

                InvoiceItem::create($invoice_item);

                 // Set Chart History.
                $chart_history['amount_type'] = DepositType::find($item_object->income_account,'credit');
                $chart_history['chartofaccount_id'] = $item_object->income_account;
                $chart_history['account_type_id'] = $chart_object['account_type_id'];
                $chart_history['detail_type'] = $chart_object['detail_type'];
                $chart_history['amount'] = $item['price'] * $item['quantity'];
                $chart_history['description'] = $invoice_item['description'] = isset($item['description'])?$item['description']:Str::limit($item['name'], 180, '');

                $chart_history_id = Charthistory::create($chart_history);

                $chartparents = app('App\Http\Controllers\Accounts\Accounting\Accounting')->parent_chartaccount_id($item_object->income_account);

                CharthistoryParent::charthistoryparentsave($chart_history_id->id,$chartparents->original['parent_id_string'],$item_object->income_account);
            }
        }

        $request['amount'] = $sub_total ;

        //Histort For Account Receiveble
        $chart =  Chartofaccounts::where('name','=','Accounts Receivable')->first();
        $chart_receivable = [];
        $chart_receivable['company_id'] = session('company_id');
        $chart_receivable['transaction_id'] = $invoice->id;
        $chart_receivable['transaction_type'] = 'Invoice';
        $chart_receivable['number'] = $invoice->invoice_number;
        $chart_receivable['currency_code'] = $currency->code;
        $chart_receivable['name'] = $customer->name;
        $chart_receivable['amount_type'] = DepositType::find($item_object->income_account,'debit');
        $chart_receivable['chartofaccount_id'] = $chart->id;
        $chart_receivable['account_type_id'] = $chart->account_type_id;
        $chart_receivable['detail_type'] = $chart->detail_type;
        $chart_receivable['amount'] = $sub_total;
        $chart_receivable['description'] = $request->notes;
        $chart_receivable['transaction_date'] = date("Y-m-d", strtotime($date[0]));

        $chart_receivable_id =  Charthistory::create($chart_receivable);

        $chartparents = app('App\Http\Controllers\Accounts\Accounting\Accounting')->parent_chartaccount_id($chart->id);

        CharthistoryParent::charthistoryparentsave($chart_receivable_id->id,$chartparents->original['parent_id_string'],$chart->id);

        $invoice->update($request->input());

        // Upload attachment
        if ($request->file('attachment')) {
            $media = $this->getMedia($request->file('attachment'), 'invoices');

            $invoice->attachMedia($media, 'attachment');
        }

        // Delete previous invoice totals
        InvoiceTotal::where('invoice_id', $invoice->id)->delete();

        // Add invoice totals
        $this->addTotals($invoice, $request, $sub_total);

        // Fire the event to make it extendible
        event(new InvoiceUpdated($invoice));

        $message = trans('messages.success.updated', ['type' => trans_choice('general.invoices', 1)]);

        Session::flash('success',$message);

        return redirect('incomes/invoices/' . $invoice->id);
    }

    public function printInvoice(Invoice $invoice)
    {
        $invoice = $this->prepareInvoice($invoice);

        $logo = $this->getLogo();

        return view($invoice->template_path, compact('invoice', 'logo'));
    }

    protected function prepareInvoice(Invoice $invoice)
    {
        $paid = 0;

        foreach ($invoice->payments as $item) {
            $item->default_currency_code = $invoice->currency_code;

            $paid += $item->getDynamicConvertedAmount();
        }

        $invoice->paid = $paid;

        $invoice->template_path = 'accounts.incomes.invoices.invoice';

        event(new InvoicePrinting($invoice));

        return $invoice;
    }

    protected function getLogo()
    {
        $logo = '';

        $media_id = setting('general.company_logo');

        if (setting('general.invoice_logo')) {
            $media_id = setting('general.invoice_logo');
        }

        $media = Media::find($media_id);
       
        if (!empty($media)) {
            $path = storage_path( 'app/uploads/' . $media->getDiskPath()); 
            if (!is_file($path)) {
                return $logo;
            }
        } else {
           // asset('public/accounts/img/company.png')
           $path = '';
             if (!is_file($path)) {
                return $logo;
            }
        }

        $image = Image::make($path)->encode()->getEncoded();

        if (empty($image)) {die;
            return $logo;

        }

        $extension = File::extension($path);

        $logo = 'data:image/' . $extension . ';base64,' . base64_encode($image);

        return $logo;
    }

    public function pdfInvoice(Invoice $invoice)
    {

        $invoice = $this->prepareInvoice($invoice);

        $logo = $this->getLogo();
       
        $html = view($invoice->template_path, compact('invoice', 'logo'))->render();

        $pdf = \App::make('dompdf.wrapper');
        $pdf->loadHTML($html);

        $pdf->setPaper('A4', 'portrait');


        $file_name = 'invoice_'.time().'.pdf';
        //dd();

        return $pdf->download($file_name);
    }

    public function emailInvoice(Invoice $invoice)
    {
        $invoice = $this->prepareInvoice($invoice);

        $logo = $this->getLogo();

        $html = view($invoice->template_path, compact('invoice', 'logo'))->render();

        $pdf = \App::make('dompdf.wrapper');
        $pdf->loadHTML($html);

        $file = storage_path('app/temp/invoice_'.time().'.pdf');

        $invoice->pdf_path = $file;

        // Save the PDF file into temp folder
        $pdf->save($file);

        // Notify the customer
        $invoice->customer->notify(new Notification($invoice));

        // Send a Mail To Customer.

        $data = array(
            'customer_email'=> $invoice->customer_email,
            'subject'=> $invoice->subject,
            'message'=> $invoice->message,
            'cc_email' => $invoice->cc_email,
            'bcc_email' => $invoice->bcc_email
        );
       

       Mail::send('accounts.email.sampleemail', compact('data') , function ($message) use ($data, $file) {

            $message->from('satishdnd9@gmail.com');
            $message->to($data['customer_email'])
                    ->subject($data['subject'])
                    ->cc($data['cc_email'] ?: [])
                    ->bcc($data['bcc_email'] ?: [])
                    ->attach($file, [
                                'as' => 'invoices.pdf', 
                                'mime' => 'application/pdf'
                            ]);
            $message->getSwiftMessage();
        });

        // Delete temp file
        File::delete($file);

        unset($invoice->paid);
        unset($invoice->template_path);
        unset($invoice->pdf_path);

        // Mark invoice as sent
        if ($invoice->invoice_status_code != 'partial') {
            $invoice->invoice_status_code = 'sent';

            $invoice->save();
        }

        // Add invoice history
        InvoiceHistory::create([
            'company_id' => $invoice->company_id,
            'invoice_id' => $invoice->id,
            'status_code' => 'sent',
            'notify' => 1,
            'description' => trans('invoices.send_mail'),
        ]);

      //  flash(trans('invoices.messages.email_sent'))->success();


        $message = trans('messages.success.added', ['type' => trans('invoices.messages.email_sent')]);

        return response()->json([
            'success' => true,
            'error' => false,
            'message' => $message,
        ]);
    }
}
