mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Merge pull request #8246 from turbo124/v5-develop
Fixes for vendor imports using CSV
This commit is contained in:
commit
87f843dd7d
@ -1 +1 @@
|
||||
5.5.65
|
||||
5.5.66
|
@ -149,12 +149,18 @@ class PaymentController extends Controller
|
||||
$payment = $payment->service()->applyCredits($payment_hash)->save();
|
||||
|
||||
$invoices = Invoice::whereIn('id', $this->transformKeys(array_column($payment_hash->invoices(), 'invoice_id')));
|
||||
|
||||
$invoices->each(function ($i){
|
||||
$i->is_proforma = false;
|
||||
$i->saveQuietly();
|
||||
});
|
||||
|
||||
event('eloquent.created: App\Models\Payment', $payment);
|
||||
|
||||
if($invoices->sum('balance') > 0){
|
||||
|
||||
$invoice = $invoices->first();
|
||||
$invoice->service()->touchPdf(true);
|
||||
|
||||
return redirect()->route('client.invoice.show', ['invoice' => $invoice->hashed_id, 'hash' => $request->input('hash')]);
|
||||
}
|
||||
|
@ -494,7 +494,7 @@ class CompanyController extends BaseController
|
||||
$account->delete();
|
||||
|
||||
if (Ninja::isHosted()) {
|
||||
\Modules\Admin\Jobs\Account\NinjaDeletedAccount::dispatch($account_key, $request->all());
|
||||
\Modules\Admin\Jobs\Account\NinjaDeletedAccount::dispatch($account_key, $request->all(), auth()->user()->email);
|
||||
}
|
||||
|
||||
LightLogs::create(new AccountDeleted())
|
||||
|
@ -52,6 +52,7 @@ class InvoicesTable extends Component
|
||||
$query = Invoice::query()
|
||||
->where('company_id', $this->company->id)
|
||||
->where('is_deleted', false)
|
||||
->where('is_proforma', false)
|
||||
->with('client.gateway_tokens', 'client.contacts')
|
||||
->orderBy($this->sort_field, $this->sort_asc ? 'asc' : 'desc');
|
||||
|
||||
|
@ -227,6 +227,8 @@ class BaseImport
|
||||
];
|
||||
|
||||
nlog("Ingest {$ex->getMessage()}");
|
||||
nlog($record);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -368,7 +370,7 @@ class BaseImport
|
||||
$payment_data['invoices'] = [
|
||||
[
|
||||
'invoice_id' => $invoice->id,
|
||||
'amount' => $payment_data['amount'] ?? null,
|
||||
'amount' => min($invoice->amount, $payment_data['amount']) ?? null,
|
||||
],
|
||||
];
|
||||
|
||||
|
@ -52,17 +52,6 @@ class VendorTransformer extends BaseTransformer
|
||||
'custom_value2' => $this->getString($data, 'vendor.custom_value2'),
|
||||
'custom_value3' => $this->getString($data, 'vendor.custom_value3'),
|
||||
'custom_value4' => $this->getString($data, 'vendor.custom_value4'),
|
||||
// 'vendor_contacts' => [
|
||||
// [
|
||||
// 'first_name' => $this->getString(
|
||||
// $data,
|
||||
// 'vendor.first_name'
|
||||
// ),
|
||||
// 'last_name' => $this->getString($data, 'vendor.last_name'),
|
||||
// 'email' => $this->getString($data, 'vendor.email'),
|
||||
// 'phone' => $this->getString($data, 'vendor.phone'),
|
||||
// ],
|
||||
// ],
|
||||
'contacts' => [
|
||||
[
|
||||
'first_name' => $this->getString(
|
||||
@ -70,7 +59,7 @@ class VendorTransformer extends BaseTransformer
|
||||
'contact.first_name'
|
||||
),
|
||||
'last_name' => $this->getString($data, 'contact.last_name'),
|
||||
'email' => $this->getString($data, 'contact.email'),
|
||||
'email' => strlen($this->getString($data, 'contact.email')) > 1 ? $this->getString($data, 'contact.email') : $this->getString($data, 'vendor.email'),
|
||||
'phone' => $this->getString($data, 'contact.phone'),
|
||||
'custom_value1' => $this->getString(
|
||||
$data,
|
||||
|
@ -80,7 +80,11 @@ class ZipQuotes implements ShouldQueue
|
||||
$path = $this->quotes->first()->client->quote_filepath($invitation);
|
||||
|
||||
$this->quotes->each(function ($quote) {
|
||||
|
||||
$quote->service()->createInvitations();
|
||||
|
||||
(new CreateEntityPdf($quote->invitations()->first()))->handle();
|
||||
|
||||
});
|
||||
|
||||
try {
|
||||
|
@ -13,6 +13,8 @@ namespace App\Listeners\Subscription;
|
||||
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\Account;
|
||||
use App\Models\Company;
|
||||
use App\Notifications\Ninja\RenewalFailureNotification;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Imdhemy\Purchases\Events\AppStore\DidRenew;
|
||||
|
||||
@ -38,10 +40,18 @@ class AppStoreRenewSubscription implements ShouldQueue
|
||||
|
||||
$inapp_transaction_id = $event->getSubscriptionId(); //$subscription_id
|
||||
|
||||
nlog("inapp upgrade processing for = {$inapp_transaction_id}");
|
||||
|
||||
MultiDB::findAndSetDbByInappTransactionId($inapp_transaction_id);
|
||||
|
||||
$account = Account::where('inapp_transaction_id', $inapp_transaction_id)->first();
|
||||
|
||||
if(!$account) {
|
||||
$ninja_company = Company::on('db-ninja-01')->find(config('ninja.ninja_default_company_id'));
|
||||
$ninja_company->notification(new RenewalFailureNotification("{$inapp_transaction_id}"))->ninja();
|
||||
return;
|
||||
}
|
||||
|
||||
if($account->plan_term == 'month')
|
||||
$account->plan_expires = now()->addMonth();
|
||||
elseif($account->plan_term == 'year')
|
||||
|
@ -145,7 +145,7 @@ class VendorContact extends Authenticatable implements HasLocalePreference
|
||||
{
|
||||
return $this
|
||||
->withTrashed()
|
||||
->company()
|
||||
// ->company()
|
||||
->where('id', $this->decodePrimaryKey($value))
|
||||
->firstOrFail();
|
||||
}
|
||||
|
@ -30,13 +30,7 @@ class ClientAccountNotFound extends Notification
|
||||
* @return void
|
||||
*/
|
||||
|
||||
|
||||
protected string $account_key;
|
||||
|
||||
public function __construct(string $account_key)
|
||||
{
|
||||
$this->account_key = $account_key;
|
||||
}
|
||||
public function __construct(protected string $account_key, protected string $email){}
|
||||
|
||||
/**
|
||||
* Get the notification's delivery channels.
|
||||
@ -77,6 +71,7 @@ class ClientAccountNotFound extends Notification
|
||||
|
||||
$content = "Client not found, unable to remove account\n";
|
||||
$content .= "Account: {$this->account_key }\n";
|
||||
$content .= "Email: {$this->email}\n";
|
||||
|
||||
return (new SlackMessage)
|
||||
->success()
|
||||
|
@ -68,7 +68,7 @@ class RenewalFailureNotification extends Notification
|
||||
public function toSlack($notifiable)
|
||||
{
|
||||
$content = "Plan paid, account not updated\n";
|
||||
$content .= "Contact: {$this->notification_message}";
|
||||
$content .= "Contact/Inapp Purchase: {$this->notification_message}";
|
||||
|
||||
return (new SlackMessage)
|
||||
->success()
|
||||
|
@ -38,9 +38,14 @@ class UserObserver
|
||||
*/
|
||||
public function updated(User $user)
|
||||
{
|
||||
// if (Ninja::isHosted() && $user->isDirty('phone')) {
|
||||
// VerifyPhone::dispatch($user);
|
||||
// }
|
||||
|
||||
if (Ninja::isHosted() && $user->isDirty('email') && $user->company_users()->where('is_owner', true)->exists()) {
|
||||
//ensure they are owner user and update email on file.
|
||||
if(class_exists(\Modules\Admin\Jobs\Account\UpdateOwnerUser::class))
|
||||
\Modules\Admin\Jobs\Account\UpdateOwnerUser::dispatch($user->account->key, $user, $user->getOriginal('email'));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -99,7 +99,7 @@ class SquarePaymentDriver extends BaseDriver
|
||||
|
||||
$amount_money = new \Square\Models\Money();
|
||||
$amount_money->setAmount($this->convertAmount($amount));
|
||||
$amount_money->setCurrency($this->square_driver->client->currency()->code);
|
||||
$amount_money->setCurrency($this->client->currency()->code);
|
||||
|
||||
$body = new \Square\Models\RefundPaymentRequest(\Illuminate\Support\Str::random(32), $amount_money, $payment->transaction_reference);
|
||||
|
||||
|
@ -193,7 +193,7 @@ class InstantPayment
|
||||
$payment_method_id = $this->request->input('payment_method_id');
|
||||
$invoice_totals = $payable_invoices->sum('amount');
|
||||
$first_invoice = $invoices->first();
|
||||
$credit_totals = $first_invoice->client->getSetting('use_credits_payment') == 'always' ? $first_invoice->client->service()->getCreditBalance() : 0;
|
||||
$credit_totals = in_array($first_invoice->client->getSetting('use_credits_payment'), ['always', 'option']) ? $first_invoice->client->service()->getCreditBalance() : 0;
|
||||
$starting_invoice_amount = $first_invoice->balance;
|
||||
|
||||
/* Schedule a job to check the gateway fees for this invoice*/
|
||||
@ -297,7 +297,7 @@ class InstantPayment
|
||||
}
|
||||
|
||||
public function processCreditPayment(Request $request, array $data)
|
||||
{
|
||||
{
|
||||
return render('gateways.credit.index', $data);
|
||||
}
|
||||
}
|
||||
|
@ -271,6 +271,7 @@ class CreditService
|
||||
|
||||
public function restoreCredit()
|
||||
{
|
||||
|
||||
$this->credit
|
||||
->client
|
||||
->service()
|
||||
|
@ -138,7 +138,7 @@ class DeletePayment
|
||||
private function updateCreditables()
|
||||
{
|
||||
if ($this->payment->credits()->exists()) {
|
||||
$this->payment->credits()->each(function ($paymentable_credit) {
|
||||
$this->payment->credits()->where('is_deleted',0)->each(function ($paymentable_credit) {
|
||||
$multiplier = 1;
|
||||
|
||||
if ($paymentable_credit->pivot->amount < 0) {
|
||||
|
@ -36,6 +36,7 @@ use App\Models\Subscription;
|
||||
use App\Models\SystemLog;
|
||||
use App\Repositories\CreditRepository;
|
||||
use App\Repositories\InvoiceRepository;
|
||||
use App\Repositories\PaymentRepository;
|
||||
use App\Repositories\RecurringInvoiceRepository;
|
||||
use App\Repositories\SubscriptionRepository;
|
||||
use App\Services\Subscription\ZeroCostProduct;
|
||||
@ -58,6 +59,8 @@ class SubscriptionService
|
||||
/** @var subscription */
|
||||
private $subscription;
|
||||
|
||||
private float $credit_payments = 0;
|
||||
|
||||
public function __construct(Subscription $subscription)
|
||||
{
|
||||
$this->subscription = $subscription;
|
||||
@ -530,13 +533,43 @@ class SubscriptionService
|
||||
->orderBy('id', 'desc')
|
||||
->first();
|
||||
|
||||
if($this->calculateProRataRefundForSubscription($last_invoice) > 0)
|
||||
//if last payment was created from a credit, do not generate a new credit, refund the old one.
|
||||
|
||||
if($last_invoice) {
|
||||
|
||||
|
||||
$last_invoice->payments->each(function ($payment){
|
||||
|
||||
$payment->credits()->where('is_deleted', 0)->each(function ($credit){
|
||||
|
||||
$this->credit_payments += $credit->pivot->sum('amount');
|
||||
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
$invoice_repo = new InvoiceRepository();
|
||||
|
||||
$invoice_repo->delete($last_invoice);
|
||||
|
||||
$payment_repo = new PaymentRepository(new CreditRepository());
|
||||
|
||||
$last_invoice->payments->each(function ($payment) use ($payment_repo){
|
||||
$payment_repo->delete($payment);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
//if there are existing credit payments, then we refund directly to the credit.
|
||||
if($this->calculateProRataRefundForSubscription($last_invoice) > 0 && $this->credit_payments == 0)
|
||||
$credit = $this->createCredit($last_invoice, $target_subscription, false);
|
||||
|
||||
$new_recurring_invoice = $this->createNewRecurringInvoice($recurring_invoice);
|
||||
|
||||
$invoice = $this->changePlanInvoice($target_subscription, $recurring_invoice->client_id);
|
||||
$invoice->recurring_id = $new_recurring_invoice->id;
|
||||
$invoice->is_proforma = false;
|
||||
$invoice->save();
|
||||
|
||||
$payment = PaymentFactory::create($invoice->company_id, $invoice->user_id, $invoice->client_id);
|
||||
@ -545,7 +578,7 @@ class SubscriptionService
|
||||
$payment->is_manual = true;
|
||||
$payment->save();
|
||||
|
||||
$payment->service()->applyCreditsToInvoice($invoice);
|
||||
$payment->service()->applyNumber()->applyCreditsToInvoice($invoice);
|
||||
|
||||
$context = [
|
||||
'context' => 'change_plan',
|
||||
|
@ -296,7 +296,7 @@ class HtmlEngine
|
||||
$data['$portal_url'] = ['value' => $this->invitation->getPortalLink(), 'label' =>''];
|
||||
|
||||
$data['$entity_number'] = &$data['$number'];
|
||||
$data['$invoice.discount'] = ['value' => Number::formatMoney($this->entity_calc->getTotalDiscount(), $this->client) ?: ' ', 'label' => ($this->entity->is_amount_discount) ? ctrans('texts.discount') : ctrans('texts.discount').' '.$this->entity->discount.'%'];
|
||||
$data['$invoice.discount'] = ['value' => Number::formatMoney($this->entity_calc->getTotalDiscount(), $this->client) ?: ' ', 'label' => ($this->entity->is_amount_discount) ? ctrans('texts.discount') : ctrans('texts.discount').' '.$this->entity->discount.'%'];
|
||||
$data['$discount'] = &$data['$invoice.discount'];
|
||||
$data['$subtotal'] = ['value' => Number::formatMoney($this->entity_calc->getSubTotal(), $this->client) ?: ' ', 'label' => ctrans('texts.subtotal')];
|
||||
$data['$gross_subtotal'] = ['value' => Number::formatMoney($this->entity_calc->getGrossSubTotal(), $this->client) ?: ' ', 'label' => ctrans('texts.subtotal')];
|
||||
|
@ -14,8 +14,8 @@ return [
|
||||
'require_https' => env('REQUIRE_HTTPS', true),
|
||||
'app_url' => rtrim(env('APP_URL', ''), '/'),
|
||||
'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
|
||||
'app_version' => '5.5.65',
|
||||
'app_tag' => '5.5.65',
|
||||
'app_version' => '5.5.66',
|
||||
'app_tag' => '5.5.66',
|
||||
'minimum_client_version' => '5.0.16',
|
||||
'terms_version' => '1.0.1',
|
||||
'api_secret' => env('API_SECRET', ''),
|
||||
|
@ -101,7 +101,7 @@
|
||||
<div class="mt-4">
|
||||
@foreach($subscription->service()->getPlans() as $_subscription)
|
||||
<button class="mt-8 mr-2">
|
||||
<a class="border mt-4 bg-white rounded py-2 px-4 hover:bg-gray-100 text-sm" target="_blank" href="{{ route('client.subscription.purchase', $_subscription->hashed_id) }}">{{ $_subscription->name }}</a>
|
||||
<a class="border mt-4 bg-white rounded py-2 px-4 hover:bg-gray-100 text-sm" href="{{ route('client.subscription.purchase', $_subscription->hashed_id) }}">{{ $_subscription->name }}</a>
|
||||
</button>
|
||||
@endforeach
|
||||
</div>
|
||||
|
Loading…
x
Reference in New Issue
Block a user