2015-03-24 09:21:12 +01:00
< ? php namespace App\Ninja\Repositories ;
2013-12-25 22:34:42 +01:00
2015-03-31 11:38:24 +02:00
use App\Models\Invoice ;
use App\Models\InvoiceItem ;
use App\Models\Invitation ;
use App\Models\Product ;
2013-12-25 22:34:42 +01:00
use Utils ;
class InvoiceRepository
{
2015-01-11 12:56:58 +01:00
public function getInvoices ( $accountId , $clientPublicId = false , $entityType = ENTITY_INVOICE , $filter = false )
{
$query = \DB :: table ( 'invoices' )
-> join ( 'clients' , 'clients.id' , '=' , 'invoices.client_id' )
-> join ( 'invoice_statuses' , 'invoice_statuses.id' , '=' , 'invoices.invoice_status_id' )
-> join ( 'contacts' , 'contacts.client_id' , '=' , 'clients.id' )
2014-05-20 23:40:09 +02:00
-> where ( 'invoices.account_id' , '=' , $accountId )
-> where ( 'clients.deleted_at' , '=' , null )
2014-06-02 18:21:47 +02:00
-> where ( 'contacts.deleted_at' , '=' , null )
2015-01-11 12:56:58 +01:00
-> where ( 'invoices.is_recurring' , '=' , false )
-> where ( 'contacts.is_primary' , '=' , true )
2015-04-16 21:57:12 +02:00
-> select ( 'clients.public_id as client_public_id' , 'invoice_number' , 'invoice_status_id' , 'clients.name as client_name' , 'invoices.public_id' , 'amount' , 'invoices.balance' , 'invoice_date' , 'due_date' , 'invoice_statuses.name as invoice_status_name' , 'clients.currency_id' , 'contacts.first_name' , 'contacts.last_name' , 'contacts.email' , 'quote_id' , 'quote_invoice_id' , 'invoices.deleted_at' , 'invoices.is_deleted' , 'invoices.partial' );
2015-01-11 12:56:58 +01:00
if ( ! \Session :: get ( 'show_trash:' . $entityType )) {
$query -> where ( 'invoices.deleted_at' , '=' , null );
}
if ( $clientPublicId ) {
$query -> where ( 'clients.public_id' , '=' , $clientPublicId );
}
if ( $filter ) {
$query -> where ( function ( $query ) use ( $filter ) {
$query -> where ( 'clients.name' , 'like' , '%' . $filter . '%' )
-> orWhere ( 'invoices.invoice_number' , 'like' , '%' . $filter . '%' )
-> orWhere ( 'invoice_statuses.name' , 'like' , '%' . $filter . '%' )
2014-02-26 17:08:40 +01:00
-> orWhere ( 'contacts.first_name' , 'like' , '%' . $filter . '%' )
-> orWhere ( 'contacts.last_name' , 'like' , '%' . $filter . '%' )
-> orWhere ( 'contacts.email' , 'like' , '%' . $filter . '%' );
2013-12-25 22:34:42 +01:00
});
2015-01-11 12:56:58 +01:00
}
return $query ;
}
public function getRecurringInvoices ( $accountId , $clientPublicId = false , $filter = false )
{
$query = \DB :: table ( 'invoices' )
-> join ( 'clients' , 'clients.id' , '=' , 'invoices.client_id' )
-> join ( 'frequencies' , 'frequencies.id' , '=' , 'invoices.frequency_id' )
-> join ( 'contacts' , 'contacts.client_id' , '=' , 'clients.id' )
-> where ( 'invoices.account_id' , '=' , $accountId )
-> where ( 'invoices.is_quote' , '=' , false )
-> where ( 'clients.deleted_at' , '=' , null )
-> where ( 'contacts.deleted_at' , '=' , null )
-> where ( 'invoices.is_recurring' , '=' , true )
-> where ( 'contacts.is_primary' , '=' , true )
-> select ( 'clients.public_id as client_public_id' , 'clients.name as client_name' , 'invoices.public_id' , 'amount' , 'frequencies.name as frequency' , 'start_date' , 'end_date' , 'clients.currency_id' , 'contacts.first_name' , 'contacts.last_name' , 'contacts.email' , 'invoices.deleted_at' , 'invoices.is_deleted' );
if ( $clientPublicId ) {
$query -> where ( 'clients.public_id' , '=' , $clientPublicId );
}
if ( ! \Session :: get ( 'show_trash:invoice' )) {
$query -> where ( 'invoices.deleted_at' , '=' , null );
}
if ( $filter ) {
$query -> where ( function ( $query ) use ( $filter ) {
$query -> where ( 'clients.name' , 'like' , '%' . $filter . '%' )
-> orWhere ( 'invoices.invoice_number' , 'like' , '%' . $filter . '%' );
2013-12-25 22:34:42 +01:00
});
2015-01-11 12:56:58 +01:00
}
2013-12-25 22:34:42 +01:00
2015-01-11 12:56:58 +01:00
return $query ;
}
2013-12-25 22:34:42 +01:00
2015-01-11 12:56:58 +01:00
public function getClientDatatable ( $contactId , $entityType , $search )
{
$query = \DB :: table ( 'invitations' )
-> join ( 'invoices' , 'invoices.id' , '=' , 'invitations.invoice_id' )
-> join ( 'clients' , 'clients.id' , '=' , 'invoices.client_id' )
2014-11-12 22:09:42 +01:00
-> where ( 'invitations.contact_id' , '=' , $contactId )
-> where ( 'invitations.deleted_at' , '=' , null )
-> where ( 'invoices.is_quote' , '=' , $entityType == ENTITY_QUOTE )
-> where ( 'invoices.is_deleted' , '=' , false )
-> where ( 'clients.deleted_at' , '=' , null )
-> where ( 'invoices.is_recurring' , '=' , false )
2015-04-16 21:57:12 +02:00
-> select ( 'invitation_key' , 'invoice_number' , 'invoice_date' , 'invoices.balance as balance' , 'due_date' , 'clients.public_id as client_public_id' , 'clients.name as client_name' , 'invoices.public_id' , 'amount' , 'start_date' , 'end_date' , 'clients.currency_id' , 'invoices.partial' );
2014-11-12 22:09:42 +01:00
2015-01-11 12:56:58 +01:00
$table = \Datatable :: query ( $query )
-> addColumn ( 'invoice_number' , function ( $model ) use ( $entityType ) { return link_to ( '/view/' . $model -> invitation_key , $model -> invoice_number ); })
-> addColumn ( 'invoice_date' , function ( $model ) { return Utils :: fromSqlDate ( $model -> invoice_date ); })
-> addColumn ( 'amount' , function ( $model ) { return Utils :: formatMoney ( $model -> amount , $model -> currency_id ); });
2014-11-12 22:09:42 +01:00
2015-01-11 12:56:58 +01:00
if ( $entityType == ENTITY_INVOICE ) {
2015-04-16 21:57:12 +02:00
$table -> addColumn ( 'balance' , function ( $model ) {
return $model -> partial > 0 ?
trans ( 'texts.partial_remaining' , [ 'partial' => Utils :: formatMoney ( $model -> partial , $model -> currency_id ), 'balance' => Utils :: formatMoney ( $model -> balance , $model -> currency_id )]) :
Utils :: formatMoney ( $model -> balance , $model -> currency_id );
});
2015-01-11 12:56:58 +01:00
}
return $table -> addColumn ( 'due_date' , function ( $model ) { return Utils :: fromSqlDate ( $model -> due_date ); })
-> make ();
}
2014-11-12 22:09:42 +01:00
2015-01-11 12:56:58 +01:00
public function getDatatable ( $accountId , $clientPublicId = null , $entityType , $search )
{
$query = $this -> getInvoices ( $accountId , $clientPublicId , $entityType , $search )
2014-05-20 23:40:09 +02:00
-> where ( 'invoices.is_quote' , '=' , $entityType == ENTITY_QUOTE ? true : false );
2014-05-17 21:29:57 +02:00
2015-01-11 12:56:58 +01:00
$table = \Datatable :: query ( $query );
2014-05-17 21:29:57 +02:00
2015-01-11 12:56:58 +01:00
if ( ! $clientPublicId ) {
$table -> addColumn ( 'checkbox' , function ( $model ) { return '<input type="checkbox" name="ids[]" value="' . $model -> public_id . '" ' . Utils :: getEntityRowClass ( $model ) . '>' ; });
}
2014-05-17 21:29:57 +02:00
2015-01-11 12:56:58 +01:00
$table -> addColumn ( " invoice_number " , function ( $model ) use ( $entityType ) { return link_to ( " { $entityType } s/ " . $model -> public_id . '/edit' , $model -> invoice_number , [ 'class' => Utils :: getEntityRowClass ( $model )]); });
2014-05-17 21:29:57 +02:00
2015-01-11 12:56:58 +01:00
if ( ! $clientPublicId ) {
$table -> addColumn ( 'client_name' , function ( $model ) { return link_to ( 'clients/' . $model -> client_public_id , Utils :: getClientDisplayName ( $model )); });
}
2014-05-17 21:29:57 +02:00
2015-01-11 12:56:58 +01:00
$table -> addColumn ( " invoice_date " , function ( $model ) { return Utils :: fromSqlDate ( $model -> invoice_date ); })
-> addColumn ( 'amount' , function ( $model ) { return Utils :: formatMoney ( $model -> amount , $model -> currency_id ); });
if ( $entityType == ENTITY_INVOICE ) {
2015-04-16 21:57:12 +02:00
$table -> addColumn ( 'balance' , function ( $model ) {
return $model -> partial > 0 ?
trans ( 'texts.partial_remaining' , [ 'partial' => Utils :: formatMoney ( $model -> partial , $model -> currency_id ), 'balance' => Utils :: formatMoney ( $model -> balance , $model -> currency_id )]) :
Utils :: formatMoney ( $model -> balance , $model -> currency_id );
});
2015-01-11 12:56:58 +01:00
}
return $table -> addColumn ( 'due_date' , function ( $model ) { return Utils :: fromSqlDate ( $model -> due_date ); })
2015-04-22 21:21:04 +02:00
-> addColumn ( 'invoice_status_name' , function ( $model ) { return $model -> quote_invoice_id ? link_to ( " invoices/ { $model -> quote_invoice_id } /edit " , trans ( 'texts.converted' )) : self :: getStatusLabel ( $model -> invoice_status_id , $model -> invoice_status_name ); })
2015-01-11 12:56:58 +01:00
-> addColumn ( 'dropdown' , function ( $model ) use ( $entityType ) {
2014-05-20 23:40:09 +02:00
2015-01-11 12:56:58 +01:00
if ( $model -> is_deleted ) {
return '<div style="height:38px"/>' ;
2014-05-20 23:40:09 +02:00
}
2015-01-11 12:56:58 +01:00
$str = ' < div class = " btn-group tr-action " style = " visibility:hidden; " >
< button type = " button " class = " btn btn-xs btn-default dropdown-toggle " data - toggle = " dropdown " >
'.trans(' texts . select ').' < span class = " caret " ></ span >
</ button >
< ul class = " dropdown-menu " role = " menu " > ' ;
if ( ! $model -> deleted_at || $model -> deleted_at == '0000-00-00' ) {
$str .= '<li><a href="' . \URL :: to ( " { $entityType } s/ " . $model -> public_id . '/edit' ) . '">' . trans ( " texts.edit_ { $entityType } " ) . ' </ a ></ li >
< li >< a href = " '. \ URL::to( " { $entityType } s / " . $model->public_id .'/clone').' " > '.trans("texts.clone_{$entityType}").' </ a ></ li >
2015-01-25 20:26:15 +01:00
< li >< a href = " ' . \ URL::to( " { $entityType } s / { $entityType } _history / { $model -> public_id } " ) . ' " > ' . trans("texts.view_history") . ' </ a ></ li >
2015-01-11 12:56:58 +01:00
< li class = " divider " ></ li > ' ;
if ( $model -> invoice_status_id < INVOICE_STATUS_SENT ) {
$str .= '<li><a href="javascript:markEntity(' . $model -> public_id . ', ' . INVOICE_STATUS_SENT . ')">' . trans ( " texts.mark_sent " ) . '</a></li>' ;
}
if ( $entityType == ENTITY_INVOICE ) {
if ( $model -> invoice_status_id < INVOICE_STATUS_PAID ) {
2015-01-11 13:30:08 +01:00
$str .= '<li><a href="' . \URL :: to ( 'payments/create/' . $model -> client_public_id . '/' . $model -> public_id ) . '">' . trans ( 'texts.enter_payment' ) . '</a></li>' ;
2015-01-11 12:56:58 +01:00
}
if ( $model -> quote_id ) {
2015-01-11 13:30:08 +01:00
$str .= '<li><a href="' . \URL :: to ( " quotes/ { $model -> quote_id } /edit " ) . '">' . trans ( " texts.view_quote " ) . '</a></li>' ;
2015-01-11 12:56:58 +01:00
}
} elseif ( $entityType == ENTITY_QUOTE ) {
if ( $model -> quote_invoice_id ) {
$str .= '<li><a href="' . \URL :: to ( " invoices/ { $model -> quote_invoice_id } /edit " ) . '">' . trans ( " texts.view_invoice " ) . '</a></li>' ;
2015-02-10 14:50:38 +01:00
} else {
$str .= '<li><a href="javascript:convertEntity(' . $model -> public_id . ')">' . trans ( " texts.convert_to_invoice " ) . '</a></li>' ;
2015-01-11 12:56:58 +01:00
}
}
$str .= ' < li class = " divider " ></ li >
< li >< a href = " javascript:archiveEntity('. $model->public_id .') " > '.trans("texts.archive_{$entityType}").' </ a ></ li >
< li >< a href = " javascript:deleteEntity('. $model->public_id .') " > '.trans("texts.delete_{$entityType}").' </ a ></ li > ' ;
} else {
2015-01-11 13:30:08 +01:00
$str .= '<li><a href="javascript:restoreEntity(' . $model -> public_id . ')">' . trans ( " texts.restore_ { $entityType } " ) . ' </ a ></ li >
2015-01-11 12:56:58 +01:00
< li >< a href = " javascript:deleteEntity('. $model->public_id .') " > '.trans("texts.delete_{$entityType}").' </ a ></ li > ' ;
2014-10-14 21:04:48 +02:00
}
2015-01-11 12:56:58 +01:00
return $str . ' </ ul >
</ div > ' ;
})
2014-11-23 22:47:10 +01:00
-> make ();
2014-05-25 20:38:40 +02:00
}
2015-01-11 12:56:58 +01:00
2015-04-22 21:21:04 +02:00
private function getStatusLabel ( $statusId , $statusName ) {
$label = trans ( " texts. { $statusName } " );
$class = 'default' ;
switch ( $statusId ) {
case INVOICE_STATUS_SENT :
$class = 'info' ;
break ;
case INVOICE_STATUS_VIEWED :
$class = 'warning' ;
break ;
case INVOICE_STATUS_PARTIAL :
$class = 'primary' ;
break ;
case INVOICE_STATUS_PAID :
$class = 'success' ;
break ;
}
return " <h4><div class= \" label label- { $class } \" > $statusName </div></h4> " ;
}
2015-01-11 12:56:58 +01:00
public function getErrors ( $input )
2014-05-25 20:38:40 +02:00
{
2015-01-11 12:56:58 +01:00
$contact = ( array ) $input -> client -> contacts [ 0 ];
2015-04-16 19:12:56 +02:00
$rules = [
'email' => 'email|required_without:first_name' ,
'first_name' => 'required_without:email' ,
];
2015-01-11 12:56:58 +01:00
$validator = \Validator :: make ( $contact , $rules );
2014-05-25 20:38:40 +02:00
2015-01-11 12:56:58 +01:00
if ( $validator -> fails ()) {
return $validator ;
}
2014-07-20 12:38:42 +02:00
2015-01-11 12:56:58 +01:00
$invoice = ( array ) $input ;
$invoiceId = isset ( $invoice [ 'public_id' ]) && $invoice [ 'public_id' ] ? Invoice :: getPrivateId ( $invoice [ 'public_id' ]) : null ;
$rules = [
'invoice_number' => 'required|unique:invoices,invoice_number,' . $invoiceId . ',id,account_id,' . \Auth :: user () -> account_id ,
'discount' => 'positive' ,
];
2013-12-31 20:49:54 +01:00
2015-01-11 12:56:58 +01:00
if ( $invoice [ 'is_recurring' ] && $invoice [ 'start_date' ] && $invoice [ 'end_date' ]) {
$rules [ 'end_date' ] = 'after:' . $invoice [ 'start_date' ];
}
2014-07-20 12:38:42 +02:00
2015-01-11 12:56:58 +01:00
$validator = \Validator :: make ( $invoice , $rules );
2014-04-03 19:54:06 +02:00
2015-01-11 12:56:58 +01:00
if ( $validator -> fails ()) {
return $validator ;
}
2013-12-31 20:49:54 +01:00
2015-01-11 12:56:58 +01:00
return false ;
2014-02-01 21:01:32 +01:00
}
2015-01-11 12:56:58 +01:00
public function save ( $publicId , $data , $entityType )
2014-05-20 23:40:09 +02:00
{
2015-01-11 12:56:58 +01:00
if ( $publicId ) {
$invoice = Invoice :: scope ( $publicId ) -> firstOrFail ();
} else {
$invoice = Invoice :: createNew ();
2014-05-20 23:40:09 +02:00
2015-01-11 12:56:58 +01:00
if ( $entityType == ENTITY_QUOTE ) {
$invoice -> is_quote = true ;
}
}
2015-02-27 09:10:23 +01:00
2015-02-28 22:42:47 +01:00
$account = \Auth :: user () -> account ;
2015-04-13 14:00:31 +02:00
if (( isset ( $data [ 'set_default_terms' ]) && $data [ 'set_default_terms' ])
|| ( isset ( $data [ 'set_default_footer' ]) && $data [ 'set_default_footer' ])) {
if ( isset ( $data [ 'set_default_terms' ]) && $data [ 'set_default_terms' ]) {
$account -> invoice_terms = trim ( $data [ 'terms' ]);
}
if ( isset ( $data [ 'set_default_footer' ]) && $data [ 'set_default_footer' ]) {
$account -> invoice_footer = trim ( $data [ 'invoice_footer' ]);
}
$account -> save ();
}
2015-01-11 12:56:58 +01:00
$invoice -> client_id = $data [ 'client_id' ];
$invoice -> discount = round ( Utils :: parseFloat ( $data [ 'discount' ]), 2 );
$invoice -> is_amount_discount = $data [ 'is_amount_discount' ] ? true : false ;
$invoice -> invoice_number = trim ( $data [ 'invoice_number' ]);
2015-04-16 19:12:56 +02:00
$invoice -> partial = round ( Utils :: parseFloat ( $data [ 'partial' ]), 2 );
2015-02-27 09:10:23 +01:00
$invoice -> invoice_date = isset ( $data [ 'invoice_date_sql' ]) ? $data [ 'invoice_date_sql' ] : Utils :: toSqlDate ( $data [ 'invoice_date' ]);
2015-01-11 12:56:58 +01:00
2015-05-05 11:48:23 +02:00
if ( ! $publicId ) {
$invoice -> is_recurring = $data [ 'is_recurring' ] && ! Utils :: isDemo () ? true : false ;
}
2015-01-11 12:56:58 +01:00
if ( $invoice -> is_recurring ) {
$invoice -> frequency_id = $data [ 'frequency_id' ] ? $data [ 'frequency_id' ] : 0 ;
$invoice -> start_date = Utils :: toSqlDate ( $data [ 'start_date' ]);
$invoice -> end_date = Utils :: toSqlDate ( $data [ 'end_date' ]);
$invoice -> due_date = null ;
} else {
2015-02-27 09:10:23 +01:00
$invoice -> due_date = isset ( $data [ 'due_date_sql' ]) ? $data [ 'due_date_sql' ] : Utils :: toSqlDate ( $data [ 'due_date' ]);
2015-01-11 12:56:58 +01:00
$invoice -> frequency_id = 0 ;
$invoice -> start_date = null ;
$invoice -> end_date = null ;
}
2015-04-27 14:28:40 +02:00
$invoice -> terms = trim ( $data [ 'terms' ]) ? trim ( $data [ 'terms' ]) : ( ! $publicId && $account -> invoice_terms ? $account -> invoice_terms : '' );
$invoice -> invoice_footer = trim ( $data [ 'invoice_footer' ]) ? trim ( $data [ 'invoice_footer' ]) : ( ! $publicId && $account -> invoice_footer ? $account -> invoice_footer : '' );
2015-01-11 12:56:58 +01:00
$invoice -> public_notes = trim ( $data [ 'public_notes' ]);
$invoice -> po_number = trim ( $data [ 'po_number' ]);
$invoice -> invoice_design_id = $data [ 'invoice_design_id' ];
2015-01-25 07:48:40 +01:00
if ( isset ( $data [ 'tax_name' ]) && isset ( $data [ 'tax_rate' ]) && $data [ 'tax_name' ]) {
2015-01-11 12:56:58 +01:00
$invoice -> tax_rate = Utils :: parseFloat ( $data [ 'tax_rate' ]);
$invoice -> tax_name = trim ( $data [ 'tax_name' ]);
} else {
$invoice -> tax_rate = 0 ;
$invoice -> tax_name = '' ;
}
$total = 0 ;
foreach ( $data [ 'invoice_items' ] as $item ) {
2015-02-27 09:10:23 +01:00
$item = ( array ) $item ;
if ( ! $item [ 'cost' ] && ! $item [ 'product_key' ] && ! $item [ 'notes' ]) {
2015-01-11 12:56:58 +01:00
continue ;
}
2015-03-10 12:15:01 +01:00
$invoiceItemCost = round ( Utils :: parseFloat ( $item [ 'cost' ]), 2 );
$invoiceItemQty = round ( Utils :: parseFloat ( $item [ 'qty' ]), 2 );
2015-01-11 12:56:58 +01:00
$invoiceItemTaxRate = 0 ;
2015-02-27 09:10:23 +01:00
if ( isset ( $item [ 'tax_rate' ]) && Utils :: parseFloat ( $item [ 'tax_rate' ]) > 0 ) {
$invoiceItemTaxRate = Utils :: parseFloat ( $item [ 'tax_rate' ]);
2015-01-11 12:56:58 +01:00
}
$lineTotal = $invoiceItemCost * $invoiceItemQty ;
$total += round ( $lineTotal + ( $lineTotal * $invoiceItemTaxRate / 100 ), 2 );
}
if ( $invoice -> discount > 0 ) {
if ( $invoice -> is_amount_discount ) {
$total -= $invoice -> discount ;
} else {
$total *= ( 100 - $invoice -> discount ) / 100 ;
}
}
$invoice -> custom_value1 = round ( $data [ 'custom_value1' ], 2 );
$invoice -> custom_value2 = round ( $data [ 'custom_value2' ], 2 );
$invoice -> custom_taxes1 = $data [ 'custom_taxes1' ] ? true : false ;
$invoice -> custom_taxes2 = $data [ 'custom_taxes2' ] ? true : false ;
// custom fields charged taxes
if ( $invoice -> custom_value1 && $invoice -> custom_taxes1 ) {
$total += $invoice -> custom_value1 ;
}
if ( $invoice -> custom_value2 && $invoice -> custom_taxes2 ) {
$total += $invoice -> custom_value2 ;
}
$total += $total * $invoice -> tax_rate / 100 ;
$total = round ( $total , 2 );
// custom fields not charged taxes
if ( $invoice -> custom_value1 && ! $invoice -> custom_taxes1 ) {
$total += $invoice -> custom_value1 ;
}
if ( $invoice -> custom_value2 && ! $invoice -> custom_taxes2 ) {
$total += $invoice -> custom_value2 ;
}
if ( $publicId ) {
$invoice -> balance = $total - ( $invoice -> amount - $invoice -> balance );
} else {
$invoice -> balance = $total ;
}
$invoice -> amount = $total ;
$invoice -> save ();
2015-02-27 09:10:23 +01:00
if ( $publicId ) {
$invoice -> invoice_items () -> forceDelete ();
}
2015-01-11 12:56:58 +01:00
foreach ( $data [ 'invoice_items' ] as $item ) {
2015-02-27 09:10:23 +01:00
$item = ( array ) $item ;
if ( ! $item [ 'cost' ] && ! $item [ 'product_key' ] && ! $item [ 'notes' ]) {
2015-01-11 12:56:58 +01:00
continue ;
}
2015-02-27 09:10:23 +01:00
if ( $item [ 'product_key' ]) {
$product = Product :: findProductByKey ( trim ( $item [ 'product_key' ]));
2015-01-11 12:56:58 +01:00
if ( ! $product ) {
$product = Product :: createNew ();
2015-02-27 09:10:23 +01:00
$product -> product_key = trim ( $item [ 'product_key' ]);
2015-01-11 12:56:58 +01:00
}
if ( \Auth :: user () -> account -> update_products ) {
2015-02-27 09:10:23 +01:00
$product -> notes = $item [ 'notes' ];
$product -> cost = $item [ 'cost' ];
2015-01-11 12:56:58 +01:00
}
$product -> save ();
}
$invoiceItem = InvoiceItem :: createNew ();
$invoiceItem -> product_id = isset ( $product ) ? $product -> id : null ;
2015-03-17 14:43:13 +01:00
$invoiceItem -> product_key = trim ( $invoice -> is_recurring ? $item [ 'product_key' ] : Utils :: processVariables ( $item [ 'product_key' ]));
2015-02-27 09:10:23 +01:00
$invoiceItem -> notes = trim ( $invoice -> is_recurring ? $item [ 'notes' ] : Utils :: processVariables ( $item [ 'notes' ]));
$invoiceItem -> cost = Utils :: parseFloat ( $item [ 'cost' ]);
$invoiceItem -> qty = Utils :: parseFloat ( $item [ 'qty' ]);
2015-01-11 12:56:58 +01:00
$invoiceItem -> tax_rate = 0 ;
2015-02-27 09:10:23 +01:00
if ( isset ( $item [ 'tax_rate' ]) && isset ( $item [ 'tax_name' ]) && $item [ 'tax_name' ]) {
$invoiceItem [ 'tax_rate' ] = Utils :: parseFloat ( $item [ 'tax_rate' ]);
$invoiceItem [ 'tax_name' ] = trim ( $item [ 'tax_name' ]);
2015-01-11 12:56:58 +01:00
}
$invoice -> invoice_items () -> save ( $invoiceItem );
}
return $invoice ;
2014-05-20 23:40:09 +02:00
}
2015-01-11 12:56:58 +01:00
public function cloneInvoice ( $invoice , $quotePublicId = null )
2014-05-20 23:40:09 +02:00
{
2015-01-11 12:56:58 +01:00
$invoice -> load ( 'invitations' , 'invoice_items' );
$account = $invoice -> account ;
$clone = Invoice :: createNew ( $invoice );
$clone -> balance = $invoice -> amount ;
2014-05-20 23:40:09 +02:00
2015-01-11 12:56:58 +01:00
// if the invoice prefix is diff than quote prefix, use the same number for the invoice
2015-02-08 19:04:36 +01:00
if (( $account -> invoice_number_prefix || $account -> quote_number_prefix )
&& $account -> invoice_number_prefix != $account -> quote_number_prefix
&& $account -> share_counter ) {
2015-01-11 12:56:58 +01:00
$invoiceNumber = $invoice -> invoice_number ;
if ( strpos ( $invoiceNumber , $account -> quote_number_prefix ) === 0 ) {
$invoiceNumber = substr ( $invoiceNumber , strlen ( $account -> quote_number_prefix ));
}
$clone -> invoice_number = $account -> invoice_number_prefix . $invoiceNumber ;
} else {
$clone -> invoice_number = $account -> getNextInvoiceNumber ();
}
2014-05-20 23:40:09 +02:00
2015-01-11 12:56:58 +01:00
foreach ([
'client_id' ,
'discount' ,
'is_amount_discount' ,
'invoice_date' ,
'po_number' ,
'due_date' ,
'is_recurring' ,
'frequency_id' ,
'start_date' ,
'end_date' ,
'terms' ,
2015-02-28 22:42:47 +01:00
'invoice_footer' ,
2015-01-11 12:56:58 +01:00
'public_notes' ,
'invoice_design_id' ,
'tax_name' ,
'tax_rate' ,
'amount' ,
'is_quote' ,
'custom_value1' ,
'custom_value2' ,
'custom_taxes1' ,
'custom_taxes2' , ] as $field ) {
$clone -> $field = $invoice -> $field ;
}
2014-05-20 23:40:09 +02:00
2015-01-11 12:56:58 +01:00
if ( $quotePublicId ) {
$clone -> is_quote = false ;
$clone -> quote_id = $quotePublicId ;
}
2014-01-12 19:55:33 +01:00
2015-01-11 12:56:58 +01:00
$clone -> save ();
2014-01-12 19:55:33 +01:00
2015-01-11 12:56:58 +01:00
if ( $quotePublicId ) {
$invoice -> quote_invoice_id = $clone -> public_id ;
$invoice -> save ();
}
foreach ( $invoice -> invoice_items as $item ) {
$cloneItem = InvoiceItem :: createNew ( $invoice );
foreach ([
'product_id' ,
'product_key' ,
'notes' ,
'cost' ,
'qty' ,
'tax_name' ,
'tax_rate' , ] as $field ) {
$cloneItem -> $field = $item -> $field ;
}
$clone -> invoice_items () -> save ( $cloneItem );
}
foreach ( $invoice -> invitations as $invitation ) {
$cloneInvitation = Invitation :: createNew ( $invoice );
$cloneInvitation -> contact_id = $invitation -> contact_id ;
$cloneInvitation -> invitation_key = str_random ( RANDOM_KEY_LENGTH );
$clone -> invitations () -> save ( $cloneInvitation );
}
return $clone ;
}
public function bulk ( $ids , $action , $statusId = false )
{
if ( ! $ids ) {
return 0 ;
}
$invoices = Invoice :: withTrashed () -> scope ( $ids ) -> get ();
foreach ( $invoices as $invoice ) {
if ( $action == 'mark' ) {
$invoice -> invoice_status_id = $statusId ;
$invoice -> save ();
} elseif ( $action == 'restore' ) {
$invoice -> restore ();
} else {
if ( $action == 'delete' ) {
$invoice -> is_deleted = true ;
$invoice -> save ();
}
$invoice -> delete ();
}
}
return count ( $invoices );
}
2013-12-25 22:34:42 +01:00
}