rework detail page

shift-build-2464
Nadim Salloum 2021-06-18 17:08:16 +03:00
parent a1b8667118
commit 3ea8c084ac
24 changed files with 753 additions and 714 deletions

View File

@ -218,28 +218,8 @@ class CarController extends Controller
return [ return [
'id' => $contract->id, 'id' => $contract->id,
'date' => $contract->date_formatted, 'date' => $contract->date_formatted,
'delivery_date' => $contract->delivery_date_formatted,
'price' => $contract->price->format(), 'price' => $contract->price->format(),
'paid' => $contract->paid->format(), 'contact' => $contact->full_title,
'left_to_pay' => $contract->left_to_pay->format(),
'type' => $contract->type,
'notes' => $contract->notes,
'is_sell_contract' => $contract->isSellContract(),
'insurance_type' => $contract->insurance_type ? InsuranceType::fromValue($contract->insurance_type)->key : null,
'contact' => [
'id' => $contact->id,
'name' => $contact->name,
'firstname' => $contact->firstname,
'lastname' => $contact->lastname,
'phone' => $contact->phone,
'address' => $contact->address,
'zip' => $contact->zip,
'city' => $contact->city,
'country' => $contact->country,
'company' => $contact->company,
'email' => $contact->email,
'link' => route('contacts.show', $contact),
],
'link' => route('contracts.show', $contract), 'link' => route('contracts.show', $contract),
]; ];
} }
@ -389,13 +369,15 @@ class CarController extends Controller
'notes' => $car->notes, 'notes' => $car->notes,
'deleted_at' => $car->deleted_at, 'deleted_at' => $car->deleted_at,
'buy_contracts' => $car->buyContracts() 'buy_contracts' => $car->buyContracts()
->orderBy('date', 'asc') ->orderBy('date', 'desc')
->paginate(50) ->with('contact')
->through(fn ($contract) => $this->getContractFields($contract)), ->get()
->map(function ($contract) { return $this->getContractFields($contract); }),
'sell_contracts' => $car->sellContracts() 'sell_contracts' => $car->sellContracts()
->orderBy('date', 'asc') ->orderBy('date', 'desc')
->paginate(50) ->with('contact')
->through(fn ($contract) => $this->getContractFields($contract)), ->get()
->map(function ($contract) { return $this->getContractFields($contract); }),
], ],
]); ]);
} }

View File

@ -213,13 +213,15 @@ class ContactController extends Controller
'country' => $contact->country, 'country' => $contact->country,
'deleted_at' => $contact->deleted_at, 'deleted_at' => $contact->deleted_at,
'buy_contracts' => $contact->buyContracts() 'buy_contracts' => $contact->buyContracts()
->orderBy('date', 'desc')
->with('car') ->with('car')
->paginate(50) ->get()
->through(fn ($contract) => $this->getContractFields($contract)), ->map(function ($contract) { return $this->getContractFields($contract); }),
'sell_contracts' => $contact->sellContracts() 'sell_contracts' => $contact->sellContracts()
->orderBy('date', 'desc')
->with('car') ->with('car')
->paginate(50) ->get()
->through(fn ($contract) => $this->getContractFields($contract)), ->map(function ($contract) { return $this->getContractFields($contract); }),
] ]
]); ]);
} }
@ -232,27 +234,8 @@ class ContactController extends Controller
return [ return [
'id' => $contract->id, 'id' => $contract->id,
'date' => $contract->date_formatted, 'date' => $contract->date_formatted,
'delivery_date' => $contract->delivery_date_formatted,
'price' => $contract->price->format(), 'price' => $contract->price->format(),
'paid' => $contract->paid->format(), 'car' => $car->name_with_year,
'left_to_pay' => $contract->left_to_pay->format(),
'type' => $contract->type,
'notes' => $contract->notes,
'is_sell_contract' => $contract->isSellContract(),
'insurance_type' => $contract->insurance_type ? InsuranceType::fromValue($contract->insurance_type)->key : null,
'car' => [
'id' => $car->id,
'stammnummer' => $car->stammnummer,
'vin' => $car->vin,
'name' => $car->name,
'initial_date' => $car->initial_date_formatted,
'colour' => $car->colour,
'last_check_date' => $car->last_check_date_formatted,
'kilometers' => $car->kilometers_formatted,
'known_damage' => $car->known_damage,
'notes' => $car->notes,
'link' => route('cars.show', $car),
],
'link' => route('contracts.show', $contract), 'link' => route('contracts.show', $contract),
]; ];
} }

View File

@ -238,42 +238,20 @@ class ContractController extends Controller
'created_at' => $document->created_at, 'created_at' => $document->created_at,
]; ];
}), }),
'payments' => $contract->payments()->orderBy('date', 'asc')->paginate(50) 'payments' => $contract->payments()->orderBy('date', 'asc')->get()
->through(fn ($payment) => [ ->map(function ($payment) {
return [
'id' => $payment->id, 'id' => $payment->id,
'date' => $payment->date, 'date' => $payment->date,
'amount' => $payment->amount->format(), 'amount' => $payment->amount->format(),
'type' => $payment->type, 'type' => $payment->type,
'delete_link' => $payment->delete_link, 'delete_link' => $payment->delete_link,
]), ];
}),
'insurance_type' => $contract->insurance_type ? InsuranceType::fromValue($contract->insurance_type)->key : null, 'insurance_type' => $contract->insurance_type ? InsuranceType::fromValue($contract->insurance_type)->key : null,
'deleted_at' => $contract->deleted_at, 'deleted_at' => $contract->deleted_at,
'contact' => [ 'contact' => $contract->contact->only(['id', 'full_title', 'link']),
'id' => $contract->contact->id, 'car' => $contract->car->only(['id', 'name_with_year', 'link']),
'name' => $contract->contact->name,
'firstname' => $contract->contact->firstname,
'lastname' => $contract->contact->lastname,
'phone' => $contract->contact->phone,
'address' => $contract->contact->address,
'zip' => $contract->contact->zip,
'city' => $contract->contact->city,
'country' => $contract->contact->country,
'company' => $contract->contact->company,
'email' => $contract->contact->email,
'link' => route('contacts.show', $contract->contact),
],
'car' => [
'id' => $contract->car->id,
'stammnummer' => $contract->car->stammnummer,
'vin' => $contract->car->vin,
'car_model' => $contract->car->carModel->only('id', 'name'),
'brand' => $contract->car->brand,
'name' => $contract->car->name,
'initial_date' => $contract->car->initial_date_formatted,
'colour' => $contract->car->colour,
'deleted_at' => $contract->car->deleted_at,
'link' => route('cars.show', $contract->car),
],
], ],
]); ]);
} }

