1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-09-21 08:51:34 +02:00

Merge pull request #4758 from turbo124/v5-develop

Fix for updating quote
This commit is contained in:
David Bomba 2021-01-25 22:23:35 +11:00 committed by GitHub
commit 337afe5220
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 83 additions and 131 deletions

View File

@ -223,7 +223,7 @@ class CreateSingleAccount extends Command
'company_id' => $company->id,
]);
$client->id_number = $this->getNextClientNumber($client);
$client->number = $this->getNextClientNumber($client);
$settings = $client->settings;
$settings->currency_id = "1";

View File

@ -400,7 +400,7 @@ class CreateTestData extends Command
'company_id' => $company->id,
]);
$client->id_number = $this->getNextClientNumber($client);
$client->number = $this->getNextClientNumber($client);
$settings = $client->settings;
$settings->currency_id = (string) rand(1, 79);

View File

@ -286,7 +286,7 @@ class DemoMode extends Command
'company_id' => $company->id,
]);
$client->id_number = $this->getNextClientNumber($client);
$client->number = $this->getNextClientNumber($client);
$settings = $client->settings;
$settings->currency_id = (string) rand(1, 3);

View File

@ -33,6 +33,7 @@
* @OA\Property(property="custom_value4", type="string", example="", description="________"),
* @OA\Property(property="vat_number", type="string", example="", description="________"),
* @OA\Property(property="id_number", type="string", example="", description="________"),
* @OA\Property(property="number", type="string", example="", description="________"),
* @OA\Property(property="shipping_address1", type="string", example="", description="________"),
* @OA\Property(property="shipping_address2", type="string", example="", description="________"),
* @OA\Property(property="shipping_city", type="string", example="", description="________"),

View File

@ -35,6 +35,7 @@
* @OA\Property(property="custom_value4", type="string", example="", description="________"),
* @OA\Property(property="vat_number", type="string", example="", description="________"),
* @OA\Property(property="id_number", type="string", example="", description="________"),
* @OA\Property(property="number", type="string", example="", description="________"),
* @OA\Property(property="is_deleted", type="boolean", example=true, description="________"),
* @OA\Property(property="last_login", type="number", format="integer", example="134341234234", description="Timestamp"),
* @OA\Property(property="created_at", type="number", format="integer", example="134341234234", description="Timestamp"),

View File

@ -32,51 +32,6 @@ class StoreQuoteRequest extends Request
return auth()->user()->can('create', Quote::class);
}
protected function prepareForValidation()
{
$input = $this->all();
if (array_key_exists('design_id', $input) && is_string($input['design_id'])) {
$input['design_id'] = $this->decodePrimaryKey($input['design_id']);
}
if ($input['client_id']) {
$input['client_id'] = $this->decodePrimaryKey($input['client_id']);
}
if (array_key_exists('assigned_user_id', $input) && is_string($input['assigned_user_id'])) {
$input['assigned_user_id'] = $this->decodePrimaryKey($input['assigned_user_id']);
}
if (isset($input['client_contacts'])) {
foreach ($input['client_contacts'] as $key => $contact) {
if (! array_key_exists('send_email', $contact) || ! array_key_exists('id', $contact)) {
unset($input['client_contacts'][$key]);
}
}
}
if (isset($input['invitations'])) {
foreach ($input['invitations'] as $key => $value) {
if (isset($input['invitations'][$key]['id']) && is_numeric($input['invitations'][$key]['id'])) {
unset($input['invitations'][$key]['id']);
}
if (isset($input['invitations'][$key]['id']) && is_string($input['invitations'][$key]['id'])) {
$input['invitations'][$key]['id'] = $this->decodePrimaryKey($input['invitations'][$key]['id']);
}
if (is_string($input['invitations'][$key]['client_contact_id'])) {
$input['invitations'][$key]['client_contact_id'] = $this->decodePrimaryKey($input['invitations'][$key]['client_contact_id']);
}
}
}
$input['line_items'] = isset($input['line_items']) ? $this->cleanItems($input['line_items']) : [];
//$input['line_items'] = json_encode($input['line_items']);
$this->replace($input);
}
public function rules()
{
$rules = [];
@ -98,4 +53,17 @@ class StoreQuoteRequest extends Request
return $rules;
}
protected function prepareForValidation()
{
$input = $this->all();
$input = $this->decodePrimaryKeys($input);
$input['line_items'] = isset($input['line_items']) ? $this->cleanItems($input['line_items']) : [];
$input['amount'] = 0;
$input['balance'] = 0;
$this->replace($input);
}
}

