mirror of
https://github.com/InvoiceShelf/InvoiceShelf.git
synced 2026-04-14 00:34:05 +00:00
Add Company VAT-ID and Tax-ID (#54)
* add company vat_id & tax_id field * add tax & vat id field in company settings * fix vat & tax id validation * add german vat & tax id translation * add translations for pdf * add vat_id and tax_id field before timestamps * make fields nullable and fix code style
This commit is contained in:
@@ -69,6 +69,8 @@ class CompaniesRequest extends FormRequest
|
||||
return collect($this->validated())
|
||||
->only([
|
||||
'name',
|
||||
'vat_id',
|
||||
'tax_id',
|
||||
])
|
||||
->merge([
|
||||
'owner_id' => $this->user()->id,
|
||||
|
||||
@@ -29,6 +29,12 @@ class CompanyRequest extends FormRequest
|
||||
'required',
|
||||
Rule::unique('companies')->ignore($this->header('company'), 'id'),
|
||||
],
|
||||
'vat_id' => [
|
||||
'nullable',
|
||||
],
|
||||
'tax_id' => [
|
||||
'nullable',
|
||||
],
|
||||
'slug' => [
|
||||
'nullable',
|
||||
],
|
||||
@@ -44,6 +50,8 @@ class CompanyRequest extends FormRequest
|
||||
->only([
|
||||
'name',
|
||||
'slug',
|
||||
'vat_id',
|
||||
'tax_id',
|
||||
])
|
||||
->toArray();
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ class CompanyResource extends JsonResource
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'name' => $this->name,
|
||||
'vat_id' => $this->vat_id,
|
||||
'tax_id' => $this->tax_id,
|
||||
'logo' => $this->logo,
|
||||
'logo_path' => $this->logo_path,
|
||||
'unique_hash' => $this->unique_hash,
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('companies', function (Blueprint $table) {
|
||||
$table->after('unique_hash', function (Blueprint $table) {
|
||||
$table->string('vat_id')->nullable();
|
||||
$table->string('tax_id')->nullable();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('companies', function (Blueprint $table) {
|
||||
$table->dropColumn('vat_id');
|
||||
$table->dropColumn('tax_id');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -863,6 +863,8 @@
|
||||
"company_info": {
|
||||
"company_info": "Firmeninfo",
|
||||
"company_name": "Name des Unternehmens",
|
||||
"vat_id": "Umsatzsteuer-Identifikationsnummer",
|
||||
"tax_id": "Steuernummer",
|
||||
"company_logo": "Firmenlogo",
|
||||
"section_description": "Informationen zu Ihrem Unternehmen, die auf Rechnungen, Angeboten und anderen von InvoiceShelf erstellten Dokumenten angezeigt werden.",
|
||||
"phone": "Telefon",
|
||||
@@ -1528,5 +1530,7 @@
|
||||
"pdf_bill_to": "Rechnungsanschrift",
|
||||
"pdf_ship_to": "Lieferanschrift",
|
||||
"pdf_received_from": "Erhalten von:",
|
||||
"pdf_tax_label": "Steuer"
|
||||
"pdf_tax_label": "Steuer",
|
||||
"pdf_tax_id": "Steuer-Nr.",
|
||||
"pdf_vat_id": "USt.-ID"
|
||||
}
|
||||
|
||||
@@ -863,6 +863,8 @@
|
||||
"company_info": {
|
||||
"company_info": "Company info",
|
||||
"company_name": "Company Name",
|
||||
"tax_id": "Tax Identification Number",
|
||||
"vat_id": "VAT Identification Number",
|
||||
"company_logo": "Company Logo",
|
||||
"section_description": "Information about your company that will be displayed on invoices, estimates and other documents created by InvoiceShelf.",
|
||||
"phone": "Phone",
|
||||
@@ -1528,5 +1530,7 @@
|
||||
"pdf_bill_to": "Bill to,",
|
||||
"pdf_ship_to": "Ship to,",
|
||||
"pdf_received_from": "Received from:",
|
||||
"pdf_tax_label": "Tax"
|
||||
"pdf_tax_label": "Tax",
|
||||
"pdf_tax_id": "Tax-ID",
|
||||
"pdf_vat_id": "VAT-ID"
|
||||
}
|
||||
|
||||
@@ -131,6 +131,25 @@
|
||||
/>
|
||||
</BaseInputGroup>
|
||||
</div>
|
||||
|
||||
<BaseInputGroup :label="$t('settings.company_info.tax_id')">
|
||||
<BaseInput
|
||||
v-model.trim="companyForm.tax_id"
|
||||
type="text"
|
||||
name="tax_id"
|
||||
/>
|
||||
</BaseInputGroup>
|
||||
|
||||
<BaseInputGroup
|
||||
:label="$t('settings.company_info.vat_id')"
|
||||
class="mt-4"
|
||||
>
|
||||
<BaseInput
|
||||
v-model.trim="companyForm.vat_id"
|
||||
type="text"
|
||||
name="vat_id"
|
||||
/>
|
||||
</BaseInputGroup>
|
||||
</div>
|
||||
|
||||
<BaseButton :loading="isSaving" :disabled="isSaving" class="mt-4">
|
||||
@@ -162,6 +181,8 @@ let logoFileName = ref(null)
|
||||
|
||||
const companyForm = reactive({
|
||||
name: null,
|
||||
tax_id: null,
|
||||
vat_id: null,
|
||||
address: {
|
||||
address_street_1: '',
|
||||
address_street_2: '',
|
||||
@@ -200,13 +221,13 @@ const rules = {
|
||||
address_street_1: {
|
||||
maxLength: helpers.withMessage(
|
||||
t('validation.address_maxlength', { count: 255 }),
|
||||
maxLength(255)
|
||||
maxLength(255),
|
||||
),
|
||||
},
|
||||
address_street_2: {
|
||||
maxLength: helpers.withMessage(
|
||||
t('validation.address_maxlength', { count: 255 }),
|
||||
maxLength(255)
|
||||
maxLength(255),
|
||||
),
|
||||
},
|
||||
},
|
||||
@@ -241,7 +262,7 @@ async function next() {
|
||||
JSON.stringify({
|
||||
name: logoFileName.value,
|
||||
data: logoFileBlob.value,
|
||||
})
|
||||
}),
|
||||
)
|
||||
await companyStore.updateCompanyLogo(logoData)
|
||||
}
|
||||
|
||||
@@ -84,6 +84,16 @@
|
||||
class="mt-2"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="space-y-6">
|
||||
<BaseInputGroup :label="$t('settings.company_info.tax_id')">
|
||||
<BaseInput v-model="companyForm.tax_id" type="text" />
|
||||
</BaseInputGroup>
|
||||
|
||||
<BaseInputGroup :label="$t('settings.company_info.vat_id')">
|
||||
<BaseInput v-model="companyForm.vat_id" type="text" />
|
||||
</BaseInputGroup>
|
||||
</div>
|
||||
</BaseInputGrid>
|
||||
|
||||
<BaseButton
|
||||
@@ -111,24 +121,7 @@
|
||||
<div class="mt-5">
|
||||
<button
|
||||
type="button"
|
||||
class="
|
||||
inline-flex
|
||||
items-center
|
||||
justify-center
|
||||
px-4
|
||||
py-2
|
||||
border border-transparent
|
||||
font-medium
|
||||
rounded-md
|
||||
text-red-700
|
||||
bg-red-100
|
||||
hover:bg-red-200
|
||||
focus:outline-none
|
||||
focus:ring-2
|
||||
focus:ring-offset-2
|
||||
focus:ring-red-500
|
||||
sm:text-sm
|
||||
"
|
||||
class="inline-flex items-center justify-center px-4 py-2 border border-transparent font-medium rounded-md text-red-700 bg-red-100 hover:bg-red-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:text-sm"
|
||||
@click="removeCompany"
|
||||
>
|
||||
{{ $t('general.delete') }}
|
||||
@@ -161,6 +154,8 @@ let isSaving = ref(false)
|
||||
const companyForm = reactive({
|
||||
name: null,
|
||||
logo: null,
|
||||
tax_id: null,
|
||||
vat_id: null,
|
||||
address: {
|
||||
address_street_1: '',
|
||||
address_street_2: '',
|
||||
@@ -194,7 +189,7 @@ const rules = computed(() => {
|
||||
required: helpers.withMessage(t('validation.required'), required),
|
||||
minLength: helpers.withMessage(
|
||||
t('validation.name_min_length'),
|
||||
minLength(3)
|
||||
minLength(3),
|
||||
),
|
||||
},
|
||||
address: {
|
||||
@@ -207,7 +202,7 @@ const rules = computed(() => {
|
||||
|
||||
const v$ = useVuelidate(
|
||||
rules,
|
||||
computed(() => companyForm)
|
||||
computed(() => companyForm),
|
||||
)
|
||||
|
||||
globalStore.fetchCountries()
|
||||
@@ -243,7 +238,7 @@ async function updateCompanyData() {
|
||||
JSON.stringify({
|
||||
name: logoFileName.value,
|
||||
data: logoFileBlob.value,
|
||||
})
|
||||
}),
|
||||
)
|
||||
}
|
||||
logoData.append('is_company_logo_removed', isCompanyLogoRemoved.value)
|
||||
|
||||
Reference in New Issue
Block a user