mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
commit
bd5292f576
2
.github/workflows/phpunit.yml
vendored
2
.github/workflows/phpunit.yml
vendored
@ -13,7 +13,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
operating-system: ['ubuntu-18.04', 'ubuntu-20.04']
|
operating-system: ['ubuntu-18.04', 'ubuntu-20.04']
|
||||||
php-versions: ['7.3', '7.4']
|
php-versions: ['7.4']
|
||||||
phpunit-versions: ['latest']
|
phpunit-versions: ['latest']
|
||||||
|
|
||||||
env:
|
env:
|
||||||
|
@ -1 +1 @@
|
|||||||
5.0.45
|
5.0.46
|
@ -325,8 +325,8 @@ class CheckData extends Command
|
|||||||
// $total_amount = $invoice->payments->whereNull('deleted_at')->sum('pivot.amount');
|
// $total_amount = $invoice->payments->whereNull('deleted_at')->sum('pivot.amount');
|
||||||
// $total_refund = $invoice->payments->whereNull('deleted_at')->sum('pivot.refunded');
|
// $total_refund = $invoice->payments->whereNull('deleted_at')->sum('pivot.refunded');
|
||||||
|
|
||||||
$total_amount = $invoice->payments->where('is_deleted', false)->whereIn('status_id', [Payment::STATUS_COMPLETED, Payment:: STATUS_PENDING, Payment::STATUS_PARTIALLY_REFUNDED])->sum('pivot.amount');
|
$total_amount = $invoice->payments->where('is_deleted', false)->whereIn('status_id', [Payment::STATUS_COMPLETED, Payment:: STATUS_PENDING, Payment::STATUS_PARTIALLY_REFUNDED, Payment::STATUS_REFUNDED])->sum('pivot.amount');
|
||||||
$total_refund = $invoice->payments->where('is_deleted', false)->whereIn('status_id', [Payment::STATUS_COMPLETED, Payment:: STATUS_PENDING, Payment::STATUS_PARTIALLY_REFUNDED])->sum('pivot.refunded');
|
$total_refund = $invoice->payments->where('is_deleted', false)->whereIn('status_id', [Payment::STATUS_COMPLETED, Payment:: STATUS_PENDING, Payment::STATUS_PARTIALLY_REFUNDED, Payment::STATUS_REFUNDED])->sum('pivot.refunded');
|
||||||
|
|
||||||
$total_invoice_payments += ($total_amount - $total_refund);
|
$total_invoice_payments += ($total_amount - $total_refund);
|
||||||
}
|
}
|
||||||
|
@ -64,10 +64,10 @@ class InvoiceItemFactory
|
|||||||
$item->discount = $faker->numberBetween(1, 10);
|
$item->discount = $faker->numberBetween(1, 10);
|
||||||
$item->notes = $faker->realText(50);
|
$item->notes = $faker->realText(50);
|
||||||
$item->product_key = $faker->word();
|
$item->product_key = $faker->word();
|
||||||
$item->custom_value1 = $faker->realText(10);
|
// $item->custom_value1 = $faker->realText(10);
|
||||||
$item->custom_value2 = $faker->realText(10);
|
// $item->custom_value2 = $faker->realText(10);
|
||||||
$item->custom_value3 = $faker->realText(10);
|
// $item->custom_value3 = $faker->realText(10);
|
||||||
$item->custom_value4 = $faker->realText(10);
|
// $item->custom_value4 = $faker->realText(10);
|
||||||
$item->tax_name1 = 'GST';
|
$item->tax_name1 = 'GST';
|
||||||
$item->tax_rate1 = 10.00;
|
$item->tax_rate1 = 10.00;
|
||||||
$item->type_id = "1";
|
$item->type_id = "1";
|
||||||
@ -98,10 +98,10 @@ class InvoiceItemFactory
|
|||||||
$item->discount = 0;
|
$item->discount = 0;
|
||||||
$item->notes = $faker->realText(20);
|
$item->notes = $faker->realText(20);
|
||||||
$item->product_key = $faker->word();
|
$item->product_key = $faker->word();
|
||||||
$item->custom_value1 = $faker->realText(10);
|
// $item->custom_value1 = $faker->realText(10);
|
||||||
$item->custom_value2 = $faker->realText(10);
|
// $item->custom_value2 = $faker->realText(10);
|
||||||
$item->custom_value3 = $faker->realText(10);
|
// $item->custom_value3 = $faker->realText(10);
|
||||||
$item->custom_value4 = $faker->realText(10);
|
// $item->custom_value4 = $faker->realText(10);
|
||||||
$item->tax_name1 = '';
|
$item->tax_name1 = '';
|
||||||
$item->tax_rate1 = 0;
|
$item->tax_rate1 = 0;
|
||||||
$item->type_id = "1";
|
$item->type_id = "1";
|
||||||
|
@ -214,7 +214,7 @@ class PaymentController extends Controller
|
|||||||
$payment_method_id = $request->input('payment_method_id');
|
$payment_method_id = $request->input('payment_method_id');
|
||||||
$invoice_totals = $payable_invoices->sum('amount');
|
$invoice_totals = $payable_invoices->sum('amount');
|
||||||
$first_invoice = $invoices->first();
|
$first_invoice = $invoices->first();
|
||||||
$credit_totals = $first_invoice->client->getSetting('use_credits_payment') == 'off' ? 0 : $first_invoice->client->service()->getCreditBalance();
|
$credit_totals = $first_invoice->client->getSetting('use_credits_payment') == 'always' ? $first_invoice->client->service()->getCreditBalance() : 0;
|
||||||
$starting_invoice_amount = $first_invoice->amount;
|
$starting_invoice_amount = $first_invoice->amount;
|
||||||
|
|
||||||
if ($gateway) {
|
if ($gateway) {
|
||||||
|
@ -128,7 +128,11 @@ class EmailController extends BaseController
|
|||||||
'body' => $body
|
'body' => $body
|
||||||
];
|
];
|
||||||
|
|
||||||
EmailEntity::dispatchNow($invitation, $invitation->company, $template, $data);
|
$entity_obj->service()->markSent()->save();
|
||||||
|
|
||||||
|
//@TODO why is this dispatchNow instead of just dispatch?
|
||||||
|
//update - changing to dispatch and see if something breaks.
|
||||||
|
EmailEntity::dispatch($invitation, $invitation->company, $template, $data)->delay(now()->addSeconds(5));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
* @OA\Property(property="project_id", type="string", example="", description="________"),
|
* @OA\Property(property="project_id", type="string", example="", description="________"),
|
||||||
* @OA\Property(property="number", type="string", example="", description="________"),
|
* @OA\Property(property="number", type="string", example="", description="________"),
|
||||||
* @OA\Property(property="time_log", type="string", example="", description="________"),
|
* @OA\Property(property="time_log", type="string", example="", description="________"),
|
||||||
* @OA\Property(property="start_time", type="integer", example="", description="________"),
|
|
||||||
* @OA\Property(property="is_running", type="boolean", example=true, description="________"),
|
* @OA\Property(property="is_running", type="boolean", example=true, description="________"),
|
||||||
* @OA\Property(property="is_deleted", type="boolean", example=true, description="________"),
|
* @OA\Property(property="is_deleted", type="boolean", example=true, description="________"),
|
||||||
* @OA\Property(property="task_status_id", type="string", example="", description="________"),
|
* @OA\Property(property="task_status_id", type="string", example="", description="________"),
|
||||||
|
@ -38,12 +38,9 @@ class StoreExpenseRequest extends Request
|
|||||||
if (isset($this->number)) {
|
if (isset($this->number)) {
|
||||||
$rules['number'] = Rule::unique('expenses')->where('company_id', auth()->user()->company()->id);
|
$rules['number'] = Rule::unique('expenses')->where('company_id', auth()->user()->company()->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// $rules['number'] = 'unique:expenses,number,'.$this->id.',id,company_id,'.auth()->user()->company()->id;
|
|
||||||
// $rules['contacts.*.email'] = 'nullable|distinct';
|
|
||||||
//$rules['number'] = new UniqueExpenseNumberRule($this->all());
|
|
||||||
$rules['client_id'] = 'bail|sometimes|exists:clients,id,company_id,'.auth()->user()->company()->id;
|
|
||||||
|
|
||||||
|
if(!empty($this->client_id))
|
||||||
|
$rules['client_id'] = 'bail|sometimes|exists:clients,id,company_id,'.auth()->user()->company()->id;
|
||||||
|
|
||||||
return $this->globalRules($rules);
|
return $this->globalRules($rules);
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ class UpdateExpenseRequest extends Request
|
|||||||
/* Ensure we have a client name, and that all emails are unique*/
|
/* Ensure we have a client name, and that all emails are unique*/
|
||||||
|
|
||||||
$rules['country_id'] = 'integer|nullable';
|
$rules['country_id'] = 'integer|nullable';
|
||||||
//$rules['id_number'] = 'unique:clients,id_number,,id,company_id,' . auth()->user()->company()->id;
|
|
||||||
$rules['contacts.*.email'] = 'nullable|distinct';
|
$rules['contacts.*.email'] = 'nullable|distinct';
|
||||||
|
|
||||||
if (isset($this->number)) {
|
if (isset($this->number)) {
|
||||||
|
@ -41,8 +41,9 @@ class RecurringInvoicesCron
|
|||||||
nlog("Sending recurring invoices ".Carbon::now()->format('Y-m-d h:i:s'));
|
nlog("Sending recurring invoices ".Carbon::now()->format('Y-m-d h:i:s'));
|
||||||
|
|
||||||
if (! config('ninja.db.multi_db_enabled')) {
|
if (! config('ninja.db.multi_db_enabled')) {
|
||||||
$recurring_invoices = RecurringInvoice::whereDate('next_send_date', '=', now())
|
$recurring_invoices = RecurringInvoice::whereDate('next_send_date', '<=', now())
|
||||||
->where('status_id', RecurringInvoice::STATUS_ACTIVE)
|
->where('status_id', RecurringInvoice::STATUS_ACTIVE)
|
||||||
|
->where('remaining_cycles', '!=', '0')
|
||||||
->with('company')
|
->with('company')
|
||||||
->cursor();
|
->cursor();
|
||||||
|
|
||||||
@ -60,8 +61,9 @@ class RecurringInvoicesCron
|
|||||||
foreach (MultiDB::$dbs as $db) {
|
foreach (MultiDB::$dbs as $db) {
|
||||||
MultiDB::setDB($db);
|
MultiDB::setDB($db);
|
||||||
|
|
||||||
$recurring_invoices = RecurringInvoice::whereDate('next_send_date', '=', now())
|
$recurring_invoices = RecurringInvoice::whereDate('next_send_date', '<=', now())
|
||||||
->where('status_id', RecurringInvoice::STATUS_ACTIVE)
|
->where('status_id', RecurringInvoice::STATUS_ACTIVE)
|
||||||
|
->where('remaining_cycles', '!=', '0')
|
||||||
->with('company')
|
->with('company')
|
||||||
->cursor();
|
->cursor();
|
||||||
|
|
||||||
|
@ -108,7 +108,6 @@ class CreateEntityPdf implements ShouldQueue
|
|||||||
$entity_design_id = 'credit_design_id';
|
$entity_design_id = 'credit_design_id';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$file_path = $path.$this->entity->number.'.pdf';
|
$file_path = $path.$this->entity->number.'.pdf';
|
||||||
|
|
||||||
$entity_design_id = $this->entity->design_id ? $this->entity->design_id : $this->decodePrimaryKey($this->entity->client->getSetting($entity_design_id));
|
$entity_design_id = $this->entity->design_id ? $this->entity->design_id : $this->decodePrimaryKey($this->entity->client->getSetting($entity_design_id));
|
||||||
@ -145,10 +144,6 @@ class CreateEntityPdf implements ShouldQueue
|
|||||||
->design($template)
|
->design($template)
|
||||||
->build();
|
->build();
|
||||||
|
|
||||||
//todo - move this to the client creation stage so we don't keep hitting this unnecessarily
|
|
||||||
//nlog("make dir => {$path}");
|
|
||||||
//Storage::makeDirectory($path, 0775);
|
|
||||||
|
|
||||||
$pdf = null;
|
$pdf = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -110,15 +110,11 @@ class EmailEntity extends BaseMailerJob implements ShouldQueue
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
// $this->failed($e);
|
|
||||||
$this->entityEmailFailed($e->getMessage());
|
$this->entityEmailFailed($e->getMessage());
|
||||||
$this->logMailError($e->getMessage(), $this->entity->client);
|
$this->logMailError($e->getMessage(), $this->entity->client);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (count(Mail::failures()) == 0) {
|
|
||||||
// $this->entityEmailSucceeded();
|
|
||||||
// }
|
|
||||||
|
|
||||||
/* Mark entity sent */
|
/* Mark entity sent */
|
||||||
$this->entity->service()->markSent()->save();
|
$this->entity->service()->markSent()->save();
|
||||||
}
|
}
|
||||||
|
@ -101,6 +101,8 @@ class Import implements ShouldQueue
|
|||||||
*/
|
*/
|
||||||
private $company;
|
private $company;
|
||||||
|
|
||||||
|
private $token;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
@ -229,6 +231,11 @@ class Import implements ShouldQueue
|
|||||||
|
|
||||||
private function processAccount(array $data) :void
|
private function processAccount(array $data) :void
|
||||||
{
|
{
|
||||||
|
if(array_key_exists('token', $data)){
|
||||||
|
$this->token = $data['token'];
|
||||||
|
unset($data['token']);
|
||||||
|
}
|
||||||
|
|
||||||
$account = $this->company->account;
|
$account = $this->company->account;
|
||||||
$account->fill($data);
|
$account->fill($data);
|
||||||
$account->save();
|
$account->save();
|
||||||
@ -965,41 +972,27 @@ class Import implements ShouldQueue
|
|||||||
$entity = Expense::where('id', $expense_id)->withTrashed()->first();
|
$entity = Expense::where('id', $expense_id)->withTrashed()->first();
|
||||||
}
|
}
|
||||||
|
|
||||||
$file_url = $resource['url'];
|
$file_url = $resource['url'];
|
||||||
$file_name = basename($file_url);
|
$file_name = $resource['name'];
|
||||||
$file_path = sys_get_temp_dir().'/'.$file_name;
|
$file_path = sys_get_temp_dir().'/'.$file_name;
|
||||||
|
|
||||||
file_put_contents($file_path, file_get_contents($file_url), LOCK_EX);
|
file_put_contents($file_path, $this->curlGet($file_url));
|
||||||
$finfo = new \finfo(FILEINFO_MIME_TYPE);
|
$finfo = new \finfo(FILEINFO_MIME_TYPE);
|
||||||
$file_info = $finfo->file($file_path);
|
$file_info = $finfo->file($file_path);
|
||||||
|
|
||||||
nlog($resource['url']);
|
$uploaded_file = new UploadedFile(
|
||||||
nlog($file_url);
|
$file_path,
|
||||||
nlog($file_name);
|
$file_name,
|
||||||
nlog($file_path);
|
$file_info,
|
||||||
nlog($file_info);
|
filesize($file_path),
|
||||||
nlog(filesize($file_path));
|
0,
|
||||||
|
false
|
||||||
$uploaded_file = new UploadedFile(
|
);
|
||||||
$file_path,
|
|
||||||
$file_name,
|
|
||||||
$file_info,
|
|
||||||
filesize($file_path),
|
|
||||||
0,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->saveDocument($uploaded_file, $entity, $is_public = true);
|
$this->saveDocument($uploaded_file, $entity, $is_public = true);
|
||||||
|
|
||||||
$uploaded_file = null;
|
|
||||||
$finfo = null;
|
|
||||||
$file_url = null;
|
|
||||||
$file_name = null;
|
|
||||||
$file_path = null;
|
|
||||||
$file_info = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function processPaymentTerms(array $data) :void
|
private function processPaymentTerms(array $data) :void
|
||||||
@ -1380,4 +1373,27 @@ $uploaded_file = new UploadedFile(
|
|||||||
|
|
||||||
info(print_r($exception->getMessage(), 1));
|
info(print_r($exception->getMessage(), 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function curlGet($url, $headers = false)
|
||||||
|
{
|
||||||
|
|
||||||
|
return $this->exec('GET', $url, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function exec($method, $url, $data)
|
||||||
|
{
|
||||||
|
nlog($this->token);
|
||||||
|
|
||||||
|
$client = new \GuzzleHttp\Client(['headers' =>
|
||||||
|
[
|
||||||
|
'X-Ninja-Token' => $this->token,
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response = $client->request('GET', $url);
|
||||||
|
|
||||||
|
return $response->getBody();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -484,7 +484,7 @@ class Client extends BaseModel implements HasLocalePreference
|
|||||||
// handle custom gateways as they are not unique'd()---------------------------------------------------------
|
// handle custom gateways as they are not unique'd()---------------------------------------------------------
|
||||||
// we need to split the query here as we allow multiple custom gateways, so we must show all of them, they query logic
|
// we need to split the query here as we allow multiple custom gateways, so we must show all of them, they query logic
|
||||||
// above only pulls in unique gateway types.. ie.. we only allow 1 credit card gateway, but many custom gateways.
|
// above only pulls in unique gateway types.. ie.. we only allow 1 credit card gateway, but many custom gateways.
|
||||||
|
|
||||||
if ($company_gateways || $company_gateways == '0') {
|
if ($company_gateways || $company_gateways == '0') {
|
||||||
$transformed_ids = $this->transformKeys(explode(',', $company_gateways));
|
$transformed_ids = $this->transformKeys(explode(',', $company_gateways));
|
||||||
$gateways = $this->company
|
$gateways = $this->company
|
||||||
@ -525,14 +525,14 @@ class Client extends BaseModel implements HasLocalePreference
|
|||||||
$fee_label = $gateway->calcGatewayFeeLabel($amount, $this);
|
$fee_label = $gateway->calcGatewayFeeLabel($amount, $this);
|
||||||
|
|
||||||
if(!$gateway_type_id){
|
if(!$gateway_type_id){
|
||||||
|
|
||||||
$payment_urls[] = [
|
$payment_urls[] = [
|
||||||
'label' => $gateway->getConfigField('name') . $fee_label,
|
'label' => $gateway->getConfigField('name') . $fee_label,
|
||||||
'company_gateway_id' => $gateway_id,
|
'company_gateway_id' => $gateway_id,
|
||||||
'gateway_type_id' => GatewayType::CREDIT_CARD,
|
'gateway_type_id' => GatewayType::CREDIT_CARD,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$payment_urls[] = [
|
$payment_urls[] = [
|
||||||
'label' => $gateway->getTypeAlias($gateway_type_id) . $fee_label,
|
'label' => $gateway->getTypeAlias($gateway_type_id) . $fee_label,
|
||||||
@ -544,6 +544,14 @@ class Client extends BaseModel implements HasLocalePreference
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (($this->getSetting('use_credits_payment') == 'option' || $this->getSetting('use_credits_payment') == 'always') && $this->service()->getCreditBalance() > 0) {
|
if (($this->getSetting('use_credits_payment') == 'option' || $this->getSetting('use_credits_payment') == 'always') && $this->service()->getCreditBalance() > 0) {
|
||||||
|
|
||||||
|
// Show credits as only payment option if both statements are true.
|
||||||
|
if (
|
||||||
|
$this->service()->getCreditBalance() > $amount
|
||||||
|
&& $this->getSetting('use_credits_payment') == 'always') {
|
||||||
|
$payment_urls = [];
|
||||||
|
}
|
||||||
|
|
||||||
$payment_urls[] = [
|
$payment_urls[] = [
|
||||||
'label' => ctrans('texts.apply_credit'),
|
'label' => ctrans('texts.apply_credit'),
|
||||||
'company_gateway_id' => CompanyGateway::GATEWAY_CREDIT,
|
'company_gateway_id' => CompanyGateway::GATEWAY_CREDIT,
|
||||||
|
@ -83,7 +83,6 @@ class Company extends BaseModel
|
|||||||
'default_task_is_date_based',
|
'default_task_is_date_based',
|
||||||
'enable_product_discount',
|
'enable_product_discount',
|
||||||
'expense_inclusive_taxes',
|
'expense_inclusive_taxes',
|
||||||
'expense_amount_is_pretax',
|
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $hidden = [
|
protected $hidden = [
|
||||||
|
@ -55,7 +55,7 @@ class Expense extends BaseModel
|
|||||||
'tax_amount2',
|
'tax_amount2',
|
||||||
'tax_amount3',
|
'tax_amount3',
|
||||||
'uses_inclusive_taxes',
|
'uses_inclusive_taxes',
|
||||||
'amount_is_pretax',
|
'calculate_tax_by_amount',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
|
@ -65,15 +65,8 @@ class Gateway extends StaticModel
|
|||||||
$link = 'https://dashboard.stripe.com/account/apikeys';
|
$link = 'https://dashboard.stripe.com/account/apikeys';
|
||||||
}
|
}
|
||||||
|
|
||||||
// $key = 'texts.gateway_help_'.$this->id;
|
|
||||||
// $str = trans($key, [
|
|
||||||
// 'link' => "<a href='$link' >Click here</a>",
|
|
||||||
// 'complete_link' => url('/complete'),
|
|
||||||
// ]);
|
|
||||||
|
|
||||||
return $link;
|
return $link;
|
||||||
|
|
||||||
//return $key != $str ? $str : '';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -93,7 +86,7 @@ class Gateway extends StaticModel
|
|||||||
break;
|
break;
|
||||||
case 20:
|
case 20:
|
||||||
return [GatewayType::CREDIT_CARD => ['refund' => true, 'token_billing' => true],
|
return [GatewayType::CREDIT_CARD => ['refund' => true, 'token_billing' => true],
|
||||||
GatewayType::BANK_TRANSFER => ['refund' => true, 'token_billing' => true],
|
GatewayType::BANK_TRANSFER => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable']],
|
||||||
GatewayType::ALIPAY => ['refund' => false, 'token_billing' => false],
|
GatewayType::ALIPAY => ['refund' => false, 'token_billing' => false],
|
||||||
GatewayType::APPLE_PAY => ['refund' => false, 'token_billing' => false]]; //Stripe
|
GatewayType::APPLE_PAY => ['refund' => false, 'token_billing' => false]]; //Stripe
|
||||||
break;
|
break;
|
||||||
|
@ -36,7 +36,7 @@ class CompanyPresenter extends EntityPresenter
|
|||||||
$settings = $this->entity->settings;
|
$settings = $this->entity->settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (strlen($settings->company_logo) > 0) ? $settings->company_logo : 'https://www.invoiceninja.com/wp-content/uploads/2019/01/InvoiceNinja-Logo-Round-300x300.png';
|
return (strlen($settings->company_logo) > 0) ? url($settings->company_logo) : 'https://www.invoiceninja.com/wp-content/uploads/2019/01/InvoiceNinja-Logo-Round-300x300.png';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function address($settings = null)
|
public function address($settings = null)
|
||||||
|
@ -91,6 +91,7 @@ class RecurringInvoice extends BaseModel
|
|||||||
'remaining_cycles',
|
'remaining_cycles',
|
||||||
'auto_bill',
|
'auto_bill',
|
||||||
'auto_bill_enabled',
|
'auto_bill_enabled',
|
||||||
|
'design_id',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
|
@ -140,11 +140,6 @@ class AuthorizeCreditCard
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private function handleResponse($data, $request)
|
private function handleResponse($data, $request)
|
||||||
{
|
{
|
||||||
$response = $data['response'];
|
$response = $data['response'];
|
||||||
@ -205,7 +200,12 @@ class AuthorizeCreditCard
|
|||||||
'data' => $this->formatGatewayResponse($data, $vars),
|
'data' => $this->formatGatewayResponse($data, $vars),
|
||||||
];
|
];
|
||||||
|
|
||||||
SystemLogger::dispatch($logger_message, SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_SUCCESS, SystemLog::TYPE_AUTHORIZE, $this->authorize->client);
|
SystemLogger::dispatch(
|
||||||
|
$logger_message,
|
||||||
|
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
||||||
|
SystemLog::EVENT_GATEWAY_SUCCESS,
|
||||||
|
SystemLog::TYPE_AUTHORIZE,
|
||||||
|
$this->authorize->client);
|
||||||
|
|
||||||
return redirect()->route('client.payments.show', ['payment' => $this->encodePrimaryKey($payment->id)]);
|
return redirect()->route('client.payments.show', ['payment' => $this->encodePrimaryKey($payment->id)]);
|
||||||
}
|
}
|
||||||
|
@ -468,4 +468,16 @@ class BaseDriver extends AbstractPaymentDriver
|
|||||||
{
|
{
|
||||||
return $this->company_gateway->id;
|
return $this->company_gateway->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function logSuccessfulGatewayResponse($response, $gateway_const)
|
||||||
|
{
|
||||||
|
|
||||||
|
SystemLogger::dispatch(
|
||||||
|
$response,
|
||||||
|
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
||||||
|
SystemLog::EVENT_GATEWAY_SUCCESS,
|
||||||
|
$gateway_const,
|
||||||
|
$this->client,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,6 +103,8 @@ class CreditCard
|
|||||||
if ($server_response->status == 'succeeded') {
|
if ($server_response->status == 'succeeded') {
|
||||||
$this->stripe->confirmGatewayFee($request);
|
$this->stripe->confirmGatewayFee($request);
|
||||||
|
|
||||||
|
$this->stripe->logSuccessfulGatewayResponse(['response' => json_decode($request->gateway_response), 'data' => $this->stripe->payment_hash], SystemLog::TYPE_STRIPE);
|
||||||
|
|
||||||
return $this->processSuccessfulPayment();
|
return $this->processSuccessfulPayment();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,8 +75,8 @@ class TaskRepository extends BaseRepository
|
|||||||
}
|
}
|
||||||
|
|
||||||
$task->time_log = json_encode($time_log);
|
$task->time_log = json_encode($time_log);
|
||||||
$task->start_time = $task->start_time ?: $task->calcStartTime();
|
// $task->start_time = $task->start_time ?: $task->calcStartTime();
|
||||||
$task->duration = $task->calcDuration();
|
// $task->duration = $task->calcDuration();
|
||||||
|
|
||||||
$task->save();
|
$task->save();
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ use App\Jobs\Entity\CreateEntityPdf;
|
|||||||
use App\Models\ClientContact;
|
use App\Models\ClientContact;
|
||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
use App\Services\AbstractService;
|
use App\Services\AbstractService;
|
||||||
|
use App\Utils\TempFile;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
|
||||||
class GetInvoicePdf extends AbstractService
|
class GetInvoicePdf extends AbstractService
|
||||||
@ -46,6 +47,12 @@ class GetInvoicePdf extends AbstractService
|
|||||||
$file_path = CreateEntityPdf::dispatchNow($invitation);
|
$file_path = CreateEntityPdf::dispatchNow($invitation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Copy from remote disk to local when using cloud file storage. */
|
||||||
|
if(config('filesystems.default') == 's3')
|
||||||
|
return TempFile::path(Storage::disk($disk)->url($file_path));
|
||||||
|
|
||||||
|
// return Storage::disk($disk)->url($file_path);
|
||||||
return Storage::disk($disk)->path($file_path);
|
return Storage::disk($disk)->path($file_path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -142,7 +142,7 @@ class RefundPayment
|
|||||||
*/
|
*/
|
||||||
private function setStatus()
|
private function setStatus()
|
||||||
{
|
{
|
||||||
if ($this->refund_data['amount'] == $this->payment->amount) {
|
if ($this->total_refund == $this->payment->amount) {
|
||||||
$this->payment->status_id = Payment::STATUS_REFUNDED;
|
$this->payment->status_id = Payment::STATUS_REFUNDED;
|
||||||
} else {
|
} else {
|
||||||
$this->payment->status_id = Payment::STATUS_PARTIALLY_REFUNDED;
|
$this->payment->status_id = Payment::STATUS_PARTIALLY_REFUNDED;
|
||||||
|
@ -111,7 +111,7 @@ trait PdfMakerUtilities
|
|||||||
{
|
{
|
||||||
foreach ($children as $child) {
|
foreach ($children as $child) {
|
||||||
$contains_html = false;
|
$contains_html = false;
|
||||||
|
|
||||||
if (isset($child['content'])) {
|
if (isset($child['content'])) {
|
||||||
$child['content'] = nl2br($child['content']);
|
$child['content'] = nl2br($child['content']);
|
||||||
}
|
}
|
||||||
@ -137,7 +137,10 @@ trait PdfMakerUtilities
|
|||||||
$_child = $this->document->createElement($child['element'], '');
|
$_child = $this->document->createElement($child['element'], '');
|
||||||
|
|
||||||
$fragment = $this->document->createDocumentFragment();
|
$fragment = $this->document->createDocumentFragment();
|
||||||
$fragment->appendXML($child['content']);
|
|
||||||
|
$fragment->appendXML(
|
||||||
|
strtr($child['content'], ['&' => '&'])
|
||||||
|
);
|
||||||
|
|
||||||
$_child->appendChild($fragment);
|
$_child->appendChild($fragment);
|
||||||
} else {
|
} else {
|
||||||
|
@ -131,7 +131,7 @@ class CompanyTransformer extends EntityTransformer
|
|||||||
'archived_at' => (int) $company->deleted_at,
|
'archived_at' => (int) $company->deleted_at,
|
||||||
'created_at' =>(int) $company->created_at,
|
'created_at' =>(int) $company->created_at,
|
||||||
'slack_webhook_url' => (string) $company->slack_webhook_url,
|
'slack_webhook_url' => (string) $company->slack_webhook_url,
|
||||||
'google_analytics_url' => (string) $company->google_analytics_key, //@deprecate
|
'google_analytics_url' => (string) $company->google_analytics_key, //@deprecate 1-2-2021
|
||||||
'google_analytics_key' => (string) $company->google_analytics_key,
|
'google_analytics_key' => (string) $company->google_analytics_key,
|
||||||
'enabled_item_tax_rates' => (int) $company->enabled_item_tax_rates,
|
'enabled_item_tax_rates' => (int) $company->enabled_item_tax_rates,
|
||||||
'client_can_register' => (bool) $company->client_can_register,
|
'client_can_register' => (bool) $company->client_can_register,
|
||||||
@ -145,13 +145,13 @@ class CompanyTransformer extends EntityTransformer
|
|||||||
'auto_start_tasks' => (bool) $company->auto_start_tasks,
|
'auto_start_tasks' => (bool) $company->auto_start_tasks,
|
||||||
'invoice_task_documents' => (bool) $company->invoice_task_documents,
|
'invoice_task_documents' => (bool) $company->invoice_task_documents,
|
||||||
'show_tasks_table' => (bool) $company->show_tasks_table,
|
'show_tasks_table' => (bool) $company->show_tasks_table,
|
||||||
'use_credits_payment' => 'always', //todo remove
|
'use_credits_payment' => 'always', // @deprecate 1-2-2021
|
||||||
'default_task_is_date_based' => (bool)$company->default_task_is_date_based,
|
'default_task_is_date_based' => (bool)$company->default_task_is_date_based,
|
||||||
'enable_product_discount' => (bool)$company->enable_product_discount,
|
'enable_product_discount' => (bool)$company->enable_product_discount,
|
||||||
'calculate_expense_tax_by_amount' =>(bool)$company->calculate_expense_tax_by_amount,
|
'calculate_expense_tax_by_amount' =>(bool)$company->calculate_expense_tax_by_amount,
|
||||||
'hide_empty_columns_on_pdf' => false, //@deprecate
|
'hide_empty_columns_on_pdf' => false, // @deprecate 1-2-2021
|
||||||
'expense_inclusive_taxes' => (bool)$company->expense_inclusive_taxes,
|
'expense_inclusive_taxes' => (bool)$company->expense_inclusive_taxes,
|
||||||
'expense_amount_is_pretax' =>( bool)$company->expense_amount_is_pretax,
|
'expense_amount_is_pretax' =>(bool)true, //@deprecate 1-2-2021
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ class ExpenseTransformer extends EntityTransformer
|
|||||||
'tax_amount2' => (float) $expense->tax_amount2,
|
'tax_amount2' => (float) $expense->tax_amount2,
|
||||||
'tax_amount3' => (float) $expense->tax_amount3,
|
'tax_amount3' => (float) $expense->tax_amount3,
|
||||||
'uses_inclusive_taxes' => (bool) $expense->uses_inclusive_taxes,
|
'uses_inclusive_taxes' => (bool) $expense->uses_inclusive_taxes,
|
||||||
'amount_is_pretax' => (bool) $expense->amount_is_pretax,
|
'calculate_tax_by_amount' => (bool) $expense->calculate_tax_by_amount,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ class TaskTransformer extends EntityTransformer
|
|||||||
'user_id' => (string) $this->encodePrimaryKey($task->user_id),
|
'user_id' => (string) $this->encodePrimaryKey($task->user_id),
|
||||||
'assigned_user_id' => (string) $this->encodePrimaryKey($task->assigned_user_id),
|
'assigned_user_id' => (string) $this->encodePrimaryKey($task->assigned_user_id),
|
||||||
'number' => (string) $task->number ?: '',
|
'number' => (string) $task->number ?: '',
|
||||||
'start_time' => (int) $task->start_time,
|
// 'start_time' => (int) $task->start_time,
|
||||||
'description' => (string) $task->description ?: '',
|
'description' => (string) $task->description ?: '',
|
||||||
'duration' => (int) $task->duration ?: 0,
|
'duration' => (int) $task->duration ?: 0,
|
||||||
'rate' => (float) $task->rate ?: 0,
|
'rate' => (float) $task->rate ?: 0,
|
||||||
|
@ -15,7 +15,7 @@ class TempFile
|
|||||||
{
|
{
|
||||||
public static function path($url) :string
|
public static function path($url) :string
|
||||||
{
|
{
|
||||||
$temp_path = tempnam(sys_get_temp_dir(), basename($url));
|
$temp_path = @tempnam(sys_get_temp_dir() . '/' . sha1(time()), basename($url));
|
||||||
copy($url, $temp_path);
|
copy($url, $temp_path);
|
||||||
|
|
||||||
return $temp_path;
|
return $temp_path;
|
||||||
|
@ -49,7 +49,7 @@ trait GeneratesCounter
|
|||||||
//todo handle if we have specific client patterns in the future
|
//todo handle if we have specific client patterns in the future
|
||||||
$pattern = $client->getSetting('invoice_number_pattern');
|
$pattern = $client->getSetting('invoice_number_pattern');
|
||||||
//Determine if we are using client_counters
|
//Determine if we are using client_counters
|
||||||
if (strpos($pattern, 'clientCounter')) {
|
if (strpos($pattern, 'clientCounter') || strpos($pattern, 'client_counter')) {
|
||||||
if (property_exists($client->settings, 'invoice_number_counter')) {
|
if (property_exists($client->settings, 'invoice_number_counter')) {
|
||||||
$counter = $client->settings->invoice_number_counter;
|
$counter = $client->settings->invoice_number_counter;
|
||||||
} else {
|
} else {
|
||||||
@ -57,7 +57,7 @@ trait GeneratesCounter
|
|||||||
}
|
}
|
||||||
|
|
||||||
$counter_entity = $client;
|
$counter_entity = $client;
|
||||||
} elseif (strpos($pattern, 'groupCounter')) {
|
} elseif (strpos($pattern, 'groupCounter') || strpos($pattern, 'group_counter')) {
|
||||||
$counter = $client->group_settings->invoice_number_counter;
|
$counter = $client->group_settings->invoice_number_counter;
|
||||||
$counter_entity = $client->group_settings;
|
$counter_entity = $client->group_settings;
|
||||||
} else {
|
} else {
|
||||||
@ -96,10 +96,10 @@ trait GeneratesCounter
|
|||||||
//todo handle if we have specific client patterns in the future
|
//todo handle if we have specific client patterns in the future
|
||||||
$pattern = $client->getSetting('credit_number_pattern');
|
$pattern = $client->getSetting('credit_number_pattern');
|
||||||
//Determine if we are using client_counters
|
//Determine if we are using client_counters
|
||||||
if (strpos($pattern, 'clientCounter')) {
|
if (strpos($pattern, 'clientCounter') || strpos($pattern, 'client_counter')) {
|
||||||
$counter = $client->settings->credit_number_counter;
|
$counter = $client->settings->credit_number_counter;
|
||||||
$counter_entity = $client;
|
$counter_entity = $client;
|
||||||
} elseif (strpos($pattern, 'groupCounter')) {
|
} elseif (strpos($pattern, 'groupCounter') || strpos($pattern, 'group_counter')) {
|
||||||
$counter = $client->group_settings->credit_number_counter;
|
$counter = $client->group_settings->credit_number_counter;
|
||||||
$counter_entity = $client->group_settings;
|
$counter_entity = $client->group_settings;
|
||||||
} else {
|
} else {
|
||||||
@ -132,10 +132,10 @@ trait GeneratesCounter
|
|||||||
//todo handle if we have specific client patterns in the future
|
//todo handle if we have specific client patterns in the future
|
||||||
$pattern = $client->getSetting('quote_number_pattern');
|
$pattern = $client->getSetting('quote_number_pattern');
|
||||||
//Determine if we are using client_counters
|
//Determine if we are using client_counters
|
||||||
if (strpos($pattern, 'clientCounter')) {
|
if (strpos($pattern, 'clientCounter') || strpos($pattern, 'client_counter')) {
|
||||||
$counter = $client->settings->{$used_counter};
|
$counter = $client->settings->{$used_counter};
|
||||||
$counter_entity = $client;
|
$counter_entity = $client;
|
||||||
} elseif (strpos($pattern, 'groupCounter')) {
|
} elseif (strpos($pattern, 'groupCounter') || strpos($pattern, 'group_counter')) {
|
||||||
$counter = $client->group_settings->{$used_counter};
|
$counter = $client->group_settings->{$used_counter};
|
||||||
$counter_entity = $client->group_settings;
|
$counter_entity = $client->group_settings;
|
||||||
} else {
|
} else {
|
||||||
|
@ -95,6 +95,8 @@ trait MakesDates
|
|||||||
|
|
||||||
private function convertToDateObject($date)
|
private function convertToDateObject($date)
|
||||||
{
|
{
|
||||||
return new DateTime($date);
|
$dt = new DateTime($date);
|
||||||
|
$dt->setTimezone(new DateTimeZone('UTC'));
|
||||||
|
return $dt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,14 +22,9 @@ trait Uploadable
|
|||||||
{
|
{
|
||||||
public function removeLogo($company)
|
public function removeLogo($company)
|
||||||
{
|
{
|
||||||
$company_logo = $company->settings->company_logo;
|
|
||||||
|
|
||||||
$file_name = basename($company_logo);
|
if (Storage::exists($company->settings->company_logo)) {
|
||||||
|
UnlinkFile::dispatchNow(config('filesystems.default'), $company->settings->company_logo);
|
||||||
$storage_path = $company->company_key . '/' . $file_name;
|
|
||||||
|
|
||||||
if (Storage::exists($storage_path)) {
|
|
||||||
UnlinkFile::dispatchNow(config('filesystems.default'), $storage_path);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,6 +33,8 @@ trait Uploadable
|
|||||||
if ($file) {
|
if ($file) {
|
||||||
$path = UploadAvatar::dispatchNow($file, $company->company_key);
|
$path = UploadAvatar::dispatchNow($file, $company->company_key);
|
||||||
|
|
||||||
|
$path = str_replace(config("ninja.app_url"), "", $path);
|
||||||
|
|
||||||
info("the path {$path}");
|
info("the path {$path}");
|
||||||
|
|
||||||
if ($path) {
|
if ($path) {
|
||||||
|
12
composer.lock
generated
12
composer.lock
generated
@ -206,16 +206,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "beganovich/snappdf",
|
"name": "beganovich/snappdf",
|
||||||
"version": "v1.4.0",
|
"version": "v1.5.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/beganovich/snappdf.git",
|
"url": "https://github.com/beganovich/snappdf.git",
|
||||||
"reference": "2c878714145ef110cfec991c2e72cb6aeee7ed43"
|
"reference": "63ad3f1a0eec7bffc3a3c85f286769fca9a33fd5"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/beganovich/snappdf/zipball/2c878714145ef110cfec991c2e72cb6aeee7ed43",
|
"url": "https://api.github.com/repos/beganovich/snappdf/zipball/63ad3f1a0eec7bffc3a3c85f286769fca9a33fd5",
|
||||||
"reference": "2c878714145ef110cfec991c2e72cb6aeee7ed43",
|
"reference": "63ad3f1a0eec7bffc3a3c85f286769fca9a33fd5",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -253,9 +253,9 @@
|
|||||||
"description": "Convert webpages or HTML into the PDF file using Chromium or Google Chrome.",
|
"description": "Convert webpages or HTML into the PDF file using Chromium or Google Chrome.",
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/beganovich/snappdf/issues",
|
"issues": "https://github.com/beganovich/snappdf/issues",
|
||||||
"source": "https://github.com/beganovich/snappdf/tree/v1.4.0"
|
"source": "https://github.com/beganovich/snappdf/tree/v1.5.0"
|
||||||
},
|
},
|
||||||
"time": "2021-01-03T20:26:24+00:00"
|
"time": "2021-01-10T17:06:47+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "brick/math",
|
"name": "brick/math",
|
||||||
|
@ -13,7 +13,7 @@ return [
|
|||||||
'require_https' => env('REQUIRE_HTTPS', true),
|
'require_https' => env('REQUIRE_HTTPS', true),
|
||||||
'app_url' => rtrim(env('APP_URL', ''), '/'),
|
'app_url' => rtrim(env('APP_URL', ''), '/'),
|
||||||
'app_domain' => env('APP_DOMAIN', ''),
|
'app_domain' => env('APP_DOMAIN', ''),
|
||||||
'app_version' => '5.0.45',
|
'app_version' => '5.0.46',
|
||||||
'minimum_client_version' => '5.0.16',
|
'minimum_client_version' => '5.0.16',
|
||||||
'terms_version' => '1.0.1',
|
'terms_version' => '1.0.1',
|
||||||
'api_secret' => env('API_SECRET', false),
|
'api_secret' => env('API_SECRET', false),
|
||||||
|
@ -0,0 +1,56 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Models\Company;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class FixCompanySettingsUrl extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
|
||||||
|
Company::all()->each(function ($company){
|
||||||
|
|
||||||
|
$settings = $company->settings;
|
||||||
|
|
||||||
|
$company_logo = $settings->company_logo;
|
||||||
|
$company_logo = str_replace(config('ninja.app_url'), '', $company_logo);
|
||||||
|
|
||||||
|
$settings->company_logo = $company_logo;
|
||||||
|
|
||||||
|
$company->settings = $settings;
|
||||||
|
$company->save();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('companies', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('logo');
|
||||||
|
$table->dropColumn('expense_amount_is_pretax');
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('tasks', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('start_time');
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('expenses', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('amount_is_pretax');
|
||||||
|
$table->boolean('calculate_tax_by_amount')->default(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
4
public/flutter_service_worker.js
vendored
4
public/flutter_service_worker.js
vendored
@ -30,8 +30,8 @@ const RESOURCES = {
|
|||||||
"assets/FontManifest.json": "cf3c681641169319e61b61bd0277378f",
|
"assets/FontManifest.json": "cf3c681641169319e61b61bd0277378f",
|
||||||
"assets/fonts/MaterialIcons-Regular.otf": "1288c9e28052e028aba623321f7826ac",
|
"assets/fonts/MaterialIcons-Regular.otf": "1288c9e28052e028aba623321f7826ac",
|
||||||
"/": "23224b5e03519aaa87594403d54412cf",
|
"/": "23224b5e03519aaa87594403d54412cf",
|
||||||
"version.json": "1a0a7ed91cd721a8aad41df0c5f792b3",
|
"version.json": "6b7a4ad416a3730ae32b64e007cef7f3",
|
||||||
"main.dart.js": "3da75d88201ca57797d16afdf5b37442",
|
"main.dart.js": "1cacb64d223fcfa75d0a4838a1fab6f4",
|
||||||
"favicon.png": "dca91c54388f52eded692718d5a98b8b"
|
"favicon.png": "dca91c54388f52eded692718d5a98b8b"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
184059
public/main.dart.js
vendored
184059
public/main.dart.js
vendored
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
|||||||
{"app_name":"invoiceninja_flutter","version":"5.0.37","build_number":"37"}
|
{"app_name":"invoiceninja_flutter","version":"5.0.38","build_number":"38"}
|
@ -8,7 +8,7 @@
|
|||||||
@endpush
|
@endpush
|
||||||
|
|
||||||
@section('body')
|
@section('body')
|
||||||
<form action="{{ route('client.payments.process') }}" method="post" id="payment-form">
|
<form action="{{ route('client.payments.process') }}" method="post" id="payment-form" onkeypress="return event.keyCode != 13;">
|
||||||
@csrf
|
@csrf
|
||||||
<input type="hidden" name="company_gateway_id" id="company_gateway_id">
|
<input type="hidden" name="company_gateway_id" id="company_gateway_id">
|
||||||
<input type="hidden" name="payment_method_id" id="payment_method_id">
|
<input type="hidden" name="payment_method_id" id="payment_method_id">
|
||||||
@ -118,21 +118,28 @@
|
|||||||
<!-- App\Utils\Number::formatMoney($invoice->amount, $invoice->client) -->
|
<!-- App\Utils\Number::formatMoney($invoice->amount, $invoice->client) -->
|
||||||
<!-- Disabled input field don't send it's value with request. -->
|
<!-- Disabled input field don't send it's value with request. -->
|
||||||
@if(!$settings->client_portal_allow_under_payment && !$settings->client_portal_allow_over_payment)
|
@if(!$settings->client_portal_allow_under_payment && !$settings->client_portal_allow_over_payment)
|
||||||
<input
|
<label>
|
||||||
name="payable_invoices[{{$key}}][amount]"
|
{{ $invoice->client->currency()->code }} ({{ $invoice->client->currency()->symbol }})
|
||||||
value="{{ $invoice->partial > 0 ? $invoice->partial : $invoice->balance }}"
|
|
||||||
class="mt-1 text-sm text-gray-800"
|
<input
|
||||||
readonly />
|
name="payable_invoices[{{$key}}][amount]"
|
||||||
|
value="{{ $invoice->partial > 0 ? $invoice->partial : $invoice->balance }}"
|
||||||
|
class="mt-1 text-sm text-gray-800"
|
||||||
|
readonly />
|
||||||
|
</label>
|
||||||
@else
|
@else
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<input
|
<label>
|
||||||
type="text"
|
|
||||||
class="input mt-0 mr-4 relative"
|
|
||||||
name="payable_invoices[{{$key}}][amount]"
|
|
||||||
value="{{ $invoice->partial > 0 ? $invoice->partial : $invoice->balance }}"/>
|
|
||||||
<span class="mt-2">{{ $invoice->client->currency()->code }} ({{ $invoice->client->currency()->symbol }})</span>
|
<span class="mt-2">{{ $invoice->client->currency()->code }} ({{ $invoice->client->currency()->symbol }})</span>
|
||||||
|
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
class="input mt-0 mr-4 relative"
|
||||||
|
name="payable_invoices[{{$key}}][amount]"
|
||||||
|
value="{{ $invoice->partial > 0 ? $invoice->partial : $invoice->balance }}"/>
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if($settings->client_portal_allow_under_payment)
|
@if($settings->client_portal_allow_under_payment)
|
||||||
<span class="mt-1 text-sm text-gray-800">{{ ctrans('texts.minimum_payment') }}: {{ $settings->client_portal_under_payment_minimum }}</span>
|
<span class="mt-1 text-sm text-gray-800">{{ ctrans('texts.minimum_payment') }}: {{ $settings->client_portal_under_payment_minimum }}</span>
|
||||||
@ -156,4 +163,4 @@
|
|||||||
|
|
||||||
@push('footer')
|
@push('footer')
|
||||||
<script src="{{ asset('js/clients/invoices/payment.js') }}"></script>
|
<script src="{{ asset('js/clients/invoices/payment.js') }}"></script>
|
||||||
@endpush
|
@endpush
|
||||||
|
8374
swagger.json
8374
swagger.json
File diff suppressed because it is too large
Load Diff
@ -71,7 +71,6 @@ class TaskApiTest extends TestCase
|
|||||||
$arr = $response->json();
|
$arr = $response->json();
|
||||||
$response->assertStatus(200);
|
$response->assertStatus(200);
|
||||||
|
|
||||||
$this->assertGreaterThan(0, $arr['data']['start_time']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testTaskPut()
|
public function testTaskPut()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user