mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Expenses
This commit is contained in:
parent
dba3a39559
commit
d1bef24ede
@ -6,6 +6,7 @@ use View;
|
|||||||
use App\Models\Activity;
|
use App\Models\Activity;
|
||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
use App\Models\Payment;
|
use App\Models\Payment;
|
||||||
|
use App\Models\VendorActivity;
|
||||||
|
|
||||||
class DashboardController extends BaseController
|
class DashboardController extends BaseController
|
||||||
{
|
{
|
||||||
@ -68,6 +69,13 @@ class DashboardController extends BaseController
|
|||||||
->take(50)
|
->take(50)
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
|
$vendoractivities = VendorActivity::where('vendor_activities.account_id', '=', Auth::user()->account_id)
|
||||||
|
->with('vendor.vendorcontacts', 'user', 'account')
|
||||||
|
->where('activity_type_id', '>', 0)
|
||||||
|
->orderBy('created_at', 'desc')
|
||||||
|
->take(50)
|
||||||
|
->get();
|
||||||
|
|
||||||
$pastDue = DB::table('invoices')
|
$pastDue = DB::table('invoices')
|
||||||
->leftJoin('clients', 'clients.id', '=', 'invoices.client_id')
|
->leftJoin('clients', 'clients.id', '=', 'invoices.client_id')
|
||||||
->leftJoin('contacts', 'contacts.client_id', '=', 'clients.id')
|
->leftJoin('contacts', 'contacts.client_id', '=', 'clients.id')
|
||||||
@ -141,6 +149,7 @@ class DashboardController extends BaseController
|
|||||||
'payments' => $payments,
|
'payments' => $payments,
|
||||||
'title' => trans('texts.dashboard'),
|
'title' => trans('texts.dashboard'),
|
||||||
'hasQuotes' => $hasQuotes,
|
'hasQuotes' => $hasQuotes,
|
||||||
|
'vendoractivities' => $vendoractivities,
|
||||||
];
|
];
|
||||||
|
|
||||||
return View::make('dashboard', $data);
|
return View::make('dashboard', $data);
|
||||||
|
198
app/Http/Controllers/PublicVendorController.php
Normal file
198
app/Http/Controllers/PublicVendorController.php
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
<?php namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Auth;
|
||||||
|
use DB;
|
||||||
|
use Input;
|
||||||
|
use Utils;
|
||||||
|
use Datatable;
|
||||||
|
use App\Models\VendorInvitation;
|
||||||
|
use App\Ninja\Repositories\VendorActivityRepository;
|
||||||
|
|
||||||
|
class PublicVendorController extends BaseController
|
||||||
|
{
|
||||||
|
private $activityRepo;
|
||||||
|
private $vendor;
|
||||||
|
|
||||||
|
public function __construct(VendorActivityRepository $activityRepo)
|
||||||
|
{
|
||||||
|
$this->activityRepo = $activityRepo;
|
||||||
|
$this->vendor = $activityRepo->vendor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function dashboard()
|
||||||
|
{
|
||||||
|
if (!$invitation = $this->getInvitation()) {
|
||||||
|
return $this->returnError();
|
||||||
|
}
|
||||||
|
|
||||||
|
$account = $invitation->account;
|
||||||
|
$color = $account->primary_color ? $account->primary_color : '#0b4d78';
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'color' => $color,
|
||||||
|
'account' => $account,
|
||||||
|
'client' => $this->vendor,
|
||||||
|
'hideLogo' => $account->isWhiteLabel(),
|
||||||
|
'clientViewCSS' => $account->clientViewCSS(),
|
||||||
|
];
|
||||||
|
|
||||||
|
return response()->view('invited.dashboard', $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function activityDatatable()
|
||||||
|
{
|
||||||
|
if (!$invitation = $this->getInvitation()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$query = $this->activityRepo->findByClientId($invoice->client_id);
|
||||||
|
$query->where('vendor_activities.adjustment', '!=', 0);
|
||||||
|
|
||||||
|
return Datatable::query($query)
|
||||||
|
->addColumn('vendor_activities.id', function ($model) { return Utils::timestampToDateTimeString(strtotime($model->created_at)); })
|
||||||
|
->addColumn('activity_type_id', function ($model) {
|
||||||
|
$data = [
|
||||||
|
'client' => Utils::getClientDisplayName($model),
|
||||||
|
'user' => $model->is_system ? ('<i>' . trans('texts.system') . '</i>') : ($model->user_first_name . ' ' . $model->user_last_name),
|
||||||
|
'invoice' => trans('texts.invoice') . ' ' . $model->invoice,
|
||||||
|
'contact' => Utils::getClientDisplayName($model),
|
||||||
|
'payment' => trans('texts.payment') . ($model->payment ? ' ' . $model->payment : ''),
|
||||||
|
];
|
||||||
|
|
||||||
|
return trans("texts.activity_{$model->activity_type_id}", $data);
|
||||||
|
})
|
||||||
|
->addColumn('balance', function ($model) { return Utils::formatMoney($model->balance, $model->currency_id, $model->country_id); })
|
||||||
|
->addColumn('adjustment', function ($model) { return $model->adjustment != 0 ? Utils::wrapAdjustment($model->adjustment, $model->currency_id, $model->country_id) : ''; })
|
||||||
|
->make();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function invoiceIndex()
|
||||||
|
{
|
||||||
|
if (!$invitation = $this->getInvitation()) {
|
||||||
|
return $this->returnError();
|
||||||
|
}
|
||||||
|
$account = $invitation->account;
|
||||||
|
$color = $account->primary_color ? $account->primary_color : '#0b4d78';
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'color' => $color,
|
||||||
|
'hideLogo' => $account->isWhiteLabel(),
|
||||||
|
'clientViewCSS' => $account->clientViewCSS(),
|
||||||
|
'title' => trans('texts.invoices'),
|
||||||
|
'entityType' => ENTITY_INVOICE,
|
||||||
|
'columns' => Utils::trans(['invoice_number', 'invoice_date', 'invoice_total', 'balance_due', 'due_date']),
|
||||||
|
];
|
||||||
|
|
||||||
|
return response()->view('public_list', $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function invoiceDatatable()
|
||||||
|
{
|
||||||
|
if (!$invitation = $this->getInvitation()) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->invoiceRepo->getClientDatatable($invitation->contact_id, ENTITY_INVOICE, Input::get('sSearch'));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function paymentIndex()
|
||||||
|
{
|
||||||
|
if (!$invitation = $this->getInvitation()) {
|
||||||
|
return $this->returnError();
|
||||||
|
}
|
||||||
|
$account = $invitation->account;
|
||||||
|
$color = $account->primary_color ? $account->primary_color : '#0b4d78';
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'color' => $color,
|
||||||
|
'hideLogo' => $account->isWhiteLabel(),
|
||||||
|
'clientViewCSS' => $account->clientViewCSS(),
|
||||||
|
'entityType' => ENTITY_PAYMENT,
|
||||||
|
'title' => trans('texts.payments'),
|
||||||
|
'columns' => Utils::trans(['invoice', 'transaction_reference', 'method', 'payment_amount', 'payment_date'])
|
||||||
|
];
|
||||||
|
|
||||||
|
return response()->view('public_list', $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function paymentDatatable()
|
||||||
|
{
|
||||||
|
if (!$invitation = $this->getInvitation()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$payments = $this->paymentRepo->findForContact($invitation->contact->id, Input::get('sSearch'));
|
||||||
|
|
||||||
|
return Datatable::query($payments)
|
||||||
|
->addColumn('invoice_number', function ($model) { return $model->invitation_key ? link_to('/view/'.$model->invitation_key, $model->invoice_number) : $model->invoice_number; })
|
||||||
|
->addColumn('transaction_reference', function ($model) { return $model->transaction_reference ? $model->transaction_reference : '<i>Manual entry</i>'; })
|
||||||
|
->addColumn('payment_type', function ($model) { return $model->payment_type ? $model->payment_type : ($model->account_gateway_id ? '<i>Online payment</i>' : ''); })
|
||||||
|
->addColumn('amount', function ($model) { return Utils::formatMoney($model->amount, $model->currency_id, $model->country_id); })
|
||||||
|
->addColumn('payment_date', function ($model) { return Utils::dateToString($model->payment_date); })
|
||||||
|
->make();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function quoteIndex()
|
||||||
|
{
|
||||||
|
if (!$invitation = $this->getInvitation()) {
|
||||||
|
return $this->returnError();
|
||||||
|
}
|
||||||
|
$account = $invitation->account;
|
||||||
|
$color = $account->primary_color ? $account->primary_color : '#0b4d78';
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'color' => $color,
|
||||||
|
'hideLogo' => $account->isWhiteLabel(),
|
||||||
|
'clientViewCSS' => $account->clientViewCSS(),
|
||||||
|
'title' => trans('texts.quotes'),
|
||||||
|
'entityType' => ENTITY_QUOTE,
|
||||||
|
'columns' => Utils::trans(['quote_number', 'quote_date', 'quote_total', 'due_date']),
|
||||||
|
];
|
||||||
|
|
||||||
|
return response()->view('public_list', $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function quoteDatatable()
|
||||||
|
{
|
||||||
|
if (!$invitation = $this->getInvitation()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->invoiceRepo->getClientDatatable($invitation->contact_id, ENTITY_QUOTE, Input::get('sSearch'));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function returnError()
|
||||||
|
{
|
||||||
|
return response()->view('error', [
|
||||||
|
'error' => trans('texts.invoice_not_found'),
|
||||||
|
'hideHeader' => true,
|
||||||
|
'clientViewCSS' => $account->clientViewCSS(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getInvitation()
|
||||||
|
{
|
||||||
|
$invitationKey = session('invitation_key');
|
||||||
|
|
||||||
|
if (!$invitationKey) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$invitation = VendorInvitation::where('invitation_key', '=', $invitationKey)->first();
|
||||||
|
|
||||||
|
if (!$invitation || $invitation->is_deleted) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$invoice = $invitation->invoice;
|
||||||
|
|
||||||
|
if (!$invoice || $invoice->is_deleted) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $invitation;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
29
app/Http/Requests/UpdateVendorRequest.php
Normal file
29
app/Http/Requests/UpdateVendorRequest.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?php namespace app\Http\Requests;
|
||||||
|
|
||||||
|
use App\Http\Requests\Request;
|
||||||
|
use Illuminate\Validation\Factory;
|
||||||
|
|
||||||
|
class UpdateVendorRequest extends Request
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function authorize()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'vendor_contacts' => 'valid_contacts',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
55
app/Listeners/VendorActivityListener.php
Normal file
55
app/Listeners/VendorActivityListener.php
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
<?php namespace app\Listeners;
|
||||||
|
|
||||||
|
use App\Events\VendorWasCreated;
|
||||||
|
use App\Events\VendorWasDeleted;
|
||||||
|
use App\Events\VendorWasArchived;
|
||||||
|
use App\Events\VendorWasRestored;
|
||||||
|
use App\Ninja\Repositories\ActivityRepository;
|
||||||
|
use App\Ninja\Repositories\VendorActivityRepository;
|
||||||
|
|
||||||
|
class VendorActivityListener
|
||||||
|
{
|
||||||
|
protected $activityRepo;
|
||||||
|
|
||||||
|
public function __construct(VendorActivityRepository $activityRepo)
|
||||||
|
{
|
||||||
|
$this->activityRepo = $activityRepo;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vendors
|
||||||
|
public function createdVendor(VendorWasCreated $event)
|
||||||
|
{
|
||||||
|
$this->activityRepo->create(
|
||||||
|
$event->vendor,
|
||||||
|
ACTIVITY_TYPE_CREATE_VENDOR
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deletedVendor(VendorWasDeleted $event)
|
||||||
|
{
|
||||||
|
$this->activityRepo->create(
|
||||||
|
$event->vendor,
|
||||||
|
ACTIVITY_TYPE_DELETE_CLIENT
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function archivedVendor(VendorWasArchived $event)
|
||||||
|
{
|
||||||
|
if ($event->client->is_deleted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->activityRepo->create(
|
||||||
|
$event->vendor,
|
||||||
|
ACTIVITY_TYPE_ARCHIVE_CLIENT
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function restoredVendor(VendorWasRestored $event)
|
||||||
|
{
|
||||||
|
$this->activityRepo->create(
|
||||||
|
$event->vendor,
|
||||||
|
ACTIVITY_TYPE_RESTORE_CLIENT
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -42,15 +42,20 @@ class VendorActivity extends Eloquent {
|
|||||||
$account = $this->account;
|
$account = $this->account;
|
||||||
$vendor = $this->vendor;
|
$vendor = $this->vendor;
|
||||||
$user = $this->user;
|
$user = $this->user;
|
||||||
$contactId = $this->contact_id;
|
$contactId = $this->contact_id;
|
||||||
$isSystem = $this->is_system;
|
$isSystem = $this->is_system;
|
||||||
|
|
||||||
$data = [
|
if($vendor) {
|
||||||
'vendor' => link_to($vendor->getRoute(), $vendor->getDisplayName()),
|
$route = $vendor->getRoute();
|
||||||
'user' => $isSystem ? '<i>' . trans('texts.system') . '</i>' : $user->getDisplayName(),
|
|
||||||
'vendorcontact' => $contactId ? $vendor->getDisplayName() : $user->getDisplayName(),
|
|
||||||
];
|
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'vendor' => link_to($route, $vendor->getDisplayName()),
|
||||||
|
'user' => $isSystem ? '<i>' . trans('texts.system') . '</i>' : $user->getDisplayName(),
|
||||||
|
'vendorcontact' => $contactId ? $vendor->getDisplayName() : $user->getDisplayName(),
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
return trans("texts.invalid_activity");
|
||||||
|
}
|
||||||
return trans("texts.activity_{$activityTypeId}", $data);
|
return trans("texts.activity_{$activityTypeId}", $data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
152
app/Ninja/Mailers/VendorContactMailer.php
Normal file
152
app/Ninja/Mailers/VendorContactMailer.php
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
<?php namespace App\Ninja\Mailers;
|
||||||
|
|
||||||
|
use HTML;
|
||||||
|
use Utils;
|
||||||
|
use Event;
|
||||||
|
use URL;
|
||||||
|
use Auth;
|
||||||
|
|
||||||
|
use App\Models\VendorActivity;
|
||||||
|
use App\Models\Gateway;
|
||||||
|
|
||||||
|
class VendorContactMailer extends Mailer
|
||||||
|
{
|
||||||
|
public static $variableFields = [
|
||||||
|
'footer',
|
||||||
|
'account',
|
||||||
|
'vendor',
|
||||||
|
'amount',
|
||||||
|
'contact',
|
||||||
|
'firstName',
|
||||||
|
'viewLink',
|
||||||
|
'viewButton',
|
||||||
|
'paymentLink',
|
||||||
|
'paymentButton',
|
||||||
|
];
|
||||||
|
|
||||||
|
private function sendInvitation($invitation, $invoice, $body, $subject, $pdfString)
|
||||||
|
{
|
||||||
|
$vendor = $invoice->vendor;
|
||||||
|
$account = $invoice->account;
|
||||||
|
|
||||||
|
if (Auth::check()) {
|
||||||
|
$user = Auth::user();
|
||||||
|
} else {
|
||||||
|
$user = $invitation->user;
|
||||||
|
if ($invitation->user->trashed()) {
|
||||||
|
$user = $account->users()->orderBy('id')->first();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$user->email || !$user->registered) {
|
||||||
|
return trans('texts.email_errors.user_unregistered');
|
||||||
|
} elseif (!$user->confirmed) {
|
||||||
|
return trans('texts.email_errors.user_unconfirmed');
|
||||||
|
} elseif (!$invitation->contact->email) {
|
||||||
|
return trans('texts.email_errors.invalid_contact_email');
|
||||||
|
} elseif ($invitation->contact->trashed()) {
|
||||||
|
return trans('texts.email_errors.inactive_contact');
|
||||||
|
}
|
||||||
|
|
||||||
|
$variables = [
|
||||||
|
'account' => $account,
|
||||||
|
'vendor' => $vendor,
|
||||||
|
'invitation' => $invitation
|
||||||
|
];
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'body' => $this->processVariables($body, $variables),
|
||||||
|
'link' => $invitation->getLink(),
|
||||||
|
'entityType' => $invoice->getEntityType(),
|
||||||
|
'invitation' => $invitation,
|
||||||
|
'account' => $account,
|
||||||
|
'vendor' => $vendor,
|
||||||
|
'invoice' => $invoice,
|
||||||
|
];
|
||||||
|
|
||||||
|
if ($account->attatchPDF()) {
|
||||||
|
$data['pdfString'] = $pdfString;
|
||||||
|
$data['pdfFileName'] = $invoice->getFileName();
|
||||||
|
}
|
||||||
|
|
||||||
|
$subject = $this->processVariables($subject, $variables);
|
||||||
|
$fromEmail = $user->email;
|
||||||
|
|
||||||
|
if ($account->email_design_id == EMAIL_DESIGN_PLAIN) {
|
||||||
|
$view = ENTITY_INVOICE;
|
||||||
|
} else {
|
||||||
|
$view = 'design' . ($account->email_design_id - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
$response = $this->sendTo($invitation->contact->email, $fromEmail, $account->getDisplayName(), $subject, $view, $data);
|
||||||
|
|
||||||
|
if ($response === true) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sendLicensePaymentConfirmation($name, $email, $amount, $license, $productId)
|
||||||
|
{
|
||||||
|
$view = 'license_confirmation';
|
||||||
|
$subject = trans('texts.payment_subject');
|
||||||
|
|
||||||
|
if ($productId == PRODUCT_ONE_CLICK_INSTALL) {
|
||||||
|
$license = "Softaculous install license: $license";
|
||||||
|
} elseif ($productId == PRODUCT_INVOICE_DESIGNS) {
|
||||||
|
$license = "Invoice designs license: $license";
|
||||||
|
} elseif ($productId == PRODUCT_WHITE_LABEL) {
|
||||||
|
$license = "White label license: $license";
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'vendor' => $name,
|
||||||
|
'amount' => Utils::formatMoney($amount, DEFAULT_CURRENCY, DEFAULT_COUNTRY),
|
||||||
|
'license' => $license
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->sendTo($email, CONTACT_EMAIL, CONTACT_NAME, $subject, $view, $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function processVariables($template, $data)
|
||||||
|
{
|
||||||
|
$account = $data['account'];
|
||||||
|
$vendor = $data['vendor'];
|
||||||
|
$invitation = $data['invitation'];
|
||||||
|
$invoice = $invitation->invoice;
|
||||||
|
|
||||||
|
$variables = [
|
||||||
|
'$footer' => $account->getEmailFooter(),
|
||||||
|
'$vendor' => $vendor->getDisplayName(),
|
||||||
|
'$account' => $account->getDisplayName(),
|
||||||
|
'$contact' => $invitation->contact->getDisplayName(),
|
||||||
|
'$firstName' => $invitation->contact->first_name,
|
||||||
|
'$amount' => $account->formatMoney($data['amount'], $vendor),
|
||||||
|
'$invoice' => $invoice->invoice_number,
|
||||||
|
'$quote' => $invoice->invoice_number,
|
||||||
|
'$link' => $invitation->getLink(),
|
||||||
|
'$dueDate' => $account->formatDate($invoice->due_date),
|
||||||
|
'$viewLink' => $invitation->getLink(),
|
||||||
|
'$viewButton' => HTML::emailViewButton($invitation->getLink(), $invoice->getEntityType()),
|
||||||
|
'$paymentLink' => $invitation->getLink('payment'),
|
||||||
|
'$paymentButton' => HTML::emailPaymentButton($invitation->getLink('payment')),
|
||||||
|
'$customClient1' => $account->custom_vendor_label1,
|
||||||
|
'$customClient2' => $account->custom_vendor_label2,
|
||||||
|
'$customInvoice1' => $account->custom_invoice_text_label1,
|
||||||
|
'$customInvoice2' => $account->custom_invoice_text_label2,
|
||||||
|
];
|
||||||
|
|
||||||
|
// Add variables for available payment types
|
||||||
|
foreach (Gateway::$paymentTypes as $type) {
|
||||||
|
$camelType = Gateway::getPaymentTypeName($type);
|
||||||
|
$type = Utils::toSnakeCase($camelType);
|
||||||
|
$variables["\${$camelType}Link"] = $invitation->getLink() . "/{$type}";
|
||||||
|
$variables["\${$camelType}Button"] = HTML::emailPaymentButton($invitation->getLink('payment') . "/{$type}");
|
||||||
|
}
|
||||||
|
|
||||||
|
$str = str_replace(array_keys($variables), array_values($variables), $template);
|
||||||
|
|
||||||
|
return $str;
|
||||||
|
}
|
||||||
|
}
|
@ -68,9 +68,9 @@ class VendorActivityRepository
|
|||||||
public function findByVendorId($vendorId)
|
public function findByVendorId($vendorId)
|
||||||
{
|
{
|
||||||
return DB::table('vendor_activities')
|
return DB::table('vendor_activities')
|
||||||
->join('accounts', 'accounts.id', '=', 'activities.account_id')
|
->join('accounts', 'accounts.id', '=', 'vendor_activities.account_id')
|
||||||
->join('users', 'users.id', '=', 'activities.user_id')
|
->join('users', 'users.id', '=', 'vendor_activities.user_id')
|
||||||
->join('vendors', 'vendors.id', '=', 'activities.vendor_id')
|
->join('vendors', 'vendors.id', '=', 'vendor_activities.vendor_id')
|
||||||
->leftJoin('vendor_contacts', 'vendor_contacts.vendor_id', '=', 'vendors.id')
|
->leftJoin('vendor_contacts', 'vendor_contacts.vendor_id', '=', 'vendors.id')
|
||||||
->where('vendors.id', '=', $vendorId)
|
->where('vendors.id', '=', $vendorId)
|
||||||
->where('vendor_contacts.is_primary', '=', 1)
|
->where('vendor_contacts.is_primary', '=', 1)
|
||||||
|
@ -892,6 +892,7 @@ return array(
|
|||||||
'activity_27' => ':user restored payment :payment',
|
'activity_27' => ':user restored payment :payment',
|
||||||
'activity_28' => ':user restored :credit credit',
|
'activity_28' => ':user restored :credit credit',
|
||||||
'activity_29' => ':contact approved quote :quote',
|
'activity_29' => ':contact approved quote :quote',
|
||||||
|
'activity_30' => ':user created :vendor',
|
||||||
|
|
||||||
'payment' => 'Payment',
|
'payment' => 'Payment',
|
||||||
'system' => 'System',
|
'system' => 'System',
|
||||||
|
@ -84,6 +84,13 @@
|
|||||||
{!! $activity->getMessage() !!}
|
{!! $activity->getMessage() !!}
|
||||||
</li>
|
</li>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
@foreach ($vendoractivities as $activity)
|
||||||
|
<li class="list-group-item">
|
||||||
|
<span style="color:#888;font-style:italic">{{ Utils::timestampToDateString(strtotime($activity->created_at)) }}:</span>
|
||||||
|
{!! $activity->getMessage() !!}
|
||||||
|
</li>
|
||||||
|
@endforeach
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
99
resources/views/vendor.blade.php
Normal file
99
resources/views/vendor.blade.php
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
|
||||||
|
{!! Former::legend('Organization') !!}
|
||||||
|
{!! Former::text('name') !!}
|
||||||
|
{!! Former::text('id_number') !!}
|
||||||
|
{!! Former::text('vat_number') !!}
|
||||||
|
{!! Former::text('work_phone')->label('Phone') !!}
|
||||||
|
{!! Former::textarea('notes') !!}
|
||||||
|
|
||||||
|
|
||||||
|
{!! Former::legend('Address') !!}
|
||||||
|
{!! Former::text('address1')->label('Street') !!}
|
||||||
|
{!! Former::text('address2')->label('Apt/Floor') !!}
|
||||||
|
{!! Former::text('city') !!}
|
||||||
|
{!! Former::text('state') !!}
|
||||||
|
{!! Former::text('postal_code') !!}
|
||||||
|
{!! Former::select('country_id')->addOption('','')->label('Country')
|
||||||
|
->fromQuery($countries, 'name', 'id') !!}
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
|
||||||
|
{!! Former::legend('VendorContacts') !!}
|
||||||
|
<div data-bind='template: { foreach: vendor_contacts,
|
||||||
|
beforeRemove: hideContact,
|
||||||
|
afterAdd: showContact }'>
|
||||||
|
{!! Former::hidden('public_id')->data_bind("value: public_id, valueUpdate: 'afterkeydown'") !!}
|
||||||
|
{!! Former::text('first_name')->data_bind("value: first_name, valueUpdate: 'afterkeydown'") !!}
|
||||||
|
{!! Former::text('last_name')->data_bind("value: last_name, valueUpdate: 'afterkeydown'") !!}
|
||||||
|
{!! Former::text('email')->data_bind("value: email, valueUpdate: 'afterkeydown'") !!}
|
||||||
|
{!! Former::text('phone')->data_bind("value: phone, valueUpdate: 'afterkeydown'") !!}
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-lg-8 col-lg-offset-4">
|
||||||
|
<span data-bind="visible: $parent.vendor_contacts().length > 1">
|
||||||
|
{!! link_to('#', 'Remove contact', array('data-bind'=>'click: $parent.removeContact')) !!}
|
||||||
|
</span>
|
||||||
|
<span data-bind="visible: $index() === ($parent.vendor_contacts().length - 1)" class="pull-right">
|
||||||
|
{!! link_to('#', 'Add contact', array('onclick'=>'return addContact()')) !!}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{!! Former::hidden('data')->data_bind("value: ko.toJSON(model)") !!}
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
$(function() {
|
||||||
|
$('#country_id').combobox();
|
||||||
|
});
|
||||||
|
|
||||||
|
function VendorContactModel() {
|
||||||
|
var self = this;
|
||||||
|
self.public_id = ko.observable('');
|
||||||
|
self.first_name = ko.observable('');
|
||||||
|
self.last_name = ko.observable('');
|
||||||
|
self.email = ko.observable('');
|
||||||
|
self.phone = ko.observable('');
|
||||||
|
}
|
||||||
|
|
||||||
|
function VendorContactsModel() {
|
||||||
|
var self = this;
|
||||||
|
self.vendor_contacts = ko.observableArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
@if ($vendor)
|
||||||
|
window.model = ko.mapping.fromJS({!! $vendor !!});
|
||||||
|
@else
|
||||||
|
window.model = new VendorContactsModel();
|
||||||
|
addContact();
|
||||||
|
@endif
|
||||||
|
|
||||||
|
model.showContact = function(elem) { if (elem.nodeType === 1) $(elem).hide().slideDown() }
|
||||||
|
model.hideContact = function(elem) { if (elem.nodeType === 1) $(elem).slideUp(function() { $(elem).remove(); }) }
|
||||||
|
|
||||||
|
|
||||||
|
ko.applyBindings(model);
|
||||||
|
|
||||||
|
function addContact() {
|
||||||
|
model.vendor_contacts.push(new VendorContactModel());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
model.removeContact = function() {
|
||||||
|
model.vendor_contacts.remove(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
236
resources/views/vendors/edit.blade.php
vendored
Normal file
236
resources/views/vendors/edit.blade.php
vendored
Normal file
@ -0,0 +1,236 @@
|
|||||||
|
@extends('header')
|
||||||
|
|
||||||
|
|
||||||
|
@section('onReady')
|
||||||
|
$('input#name').focus();
|
||||||
|
@stop
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
|
||||||
|
@if ($errors->first('vendor_contacts'))
|
||||||
|
<div class="alert alert-danger">{{ trans($errors->first('vendor_contacts')) }}</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
{!! Former::open($url)
|
||||||
|
->autocomplete('off')
|
||||||
|
->rules(
|
||||||
|
['email' => 'email']
|
||||||
|
)->addClass('col-md-12 warn-on-exit')
|
||||||
|
->method($method) !!}
|
||||||
|
|
||||||
|
@include('partials.autocomplete_fix')
|
||||||
|
|
||||||
|
@if ($vendor)
|
||||||
|
{!! Former::populate($vendor) !!}
|
||||||
|
{!! Former::hidden('public_id') !!}
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
|
||||||
|
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h3 class="panel-title">{!! trans('texts.organization') !!}</h3>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
|
||||||
|
{!! Former::text('name')->data_bind("attr { placeholder: placeholderName }") !!}
|
||||||
|
{!! Former::text('id_number') !!}
|
||||||
|
{!! Former::text('vat_number') !!}
|
||||||
|
{!! Former::text('website') !!}
|
||||||
|
{!! Former::text('work_phone') !!}
|
||||||
|
|
||||||
|
@if (Auth::user()->isPro())
|
||||||
|
@if ($customLabel1)
|
||||||
|
{!! Former::text('custom_value1')->label($customLabel1) !!}
|
||||||
|
@endif
|
||||||
|
@if ($customLabel2)
|
||||||
|
{!! Former::text('custom_value2')->label($customLabel2) !!}
|
||||||
|
@endif
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h3 class="panel-title">{!! trans('texts.address') !!}</h3>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
|
||||||
|
{!! Former::text('address1') !!}
|
||||||
|
{!! Former::text('address2') !!}
|
||||||
|
{!! Former::text('city') !!}
|
||||||
|
{!! Former::text('state') !!}
|
||||||
|
{!! Former::text('postal_code') !!}
|
||||||
|
{!! Former::select('country_id')->addOption('','')
|
||||||
|
->fromQuery($countries, 'name', 'id') !!}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
|
||||||
|
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h3 class="panel-title">{!! trans('texts.contacts') !!}</h3>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
|
||||||
|
<div data-bind='template: { foreach: vendorcontacts,
|
||||||
|
beforeRemove: hideContact,
|
||||||
|
afterAdd: showContact }'>
|
||||||
|
{!! Former::hidden('public_id')->data_bind("value: public_id, valueUpdate: 'afterkeydown',
|
||||||
|
attr: {name: 'vendor_contacts[' + \$index() + '][public_id]'}") !!}
|
||||||
|
{!! Former::text('first_name')->data_bind("value: first_name, valueUpdate: 'afterkeydown',
|
||||||
|
attr: {name: 'vendor_contacts[' + \$index() + '][first_name]'}") !!}
|
||||||
|
{!! Former::text('last_name')->data_bind("value: last_name, valueUpdate: 'afterkeydown',
|
||||||
|
attr: {name: 'vendor_contacts[' + \$index() + '][last_name]'}") !!}
|
||||||
|
{!! Former::text('email')->data_bind("value: email, valueUpdate: 'afterkeydown',
|
||||||
|
attr: {name: 'vendor_contacts[' + \$index() + '][email]', id:'email'+\$index()}") !!}
|
||||||
|
{!! Former::text('phone')->data_bind("value: phone, valueUpdate: 'afterkeydown',
|
||||||
|
attr: {name: 'vendor_contacts[' + \$index() + '][phone]'}") !!}
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-lg-8 col-lg-offset-4 bold">
|
||||||
|
<span class="redlink bold" data-bind="visible: $parent.vendorcontacts().length > 1">
|
||||||
|
{!! link_to('#', trans('texts.remove_contact').' -', array('data-bind'=>'click: $parent.removeContact')) !!}
|
||||||
|
</span>
|
||||||
|
<span data-bind="visible: $index() === ($parent.vendorcontacts().length - 1)" class="pull-right greenlink bold">
|
||||||
|
{!! link_to('#', trans('texts.add_contact').' +', array('onclick'=>'return addContact()')) !!}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h3 class="panel-title">{!! trans('texts.additional_info') !!}</h3>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
|
||||||
|
{!! Former::select('currency_id')->addOption('','')
|
||||||
|
->placeholder($account->currency ? $account->currency->name : '')
|
||||||
|
->fromQuery($currencies, 'name', 'id') !!}
|
||||||
|
{!! Former::select('language_id')->addOption('','')
|
||||||
|
->placeholder($account->language ? $account->language->name : '')
|
||||||
|
->fromQuery($languages, 'name', 'id') !!}
|
||||||
|
{!! Former::select('payment_terms')->addOption('','')
|
||||||
|
->fromQuery($paymentTerms, 'name', 'num_days')
|
||||||
|
->help(trans('texts.payment_terms_help')) !!}
|
||||||
|
{!! Former::select('size_id')->addOption('','')
|
||||||
|
->fromQuery($sizes, 'name', 'id') !!}
|
||||||
|
{!! Former::select('industry_id')->addOption('','')
|
||||||
|
->fromQuery($industries, 'name', 'id') !!}
|
||||||
|
{!! Former::textarea('private_notes') !!}
|
||||||
|
|
||||||
|
|
||||||
|
@if (isset($proPlanPaid))
|
||||||
|
{!! Former::populateField('pro_plan_paid', $proPlanPaid) !!}
|
||||||
|
{!! Former::text('pro_plan_paid')
|
||||||
|
->data_date_format('yyyy-mm-dd')
|
||||||
|
->addGroupClass('pro_plan_paid_date')
|
||||||
|
->append('<i class="glyphicon glyphicon-calendar"></i>') !!}
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(function() {
|
||||||
|
$('#pro_plan_paid').datepicker();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{!! Former::hidden('data')->data_bind("value: ko.toJSON(model)") !!}
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
$(function() {
|
||||||
|
$('#country_id').combobox();
|
||||||
|
});
|
||||||
|
|
||||||
|
function VendorContactModel(data) {
|
||||||
|
var self = this;
|
||||||
|
self.public_id = ko.observable('');
|
||||||
|
self.first_name = ko.observable('');
|
||||||
|
self.last_name = ko.observable('');
|
||||||
|
self.email = ko.observable('');
|
||||||
|
self.phone = ko.observable('');
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
ko.mapping.fromJS(data, {}, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function VendorModel(data) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
self.vendor_contacts = ko.observableArray();
|
||||||
|
|
||||||
|
self.mapping = {
|
||||||
|
'vendor_contacts': {
|
||||||
|
create: function(options) {
|
||||||
|
return new VendorContactModel(options.data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
ko.mapping.fromJS(data, self.mapping, this);
|
||||||
|
} else {
|
||||||
|
self.vendor_contacts.push(new VendorContactModel());
|
||||||
|
}
|
||||||
|
|
||||||
|
self.placeholderName = ko.computed(function() {
|
||||||
|
if (self.vendor_contacts().length == 0) return '';
|
||||||
|
var contact = self.vendor_contacts()[0];
|
||||||
|
if (contact.first_name() || contact.last_name()) {
|
||||||
|
return contact.first_name() + ' ' + contact.last_name();
|
||||||
|
} else {
|
||||||
|
return contact.email();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@if ($data)
|
||||||
|
window.model = new VendorModel({!! $data !!});
|
||||||
|
@else
|
||||||
|
window.model = new VendorModel({!! $vendor !!});
|
||||||
|
@endif
|
||||||
|
|
||||||
|
model.showContact = function(elem) { if (elem.nodeType === 1) $(elem).hide().slideDown() }
|
||||||
|
model.hideContact = function(elem) { if (elem.nodeType === 1) $(elem).slideUp(function() { $(elem).remove(); }) }
|
||||||
|
|
||||||
|
|
||||||
|
ko.applyBindings(model);
|
||||||
|
|
||||||
|
function addContact() {
|
||||||
|
model.vendorcontacts.push(new VendorContactModel());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
model.removeContact = function() {
|
||||||
|
model.vendorcontacts.remove(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<center class="buttons">
|
||||||
|
{!! Button::normal(trans('texts.cancel'))->large()->asLinkTo(URL::to('/vendors/' . ($vendor ? $vendor->public_id : '')))->appendIcon(Icon::create('remove-circle')) !!}
|
||||||
|
{!! Button::success(trans('texts.save'))->submit()->large()->appendIcon(Icon::create('floppy-disk')) !!}
|
||||||
|
</center>
|
||||||
|
|
||||||
|
{!! Former::close() !!}
|
||||||
|
</div>
|
||||||
|
@stop
|
304
resources/views/vendors/show.blade.php
vendored
Normal file
304
resources/views/vendors/show.blade.php
vendored
Normal file
@ -0,0 +1,304 @@
|
|||||||
|
@extends('header')
|
||||||
|
|
||||||
|
@section('head')
|
||||||
|
@parent
|
||||||
|
|
||||||
|
@if ($vendor->hasAddress())
|
||||||
|
<style>
|
||||||
|
#map {
|
||||||
|
width: 100%;
|
||||||
|
height: 200px;
|
||||||
|
border-width: 1px;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: #ddd;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script src="https://maps.googleapis.com/maps/api/js"></script>
|
||||||
|
@endif
|
||||||
|
@stop
|
||||||
|
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
|
||||||
|
<div class="pull-right">
|
||||||
|
{!! Former::open('vendors/bulk')->addClass('mainForm') !!}
|
||||||
|
<div style="display:none">
|
||||||
|
{!! Former::text('action') !!}
|
||||||
|
{!! Former::text('public_id')->value($vendor->public_id) !!}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@if ($gatewayLink)
|
||||||
|
{!! Button::normal(trans('texts.view_in_stripe'))->asLinkTo($gatewayLink)->withAttributes(['target' => '_blank']) !!}
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@if ($vendor->trashed())
|
||||||
|
{!! Button::primary(trans('texts.restore_vendor'))->withAttributes(['onclick' => 'onRestoreClick()']) !!}
|
||||||
|
@else
|
||||||
|
{!! DropdownButton::normal(trans('texts.edit_vendor'))
|
||||||
|
->withAttributes(['class'=>'normalDropDown'])
|
||||||
|
->withContents([
|
||||||
|
['label' => trans('texts.archive_vendor'), 'url' => "javascript:onArchiveClick()"],
|
||||||
|
['label' => trans('texts.delete_vendor'), 'url' => "javascript:onDeleteClick()"],
|
||||||
|
]
|
||||||
|
)->split() !!}
|
||||||
|
|
||||||
|
{!! DropdownButton::primary(trans('texts.new_expense'))
|
||||||
|
->withAttributes(['class'=>'primaryDropDown'])
|
||||||
|
->withContents($actionLinks)->split() !!}
|
||||||
|
@endif
|
||||||
|
{!! Former::close() !!}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<h2>{{ $vendor->getDisplayName() }}</h2>
|
||||||
|
{{--
|
||||||
|
@if ($vendor->last_login > 0)
|
||||||
|
<h3 style="margin-top:0px"><small>
|
||||||
|
{{ trans('texts.last_logged_in') }} {{ Utils::timestampToDateTimeString(strtotime($vendor->last_login)) }}
|
||||||
|
</small></h3>
|
||||||
|
@endif
|
||||||
|
--}}
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-body">
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="col-md-3">
|
||||||
|
<h3>{{ trans('texts.details') }}</h3>
|
||||||
|
@if ($vendor->id_number)
|
||||||
|
<p><i class="fa fa-id-number" style="width: 20px"></i>{{ trans('texts.id_number').': '.$vendor->id_number }}</p>
|
||||||
|
@endif
|
||||||
|
@if ($vendor->vat_number)
|
||||||
|
<p><i class="fa fa-vat-number" style="width: 20px"></i>{{ trans('texts.vat_number').': '.$vendor->vat_number }}</p>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@if ($vendor->address1)
|
||||||
|
{{ $vendor->address1 }}<br/>
|
||||||
|
@endif
|
||||||
|
@if ($vendor->address2)
|
||||||
|
{{ $vendor->address2 }}<br/>
|
||||||
|
@endif
|
||||||
|
@if ($vendor->getCityState())
|
||||||
|
{{ $vendor->getCityState() }}<br/>
|
||||||
|
@endif
|
||||||
|
@if ($vendor->country)
|
||||||
|
{{ $vendor->country->name }}<br/>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@if ($vendor->account->custom_vendor_label1 && $vendor->custom_value1)
|
||||||
|
{{ $vendor->account->custom_vendor_label1 . ': ' . $vendor->custom_value1 }}<br/>
|
||||||
|
@endif
|
||||||
|
@if ($vendor->account->custom_vendor_label2 && $vendor->custom_value2)
|
||||||
|
{{ $vendor->account->custom_vendor_label2 . ': ' . $vendor->custom_value2 }}<br/>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@if ($vendor->work_phone)
|
||||||
|
<i class="fa fa-phone" style="width: 20px"></i>{{ $vendor->work_phone }}
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@if ($vendor->private_notes)
|
||||||
|
<p><i>{{ $vendor->private_notes }}</i></p>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@if ($vendor->vendor_industry)
|
||||||
|
{{ $vendor->vendor_industry->name }}<br/>
|
||||||
|
@endif
|
||||||
|
@if ($vendor->vendor_size)
|
||||||
|
{{ $vendor->vendor_size->name }}<br/>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@if ($vendor->website)
|
||||||
|
<p>{!! Utils::formatWebsite($vendor->website) !!}</p>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@if ($vendor->language)
|
||||||
|
<p><i class="fa fa-language" style="width: 20px"></i>{{ $vendor->language->name }}</p>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<p>{{ $vendor->payment_terms ? trans('texts.payment_terms') . ": " . trans('texts.payment_terms_net') . " " . $vendor->payment_terms : '' }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-3">
|
||||||
|
<h3>{{ trans('texts.contacts') }}</h3>
|
||||||
|
@foreach ($vendor->vendorcontacts as $contact)
|
||||||
|
@if ($contact->first_name || $contact->last_name)
|
||||||
|
<b>{{ $contact->first_name.' '.$contact->last_name }}</b><br/>
|
||||||
|
@endif
|
||||||
|
@if ($contact->email)
|
||||||
|
<i class="fa fa-envelope" style="width: 20px"></i>{!! HTML::mailto($contact->email, $contact->email) !!}<br/>
|
||||||
|
@endif
|
||||||
|
@if ($contact->phone)
|
||||||
|
<i class="fa fa-phone" style="width: 20px"></i>{{ $contact->phone }}<br/>
|
||||||
|
@endif
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-4">
|
||||||
|
<h3>{{ trans('texts.standing') }}
|
||||||
|
<table class="table" style="width:100%">
|
||||||
|
<tr>
|
||||||
|
<td><small>{{ trans('texts.paid_to_date') }}</small></td>
|
||||||
|
<td style="text-align: right">{{ Utils::formatMoney($vendor->paid_to_date, $vendor->getCurrencyId()) }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><small>{{ trans('texts.balance') }}</small></td>
|
||||||
|
<td style="text-align: right">{{ Utils::formatMoney($vendor->balance, $vendor->getCurrencyId()) }}</td>
|
||||||
|
</tr>
|
||||||
|
@if ($credit > 0)
|
||||||
|
<tr>
|
||||||
|
<td><small>{{ trans('texts.credit') }}</small></td>
|
||||||
|
<td style="text-align: right">{{ Utils::formatMoney($credit, $vendor->getCurrencyId()) }}</td>
|
||||||
|
</tr>
|
||||||
|
@endif
|
||||||
|
</table>
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@if ($vendor->hasAddress())
|
||||||
|
<div id="map"></div>
|
||||||
|
<br/>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<ul class="nav nav-tabs nav-justified">
|
||||||
|
{!! HTML::tab_link('#activity', trans('texts.activity'), true) !!}
|
||||||
|
{!! HTML::tab_link('#credits', trans('texts.expenses')) !!}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="tab-content">
|
||||||
|
<div class="tab-pane active" id="activity">
|
||||||
|
|
||||||
|
{!! Datatable::table()
|
||||||
|
->addColumn(
|
||||||
|
trans('texts.date'),
|
||||||
|
trans('texts.message'),
|
||||||
|
trans('texts.balance'),
|
||||||
|
trans('texts.adjustment'))
|
||||||
|
->setUrl(url('api/vendoractivities/'. $vendor->public_id))
|
||||||
|
->setCustomValues('entityType', 'activity')
|
||||||
|
->setOptions('sPaginationType', 'bootstrap')
|
||||||
|
->setOptions('bFilter', false)
|
||||||
|
->setOptions('aaSorting', [['0', 'desc']])
|
||||||
|
->render('datatable') !!}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tab-pane" id="expenses">
|
||||||
|
|
||||||
|
{!! Datatable::table()
|
||||||
|
->addColumn(
|
||||||
|
trans('texts.credit_amount'),
|
||||||
|
trans('texts.credit_balance'),
|
||||||
|
trans('texts.credit_date'),
|
||||||
|
trans('texts.private_notes'))
|
||||||
|
->setUrl(url('api/credits/' . $vendor->public_id))
|
||||||
|
->setCustomValues('entityType', 'credits')
|
||||||
|
->setOptions('sPaginationType', 'bootstrap')
|
||||||
|
->setOptions('bFilter', false)
|
||||||
|
->setOptions('aaSorting', [['0', 'asc']])
|
||||||
|
->render('datatable')
|
||||||
|
!!}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
var loadedTabs = {};
|
||||||
|
|
||||||
|
$(function() {
|
||||||
|
$('.normalDropDown:not(.dropdown-toggle)').click(function() {
|
||||||
|
window.location = '{{ URL::to('vendors/' . $vendor->public_id . '/edit') }}';
|
||||||
|
});
|
||||||
|
$('.primaryDropDown:not(.dropdown-toggle)').click(function() {
|
||||||
|
window.location = '{{ URL::to('invoices/create/' . $vendor->public_id ) }}';
|
||||||
|
});
|
||||||
|
|
||||||
|
// load datatable data when tab is shown and remember last tab selected
|
||||||
|
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
|
||||||
|
var target = $(e.target).attr("href") // activated tab
|
||||||
|
target = target.substring(1);
|
||||||
|
localStorage.setItem('vendor_tab', target);
|
||||||
|
if (!loadedTabs.hasOwnProperty(target)) {
|
||||||
|
loadedTabs[target] = true;
|
||||||
|
window['load_' + target]();
|
||||||
|
if (target == 'invoices' && window.hasOwnProperty('load_recurring_invoices')) {
|
||||||
|
window['load_recurring_invoices']();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var tab = localStorage.getItem('vendor_tab');
|
||||||
|
if (tab && tab != 'activity') {
|
||||||
|
$('.nav-tabs a[href="#' + tab.replace('#', '') + '"]').tab('show');
|
||||||
|
} else {
|
||||||
|
window['load_activity']();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function onArchiveClick() {
|
||||||
|
$('#action').val('archive');
|
||||||
|
$('.mainForm').submit();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onRestoreClick() {
|
||||||
|
$('#action').val('restore');
|
||||||
|
$('.mainForm').submit();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onDeleteClick() {
|
||||||
|
if (confirm("{!! trans('texts.are_you_sure') !!}")) {
|
||||||
|
$('#action').val('delete');
|
||||||
|
$('.mainForm').submit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@if ($vendor->hasAddress())
|
||||||
|
function initialize() {
|
||||||
|
var mapCanvas = document.getElementById('map');
|
||||||
|
var mapOptions = {
|
||||||
|
zoom: {{ DEFAULT_MAP_ZOOM }},
|
||||||
|
mapTypeId: google.maps.MapTypeId.ROADMAP,
|
||||||
|
zoomControl: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
var map = new google.maps.Map(mapCanvas, mapOptions)
|
||||||
|
var address = "{{ "{$vendor->address1} {$vendor->address2} {$vendor->city} {$vendor->state} {$vendor->postal_code} " . ($vendor->country ? $vendor->country->name : '') }}";
|
||||||
|
|
||||||
|
geocoder = new google.maps.Geocoder();
|
||||||
|
geocoder.geocode( { 'address': address}, function(results, status) {
|
||||||
|
if (status == google.maps.GeocoderStatus.OK) {
|
||||||
|
if (status != google.maps.GeocoderStatus.ZERO_RESULTS) {
|
||||||
|
var result = results[0];
|
||||||
|
map.setCenter(result.geometry.location);
|
||||||
|
|
||||||
|
var infowindow = new google.maps.InfoWindow(
|
||||||
|
{ content: '<b>'+result.formatted_address+'</b>',
|
||||||
|
size: new google.maps.Size(150, 50)
|
||||||
|
});
|
||||||
|
|
||||||
|
var marker = new google.maps.Marker({
|
||||||
|
position: result.geometry.location,
|
||||||
|
map: map,
|
||||||
|
title:address,
|
||||||
|
});
|
||||||
|
google.maps.event.addListener(marker, 'click', function() {
|
||||||
|
infowindow.open(map, marker);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$('#map').hide();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$('#map').hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
google.maps.event.addDomListener(window, 'load', initialize);
|
||||||
|
@endif
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
@stop
|
Loading…
x
Reference in New Issue
Block a user