Merge branch 'expense-refactor' into 'master'

add customer in expense

See merge request mohit.panjvani/crater-web!172
This commit is contained in:
Mohit Panjwani
2020-03-20 07:12:39 +00:00
12 changed files with 107 additions and 13 deletions

View File

@ -5,6 +5,7 @@ use Illuminate\Database\Eloquent\Model;
use Spatie\MediaLibrary\HasMedia\HasMedia; use Spatie\MediaLibrary\HasMedia\HasMedia;
use Spatie\MediaLibrary\HasMedia\HasMediaTrait; use Spatie\MediaLibrary\HasMedia\HasMediaTrait;
use Crater\ExpenseCategory; use Crater\ExpenseCategory;
use Crater\User;
use Carbon\Carbon; use Carbon\Carbon;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
@ -16,6 +17,7 @@ class Expense extends Model implements HasMedia
'expense_category_id', 'expense_category_id',
'amount', 'amount',
'company_id', 'company_id',
'user_id',
'expense_date', 'expense_date',
'notes', 'notes',
'attachment_receipt' 'attachment_receipt'
@ -32,6 +34,11 @@ class Expense extends Model implements HasMedia
return $this->belongsTo(ExpenseCategory::class, 'expense_category_id'); return $this->belongsTo(ExpenseCategory::class, 'expense_category_id');
} }
public function user()
{
return $this->belongsTo(User::class);
}
public function getFormattedExpenseDateAttribute($value) public function getFormattedExpenseDateAttribute($value)
{ {
$dateFormat = CompanySetting::getSetting('carbon_date_format', $this->company_id); $dateFormat = CompanySetting::getSetting('carbon_date_format', $this->company_id);
@ -81,6 +88,11 @@ class Expense extends Model implements HasMedia
return $query->where('expenses.expense_category_id', $categoryId); return $query->where('expenses.expense_category_id', $categoryId);
} }
public function scopeWhereUser($query, $user_id)
{
return $query->where('expenses.user_id', $user_id);
}
public function scopeApplyFilters($query, array $filters) public function scopeApplyFilters($query, array $filters)
{ {
$filters = collect($filters); $filters = collect($filters);
@ -89,6 +101,10 @@ class Expense extends Model implements HasMedia
$query->whereCategory($filters->get('expense_category_id')); $query->whereCategory($filters->get('expense_category_id'));
} }
if ($filters->get('user_id')) {
$query->whereUser($filters->get('user_id'));
}
if ($filters->get('from_date') && $filters->get('to_date')) { if ($filters->get('from_date') && $filters->get('to_date')) {
$start = Carbon::createFromFormat('d/m/Y', $filters->get('from_date')); $start = Carbon::createFromFormat('d/m/Y', $filters->get('from_date'));
$end = Carbon::createFromFormat('d/m/Y', $filters->get('to_date')); $end = Carbon::createFromFormat('d/m/Y', $filters->get('to_date'));

View File

@ -24,9 +24,11 @@ class ExpensesController extends Controller
$limit = $request->has('limit') ? $request->limit : 10; $limit = $request->has('limit') ? $request->limit : 10;
$expenses = Expense::with('category') $expenses = Expense::with('category')
->leftJoin('users', 'users.id', '=', 'expenses.user_id')
->join('expense_categories', 'expense_categories.id', '=', 'expenses.expense_category_id') ->join('expense_categories', 'expense_categories.id', '=', 'expenses.expense_category_id')
->applyFilters($request->only([ ->applyFilters($request->only([
'expense_category_id', 'expense_category_id',
'user_id',
'search', 'search',
'from_date', 'from_date',
'to_date', 'to_date',
@ -34,11 +36,16 @@ class ExpensesController extends Controller
'orderBy' 'orderBy'
])) ]))
->whereCompany($request->header('company')) ->whereCompany($request->header('company'))
->select('expenses.*', 'expense_categories.name') ->select('expenses.*', 'expense_categories.name', 'users.name as user_name')
->paginate($limit); ->paginate($limit);
$customers = User::customer()
->whereCompany($request->header('company'))
->get();
return response()->json([ return response()->json([
'expenses' => $expenses, 'expenses' => $expenses,
'customers' => $customers,
'currency' => Currency::findOrFail( 'currency' => Currency::findOrFail(
CompanySetting::getSetting('currency', $request->header('company')) CompanySetting::getSetting('currency', $request->header('company'))
) )
@ -53,9 +60,13 @@ class ExpensesController extends Controller
public function create(Request $request) public function create(Request $request)
{ {
$categories = ExpenseCategory::whereCompany($request->header('company'))->get(); $categories = ExpenseCategory::whereCompany($request->header('company'))->get();
$customers = User::customer()
->whereCompany($request->header('company'))
->get();
return response()->json([ return response()->json([
'categories' => $categories 'categories' => $categories,
'customers' => $customers
]); ]);
} }
@ -72,6 +83,7 @@ class ExpensesController extends Controller
$expense = new Expense(); $expense = new Expense();
$expense->notes = $request->notes; $expense->notes = $request->notes;
$expense->expense_category_id = $request->expense_category_id; $expense->expense_category_id = $request->expense_category_id;
$expense->user_id = $request->user_id;
$expense->amount = $request->amount; $expense->amount = $request->amount;
$expense->company_id = $request->header('company'); $expense->company_id = $request->header('company');
$expense->expense_date = $expense_date; $expense->expense_date = $expense_date;
@ -107,7 +119,9 @@ class ExpensesController extends Controller
public function edit(Request $request,$id) public function edit(Request $request,$id)
{ {
$categories = ExpenseCategory::whereCompany($request->header('company'))->get(); $categories = ExpenseCategory::whereCompany($request->header('company'))->get();
$customers = User::where('role', 'customer')->whereCompany($request->header('company'))->get(); $customers = User::customer()
->whereCompany($request->header('company'))
->get();
$expense = Expense::with('category')->where('id', $id)->first(); $expense = Expense::with('category')->where('id', $id)->first();
return response()->json([ return response()->json([
@ -132,6 +146,7 @@ class ExpensesController extends Controller
$expense->notes = $request->notes; $expense->notes = $request->notes;
$expense->expense_category_id = $request->expense_category_id; $expense->expense_category_id = $request->expense_category_id;
$expense->amount = $request->amount; $expense->amount = $request->amount;
$expense->user_id = $request->user_id;
$expense->expense_date = $expense_date; $expense->expense_date = $expense_date;
$expense->save(); $expense->save();

View File

@ -9,6 +9,7 @@ use carbon\carbon;
use Crater\MemberLoan; use Crater\MemberLoan;
use Crater\Address; use Crater\Address;
use Crater\Payment; use Crater\Payment;
use Crater\Expense;
use Crater\Company; use Crater\Company;
use Crater\Notifications\MailResetPasswordNotification; use Crater\Notifications\MailResetPasswordNotification;
use Spatie\MediaLibrary\HasMedia\HasMedia; use Spatie\MediaLibrary\HasMedia\HasMedia;
@ -105,6 +106,11 @@ class User extends Authenticatable implements HasMedia
return $this->hasMany(Address::class); return $this->hasMany(Address::class);
} }
public function expenses()
{
return $this->hasMany(Expense::class);
}
public function billingAddress() public function billingAddress()
{ {
return $this->hasOne(Address::class)->where('type', Address::BILLING_TYPE); return $this->hasOne(Address::class)->where('type', Address::BILLING_TYPE);

View File

@ -23,6 +23,8 @@ class CreateExpensesTable extends Migration
$table->foreign('expense_category_id')->references('id')->on('expense_categories')->onDelete('cascade'); $table->foreign('expense_category_id')->references('id')->on('expense_categories')->onDelete('cascade');
$table->integer('company_id')->unsigned()->nullable(); $table->integer('company_id')->unsigned()->nullable();
$table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade'); $table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade');
$table->integer('user_id')->unsigned()->nullable();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->timestamps(); $table->timestamps();
}); });
} }

View File

@ -412,6 +412,8 @@
"title": "النفقات", "title": "النفقات",
"expenses_list": "قائمة النفقات", "expenses_list": "قائمة النفقات",
"expense_title": "Title", "expense_title": "Title",
"select_a_customer": "حدد عميلاً",
"customer": "العميل",
"contact": "تواصل", "contact": "تواصل",
"category": "الفئة", "category": "الفئة",
"from_date": "من تاريخ", "from_date": "من تاريخ",

View File

@ -201,6 +201,7 @@
"action": "Aktion", "action": "Aktion",
"add_expense": "Aufwendung hinzufügen", "add_expense": "Aufwendung hinzufügen",
"add_new_expense": "Neue Aufwendung hinzufügen", "add_new_expense": "Neue Aufwendung hinzufügen",
"select_a_customer": "Wählen Sie einen Kunden aus",
"amount": "Summe", "amount": "Summe",
"categories": { "categories": {
"actions": "Aktionen", "actions": "Aktionen",
@ -215,6 +216,7 @@
"title": "Titel" "title": "Titel"
}, },
"category": "Kategorie", "category": "Kategorie",
"customer": "Kunden",
"category_id": "Kategorie-Id", "category_id": "Kategorie-Id",
"confirm_delete": "Sie können diese Ausgabe nicht wiederherstellen. | Sie können diese Ausgaben nicht wiederherstellen.", "confirm_delete": "Sie können diese Ausgabe nicht wiederherstellen. | Sie können diese Ausgaben nicht wiederherstellen.",
"contact": "Kontakt", "contact": "Kontakt",

View File

@ -426,7 +426,9 @@
"expenses": { "expenses": {
"title": "Expenses", "title": "Expenses",
"expenses_list": "Expenses List", "expenses_list": "Expenses List",
"select_a_customer": "Select a customer",
"expense_title": "Title", "expense_title": "Title",
"customer": "Customer",
"contact": "Contact", "contact": "Contact",
"category": "Category", "category": "Category",
"from_date": "From Date", "from_date": "From Date",

View File

@ -412,6 +412,8 @@
"expenses_list": "Lista de gastos", "expenses_list": "Lista de gastos",
"expense_title": "Título", "expense_title": "Título",
"contact": "Contacto", "contact": "Contacto",
"customer": "Cliente",
"select_a_customer": "Selecciona un cliente",
"category": "Categoría", "category": "Categoría",
"from_date": "Desde la fecha", "from_date": "Desde la fecha",
"to_date": "Hasta la fecha", "to_date": "Hasta la fecha",

View File

@ -410,6 +410,8 @@
"expenses_list": "Liste des dépenses", "expenses_list": "Liste des dépenses",
"expense_title": "Titre", "expense_title": "Titre",
"contact": "Contact", "contact": "Contact",
"customer": "Client Client",
"select_a_customer": "Sélectionnez un client",
"category": "Catégorie", "category": "Catégorie",
"from_date": "A partir de la date", "from_date": "A partir de la date",
"to_date": "À ce jour", "to_date": "À ce jour",

View File

@ -414,6 +414,7 @@
"expense_title": "Título", "expense_title": "Título",
"contact": "Contato", "contact": "Contato",
"category": "Categoria", "category": "Categoria",
"customer": "Cliente",
"from_date": "A partir da Data", "from_date": "A partir da Data",
"to_date": "Até a Data", "to_date": "Até a Data",
"expense_date": "Data", "expense_date": "Data",

View File

@ -102,6 +102,19 @@
<span v-if="!$v.formData.amount.minValue" class="text-danger">{{ $t('validation.price_minvalue') }}</span> <span v-if="!$v.formData.amount.minValue" class="text-danger">{{ $t('validation.price_minvalue') }}</span>
</div> </div>
</div> </div>
<div class="form-group col-sm-6">
<label class="form-label">{{ $t('expenses.customer') }}</label>
<base-select
ref="baseSelect"
v-model="customer"
:options="customerList"
:searchable="true"
:show-labels="false"
:placeholder="$t('customers.select_a_customer')"
label="name"
track-by="id"
/>
</div>
<div class="form-group col-sm-6"> <div class="form-group col-sm-6">
<label for="description">{{ $t('expenses.note') }}</label> <label for="description">{{ $t('expenses.note') }}</label>
<base-text-area <base-text-area
@ -169,7 +182,8 @@ export default {
expense_category_id: null, expense_category_id: null,
expense_date: new Date(), expense_date: new Date(),
amount: null, amount: null,
notes: '' notes: '',
user_id: null
}, },
money: { money: {
decimal: '.', decimal: '.',
@ -185,7 +199,9 @@ export default {
passData: [], passData: [],
contacts: [], contacts: [],
previewReceipt: null, previewReceipt: null,
fileSendUrl: '/api/expenses' fileSendUrl: '/api/expenses',
customer: null,
customerList: []
} }
}, },
validations: { validations: {
@ -297,6 +313,8 @@ export default {
}, },
async fetchInitialData () { async fetchInitialData () {
this.fetchCategories() this.fetchCategories()
let fetchData = await this.fetchCreateExpense()
this.customerList = fetchData.data.customers
if (this.isEdit) { if (this.isEdit) {
let response = await this.fetchExpense(this.$route.params.id) let response = await this.fetchExpense(this.$route.params.id)
this.category = response.data.expense.category this.category = response.data.expense.category
@ -304,6 +322,9 @@ export default {
this.formData.expense_date = moment(this.formData.expense_date).toString() this.formData.expense_date = moment(this.formData.expense_date).toString()
this.formData.amount = (response.data.expense.amount) this.formData.amount = (response.data.expense.amount)
this.fileSendUrl = `/api/expenses/${this.$route.params.id}` this.fileSendUrl = `/api/expenses/${this.$route.params.id}`
if (response.data.expense.user_id) {
this.customer = this.customerList.find(customer => customer.id === response.data.expense.user_id)
}
} }
}, },
async sendData () { async sendData () {
@ -322,6 +343,7 @@ export default {
data.append('expense_date', moment(this.formData.expense_date).format('DD/MM/YYYY')) data.append('expense_date', moment(this.formData.expense_date).format('DD/MM/YYYY'))
data.append('amount', (this.formData.amount)) data.append('amount', (this.formData.amount))
data.append('notes', this.formData.notes ? this.formData.notes : '') data.append('notes', this.formData.notes ? this.formData.notes : '')
data.append('user_id', this.customer ? this.customer.id : '')
if (this.isEdit) { if (this.isEdit) {
this.isLoading = true this.isLoading = true

View File

@ -43,7 +43,19 @@
<transition name="fade"> <transition name="fade">
<div v-show="showFilters" class="filter-section"> <div v-show="showFilters" class="filter-section">
<div class="row"> <div class="row">
<div class="col-md-4"> <div class="col-md-3">
<label>{{ $t('expenses.customer') }}</label>
<base-select
v-model="filters.user"
:options="customers"
:searchable="true"
:show-labels="false"
:placeholder="$t('expenses.select_a_customer')"
label="name"
@click="filter = ! filter"
/>
</div>
<div class="col-md-3">
<label>{{ $t('expenses.category') }}</label> <label>{{ $t('expenses.category') }}</label>
<base-select <base-select
v-model="filters.category" v-model="filters.category"
@ -55,7 +67,7 @@
@click="filter = ! filter" @click="filter = ! filter"
/> />
</div> </div>
<div class="col-md-4"> <div class="col-md-3">
<label>{{ $t('expenses.from_date') }}</label> <label>{{ $t('expenses.from_date') }}</label>
<base-date-picker <base-date-picker
v-model="filters.from_date" v-model="filters.from_date"
@ -63,7 +75,7 @@
calendar-button-icon="calendar" calendar-button-icon="calendar"
/> />
</div> </div>
<div class="col-md-4"> <div class="col-md-3">
<label>{{ $t('expenses.to_date') }}</label> <label>{{ $t('expenses.to_date') }}</label>
<base-date-picker <base-date-picker
v-model="filters.to_date" v-model="filters.to_date"
@ -161,6 +173,11 @@
sort-as="name" sort-as="name"
show="category.name" show="category.name"
/> />
<table-column
:label="$t('expenses.customer')"
sort-as="user_name"
show="user_name"
/>
<table-column <table-column
:label="$t('expenses.date')" :label="$t('expenses.date')"
sort-as="expense_date" sort-as="expense_date"
@ -237,10 +254,12 @@ export default {
showFilters: false, showFilters: false,
filtersApplied: false, filtersApplied: false,
isRequestOngoing: true, isRequestOngoing: true,
customers: [],
filters: { filters: {
category: null, category: null,
from_date: '', from_date: '',
to_date: '' to_date: '',
user: ''
} }
} }
}, },
@ -308,6 +327,7 @@ export default {
]), ]),
async fetchData ({ page, filter, sort }) { async fetchData ({ page, filter, sort }) {
let data = { let data = {
user_id: this.filters.user ? this.filters.user.id : null,
expense_category_id: this.filters.category !== null ? this.filters.category.id : '', expense_category_id: this.filters.category !== null ? this.filters.category.id : '',
from_date: this.filters.from_date === '' ? this.filters.from_date : moment(this.filters.from_date).format('DD/MM/YYYY'), from_date: this.filters.from_date === '' ? this.filters.from_date : moment(this.filters.from_date).format('DD/MM/YYYY'),
to_date: this.filters.to_date === '' ? this.filters.to_date : moment(this.filters.to_date).format('DD/MM/YYYY'), to_date: this.filters.to_date === '' ? this.filters.to_date : moment(this.filters.to_date).format('DD/MM/YYYY'),
@ -318,6 +338,7 @@ export default {
this.isRequestOngoing = true this.isRequestOngoing = true
let response = await this.fetchExpenses(data) let response = await this.fetchExpenses(data)
this.customers = response.data.customers
this.isRequestOngoing = false this.isRequestOngoing = false
return { return {
@ -340,7 +361,8 @@ export default {
this.filters = { this.filters = {
category: null, category: null,
from_date: '', from_date: '',
to_date: '' to_date: '',
user: null
} }
this.$nextTick(() => { this.$nextTick(() => {