View File

@ -32,6 +32,16 @@ class Car extends Model
return $out; return $out;
} }
public function getNameWithYearAttribute()
{
return $this->name . ' (' . $this->year . ')';
}
public function getYearAttribute()
{
return Carbon::parse($this->initial_date)->format('Y');
}
public function getKilometersFormattedAttribute() public function getKilometersFormattedAttribute()
{ {
return number_format($this->kilometers, 0, '.', '\''); return number_format($this->kilometers, 0, '.', '\'');
@ -56,6 +66,11 @@ class Car extends Model
return null; return null;
} }
public function getLinkAttribute()
{
return route('cars.show', $this);
}
public function brand() public function brand()
{ {
return $this->carModel->brand(); return $this->carModel->brand();

View File

@ -63,6 +63,11 @@ class Contact extends Model
return $this->zip . ' ' . $this->city; return $this->zip . ' ' . $this->city;
} }
public function getLinkAttribute()
{
return route('contacts.show', $this);
}
public function scopeOrderByName($query, $direction) public function scopeOrderByName($query, $direction)
{ {
$query->orderBy('lastname', $direction)->orderBy('firstname', $direction); $query->orderBy('lastname', $direction)->orderBy('firstname', $direction);

854
public/js/app.js vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
<template> <template>
<inertia-link :href="href" class="justify-center inline-flex items-center px-4 py-2 font-semibold text-xs text-red-300 hover:text-red-500 uppercase tracking-widest hover:font-underline transition"> <inertia-link :href="href" class="justify-center inline-flex items-center px-4 py-2 font-semibold text-xs text-red-400 hover:text-red-500 uppercase tracking-widest hover:font-underline transition">
<unicon fill="currentColor" class="mr-1" height="22" width="22" name="trash-alt"></unicon> <unicon fill="currentColor" class="mr-1" height="22" width="22" name="trash-alt"></unicon>
löschen löschen
</inertia-link> </inertia-link>

View File

@ -1,23 +0,0 @@
<template>
<contract-card :contract="contract" :meta="meta" />
</template>
<script>
import ContractCard from '@/Components/ContractCard.vue';
export default {
components: {
ContractCard,
},
props: {
contract: Object,
},
data() {
return {
meta: {
contact: 'Verkäufer',
},
};
},
};
</script>

View File

@ -1,43 +1,43 @@
<template> <template>
<div class="p-5 bg-white shadow rounded-md font-medium"> <div class="p-5 bg-white shadow rounded-md font-medium">
<div v-if="car.name" class="font-bold pb-1 mb-1 text-2xl border-b"> <div v-if="!hideEmpty || car.name" class="font-bold">
{{ car.name }} {{ car.name ? car.name : '-' }}
</div> </div>
<div class="grid grid-cols-2 xl:grid-cols-4 gap-2 w-full"> <div class="grid grid-cols-2 xl:grid-cols-4 gap-0 w-full">
<div v-if="!hideEmpty || car.stammnummer" class="col-span-1"> <div v-if="!hideEmpty || car.stammnummer" class="col-span-2">
Stammnummer Stammnummer
</div> </div>
<div v-if="!hideEmpty || car.stammnummer" class="col-span-1 xl:col-span-3"> <div v-if="!hideEmpty || car.stammnummer" class="col-span-2">
{{ car.stammnummer ? car.stammnummer : '-' }} {{ car.stammnummer ? car.stammnummer : '-' }}
</div> </div>
<div v-if="!hideEmpty || car.vin" class="col-span-1"> <div v-if="!hideEmpty || car.vin" class="col-span-2">
Chassisnummer Chassisnummer
</div> </div>
<div v-if="!hideEmpty || car.vin" class="col-span-1 xl:col-span-3"> <div v-if="!hideEmpty || car.vin" class="col-span-2">
{{ car.vin ? car.vin : '-'}} {{ car.vin ? car.vin : '-'}}
</div> </div>
<div v-if="!hideEmpty || car.colour" class="col-span-1"> <div v-if="!hideEmpty || car.colour" class="col-span-2">
Farbe Farbe
</div> </div>
<div v-if="!hideEmpty || car.colour" class="col-span-1"> <div v-if="!hideEmpty || car.colour" class="col-span-2">
{{ car.colour ? car.colour : '-' }} {{ car.colour ? car.colour : '-' }}
</div> </div>
<div v-if="!hideEmpty || car.kilometers" class="col-span-1"> <div v-if="!hideEmpty || car.kilometers" class="col-span-2">
Kilometerstand Kilometerstand
</div> </div>
<div v-if="!hideEmpty || car.kilometers" class="col-span-1"> <div v-if="!hideEmpty || car.kilometers" class="col-span-2">
{{ car.kilometers ? car.kilometers + ' KM' : '-' }} {{ car.kilometers ? car.kilometers + ' KM' : '-' }}
</div> </div>
<div v-if="!hideEmpty || car.initial_date" class="col-span-1"> <div v-if="!hideEmpty || car.initial_date" class="col-span-2">
Erstzulassung Erstzulassung
</div> </div>
<div v-if="!hideEmpty || car.initial_date" class="col-span-1"> <div v-if="!hideEmpty || car.initial_date" class="col-span-2">
{{ car.initial_date ? car.initial_date : '-' }} {{ car.initial_date ? car.initial_date : '-' }}
</div> </div>
<div v-if="!hideEmpty || car.last_check_date" class="col-span-1"> <div v-if="!hideEmpty || car.last_check_date" class="col-span-2">
Letzte Prüfung Letzte Prüfung
</div> </div>
<div v-if="!hideEmpty || car.last_check_date" class="col-span-1"> <div v-if="!hideEmpty || car.last_check_date" class="col-span-2">
{{ car.last_check_date ? car.last_check_date : '-' }} {{ car.last_check_date ? car.last_check_date : '-' }}
</div> </div>
</div> </div>

View File

@ -1,102 +0,0 @@
<template>
<div class="py-3 grid grid-cols-12 gap-3 w-full">
<div v-if="contract.contact" class="sm:col-span-6 col-span-12">
<h3 class="mb-3">{{ meta.contact }}</h3>
<contact-card :contact="contract.contact" />
</div>
<div v-if="contract.car" class="sm:col-span-8 col-span-12">
<h3 class="mb-3">Auto</h3>
<car-card hide-empty="true" :car="contract.car" />
</div>
<div :class="contractClasses">
<h3>Vertragsinformationen</h3>
<div class="mt-3 p-5 bg-white shadow rounded-md font-medium">
<div class="grid grid-cols-4 gap-2">
<div class="col-span-2">
Datum
</div>
<div class="col-span-2">
{{ contract.date }}
</div>
<div class="col-span-2">
Lieferdatum
</div>
<div class="col-span-2">
{{ contract.delivery_date }}
</div>
<div class="col-span-2" v-if="contract.is_sell_contract && contract.insurance_type">
Versicherung
</div>
<div class="col-span-2" v-if="contract.is_sell_contract && contract.insurance_type">
{{ contract.insurance_type }}
</div>
<div class="col-span-2">
Betrag
</div>
<div class="col-span-2 font-bold">
{{ contract.price }}
</div>
<div class="col-span-2">
Bezahlt
</div>
<div class="col-span-2">
{{ contract.paid }}
</div>
<div class="col-span-2">
Offener Betrag
</div>
<div class="col-span-2">
{{ contract.left_to_pay }}
</div>
<div v-if="contract.notes" class="col-span-2">
Bemerkung
</div>
<div v-if="contract.notes" class="col-span-2">
{{ contract.notes }}
</div>
</div>
<div v-if="contract.link" class="pt-3 mt-3 border-t">
<inertia-link :href="contract.link" class="pt-1 pb-1 flex items-center hover:text-indigo-600">
<unicon fill="currentColor" class="mr-1" height="22" width="22" name="arrow-right"></unicon>
Zum Vertrag
</inertia-link>
</div>
</div>
</div>
</div>
</template>
<script>
import SimpleTable from '@/Components/SimpleTable.vue';
import ContactCard from '@/Components/ContactCard.vue';
import CarCard from '@/Components/CarCard.vue';
import PrintButton from './Buttons/PrintButton.vue';
export default {
components: {
SimpleTable,
ContactCard,
CarCard,
PrintButton,
},
props: {
contract: Object,
meta: Object,
},
computed: {
contractClasses() {
return `col-span-12 h-full relative sm:col-span-${this.contract.car ? '4' : '6'}`;
},
},
data() {
return {
sellContractsColumns: [
{ key: 'buyer', value: 'Käufer' },
{ key: 'date', value: 'Verkaufsdatum' },
{ key: 'price', value: 'Verkaufspreis' },
{ key: 'insurance_type', value: 'Versicherungstyp' },
],
};
},
};
</script>

View File

@ -1,7 +1,7 @@
<template> <template>
<a target="_blank" :href="document.link" class="p-3 col-span-2 grid relative grid-flow-rows cursor-pointer group auto-rows-max hover:bg-gray-50 bg-white transition shadow rounded-md font-medium"> <a target="_blank" :href="document.link" class="p-3 col-span-2 grid relative grid-flow-rows cursor-pointer group auto-rows-max hover:bg-gray-50 bg-white transition shadow rounded-md font-medium">
<a @click="deleteDocument" href="#" class="absolute right-0 opacity-0 group-hover:opacity-80 transition"> <a @click="deleteDocument" href="#" class="absolute right-0 opacity-0 group-hover:opacity-80 transition">
<unicon fill="#f54242" hover-fill="red" class="p-2" height="40" width="40" name="trash-alt"></unicon> <unicon fill="#f04040" hover-fill="red" class="p-2" height="40" width="40" name="trash-alt"></unicon>
</a> </a>
<span class="justify-center inline-flex text-indigo-800 group-hover:text-indigo-700 items-center mx-auto"> <span class="justify-center inline-flex text-indigo-800 group-hover:text-indigo-700 items-center mx-auto">
<unicon fill="currentColor" class="p-2" height="70" width="70" name="file-alt"></unicon> <unicon fill="currentColor" class="p-2" height="70" width="70" name="file-alt"></unicon>

View File

@ -1,6 +1,6 @@
<template> <template>
<h3 class="mb-3">Dokumente</h3> <small-title title="Dokumente" class="mb-3" />
<div class="grid sm:grid-cols-8 grid-cols-6 gap-3"> <div class="grid md:grid-cols-6 sm:grid-cols-4 grid-cols-2 gap-3">
<template v-for="document in documents" :key="document.id"> <template v-for="document in documents" :key="document.id">
<document-item @delete="deleteDocument" :document="document" /> <document-item @delete="deleteDocument" :document="document" />
</template> </template>
@ -12,11 +12,13 @@
import { useForm } from '@inertiajs/inertia-vue3'; import { useForm } from '@inertiajs/inertia-vue3';
import DocumentItem from './Item.vue'; import DocumentItem from './Item.vue';
import DocumentUpload from './Upload.vue'; import DocumentUpload from './Upload.vue';
import SmallTitle from './../SmallTitle.vue';
export default { export default {
components: { components: {
DocumentItem, DocumentItem,
DocumentUpload, DocumentUpload,
SmallTitle,
}, },
props: { props: {
initial_documents: Object, initial_documents: Object,

View File

@ -1,5 +1,5 @@
<template> <template>
<standard-button class="mb-3" colour="green" @click="openModal" :href="route('payments.create', contract.id)"> <standard-button colour="green" @click="openModal" :href="route('payments.create', contract.id)">
<unicon fill="white" class="mr-1" height="22" width="22" name="plus-circle"></unicon> <unicon fill="white" class="mr-1" height="22" width="22" name="plus-circle"></unicon>
Neue Einzahlung Neue Einzahlung
</standard-button> </standard-button>

View File

@ -1,7 +1,4 @@
<template> <template>
<span class="w-full inline-flex items-end justify-between mb-3">
<h3>Einzahlungen</h3>
</span>
<div class="w-full mx-auto"> <div class="w-full mx-auto">
<simple-table :data="payments" :columns="columns" @delete="deletePayment" /> <simple-table :data="payments" :columns="columns" @delete="deletePayment" />
<p class="py-5 text-xl">Total <span class="font-bold ml-5">{{ contract.paid }}</span> / {{ contract.price }}</p> <p class="py-5 text-xl">Total <span class="font-bold ml-5">{{ contract.paid }}</span> / {{ contract.price }}</p>

View File

@ -1,23 +0,0 @@
<template>
<contract-card :contract="contract" :meta="meta" />
</template>
<script>
import ContractCard from '@/Components/ContractCard.vue';
export default {
components: {
ContractCard,
},
props: {
contract: Object,
},
data() {
return {
meta: {
contact: 'Käufer',
},
};
},
};
</script>

View File

@ -4,11 +4,12 @@
<slot name="header"></slot> <slot name="header"></slot>
</template> </template>
<div class="grid grid-cols-12 gap-12 mb-8"> <div class="grid grid-cols-12 gap-12 mb-8">
<div class="xl:col-span-6 sm:col-span-8 col-span-12"> <div class="xl:col-span-6 col-span-12">
<slot name="info"></slot> <slot name="info"></slot>
</div> </div>
<div class="xl:col-span-3 sm:col-span-4 col-span-12"> <div class="xl:col-span-3 xl:col-end-13 col-span-12">
<div class="w-full flex flex-col"> <div class="w-full flex flex-col">
<small-title title="Aktionen" class="mb-3" />
<slot name="actions"></slot> <slot name="actions"></slot>
</div> </div>
</div> </div>
@ -21,10 +22,12 @@
<script> <script>
import Layout from '@/Layouts/Layout'; import Layout from '@/Layouts/Layout';
import SmallTitle from './SmallTitle.vue';
export default { export default {
components: { components: {
Layout, Layout,
SmallTitle,
}, },
}; };
</script> </script>

View File

@ -1,8 +1,11 @@
<template> <template>
<div> <div>
<p v-if="title" class="font-semibold text-2xl font-medium mb-4 text-indigo-900 leading-tight">{{ title }}</p> <span v-if="title" class="flex justify-between items-end mb-4">
<div v-if="form" class="my-6 flex justify-between items-center"> <p v-if="title" class="font-semibold text-2xl font-medium text-indigo-900 leading-tight">{{ title }}</p>
<div class="flex items-center w-full max-w-md mr-4"> <slot name="actions" class=""></slot>
</span>
<div v-if="form || print" class="my-4 flex justify-between items-center">
<div v-if="form" class="flex items-center w-full max-w-md mr-4">
<div class="flex w-full bg-white shadow rounded"> <div class="flex w-full bg-white shadow rounded">
<input type="text" ref="search" v-model="form.search" autofocus="true" name="search" placeholder="Suchen..." class="relative border-gray-200 w-full px-6 py-3 focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50 rounded" autocomplete="off"> <input type="text" ref="search" v-model="form.search" autofocus="true" name="search" placeholder="Suchen..." class="relative border-gray-200 w-full px-6 py-3 focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50 rounded" autocomplete="off">
</div> </div>
@ -13,7 +16,7 @@
Excel-Export Excel-Export
</a> </a>
</div> </div>
<div v-if="data.total === undefined || data.total > 0" class="bg-white shadow rounded-md sm:rounded-lg overflow-x-auto"> <div v-if="(data.total === undefined && data.length > 0) || data.total > 0" class="bg-white shadow rounded-md sm:rounded-lg overflow-x-auto">
<table class="w-full whitespace-nowrap"> <table class="w-full whitespace-nowrap">
<tr class="text-left font-bold"> <tr class="text-left font-bold">
<th v-for="(col, index) in columns" :key="col.key" class="px-6 pt-4 pb-4" :colspan="[index == (columns.length - 1) ? 2 : 1]"> <th v-for="(col, index) in columns" :key="col.key" class="px-6 pt-4 pb-4" :colspan="[index == (columns.length - 1) ? 2 : 1]">
@ -29,18 +32,18 @@
</tr> </tr>
<tr v-for="row in (this.data.data ? this.data.data : this.data)" :key="row.link" class="hover:bg-indigo-100 focus-within:bg-indigo-100"> <tr v-for="row in (this.data.data ? this.data.data : this.data)" :key="row.link" class="hover:bg-indigo-100 focus-within:bg-indigo-100">
<td v-for="col in columns" :key="col.key" class="border-t"> <td v-for="col in columns" :key="col.key" class="border-t">
<inertia-link v-if="row.link" class="px-6 py-4 flex items-center" :href="row.link"> <inertia-link v-if="row.link" class="px-6 xl:py-4 py-2 flex items-center" :href="row.link">
{{ resolve(col.key, row) }} {{ resolve(col.key, row) }}
</inertia-link> </inertia-link>
<span v-else-if="col.key == 'delete'" class="p-3 cursor-pointer" @click="this.$emit('delete', row.id)"> <span v-else-if="col.key == 'delete'" class="p-3 cursor-pointer" @click="this.$emit('delete', row.id)">
<unicon fill="red" height="24" width="24" name="trash-alt"></unicon> <unicon fill="#f04040" hover-fill="red" height="24" width="24" name="trash-alt"></unicon>
</span> </span>
<span v-else class="px-6 py-4 flex items-center"> <span v-else class="px-6 xl:py-4 py-2 flex items-center">
{{ resolve(col.key, row) }} {{ resolve(col.key, row) }}
</span> </span>
</td> </td>
<td v-if="row.link && !hideArrow" class="border-t w-px"> <td v-if="row.link && !hideArrow" class="border-t w-px">
<inertia-link class="px-4 flex items-center" :href="row.link" tabindex="-1"> <inertia-link class="xl:py-4 py-2 flex items-center" :href="row.link" tabindex="-1">
<unicon class="m-2" height="22" width="22" name="angle-right"></unicon> <unicon class="m-2" height="22" width="22" name="angle-right"></unicon>
</inertia-link> </inertia-link>
</td> </td>

View File

@ -0,0 +1,12 @@
<template>
<h3 class="font-semibold">{{ title }}</h3>
</template>
<script>
export default ({
props: {
title: String,
},
})
</script>

View File

@ -32,8 +32,8 @@ export default {
return { return {
currentRoute: 'cars', currentRoute: 'cars',
columns: [ columns: [
{ key: 'name', value: 'Name', sortable: true }, { key: 'name', value: 'Marke & Modell', sortable: true },
{ key: 'stammnummer', value: 'Stammummer', sortable: true }, { key: 'stammnummer', value: 'Stammnummer', sortable: true },
{ key: 'buy_contract.date', value: 'Einkaufsdatum', sortable: true }, { key: 'buy_contract.date', value: 'Einkaufsdatum', sortable: true },
{ key: 'buy_contract.price', value: 'Einkaufspreis', sortable: true }, { key: 'buy_contract.price', value: 'Einkaufspreis', sortable: true },
{ key: 'sell_contract.date', value: 'Verkaufssdatum', sortable: true }, { key: 'sell_contract.date', value: 'Verkaufssdatum', sortable: true },

View File

@ -18,33 +18,25 @@
</div> </div>
</template> </template>
<template #more> <template #more>
<div class="sm:col-span-6 col-span-12"> <div class="xl:col-span-6 col-span-12">
<div class="whitespace-nowrap"> <simple-table :title="car.buy_contracts.total > 1 ? car.buy_contracts.total + ' Ankaufsverträge' : 'Ankaufsvertrag'" :data="car.buy_contracts" :columns="buyContractColumns" :currentRoute="currentRoute" :hideArrow="true">
<h1 class="font-bold text-3xl">{{ car.buy_contracts.total > 1 ? car.buy_contracts.total + ' Ankaufsverträge' : 'Ankaufsvertrag' }}</h1> <template #actions>
</div> <standard-button v-if="!car.deleted_at" colour="green" :href="route('contracts.create_from_car', [0, car.id])">
<div v-for="contract in car.buy_contracts.data" :key="contract.id"> <unicon fill="currentColor" class="mr-1" height="22" width="22" name="plus-circle"></unicon>
<buy-contract-card :contract="contract"/> Ankaufsvertrag
</div> </standard-button>
<div v-if="!car.deleted_at && car.buy_contracts.total <= car.sell_contracts.total"> </template>
<inertia-link :href="route('contracts.create_from_car', [0, car.id])" class="w-full py-6 mt-12 inline-flex items-center px-4 bg-green-800 border border-transparent rounded-md font-semibold justify-center text-md text-white uppercase tracking-widest hover:bg-green-700 focus:outline-none focus:border-green-900 focus:ring focus:ring-green-300 disabled:opacity-25 transition" > </simple-table>
<unicon fill="white" class="mr-1" height="22" width="22" name="plus-circle"></unicon>
Neuer Ankaufsvertrag
</inertia-link>
</div>
</div> </div>
<div class="sm:col-span-6 col-span-12"> <div class="xl:col-span-6 col-span-12">
<div class="whitespace-nowrap"> <simple-table :title="car.sell_contracts.total > 1 ? car.sell_contracts.total + ' Verkaufsverträge' : 'Verkaufsvertrag'" :data="car.sell_contracts" :columns="sellContractColumns" :currentRoute="currentRoute" :hideArrow="true">
<h1 class="font-bold text-3xl">{{ car.sell_contracts.total > 1 ? car.sell_contracts.total + ' Verkaufsverträge' : 'Verkaufsvertrag' }}</h1> <template #actions>
</div> <standard-button v-if="!car.deleted_at" colour="green" :href="route('contracts.create_from_car', [1, car.id])">
<div v-for="contract in car.sell_contracts.data" :key="contract.id"> <unicon fill="currentColor" class="mr-1" height="22" width="22" name="plus-circle"></unicon>
<sell-contract-card :contract="contract"/> Verkaufssvertrag
</div> </standard-button>
<div v-if="!car.deleted_at && car.buy_contracts.total > car.sell_contracts.total"> </template>
<inertia-link :href="route('contracts.create_from_car', [1, car.id])" class="py-6 w-full mt-12 inline-flex items-center px-4 bg-green-800 border border-transparent rounded-md font-semibold justify-center text-md text-white uppercase tracking-widest hover:bg-green-700 focus:outline-none focus:border-green-900 focus:ring focus:ring-green-300 disabled:opacity-25 transition" > </simple-table>
<unicon fill="white" class="mr-1" height="22" width="22" name="plus-circle"></unicon>
Neuer Verkaufssvertrag
</inertia-link>
</div>
</div> </div>
</template> </template>
</show-page> </show-page>
@ -59,6 +51,8 @@ import SellContractCard from '@/Components/SellContractCard.vue';
import EditButton from '@/Components/Buttons/EditButton.vue'; import EditButton from '@/Components/Buttons/EditButton.vue';
import DeleteButton from '@/Components/Buttons/DeleteButton.vue'; import DeleteButton from '@/Components/Buttons/DeleteButton.vue';
import RestoreButton from '@/Components/Buttons/RestoreButton.vue'; import RestoreButton from '@/Components/Buttons/RestoreButton.vue';
import StandardButton from '@/Components/Buttons/StandardButton.vue';
import SimpleTable from '@/Components/SimpleTable.vue';
export default { export default {
components: { components: {
@ -70,6 +64,8 @@ export default {
EditButton, EditButton,
DeleteButton, DeleteButton,
RestoreButton, RestoreButton,
StandardButton,
SimpleTable,
}, },
props: { props: {
car: Object, car: Object,
@ -77,6 +73,16 @@ export default {
data() { data() {
return { return {
currentRoute: 'cars.show', currentRoute: 'cars.show',
buyContractColumns: [
{ key: 'date', value: 'Datum', sortable: false },
{ key: 'contact', value: 'Verkäufer', sortable: false },
{ key: 'price', value: 'Einkaufspreis', sortable: false },
],
sellContractColumns: [
{ key: 'date', value: 'Datum', sortable: false },
{ key: 'contact', value: 'Käufer', sortable: false },
{ key: 'price', value: 'Verkaufspreis', sortable: false },
],
}; };
}, },
}; };

View File

@ -32,8 +32,8 @@ export default {
return { return {
currentRoute: 'cars.sold', currentRoute: 'cars.sold',
columns: [ columns: [
{ key: 'name', value: 'Name', sortable: true }, { key: 'name', value: 'Marke & Modell', sortable: true },
{ key: 'stammnummer', value: 'Stammummer', sortable: true }, { key: 'stammnummer', value: 'Stammnummer', sortable: true },
{ key: 'buy_contract.date', value: 'Einkaufsdatum', sortable: true }, { key: 'buy_contract.date', value: 'Einkaufsdatum', sortable: true },
{ key: 'buy_contract.price', value: 'Einkaufspreis', sortable: true }, { key: 'buy_contract.price', value: 'Einkaufspreis', sortable: true },
{ key: 'sell_contract.date', value: 'Verkaufssdatum', sortable: true }, { key: 'sell_contract.date', value: 'Verkaufssdatum', sortable: true },

View File

@ -32,8 +32,8 @@ export default {
return { return {
currentRoute: 'cars.unsold', currentRoute: 'cars.unsold',
columns: [ columns: [
{ key: 'name', value: 'Name', sortable: true }, { key: 'name', value: 'Marke & Modell', sortable: true },
{ key: 'stammnummer', value: 'Stammummer', sortable: true }, { key: 'stammnummer', value: 'Stammnummer', sortable: true },
{ key: 'initial_date', value: 'Inverkehrssetzung', sortable: true }, { key: 'initial_date', value: 'Inverkehrssetzung', sortable: true },
{ key: 'buy_contract.date', value: 'Einkaufsdatum', sortable: true }, { key: 'buy_contract.date', value: 'Einkaufsdatum', sortable: true },
{ key: 'buy_contract.price', value: 'Einkaufspreis', sortable: true }, { key: 'buy_contract.price', value: 'Einkaufspreis', sortable: true },

View File

@ -21,33 +21,25 @@
</template> </template>
<template #more> <template #more>
<div class="sm:col-span-10 col-span-12"> <div class="xl:col-span-6 col-span-12">
<div class="whitespace-nowrap"> <simple-table :title="contact.buy_contracts.total > 1 ? contact.buy_contracts.total + ' Ankaufsverträge' : 'Ankaufsvertrag'" :data="contact.buy_contracts" :columns="buyContractColumns" :currentRoute="currentRoute" :hideArrow="true">
<h1 class="font-bold text-3xl">{{ contact.buy_contracts.total > 1 ? contact.buy_contracts.total + ' Ankaufsverträge' : 'Ankaufsvertrag' }}</h1> <template #actions>
</div> <standard-button v-if="!contact.deleted_at" colour="green" :href="route('contracts.create_from_contact', [0, contact.id])">
<div v-if="!contact.deleted_at"> <unicon fill="currentColor" class="mr-1" height="22" width="22" name="plus-circle"></unicon>
<inertia-link :href="route('contracts.create_from_contact', [0, contact.id])" class="w-full py-6 mt-12 inline-flex items-center px-4 bg-green-800 border border-transparent rounded-md font-semibold justify-center text-md text-white uppercase tracking-widest hover:bg-green-700 focus:outline-none focus:border-green-900 focus:ring focus:ring-green-300 disabled:opacity-25 transition" > Ankaufsvertrag
<unicon fill="white" class="mr-1" height="22" width="22" name="plus-circle"></unicon> </standard-button>
Neuer Ankaufsvertrag </template>
</inertia-link> </simple-table>
</div>
<div v-for="contract in contact.buy_contracts.data" :key="contract.id">
<buy-contract-card :contract="contract"/>
</div>
</div> </div>
<div class="sm:col-span-10 col-span-12"> <div class="xl:col-span-6 col-span-12">
<div class="whitespace-nowrap"> <simple-table :title="contact.sell_contracts.total > 1 ? contact.sell_contracts.total + ' Verkaufsverträge' : 'Verkaufsvertrag'" :data="contact.sell_contracts" :columns="sellContractColumns" :currentRoute="currentRoute" :hideArrow="true">
<h1 class="font-bold text-3xl">{{ contact.sell_contracts.total > 1 ? contact.sell_contracts.total + ' Verkaufsverträge' : 'Verkaufsvertrag' }}</h1> <template #actions>
</div> <standard-button v-if="!contact.deleted_at" colour="green" :href="route('contracts.create_from_contact', [1, contact.id])">
<div v-if="!contact.deleted_at"> <unicon fill="currentColor" class="mr-1" height="22" width="22" name="plus-circle"></unicon>
<inertia-link :href="route('contracts.create_from_contact', [1, contact.id])" class="py-6 w-full mt-12 inline-flex items-center px-4 bg-green-800 border border-transparent rounded-md font-semibold justify-center text-md text-white uppercase tracking-widest hover:bg-green-700 focus:outline-none focus:border-green-900 focus:ring focus:ring-green-300 disabled:opacity-25 transition" > Verkaufssvertrag
<unicon fill="white" class="mr-1" height="22" width="22" name="plus-circle"></unicon> </standard-button>
Neuer Verkaufssvertrag </template>
</inertia-link> </simple-table>
</div>
<div v-for="contract in contact.sell_contracts.data" :key="contract.id">
<sell-contract-card :contract="contract"/>
</div>
</div> </div>
</template> </template>
</show-page> </show-page>
@ -62,6 +54,8 @@ import SellContractCard from '@/Components/SellContractCard.vue';
import EditButton from '@/Components/Buttons/EditButton.vue'; import EditButton from '@/Components/Buttons/EditButton.vue';
import DeleteButton from '@/Components/Buttons/DeleteButton.vue'; import DeleteButton from '@/Components/Buttons/DeleteButton.vue';
import RestoreButton from '@/Components/Buttons/RestoreButton.vue'; import RestoreButton from '@/Components/Buttons/RestoreButton.vue';
import SimpleTable from '@/Components/SimpleTable.vue';
import StandardButton from '@/Components/Buttons/StandardButton.vue';
export default { export default {
components: { components: {
@ -73,6 +67,8 @@ export default {
EditButton, EditButton,
DeleteButton, DeleteButton,
RestoreButton, RestoreButton,
SimpleTable,
StandardButton,
}, },
props: { props: {
@ -81,6 +77,16 @@ export default {
data() { data() {
return { return {
currentRoute: 'contacts.show', currentRoute: 'contacts.show',
buyContractColumns: [
{ key: 'date', value: 'Datum', sortable: false },
{ key: 'car', value: 'Auto', sortable: false},
{ key: 'price', value: 'Einkaufspreis', sortable: false },
],
sellContractColumns: [
{ key: 'date', value: 'Datum', sortable: false },
{ key: 'car', value: 'Auto', sortable: false},
{ key: 'price', value: 'Verkaufspreis', sortable: false },
],
}; };
}, },
}; };

View File

@ -4,58 +4,71 @@
{{ contract.type_formatted }} vom {{ contract.date }} {{ contract.type_formatted }} vom {{ contract.date }}
</template> </template>
<template #info> <template #info>
<div class="p-5 bg-white shadow rounded-md font-medium"> <small-title title="Vertragsinformationen" class="mb-3" />
<div class="font-bold pb-1 mb-1 text-2xl border-b"> <div class="grid grid-cols-12 gap-2 p-5 bg-white shadow rounded-md font-medium">
{{ contract.type_formatted }} vom {{ contract.date }} <div class="col-span-4">
</div> Datum
<div class="grid grid-cols-4 gap-2 w-full"> </div>
<div class="lg:col-span-1 col-span-2"> <div class="col-span-8">
Datum {{ contract.date }}
</div>
<div class="col-span-12 sm:col-span-4 pt-3 sm:pt-0">
{{ contactTitle }}
</div>
<div class="col-span-12 sm:col-span-8">
<inertia-link :href="contract.contact.link" class="font-bold flex items-center hover:text-indigo-600">
<unicon fill="currentColor" class="mr-1" height="22" width="22" name="arrow-right"></unicon>
{{ contract.contact.full_title }}
</inertia-link>
</div>
<div class="col-span-12 sm:col-span-4 pt-3 sm:pt-0">
Auto
</div>
<div class="col-span-12 sm:col-span-8 pb-3 sm:pb-0">
<inertia-link :href="contract.car.link" class="font-bold flex items-center hover:text-indigo-600">
<unicon fill="currentColor" class="mr-1" height="22" width="22" name="arrow-right"></unicon>
{{ contract.car.name_with_year }}
</inertia-link>
</div>
<div class="col-span-4">
Lieferdatum
</div>
<div class="col-span-8">
{{ contract.delivery_date }}
</div>
<div v-if="contract.is_sell_contract && contract.insurance_type" class="col-span-4">
Versicherung
</div>
<div v-if="contract.is_sell_contract && contract.insurance_type" class="col-span-8">
{{ contract.insurance_type }}
</div>
<div class="col-span-4">
Betrag
</div>
<div class="col-span-8 font-bold">
{{ contract.price }}
</div>
<div class="col-span-4">
Bezahlt
</div>
<div class="col-span-8">
{{ contract.paid }}
</div>
<div class="col-span-4">
Offener Betrag
</div>
<div class="col-span-8">
{{ contract.left_to_pay }}
</div>
<div v-if="contract.notes" class="mt-3 col-span-12">
<p class="font-bold">Bemerkungen</p>
{{ contract.notes }}
</div>
</div> </div>
<div class="lg:col-span-3 col-span-2">
{{ contract.date }}
</div>
<div class="lg:col-span-1 col-span-2">
Lieferdatum
</div>
<div class="lg:col-span-3 col-span-2">
{{ contract.delivery_date }}
</div>
<div v-if="contract.is_sell_contract && contract.insurance_type" class="lg:col-span-1 col-span-2">
Versicherung
</div>
<div v-if="contract.is_sell_contract && contract.insurance_type" class="lg:col-span-3 col-span-2">
{{ contract.insurance_type }}
</div>
<div class="lg:col-span-1 col-span-2">
Betrag
</div>
<div class="lg:col-span-3 col-span-2 font-bold">
{{ contract.price }}
</div>
<div class="lg:col-span-1 col-span-2">
Bezahlt
</div>
<div class="lg:col-span-3 col-span-2">
{{ contract.paid }}
</div>
<div class="lg:col-span-1 col-span-2">
Offener Betrag
</div>
<div class="lg:col-span-3 col-span-2">
{{ contract.left_to_pay }}
</div>
<div v-if="contract.notes" class="mt-3 col-span-4">
<p class="font-bold">Bemerkungen</p>
{{ contract.notes }}
</div>
</div>
</div>
</template> </template>
<template #actions> <template #actions>
<edit-button v-if="!contract.deleted_at" :href="route('contracts.edit', contract.id)" /> <edit-button v-if="!contract.deleted_at" :href="route('contracts.edit', contract.id)" />
<print-button :href="route('contracts.print', contract.id)" /> <print-button :href="route('contracts.print', contract.id)" />
<payments-upload v-if="!contract.deleted_at" :show_upload="!contract.deleted_at" :contract="contract" />
<delete-button v-if="!contract.deleted_at" :href="route('contracts.destroy', contract.id)" /> <delete-button v-if="!contract.deleted_at" :href="route('contracts.destroy', contract.id)" />
<restore-button v-if="contract.deleted_at" :href="route('contracts.restore', contract.id)" /> <restore-button v-if="contract.deleted_at" :href="route('contracts.restore', contract.id)" />
<div v-if="contract.deleted_at"> <div v-if="contract.deleted_at">
@ -63,20 +76,16 @@
</div> </div>
</template> </template>
<template #more> <template #more>
<div class="lg:col-span-7 col-span-12"> <div class="xl:col-span-6 col-span-12">
<h3 class="mb-3">Auto</h3> <span class="w-full inline-flex items-end justify-between mb-3">
<car-card :car="contract.car" hideEmpty="true" /> <small-title title="Einzahlungen" />
</div> <payments-upload v-if="!contract.deleted_at" :show_upload="!contract.deleted_at" :contract="contract" />
<div class="lg:col-span-5 col-span-12"> </span>
<h3 class="mb-3">{{ contactTitle }}</h3>
<contact-card :contact="contract.contact" />
</div>
<div class="xl:col-span-7 col-span-12 mt-4">
<documents-view :initial_documents="contract.documents" :id="contract.id" :show_upload="!contract.deleted_at" />
</div>
<div class="xl:col-span-5 col-span-12">
<payments-view :payments="contract.payments" :contract="contract" /> <payments-view :payments="contract.payments" :contract="contract" />
</div> </div>
<div class="xl:col-span-6 col-span-12 mt-4">
<documents-view :initial_documents="contract.documents" :id="contract.id" :show_upload="!contract.deleted_at" />
</div>
</template> </template>
</show-page> </show-page>
</template> </template>
@ -93,6 +102,7 @@ import EditButton from '@/Components/Buttons/EditButton.vue';
import DocumentsView from '@/Components/Documents/View.vue'; import DocumentsView from '@/Components/Documents/View.vue';
import PaymentsView from '@/Components/Payments/View.vue'; import PaymentsView from '@/Components/Payments/View.vue';
import PaymentsUpload from '@/Components/Payments/Upload.vue'; import PaymentsUpload from '@/Components/Payments/Upload.vue';
import SmallTitle from '../../Components/SmallTitle.vue';
export default { export default {
components: { components: {
@ -107,6 +117,7 @@ export default {
DocumentsView, DocumentsView,
PaymentsView, PaymentsView,
PaymentsUpload, PaymentsUpload,
SmallTitle,
}, },
props: { props: {
contract: Object, contract: Object,