View File

@ -59,22 +59,12 @@ class UpdateQuoteRequest extends Request
{
$input = $this->all();
if (array_key_exists('design_id', $input) && is_string($input['design_id'])) {
$input['design_id'] = $this->decodePrimaryKey($input['design_id']);
}
if (isset($input['client_id'])) {
$input['client_id'] = $this->decodePrimaryKey($input['client_id']);
}
$input = $this->decodePrimaryKeys($input);
if (isset($input['line_items'])) {
$input['line_items'] = isset($input['line_items']) ? $this->cleanItems($input['line_items']) : [];
}
if (array_key_exists('assigned_user_id', $input) && is_string($input['assigned_user_id'])) {
$input['assigned_user_id'] = $this->decodePrimaryKey($input['assigned_user_id']);
}
if (array_key_exists('documents', $input)) {
unset($input['documents']);
}

View File

@ -123,6 +123,7 @@ class PaymentEmailEngine extends BaseEmailEngine
$data['$address1'] = ['value' => $this->client->address1 ?: ' ', 'label' => ctrans('texts.address1')];
$data['$address2'] = ['value' => $this->client->address2 ?: ' ', 'label' => ctrans('texts.address2')];
$data['$id_number'] = ['value' => $this->client->id_number ?: ' ', 'label' => ctrans('texts.id_number')];
$data['$client.number'] = ['value' => $this->client->number ?: ' ', 'label' => ctrans('texts.number')];
$data['$vat_number'] = ['value' => $this->client->vat_number ?: ' ', 'label' => ctrans('texts.vat_number')];
$data['$website'] = ['value' => $this->client->present()->website() ?: ' ', 'label' => ctrans('texts.website')];
$data['$phone'] = ['value' => $this->client->present()->phone() ?: ' ', 'label' => ctrans('texts.phone')];

View File

@ -73,7 +73,8 @@ class Client extends BaseModel implements HasLocalePreference
'id_number',
'group_settings_id',
'public_notes',
'phone'
'phone',
'number',
];
protected $with = [

View File

@ -44,6 +44,7 @@ class Vendor extends BaseModel
'custom_value2',
'custom_value3',
'custom_value4',
'number',
];
protected $casts = [

View File

@ -94,6 +94,7 @@ class AuthorizePaymentMethod
if ($client_gateway_token = $this->authorize->findClientGatewayRecord()) {
$payment_profile = $this->addPaymentMethodToClient($client_gateway_token->gateway_customer_reference, $data);
$gateway_customer_reference = $client_gateway_token->gateway_customer_reference;
} else {
$gateway_customer_reference = (new AuthorizeCreateCustomer($this->authorize, $this->authorize->client))->create($data);
$payment_profile = $this->addPaymentMethodToClient($gateway_customer_reference, $data);

View File

@ -60,8 +60,8 @@ class ClientRepository extends BaseRepository
$client->fill($data);
if (!isset($client->id_number) || empty($client->id_number)) {
$client->id_number = $this->getNextClientNumber($client);
if (!isset($client->number) || empty($client->number)) {
$client->number = $this->getNextClientNumber($client);
}
if (empty($data['name'])) {

View File

@ -47,8 +47,8 @@ class VendorRepository extends BaseRepository
$vendor->save();
if ($vendor->id_number == '' || ! $vendor->id_number) {
$vendor->id_number = $this->getNextVendorNumber($vendor);
if ($vendor->number == '' || ! $vendor->number) {
$vendor->number = $this->getNextVendorNumber($vendor);
} //todo write tests for this and make sure that custom vendor numbers also works as expected from here
$vendor->save();

View File

@ -41,6 +41,7 @@ class CreateInvitations
$invitation = QuoteInvitation::whereCompanyId($this->quote->company_id)
->whereClientContactId($contact->id)
->whereQuoteId($this->quote->id)
->withTrashed()
->first();
if (! $invitation && $contact->send_email) {

View File

@ -147,6 +147,7 @@ class ClientTransformer extends EntityTransformer
'archived_at' => (int) $client->deleted_at,
'created_at' => (int) $client->created_at,
'display_name' => $client->present()->name(),
'number' => (string) $client->number ?: '',
];
}
}

View File

@ -216,6 +216,7 @@ class HtmlEngine
$data['$address1'] = ['value' => $this->client->address1 ?: ' ', 'label' => ctrans('texts.address1')];
$data['$address2'] = ['value' => $this->client->address2 ?: ' ', 'label' => ctrans('texts.address2')];
$data['$id_number'] = ['value' => $this->client->id_number ?: ' ', 'label' => ctrans('texts.id_number')];
$data['$client.number'] = ['value' => $this->client->number ?: ' ', 'label' => ctrans('texts.number')];
$data['$vat_number'] = ['value' => $this->client->vat_number ?: ' ', 'label' => ctrans('texts.vat_number')];
$data['$website'] = ['value' => $this->client->present()->website() ?: ' ', 'label' => ctrans('texts.website')];
$data['$phone'] = ['value' => $this->client->present()->phone() ?: ' ', 'label' => ctrans('texts.phone')];

View File

@ -355,9 +355,9 @@ trait GeneratesCounter
* @param int $counter The counter
* @param int $padding The padding
*
* @param $pattern
* @param string $prefix
* @return string The padded and prefixed entity number
* @param string $pattern
* @param string $prefix
* @return string The padded and prefixed entity number
*/
private function checkEntityNumber($class, $entity, $counter, $padding, $pattern, $prefix = '')
{
@ -370,13 +370,7 @@ trait GeneratesCounter
$number = $this->prefixCounter($number, $prefix);
if ($class == Invoice::class || $class == RecurringInvoice::class) {
$check = $class::whereCompanyId($entity->company_id)->whereNumber($number)->withTrashed()->first();
} elseif ($class == Client::class || $class == Vendor::class) {
$check = $class::whereCompanyId($entity->company_id)->whereIdNumber($number)->withTrashed()->first();
} else {
$check = $class::whereCompanyId($entity->company_id)->whereNumber($number)->withTrashed()->first();
}
$check = $class::whereCompanyId($entity->company_id)->whereNumber($number)->withTrashed()->first();
$counter++;
} while ($check);
@ -388,11 +382,12 @@ trait GeneratesCounter
/*Check if a number is available for use. */
public function checkNumberAvailable($class, $entity, $number) :bool
{
if ($entity = $class::whereCompanyId($entity->company_id)->whereNumber($number)->withTrashed()->first()) {
return false;
}
if ($entity = $class::whereCompanyId($entity->company_id)->whereNumber($number)->withTrashed()->first())
return false;
return true;
}
/**
@ -611,6 +606,9 @@ trait GeneratesCounter
$search[] = '{$vendor_id_number}';
$replace[] = $entity->vendor->id_number;
$search[] = '{$vendor_number}';
$replace[] = $entity->vendor->number;
$search[] = '{$vendor_custom1}';
$replace[] = $entity->vendor->custom_value1;
@ -643,6 +641,9 @@ trait GeneratesCounter
$search[] = '{$client_custom4}';
$replace[] = $client->custom_value4;
$search[] = '{$client_number}';
$replace[] = $client->number;
$search[] = '{$client_id_number}';
$replace[] = $client->id_number;
}

View File

@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddNumberFieldToClientsAndVendors extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('clients', function (Blueprint $table) {
$table->string('number')->nullable();
});
Schema::table('vendors', function (Blueprint $table) {
$table->string('number')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
}
}

View File

@ -294,7 +294,7 @@ class RandomDataSeeder extends Seeder
foreach ($clients as $client) {
//$client->getNextClientNumber($client);
$client->id_number = $client->getNextClientNumber($client);
$client->number = $client->getNextClientNumber($client);
$client->save();
}

View File

@ -3210,7 +3210,6 @@ return [
'waiting_for_approval' => 'Waiting for approval',
'quote_still_not_approved' => 'This quote is still not approved',
'list_of_credits' => 'Credits',
'required_extensions' => 'Required extensions',
'php_version' => 'PHP version',
'writable_env_file' => 'Writable .env file',
@ -3218,11 +3217,9 @@ return [
'minumum_php_version' => 'Minimum PHP version',
'satisfy_requirements' => 'Make sure all requirements are satisfied.',
'oops_issues' => 'Oops, something doesn\'t look right!',
'open_in_new_tab' => 'Open in new tab',
'complete_your_payment' => 'Complete payment',
'authorize_for_future_use' => 'Authorize payment method for future use',
'page' => 'Page',
'per_page' => 'Per page',
'of' => 'Of',
@ -3230,122 +3227,81 @@ return [
'to_view_entity_password' => 'To view the :entity you need to enter password.',
'showing_x_of' => 'Showing :first to :last out of :total results',
'no_results' => 'No results found.',
'payment_failed_subject' => 'Payment failed for Client :client',
'payment_failed_body' => 'A payment made by client :client failed with message :message',
'register' => 'Register',
'register_label' => 'Create your account in seconds',
'password_confirmation' => 'Confirm your password',
'verification' => 'Verification',
'complete_your_bank_account_verification' => 'Before using bank account they must be verified.',
'complete_your_bank_account_verification' => 'Before using a bank account it must be verified.',
'checkout_com' => 'Checkout.com',
'footer_label' => 'Copyright © :year :company.',
'credit_card_invalid' => 'Provided credit card number is not valid.',
'month_invalid' => 'Provided month is not valid.',
'year_invalid' => 'Provided year is not valid.',
'https_required' => 'HTTPS is required, form will fail',
'if_you_need_help' => 'If you need help you can post to our',
'reversed' => 'Reversed',
'update_password_on_confirm' => 'After updating password, your account will be confirmed.',
'bank_account_not_linked' => 'To pay with bank account, first you have to add it as payment method.',
'bank_account_not_linked' => 'To pay with a bank account, first you have to add it as payment method.',
'application_settings_label' => 'Let\'s store basic information about your Invoice Ninja!',
'recommended_in_production' => 'Highly recommended in production',
'enable_only_for_development' => 'Enable only for development',
'test_pdf' => 'Test PDF',
'cancelled' => 'Cancelled',
'checkout_authorize_label' => 'Checkout.com can be can saved as payment method for future use, once you complete your first transaction. Don\'t forget to check "Store credit card details" during payment process.',
'sofort_authorize_label' => 'Bank account (SOFORT) can be can saved as payment method for future use, once you complete your first transaction. Don\'t forget to check "Store payment details" during payment process.',
'node_status' => 'Node status',
'npm_status' => 'NPM status',
'node_status_not_found' => 'I could not find Node anywhere. Is it installed?',
'npm_status_not_found' => 'I could not find NPM anywhere. Is it installed?',
'locked_invoice' => 'This invoice is locked and unable to be modified',
'downloads' => 'Downloads',
'resource' => 'Resource',
'document_details' => 'Details about the document.',
'width' => 'Width',
'height' => 'Height',
'document_details' => 'Details about the document',
'hash' => 'Hash',
'resources' => 'Resources',
'allowed_file_types' => 'Allowed file types:',
'common_codes' => 'Common codes and their meanings',
'payment_error_code_20087' => '20087: Bad Track Data (invalid CVV and/or expiry date)',
'download_selected' => 'Download selected',
'to_pay_invoices' => 'To pay invoices, you have to',
'add_payment_method_first' => 'add payment method',
'no_items_selected' => 'No items selected.',
'payment_due' => 'Payment due',
'account_balance' => 'Account balance',
'password_strength' => 'Password strength too weak',
'thanks' => 'Thanks',
'minimum_required_payment' => 'Minimum required payment is :amount',
'under_payments_disabled' => 'Company doesn\'t support under payments.',
'over_payments_disabled' => 'Company doesn\'t support over payments.',
'paused' => 'Paused',
'saved_at' => 'Saved at :time',
'credit_payment' => 'Credit applied to Invoice :invoice_number',
'credit_subject' => 'New credit :number from :account',
'credit_message' => 'To view your credit for :amount, click the link below.',
'payment_type_Crypto' => 'Cryptocurrency',
'payment_type_Credit' => 'Credit',
'store_for_future_use' => 'Store for future use',
'pay_with_credit' => 'Pay with credit',
'payment_method_saving_failed' => 'Payment method can\'t be saved for future use.',
'pay_with' => 'Pay with',
'n/a' => 'N/A',
'payment_number' => 'Payment Number',
'activity_63' => ':user emailed reminder 1 for invoice :invoice to :contact',
'activity_64' => ':user emailed reminder 2 for invoice :invoice to :contact',
'activity_65' => ':user emailed reminder 3 for invoice :invoice to :contact',
'activity_66' => ':user emailed reminder endless for invoice :invoice to :contact',
'by_clicking_next_you_accept_terms' => 'By clicking "Next step" you accept terms.',
'not_specified' => 'Not specified',
'before_proceeding_with_payment_warning' => 'Before proceeding with payment, you have to fill following fields',
'after_completing_go_back_to_previous_page' => 'After completing, go back to previous page.',
'billing_country' => 'Billing Country',
'shipping_country' => 'Shipping Country',
'service' => 'Service',
'pay' => 'Pay',
'instructions' => 'Instructions',
'notification_invoice_reminder1_sent_subject' => 'Reminder 1 for Invoice :invoice was sent to :client',
'notification_invoice_reminder2_sent_subject' => 'Reminder 2 for Invoice :invoice was sent to :client',
'notification_invoice_reminder3_sent_subject' => 'Reminder 3 for Invoice :invoice was sent to :client',
@ -3355,26 +3311,19 @@ return [
'custom_value4' => 'Custom Value',
'inclusive_taxes' => 'Include taxes',
'sort_order' => 'Sort Order',
'setup_steps_notice' => 'To proceed to next step, make sure you test each section.',
'setup_phantomjs_note' => 'Note about Phantom JS. Read more.',
'currency_armenian_dram' => 'Armenian Dram',
'currency_albanian_lek' => 'Albanian Lek',
'endless' => 'Endless',
'minimum_payment' => 'Minimum Payment',
'no_action_provided' => 'No action provided. If you believe this is wrong, please contact the support.',
'no_payable_invoices_selected' => 'No payable invoices selected. Make sure you are not trying to pay draft invoice or invoice with zero balance due.',
'required_payment_information' => 'Required payment details',
'required_payment_information_more' => 'To complete a payment we need more details about you.',
'required_client_info_save_label' => 'We will save this, so you don\'t have to enter it next time.',
'notification_credit_bounced' => 'We were unable to deliver Credit :invoice to :contact. \n :error',
'notification_credit_bounced_subject' => 'Unable to deliver Credit :invoice',
'company_limit_reached' => 'Limit of 10 companies per account.',
'credits_applied_validation' => 'Total credits applied cannot be MORE than total of invoices',
'credit_number_taken' => 'Credit number already taken',
@ -3429,4 +3378,5 @@ return [
'self_update_not_available' => 'Self update not available on this system.',
'user_detached' => 'User detached from company',
'create_webhook_failure' => 'Failed to create Webhook',
'number' => 'Number',
];