mirror of
https://github.com/crater-invoice/crater.git
synced 2025-10-27 19:51:09 -04:00
Fix Invoice/Estimate template issues and Add Payment Receipt, Custom Payment Modes and Item units
This commit is contained in:
committed by
Mohit Panjwani
parent
56a955befd
commit
4c33a5d88c
51
app/Console/Commands/ResetApp.php
Normal file
51
app/Console/Commands/ResetApp.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use Illuminate\Filesystem\Filesystem;
|
||||
|
||||
class ResetApp extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'reset:app';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Clean database, database_created and public/storage folder';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
if ($this->confirm('Do you wish to continue? This will delete your tables')) {
|
||||
Artisan::call('migrate:reset --force');
|
||||
|
||||
\Storage::disk('local')->delete('database_created');
|
||||
|
||||
$file = new Filesystem;
|
||||
$file->cleanDirectory('storage/app/public');
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -12,7 +12,7 @@ class Kernel extends ConsoleKernel
|
||||
* @var array
|
||||
*/
|
||||
protected $commands = [
|
||||
|
||||
Commands\ResetApp::class
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@ -19,7 +19,7 @@ use Crater\Currency;
|
||||
use Crater\CompanySetting;
|
||||
|
||||
class CompanyController extends Controller
|
||||
{
|
||||
{
|
||||
/**
|
||||
* Retrive the Admin account.
|
||||
* @return \Crater\User
|
||||
@ -66,9 +66,9 @@ class CompanyController extends Controller
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get Admin Account alongside the country from the addresses table and
|
||||
* Get Admin Account alongside the country from the addresses table and
|
||||
* The company from companies table
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
@ -148,6 +148,7 @@ class CompanyController extends Controller
|
||||
["code"=>"fr", "name" => "French"],
|
||||
["code"=>"es", "name" => "Spanish"],
|
||||
["code"=>"ar", "name" => "العربية"],
|
||||
["code"=>"de", "name" => "German"]
|
||||
];
|
||||
|
||||
return response()->json([
|
||||
@ -191,7 +192,7 @@ class CompanyController extends Controller
|
||||
'success' => true
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
public function getCustomizeSetting (Request $request)
|
||||
{
|
||||
$invoice_prefix = CompanySetting::getSetting('invoice_prefix', $request->header('company'));
|
||||
|
||||
@ -406,6 +406,10 @@ class EstimatesController extends Controller
|
||||
{
|
||||
$estimate = Estimate::with(['items', 'items.taxes', 'user', 'estimateTemplate', 'taxes'])->find($id);
|
||||
$invoice_date = Carbon::parse($estimate->estimate_date);
|
||||
$invoice_prefix = CompanySetting::getSetting(
|
||||
'invoice_prefix',
|
||||
$request->header('company')
|
||||
);
|
||||
$due_date = Carbon::parse($estimate->estimate_date)->addDays(7);
|
||||
$tax_per_item = CompanySetting::getSetting(
|
||||
'tax_per_item',
|
||||
@ -425,7 +429,7 @@ class EstimatesController extends Controller
|
||||
$invoice = Invoice::create([
|
||||
'invoice_date' => $invoice_date,
|
||||
'due_date' => $due_date,
|
||||
'invoice_number' => "INV-".Invoice::getNextInvoiceNumber(),
|
||||
'invoice_number' => $invoice_prefix."-".Invoice::getNextInvoiceNumber($invoice_prefix),
|
||||
'reference_number' => $estimate->reference_number,
|
||||
'user_id' => $estimate->user_id,
|
||||
'company_id' => $request->header('company'),
|
||||
|
||||
@ -6,6 +6,7 @@ use Crater\Invoice;
|
||||
use PDF;
|
||||
use Crater\CompanySetting;
|
||||
use Crater\Estimate;
|
||||
use Crater\Payment;
|
||||
use Crater\User;
|
||||
use Crater\Company;
|
||||
use Crater\InvoiceTemplate;
|
||||
@ -376,4 +377,34 @@ class FrontendController extends Controller
|
||||
|
||||
return $pdf->stream();
|
||||
}
|
||||
|
||||
public function getPaymentPdf($id)
|
||||
{
|
||||
$payment = Payment::with([
|
||||
'user',
|
||||
'invoice',
|
||||
'paymentMethod'
|
||||
])
|
||||
->where('unique_hash', $id)
|
||||
->first();
|
||||
|
||||
$company = Company::find($payment->company_id);
|
||||
$companyAddress = User::with(['addresses', 'addresses.country'])->find(1);
|
||||
|
||||
$logo = $company->getMedia('logo')->first();
|
||||
|
||||
if($logo) {
|
||||
$logo = $logo->getFullUrl();
|
||||
}
|
||||
|
||||
view()->share([
|
||||
'payment' => $payment,
|
||||
'company_address' => $companyAddress,
|
||||
'logo' => $logo ?? null
|
||||
]);
|
||||
|
||||
$pdf = PDF::loadView('app.pdf.payment.payment');
|
||||
|
||||
return $pdf->stream();
|
||||
}
|
||||
}
|
||||
|
||||
@ -497,4 +497,94 @@ class InvoicesController extends Controller
|
||||
'invoices' => $invoices
|
||||
]);
|
||||
}
|
||||
|
||||
public function cloneInvoice(Request $request)
|
||||
{
|
||||
$oldInvoice = Invoice::with([
|
||||
'items.taxes',
|
||||
'user',
|
||||
'invoiceTemplate',
|
||||
'taxes.taxType'
|
||||
])
|
||||
->find($request->id);
|
||||
|
||||
$date = Carbon::now();
|
||||
$invoice_prefix = CompanySetting::getSetting(
|
||||
'invoice_prefix',
|
||||
$request->header('company')
|
||||
);
|
||||
$tax_per_item = CompanySetting::getSetting(
|
||||
'tax_per_item',
|
||||
$request->header('company')
|
||||
) ? CompanySetting::getSetting(
|
||||
'tax_per_item',
|
||||
$request->header('company')
|
||||
) : 'NO';
|
||||
$discount_per_item = CompanySetting::getSetting(
|
||||
'discount_per_item',
|
||||
$request->header('company')
|
||||
) ? CompanySetting::getSetting(
|
||||
'discount_per_item',
|
||||
$request->header('company')
|
||||
) : 'NO';
|
||||
|
||||
$invoice = Invoice::create([
|
||||
'invoice_date' => $date,
|
||||
'due_date' => $date,
|
||||
'invoice_number' => $invoice_prefix."-".Invoice::getNextInvoiceNumber($invoice_prefix),
|
||||
'reference_number' => $oldInvoice->reference_number,
|
||||
'user_id' => $oldInvoice->user_id,
|
||||
'company_id' => $request->header('company'),
|
||||
'invoice_template_id' => 1,
|
||||
'status' => Invoice::STATUS_DRAFT,
|
||||
'paid_status' => Invoice::STATUS_UNPAID,
|
||||
'sub_total' => $oldInvoice->sub_total,
|
||||
'discount' => $oldInvoice->discount,
|
||||
'discount_type' => $oldInvoice->discount_type,
|
||||
'discount_val' => $oldInvoice->discount_val,
|
||||
'total' => $oldInvoice->total,
|
||||
'due_amount' => $oldInvoice->total,
|
||||
'tax_per_item' => $oldInvoice->tax_per_item,
|
||||
'discount_per_item' => $oldInvoice->discount_per_item,
|
||||
'tax' => $oldInvoice->tax,
|
||||
'notes' => $oldInvoice->notes,
|
||||
'unique_hash' => str_random(60)
|
||||
]);
|
||||
|
||||
$invoiceItems = $oldInvoice->items->toArray();
|
||||
|
||||
foreach ($invoiceItems as $invoiceItem) {
|
||||
$invoiceItem['company_id'] = $request->header('company');
|
||||
$invoiceItem['name'] = $invoiceItem['name'];
|
||||
$item = $invoice->items()->create($invoiceItem);
|
||||
|
||||
if (array_key_exists('taxes', $invoiceItem) && $invoiceItem['taxes']) {
|
||||
foreach ($invoiceItem['taxes'] as $tax) {
|
||||
$tax['company_id'] = $request->header('company');
|
||||
|
||||
if ($tax['amount']) {
|
||||
$item->taxes()->create($tax);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($oldInvoice->taxes) {
|
||||
foreach ($oldInvoice->taxes->toArray() as $tax) {
|
||||
$tax['company_id'] = $request->header('company');
|
||||
$invoice->taxes()->create($tax);
|
||||
}
|
||||
}
|
||||
|
||||
$invoice = Invoice::with([
|
||||
'items',
|
||||
'user',
|
||||
'invoiceTemplate',
|
||||
'taxes'
|
||||
])->find($invoice->id);
|
||||
|
||||
return response()->json([
|
||||
'invoice' => $invoice
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,14 +14,17 @@ class ItemsController extends Controller
|
||||
{
|
||||
$limit = $request->has('limit') ? $request->limit : 10;
|
||||
|
||||
$items = Item::applyFilters($request->only([
|
||||
$items = Item::with(['taxes'])
|
||||
->leftJoin('units', 'units.id', '=', 'items.unit_id')
|
||||
->applyFilters($request->only([
|
||||
'search',
|
||||
'price',
|
||||
'unit',
|
||||
'unit_id',
|
||||
'orderByField',
|
||||
'orderBy'
|
||||
]))
|
||||
->whereCompany($request->header('company'))
|
||||
->select('items.*', 'units.name as unit_name')
|
||||
->latest()
|
||||
->paginate($limit);
|
||||
|
||||
@ -33,7 +36,7 @@ class ItemsController extends Controller
|
||||
|
||||
public function edit(Request $request, $id)
|
||||
{
|
||||
$item = Item::with('taxes')->find($id);
|
||||
$item = Item::with(['taxes', 'unit'])->find($id);
|
||||
|
||||
return response()->json([
|
||||
'item' => $item,
|
||||
@ -54,7 +57,7 @@ class ItemsController extends Controller
|
||||
{
|
||||
$item = new Item();
|
||||
$item->name = $request->name;
|
||||
$item->unit = $request->unit;
|
||||
$item->unit_id = $request->unit_id;
|
||||
$item->description = $request->description;
|
||||
$item->company_id = $request->header('company');
|
||||
$item->price = $request->price;
|
||||
@ -85,7 +88,7 @@ class ItemsController extends Controller
|
||||
{
|
||||
$item = Item::find($id);
|
||||
$item->name = $request->name;
|
||||
$item->unit = $request->unit;
|
||||
$item->unit_id = $request->unit_id;
|
||||
$item->description = $request->description;
|
||||
$item->price = $request->price;
|
||||
$item->save();
|
||||
@ -145,7 +148,7 @@ class ItemsController extends Controller
|
||||
$items = [];
|
||||
foreach ($request->id as $id) {
|
||||
$item = Item::deleteItem($id);
|
||||
if (!$item) {
|
||||
if ($item) {
|
||||
array_push($items, $id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,7 +46,9 @@ class OnboardingController extends Controller
|
||||
$languages = [
|
||||
["code"=>"en", "name" => "English"],
|
||||
["code"=>"fr", "name" => "French"],
|
||||
["code"=>"es", "name" => "Spanish"]
|
||||
["code"=>"es", "name" => "Spanish"],
|
||||
["code"=>"ar", "name" => "العربية"],
|
||||
["code"=>"de", "name" => "German"]
|
||||
];
|
||||
$fiscal_years = [
|
||||
['key' => 'january-december' , 'value' => '1-12'],
|
||||
@ -304,6 +306,10 @@ class OnboardingController extends Controller
|
||||
|
||||
Artisan::call('passport:install --force');
|
||||
|
||||
Artisan::call('db:seed', ['--class' => 'PaymentMethodSeeder', '--force' => true]);
|
||||
|
||||
Artisan::call('db:seed', ['--class' => 'UnitSeeder', '--force' => true]);
|
||||
|
||||
$client = DB::table('oauth_clients')->find(2);
|
||||
|
||||
$path = base_path('.env');
|
||||
|
||||
@ -4,13 +4,16 @@ namespace Crater\Http\Controllers;
|
||||
use Illuminate\Http\Request;
|
||||
use Crater\CompanySetting;
|
||||
use Crater\Currency;
|
||||
use Crater\Company;
|
||||
use Crater\Invoice;
|
||||
use Crater\Payment;
|
||||
use Crater\PaymentMethod;
|
||||
use Carbon\Carbon;
|
||||
use function MongoDB\BSON\toJSON;
|
||||
use Crater\User;
|
||||
use Crater\Http\Requests\PaymentRequest;
|
||||
use Validator;
|
||||
use Crater\Mail\PaymentPdf;
|
||||
|
||||
class PaymentController extends Controller
|
||||
{
|
||||
@ -23,19 +26,20 @@ class PaymentController extends Controller
|
||||
{
|
||||
$limit = $request->has('limit') ? $request->limit : 10;
|
||||
|
||||
$payments = Payment::with('user', 'invoice')
|
||||
$payments = Payment::with(['user', 'invoice', 'paymentMethod'])
|
||||
->join('users', 'users.id', '=', 'payments.user_id')
|
||||
->leftJoin('invoices', 'invoices.id', '=', 'payments.invoice_id')
|
||||
->leftJoin('payment_methods', 'payment_methods.id', '=', 'payments.payment_method_id')
|
||||
->applyFilters($request->only([
|
||||
'search',
|
||||
'payment_number',
|
||||
'payment_mode',
|
||||
'payment_method_id',
|
||||
'customer_id',
|
||||
'orderByField',
|
||||
'orderBy'
|
||||
]))
|
||||
->whereCompany($request->header('company'))
|
||||
->select('payments.*', 'users.name', 'invoices.invoice_number')
|
||||
->select('payments.*', 'users.name', 'invoices.invoice_number', 'payment_methods.name as payment_mode')
|
||||
->latest()
|
||||
->paginate($limit);
|
||||
|
||||
@ -66,6 +70,9 @@ class PaymentController extends Controller
|
||||
'customers' => User::where('role', 'customer')
|
||||
->whereCompany($request->header('company'))
|
||||
->get(),
|
||||
'paymentMethods' => PaymentMethod::whereCompany($request->header('company'))
|
||||
->latest()
|
||||
->get(),
|
||||
'nextPaymentNumberAttribute' => $nextPaymentNumberAttribute,
|
||||
'nextPaymentNumber' => $payment_prefix.'-'.$nextPaymentNumber,
|
||||
'payment_prefix' => $payment_prefix
|
||||
@ -113,13 +120,15 @@ class PaymentController extends Controller
|
||||
'user_id' => $request->user_id,
|
||||
'company_id' => $request->header('company'),
|
||||
'invoice_id' => $request->invoice_id,
|
||||
'payment_mode' => $request->payment_mode,
|
||||
'payment_method_id' => $request->payment_method_id,
|
||||
'amount' => $request->amount,
|
||||
'notes' => $request->notes,
|
||||
'unique_hash' => str_random(60)
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'payment' => $payment,
|
||||
'shareable_link' => url('/payments/pdf/'.$payment->unique_hash),
|
||||
'success' => true
|
||||
]);
|
||||
}
|
||||
@ -132,7 +141,12 @@ class PaymentController extends Controller
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
//
|
||||
$payment = Payment::with(['user', 'invoice', 'paymentMethod'])->find($id);
|
||||
|
||||
return response()->json([
|
||||
'payment' => $payment,
|
||||
'shareable_link' => url('/payments/pdf/'.$payment->unique_hash)
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -143,7 +157,7 @@ class PaymentController extends Controller
|
||||
*/
|
||||
public function edit(Request $request, $id)
|
||||
{
|
||||
$payment = Payment::with('user', 'invoice')->find($id);
|
||||
$payment = Payment::with(['user', 'invoice', 'paymentMethod'])->find($id);
|
||||
|
||||
$invoices = Invoice::where('paid_status', '<>', Invoice::STATUS_PAID)
|
||||
->where('user_id', $payment->user_id)->where('due_amount', '>', 0)
|
||||
@ -154,8 +168,12 @@ class PaymentController extends Controller
|
||||
'customers' => User::where('role', 'customer')
|
||||
->whereCompany($request->header('company'))
|
||||
->get(),
|
||||
'paymentMethods' => PaymentMethod::whereCompany($request->header('company'))
|
||||
->latest()
|
||||
->get(),
|
||||
'nextPaymentNumber' => $payment->getPaymentNumAttribute(),
|
||||
'payment_prefix' => $payment->getPaymentPrefixAttribute(),
|
||||
'shareable_link' => url('/payments/pdf/'.$payment->unique_hash),
|
||||
'payment' => $payment,
|
||||
'invoices' => $invoices
|
||||
]);
|
||||
@ -208,13 +226,14 @@ class PaymentController extends Controller
|
||||
$payment->payment_number = $number_attributes['payment_number'];
|
||||
$payment->user_id = $request->user_id;
|
||||
$payment->invoice_id = $request->invoice_id;
|
||||
$payment->payment_mode = $request->payment_mode;
|
||||
$payment->payment_method_id = $request->payment_method_id;
|
||||
$payment->amount = $request->amount;
|
||||
$payment->notes = $request->notes;
|
||||
$payment->save();
|
||||
|
||||
return response()->json([
|
||||
'payment' => $payment,
|
||||
'shareable_link' => url('/payments/pdf/'.$payment->unique_hash),
|
||||
'success' => true
|
||||
]);
|
||||
}
|
||||
@ -276,4 +295,37 @@ class PaymentController extends Controller
|
||||
'success' => true
|
||||
]);
|
||||
}
|
||||
|
||||
public function sendPayment(Request $request)
|
||||
{
|
||||
$payment = Payment::findOrFail($request->id);
|
||||
|
||||
$data['payment'] = $payment->toArray();
|
||||
$userId = $data['payment']['user_id'];
|
||||
$data['user'] = User::find($userId)->toArray();
|
||||
$data['company'] = Company::find($payment->company_id);
|
||||
$email = $data['user']['email'];
|
||||
$notificationEmail = CompanySetting::getSetting(
|
||||
'notification_email',
|
||||
$request->header('company')
|
||||
);
|
||||
|
||||
if (!$email) {
|
||||
return response()->json([
|
||||
'error' => 'user_email_does_not_exist'
|
||||
]);
|
||||
}
|
||||
|
||||
if (!$notificationEmail) {
|
||||
return response()->json([
|
||||
'error' => 'notification_email_does_not_exist'
|
||||
]);
|
||||
}
|
||||
|
||||
\Mail::to($email)->send(new PaymentPdf($data, $notificationEmail));
|
||||
|
||||
return response()->json([
|
||||
'success' => true
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
119
app/Http/Controllers/PaymentMethodController.php
Normal file
119
app/Http/Controllers/PaymentMethodController.php
Normal file
@ -0,0 +1,119 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Controllers;
|
||||
|
||||
use Crater\PaymentMethod;
|
||||
use Illuminate\Http\Request;
|
||||
use Crater\Http\Requests\PaymentMethodRequest;
|
||||
|
||||
class PaymentMethodController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$paymentMethods = PaymentMethod::whereCompany($request->header('company'))
|
||||
->latest()
|
||||
->get();
|
||||
|
||||
return response()->json([
|
||||
'paymentMethods' => $paymentMethods
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(PaymentMethodRequest $request)
|
||||
{
|
||||
$paymentMethod = new PaymentMethod;
|
||||
$paymentMethod->name = $request->name;
|
||||
$paymentMethod->company_id = $request->header('company');
|
||||
$paymentMethod->save();
|
||||
|
||||
return response()->json([
|
||||
'paymentMethod' => $paymentMethod
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param \Crater\PaymentMethod $paymentMethod
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show(PaymentMethod $paymentMethod)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \Crater\PaymentMethod $paymentMethod
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit(PaymentMethod $paymentMethod)
|
||||
{
|
||||
return response()->json([
|
||||
'paymentMethod' => $paymentMethod
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Crater\PaymentMethod $paymentMethod
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(PaymentMethodRequest $request, PaymentMethod $paymentMethod)
|
||||
{
|
||||
$paymentMethod->name = $request->name;
|
||||
$paymentMethod->company_id = $request->header('company');
|
||||
$paymentMethod->save();
|
||||
|
||||
return response()->json([
|
||||
'paymentMethod' => $paymentMethod
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \Crater\PaymentMethod $paymentMethod
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy(PaymentMethod $paymentMethod)
|
||||
{
|
||||
$payments = $paymentMethod->payments;
|
||||
|
||||
if ($payments->count() > 0) {
|
||||
return response()->json([
|
||||
'error' => 'payments_attached'
|
||||
]);
|
||||
}
|
||||
|
||||
$paymentMethod->delete();
|
||||
|
||||
return response()->json([
|
||||
'success' => 'Payment method deleted successfully'
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -4,6 +4,8 @@ namespace Crater\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Crater\Setting;
|
||||
use Crater\Mail\TestMail;
|
||||
use Mail;
|
||||
|
||||
class SettingsController extends Controller
|
||||
{
|
||||
@ -23,4 +25,18 @@ class SettingsController extends Controller
|
||||
]);
|
||||
}
|
||||
|
||||
public function testEmailConfig(Request $request)
|
||||
{
|
||||
$this->validate($request, [
|
||||
'to' => 'required|email',
|
||||
'subject' => 'required',
|
||||
'message' => 'required'
|
||||
]);
|
||||
|
||||
Mail::to($request->to)->send(new TestMail($request->subject, $request->message));
|
||||
|
||||
return response()->json([
|
||||
'success' => true
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
119
app/Http/Controllers/UnitController.php
Normal file
119
app/Http/Controllers/UnitController.php
Normal file
@ -0,0 +1,119 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Controllers;
|
||||
|
||||
use Crater\Unit;
|
||||
use Illuminate\Http\Request;
|
||||
use Crater\Http\Requests\UnitRequest;
|
||||
|
||||
class UnitController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$units = Unit::whereCompany($request->header('company'))
|
||||
->latest()
|
||||
->get();
|
||||
|
||||
return response()->json([
|
||||
'units' => $units
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(UnitRequest $request)
|
||||
{
|
||||
$unit = new Unit;
|
||||
$unit->name = $request->name;
|
||||
$unit->company_id = $request->header('company');
|
||||
$unit->save();
|
||||
|
||||
return response()->json([
|
||||
'unit' => $unit
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param \Crater\Unit $unit
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show(Unit $unit)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \Crater\Unit $unit
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit(Unit $unit)
|
||||
{
|
||||
return response()->json([
|
||||
'unit' => $unit
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Crater\Unit $unit
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(UnitRequest $request, Unit $unit)
|
||||
{
|
||||
$unit->name = $request->name;
|
||||
$unit->company_id = $request->header('company');
|
||||
$unit->save();
|
||||
|
||||
return response()->json([
|
||||
'unit' => $unit
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \Crater\Unit $unit
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy(Unit $unit)
|
||||
{
|
||||
$items = $unit->items;
|
||||
|
||||
if ($items->count() > 0) {
|
||||
return response()->json([
|
||||
'error' => 'items_attached'
|
||||
]);
|
||||
}
|
||||
|
||||
$unit->delete();
|
||||
|
||||
return response()->json([
|
||||
'success' => 'Unit deleted successfully'
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -7,6 +7,8 @@ use Crater\User;
|
||||
use Crater\Currency;
|
||||
use Crater\Setting;
|
||||
use Crater\Item;
|
||||
use Crater\PaymentMethod;
|
||||
use Crater\Unit;
|
||||
use Crater\TaxType;
|
||||
use DB;
|
||||
use Carbon\Carbon;
|
||||
@ -46,10 +48,18 @@ class UsersController extends Controller
|
||||
$request->header('company')
|
||||
);
|
||||
|
||||
$items = Item::all();
|
||||
$items = Item::with('taxes')->get();
|
||||
|
||||
$taxTypes = TaxType::latest()->get();
|
||||
|
||||
$paymentMethods = PaymentMethod::whereCompany($request->header('company'))
|
||||
->latest()
|
||||
->get();
|
||||
|
||||
$units = Unit::whereCompany($request->header('company'))
|
||||
->latest()
|
||||
->get();
|
||||
|
||||
return response()->json([
|
||||
'user' => $user,
|
||||
'customers' => $customers,
|
||||
@ -61,6 +71,8 @@ class UsersController extends Controller
|
||||
'items' => $items,
|
||||
'taxTypes' => $taxTypes,
|
||||
'moment_date_format' => $moment_date_format,
|
||||
'paymentMethods' => $paymentMethods,
|
||||
'units' => $units,
|
||||
'fiscal_year' => $fiscal_year,
|
||||
]);
|
||||
}
|
||||
|
||||
40
app/Http/Requests/PaymentMethodRequest.php
Normal file
40
app/Http/Requests/PaymentMethodRequest.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class PaymentMethodRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
$data = [
|
||||
'name' => 'required|unique:payment_methods,name'
|
||||
];
|
||||
|
||||
if ($this->getMethod() == 'PUT') {
|
||||
$data['name'] = [
|
||||
'required',
|
||||
Rule::unique('payment_methods')->ignore($this->route('payment_method'), 'id')
|
||||
];
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
40
app/Http/Requests/UnitRequest.php
Normal file
40
app/Http/Requests/UnitRequest.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class UnitRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
$data = [
|
||||
'name' => 'required|unique:units,name'
|
||||
];
|
||||
|
||||
if ($this->getMethod() == 'PUT') {
|
||||
$data['name'] = [
|
||||
'required',
|
||||
Rule::unique('units')->ignore($this->route('unit'), 'id')
|
||||
];
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
19
app/Item.php
19
app/Item.php
@ -24,19 +24,24 @@ class Item extends Model
|
||||
'formattedCreatedAt'
|
||||
];
|
||||
|
||||
public function unit()
|
||||
{
|
||||
return $this->belongsTo(Unit::class);
|
||||
}
|
||||
|
||||
public function scopeWhereSearch($query, $search)
|
||||
{
|
||||
return $query->where('name', 'LIKE', '%'.$search.'%');
|
||||
return $query->where('items.name', 'LIKE', '%'.$search.'%');
|
||||
}
|
||||
|
||||
public function scopeWherePrice($query, $price)
|
||||
{
|
||||
return $query->where('price', $price);
|
||||
return $query->where('items.price', $price);
|
||||
}
|
||||
|
||||
public function scopeWhereUnit($query, $unit)
|
||||
public function scopeWhereUnit($query, $unit_id)
|
||||
{
|
||||
return $query->where('unit', $unit);
|
||||
return $query->where('items.unit_id', $unit_id);
|
||||
}
|
||||
|
||||
public function scopeWhereOrder($query, $orderByField, $orderBy)
|
||||
@ -56,8 +61,8 @@ class Item extends Model
|
||||
$query->wherePrice($filters->get('price'));
|
||||
}
|
||||
|
||||
if ($filters->get('unit')) {
|
||||
$query->whereUnit($filters->get('unit'));
|
||||
if ($filters->get('unit_id')) {
|
||||
$query->whereUnit($filters->get('unit_id'));
|
||||
}
|
||||
|
||||
if ($filters->get('orderByField') || $filters->get('orderBy')) {
|
||||
@ -80,7 +85,7 @@ class Item extends Model
|
||||
|
||||
public function scopeWhereCompany($query, $company_id)
|
||||
{
|
||||
$query->where('company_id', $company_id);
|
||||
$query->where('items.company_id', $company_id);
|
||||
}
|
||||
|
||||
public function invoiceItems()
|
||||
|
||||
162
app/Listeners/Updates/v2/Version220.php
Normal file
162
app/Listeners/Updates/v2/Version220.php
Normal file
@ -0,0 +1,162 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Listeners\Updates\v2;
|
||||
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Crater\Setting;
|
||||
use Crater\Unit;
|
||||
use Crater\PaymentMethod;
|
||||
use Crater\Currency;
|
||||
use Crater\Payment;
|
||||
use Crater\Item;
|
||||
use Crater\User;
|
||||
use Crater\Listeners\Updates\Listener;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
||||
class Version220 extends Listener
|
||||
{
|
||||
const VERSION = '2.2.0';
|
||||
|
||||
/**
|
||||
* Create the event listener.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
* @param object $event
|
||||
* @return void
|
||||
*/
|
||||
public function handle($event)
|
||||
{
|
||||
if ($this->isListenerFired($event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->changeMigrations();
|
||||
|
||||
$this->addSeederData();
|
||||
|
||||
$this->databaseChanges();
|
||||
|
||||
$this->changeMigrations(true);
|
||||
|
||||
Setting::setSetting('version', static::VERSION);
|
||||
}
|
||||
|
||||
public function changeMigrations($removeColumn = false)
|
||||
{
|
||||
if ($removeColumn) {
|
||||
\Schema::table('items', function (Blueprint $table) {
|
||||
$table->dropColumn('unit');
|
||||
});
|
||||
|
||||
\Schema::table('payments', function (Blueprint $table) {
|
||||
$table->dropColumn('payment_mode');
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
\Schema::create('units', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->string('name');
|
||||
$table->integer('company_id')->unsigned()->nullable();
|
||||
$table->foreign('company_id')->references('id')->on('companies');
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
\Schema::table('items', function (Blueprint $table) {
|
||||
$table->integer('unit_id')->unsigned()->nullable();
|
||||
$table->foreign('unit_id')->references('id')->on('units')->onDelete('cascade');
|
||||
});
|
||||
|
||||
\Schema::create('payment_methods', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->string('name');
|
||||
$table->integer('company_id')->unsigned()->nullable();
|
||||
$table->foreign('company_id')->references('id')->on('companies');
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
\Schema::table('payments', function (Blueprint $table) {
|
||||
$table->string('unique_hash')->nullable();
|
||||
$table->integer('payment_method_id')->unsigned()->nullable();
|
||||
$table->foreign('payment_method_id')->references('id')->on('payment_methods')->onDelete('cascade');
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function addSeederData()
|
||||
{
|
||||
$company_id = User::where('role', 'admin')->first()->company_id;
|
||||
|
||||
Unit::create(['name' => 'box', 'company_id' => $company_id]);
|
||||
Unit::create(['name' => 'cm', 'company_id' => $company_id]);
|
||||
Unit::create(['name' => 'dz', 'company_id' => $company_id]);
|
||||
Unit::create(['name' => 'ft', 'company_id' => $company_id]);
|
||||
Unit::create(['name' => 'g', 'company_id' => $company_id]);
|
||||
Unit::create(['name' => 'in', 'company_id' => $company_id]);
|
||||
Unit::create(['name' => 'kg', 'company_id' => $company_id]);
|
||||
Unit::create(['name' => 'km', 'company_id' => $company_id]);
|
||||
Unit::create(['name' => 'lb', 'company_id' => $company_id]);
|
||||
Unit::create(['name' => 'mg', 'company_id' => $company_id]);
|
||||
Unit::create(['name' => 'pc', 'company_id' => $company_id]);
|
||||
|
||||
PaymentMethod::create(['name' => 'Cash', 'company_id' => $company_id]);
|
||||
PaymentMethod::create(['name' => 'Check', 'company_id' => $company_id]);
|
||||
PaymentMethod::create(['name' => 'Credit Card', 'company_id' => $company_id]);
|
||||
PaymentMethod::create(['name' => 'Bank Transfer', 'company_id' => $company_id]);
|
||||
|
||||
Currency::create([
|
||||
'name' => 'Serbian Dinar',
|
||||
'code' => 'RSD',
|
||||
'symbol' => 'RSD',
|
||||
'precision' => '2',
|
||||
'thousand_separator' => '.',
|
||||
'decimal_separator' => ','
|
||||
]);
|
||||
}
|
||||
|
||||
public function databaseChanges()
|
||||
{
|
||||
$payments = Payment::all();
|
||||
|
||||
if ($payments) {
|
||||
foreach ($payments as $payment) {
|
||||
$payment->unique_hash = str_random(60);
|
||||
$payment->save();
|
||||
|
||||
$paymentMethod = PaymentMethod::where('name', $payment->payment_mode)
|
||||
->first();
|
||||
|
||||
if ($paymentMethod) {
|
||||
$payment->payment_method_id = $paymentMethod->id;
|
||||
$payment->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$items = Item::all();
|
||||
|
||||
if ($items) {
|
||||
foreach ($items as $item) {
|
||||
$unit = Unit::where('name', $item->unit)
|
||||
->first();
|
||||
|
||||
if ($unit) {
|
||||
$item->unit_id = $unit->id;
|
||||
$item->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
38
app/Mail/PaymentPdf.php
Normal file
38
app/Mail/PaymentPdf.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Mail;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class PaymentPdf extends Mailable
|
||||
{
|
||||
use Queueable, SerializesModels;
|
||||
|
||||
public $data = [];
|
||||
|
||||
public $notificationEmail = '';
|
||||
|
||||
/**
|
||||
* Create a new message instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($data, $notificationEmail)
|
||||
{
|
||||
$this->data = $data;
|
||||
$this->notificationEmail = $notificationEmail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the message.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
return $this->from($this->notificationEmail)->markdown('emails.send.payment', ['data', $this->data]);
|
||||
}
|
||||
}
|
||||
38
app/Mail/TestMail.php
Normal file
38
app/Mail/TestMail.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
namespace Crater\Mail;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
|
||||
class TestMail extends Mailable
|
||||
{
|
||||
use Queueable, SerializesModels;
|
||||
public $subject;
|
||||
public $message;
|
||||
|
||||
/**
|
||||
* Create a new message instance.
|
||||
*
|
||||
* @param $subject
|
||||
* @param $message
|
||||
*/
|
||||
public function __construct($subject, $message)
|
||||
{
|
||||
$this->subject = $subject;
|
||||
$this->message = $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the message.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
return $this->subject($this->subject)->markdown('emails.test')->with([
|
||||
'my_message' => $this->message
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -5,6 +5,7 @@ use Crater\User;
|
||||
use Crater\Invoice;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Crater\PaymentMethod;
|
||||
|
||||
class Payment extends Model
|
||||
{
|
||||
@ -19,9 +20,11 @@ class Payment extends Model
|
||||
protected $fillable = [
|
||||
'user_id',
|
||||
'invoice_id',
|
||||
'payment_method_id',
|
||||
'payment_date',
|
||||
'company_id',
|
||||
'notes',
|
||||
'unique_hash',
|
||||
'payment_number',
|
||||
'payment_mode',
|
||||
'amount'
|
||||
@ -84,7 +87,6 @@ class Payment extends Model
|
||||
return $prefix;
|
||||
}
|
||||
|
||||
|
||||
public function invoice()
|
||||
{
|
||||
return $this->belongsTo(Invoice::class);
|
||||
@ -95,6 +97,11 @@ class Payment extends Model
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function paymentMethod()
|
||||
{
|
||||
return $this->belongsTo(PaymentMethod::class);
|
||||
}
|
||||
|
||||
public function getFormattedCreatedAtAttribute($value)
|
||||
{
|
||||
$dateFormat = CompanySetting::getSetting('carbon_date_format', $this->company_id);
|
||||
@ -123,9 +130,9 @@ class Payment extends Model
|
||||
return $query->where('payments.payment_number', 'LIKE', '%'.$paymentNumber.'%');
|
||||
}
|
||||
|
||||
public function scopePaymentMode($query, $paymentMode)
|
||||
public function scopePaymentMethod($query, $paymentMethodId)
|
||||
{
|
||||
return $query->where('payments.payment_mode', $paymentMode);
|
||||
return $query->where('payments.payment_method_id', $paymentMethodId);
|
||||
}
|
||||
|
||||
public function scopeApplyFilters($query, array $filters)
|
||||
@ -140,8 +147,8 @@ class Payment extends Model
|
||||
$query->paymentNumber($filters->get('payment_number'));
|
||||
}
|
||||
|
||||
if ($filters->get('payment_mode')) {
|
||||
$query->paymentMode($filters->get('payment_mode'));
|
||||
if ($filters->get('payment_method_id')) {
|
||||
$query->paymentMethod($filters->get('payment_method_id'));
|
||||
}
|
||||
|
||||
if ($filters->get('customer_id')) {
|
||||
|
||||
25
app/PaymentMethod.php
Normal file
25
app/PaymentMethod.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Crater;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class PaymentMethod extends Model
|
||||
{
|
||||
protected $fillable = ['name', 'company_id'];
|
||||
|
||||
public function payments()
|
||||
{
|
||||
return $this->hasMany(Payment::class);
|
||||
}
|
||||
|
||||
public function company()
|
||||
{
|
||||
return $this->belongsTo(Company::class);
|
||||
}
|
||||
|
||||
public function scopeWhereCompany($query, $company_id)
|
||||
{
|
||||
$query->where('company_id', $company_id);
|
||||
}
|
||||
}
|
||||
@ -10,6 +10,7 @@ use Crater\Listeners\Updates\v2\Version200;
|
||||
use Crater\Listeners\Updates\v2\Version201;
|
||||
use Crater\Listeners\Updates\v2\Version202;
|
||||
use Crater\Listeners\Updates\v2\Version210;
|
||||
use Crater\Listeners\Updates\v2\Version220;
|
||||
|
||||
class EventServiceProvider extends ServiceProvider
|
||||
{
|
||||
@ -25,6 +26,7 @@ class EventServiceProvider extends ServiceProvider
|
||||
Version201::class,
|
||||
Version202::class,
|
||||
Version210::class,
|
||||
Version220::class,
|
||||
],
|
||||
Registered::class => [
|
||||
SendEmailVerificationNotification::class,
|
||||
|
||||
26
app/Unit.php
Normal file
26
app/Unit.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Crater;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Crater\Item;
|
||||
|
||||
class Unit extends Model
|
||||
{
|
||||
protected $fillable = ['name', 'company_id'];
|
||||
|
||||
public function items()
|
||||
{
|
||||
return $this->hasMany(Item::class);
|
||||
}
|
||||
|
||||
public function company()
|
||||
{
|
||||
return $this->belongsTo(Company::class);
|
||||
}
|
||||
|
||||
public function scopeWhereCompany($query, $company_id)
|
||||
{
|
||||
$query->where('company_id', $company_id);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user