added Liana theme part to invoice

pull/49/head
A1Gard 3 months ago
parent 925437ac3c
commit a0bd025b7e

@ -234,18 +234,18 @@ class ClientController extends Controller
if (mb_strlen($q) < 3) { if (mb_strlen($q) < 3) {
return abort(403, __('Search word is too short')); return abort(403, __('Search word is too short'));
} }
$q = '%'.$q.'%'; $q = '%' . $q . '%';
$posts = Post::where('status', 1)->where(function($query) use ($q) { $posts = Post::where('status', 1)->where(function ($query) use ($q) {
$query->where('title', 'LIKE', $q) $query->where('title', 'LIKE', $q)
->orWhere('subtitle', 'LIKE', $q) ->orWhere('subtitle', 'LIKE', $q)
->orWhere('body', 'LIKE', $q); ->orWhere('body', 'LIKE', $q);
})->paginate(100); })->paginate(100);
$products = Product::where('status', 1)->where(function($query) use ($q) { $products = Product::where('status', 1)->where(function ($query) use ($q) {
$query->where('name', 'LIKE', $q) $query->where('name', 'LIKE', $q)
->orWhere('excerpt', 'LIKE', $q) ->orWhere('excerpt', 'LIKE', $q)
->orWhere('description', 'LIKE', $q); ->orWhere('description', 'LIKE', $q);
})->paginate(100); })->paginate(100);
$clips = Clip::where('status', 1)->where(function($query) use ($q) { $clips = Clip::where('status', 1)->where(function ($query) use ($q) {
$query->where('title', 'LIKE', $q) $query->where('title', 'LIKE', $q)
->orWhere('body', 'LIKE', $q); ->orWhere('body', 'LIKE', $q);
})->paginate(100); })->paginate(100);
@ -469,7 +469,7 @@ class ClientController extends Controller
{ {
$area = 'login'; $area = 'login';
$title = __("sign in"); $title = __("sign in");
$subtitle = 'Sign in as customer'; $subtitle = __('Sign in as customer');
return view('client.default-list', compact('area', 'title', 'subtitle')); return view('client.default-list', compact('area', 'title', 'subtitle'));
} }
@ -624,12 +624,13 @@ class ClientController extends Controller
} }
public function pay($hash){ public function pay($hash)
{
$invoice = Invoice::where('hash', $hash)->first(); $invoice = Invoice::where('hash', $hash)->first();
// dd($invoice->created_at->timestamp , (time() - 3600)); // dd($invoice->created_at->timestamp , (time() - 3600));
if (!in_array($invoice->status, ['PENDING', 'CANCELED', 'FAILED'] ) || $invoice->created_at->timestamp < (time() - 3600) ){ if (!in_array($invoice->status, ['PENDING', 'CANCELED', 'FAILED']) || $invoice->created_at->timestamp < (time() - 3600)) {
return redirect()->back()->withErrors(__('This payment method is not available.')); return redirect()->back()->withErrors(__('This payment method is not available.'));
} }
$activeGateway = config('xshop.payment.active_gateway'); $activeGateway = config('xshop.payment.active_gateway');

@ -7,6 +7,8 @@ use App\Models\Customer;
use App\Models\Invoice; use App\Models\Invoice;
use App\Models\Product; use App\Models\Product;
use App\Models\Ticket; use App\Models\Ticket;
use chillerlan\QRCode\QRCode;
use chillerlan\QRCode\QROptions;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Validation\Rules\In; use Illuminate\Validation\Rules\In;
@ -18,18 +20,18 @@ class CustomerController extends Controller
$address->address = $request->input('address'); $address->address = $request->input('address');
$address->lat = $request->input('lat'); $address->lat = $request->input('lat');
$address->lng = $request->input('lng'); $address->lng = $request->input('lng');
$address->state_id = $request->input('state_id')??null; $address->state_id = $request->input('state_id') ?? null;
$address->city_id = $request->input('city_id')??null; $address->city_id = $request->input('city_id') ?? null;
$address->zip = $request->input('zip'); $address->zip = $request->input('zip');
$address->save(); $address->save();
return $address; return $address;
} }
// //
public function __construct() public function __construct()
{ {
$this->middleware(function ($request, $next) { $this->middleware(function ($request, $next) {
if (!auth('customer')->check()) { if (!auth('customer')->check()) {
@ -76,7 +78,22 @@ class CustomerController extends Controller
public function invoice(Invoice $invoice) public function invoice(Invoice $invoice)
{ {
return $invoice; if (!auth('customer')->check() || $invoice->customer_id != auth('customer')->id()) {
return redirect()->route('client.sign-in')->withErrors([__('You need to login to access this page')]);
}
$area = 'invoice';
$title = __("Invoice");
$subtitle = __("Invoice ID:") . ' ' . $invoice->hash;
$options = new QROptions([
'version' => 5,
'outputType' => QRCode::OUTPUT_MARKUP_SVG,
'eccLevel' => QRCode::ECC_L,
// 'imageTransparent' => true,
]);
$qr = new QRCode($options);
return view('client.invoice', compact('area', 'title', 'subtitle','invoice','qr'));
} }
@ -108,7 +125,8 @@ class CustomerController extends Controller
} }
public function addresses(){ public function addresses()
{
return auth('customer')->user()->addresses; return auth('customer')->user()->addresses;
} }
@ -142,10 +160,10 @@ class CustomerController extends Controller
if ($item->customer_id != auth('customer')->id()) { if ($item->customer_id != auth('customer')->id()) {
return abort(403); return abort(403);
} }
$add = $item->address ; $add = $item->address;
$item->delete(); $item->delete();
return ['OK' => true, "message" => __(":ADDRESS removed",['ADDRESS' => $add])]; return ['OK' => true, "message" => __(":ADDRESS removed", ['ADDRESS' => $add])];
} }
public function addressStore(Request $request) public function addressStore(Request $request)
@ -164,11 +182,12 @@ class CustomerController extends Controller
$address = new Address(); $address = new Address();
$address->customer_id = auth('customer')->user()->id; $address->customer_id = auth('customer')->user()->id;
$address = $this->addressSave($address, $request); $address = $this->addressSave($address, $request);
return ['OK' => true,'message' => __("Address added successfully"), 'list'=> auth('customer')->user()->addresses]; return ['OK' => true, 'message' => __("Address added successfully"), 'list' => auth('customer')->user()->addresses];
} }
public function submitTicket(Request $request){ public function submitTicket(Request $request)
{
$request->validate([ $request->validate([
'title' => ['required', 'string', 'max:255'], 'title' => ['required', 'string', 'max:255'],
'body' => ['required', 'string'], 'body' => ['required', 'string'],
@ -182,12 +201,14 @@ class CustomerController extends Controller
return redirect()->route('client.profile')->with('message', __('Ticket added successfully')); return redirect()->route('client.profile')->with('message', __('Ticket added successfully'));
} }
public function showTicket(Ticket $ticket){ public function showTicket(Ticket $ticket)
return view('client.ticket',compact('ticket')); {
return view('client.ticket', compact('ticket'));
} }
public function ticketAnswer(Ticket $ticket, Request $request){ public function ticketAnswer(Ticket $ticket, Request $request)
{
$request->validate([ $request->validate([
'body' => ['required', 'string'], 'body' => ['required', 'string'],
@ -201,7 +222,7 @@ class CustomerController extends Controller
$nticket->body = trim($request->body); $nticket->body = trim($request->body);
$nticket->customer_id = auth('customer')->user()->id; $nticket->customer_id = auth('customer')->user()->id;
$nticket->save(); $nticket->save();
return redirect(route('client.profile').'#tickets')->with('message', __('Ticket answered successfully')); return redirect(route('client.profile') . '#tickets')->with('message', __('Ticket answered successfully'));
} }

@ -8,4 +8,12 @@ use Illuminate\Database\Eloquent\Model;
class Address extends Model class Address extends Model
{ {
use HasFactory; use HasFactory;
public function state(){
return $this->belongsTo(State::class);
}
public function city(){
return $this->belongsTo(City::class);
}
} }

@ -24,7 +24,7 @@ class Invoice extends Model
public static $invoiceStatus = ['PENDING', 'CANCELED', 'FAILED', 'PAID', 'PROCESSING', 'COMPLETED']; public static $invoiceStatus = ['PENDING', 'CANCELED', 'FAILED', 'PAID', 'PROCESSING', 'COMPLETED'];
public function getRouteKey() public function getRouteKeyName()
{ {
return 'hash'; return 'hash';
} }
@ -147,4 +147,9 @@ class Invoice extends Model
return $payment; return $payment;
} }
public function address()
{
return $this->belongsTo(Address::class);
}
} }

2
composer.lock generated

@ -10516,5 +10516,5 @@
"php": "^8.2" "php": "^8.2"
}, },
"platform-dev": [], "platform-dev": [],
"plugin-api-version": "2.3.0" "plugin-api-version": "2.6.0"
} }

@ -38,4 +38,4 @@ import "../views/segments/customer/AvisaCustomer/AvisaCustomer.js";
import "../views/segments/attachments_page/DenaAttachList/DenaAttachList.js"; import "../views/segments/attachments_page/DenaAttachList/DenaAttachList.js";
import "../views/segments/attachment/AttachmentWithPreview/AttachmentWithPreview.js"; import "../views/segments/attachment/AttachmentWithPreview/AttachmentWithPreview.js";
import "../views/segments/contact/MeloContact/MeloContact.js"; import "../views/segments/contact/MeloContact/MeloContact.js";
import "../views/segments/index/InlineMap/InlineMap.js"; import "../views/segments/invoice/LianaInvoice/LianaInvoice.js";

@ -162,3 +162,11 @@ body {
height: 64px; height: 64px;
object-fit: cover; object-fit: cover;
} }
@media print {
.no-print{
display: none;
}
}

@ -49,4 +49,4 @@ $xshop-shadow:2px 2px 4px #777777;
@import "../views/segments/attachments_page/DenaAttachList/DenaAttachList"; @import "../views/segments/attachments_page/DenaAttachList/DenaAttachList";
@import "../views/segments/attachment/AttachmentWithPreview/AttachmentWithPreview"; @import "../views/segments/attachment/AttachmentWithPreview/AttachmentWithPreview";
@import "../views/segments/contact/MeloContact/MeloContact"; @import "../views/segments/contact/MeloContact/MeloContact";
@import "../views/segments/index/InlineMap/InlineMap"; @import "../views/segments/invoice/LianaInvoice/LianaInvoice";

@ -0,0 +1,29 @@
@extends('website.inc.website-layout')
@section('title')
{{$title}} - {{config('app.name')}}
@endsection
@section('content')
<main>
<div class="no-print">
@if(\App\Models\Area::where('name',$area)->first()->use_default)
@foreach(getParts('default_header') as $part)
@php($p = $part->getBladeWithData())
@include($p['blade'],['data' => $p['data']])
@endforeach
@endif
</div>
@foreach(getParts($area) as $part)
@php($p = $part->getBladeWithData())
@include($p['blade'],['data' => $p['data']])
@endforeach
<div class="no-print">
@if(\App\Models\Area::where('name',$area)->first()->use_default)
@foreach(getParts('default_footer') as $part)
@php($p = $part->getBladeWithData())
@include($p['blade'],['data' => $p['data']])
@endforeach
@endif
</div>
</main>
@endsection

@ -0,0 +1,118 @@
<section class='LianaInvoice'>
<div class="p-3">
<div class="row mb-4">
<div class="col-10">
<div class="overflow-hidden">
<img src="{{asset('upload/images/logo.png')}}" class="float-end liana-logo" alt="">
<h3 class="mt-3">
{{config('app.name')}}
</h3>
</div>
{{-- @php($invoice == \App\Models\Invoice::first())--}}
<div class="row">
<div class="col">
{{__("Date")}}: {{$invoice->created_at->ldate('Y-m-d')}}
</div>
<div class="col-7 text-center">
{{__("Customer")}}: {{$invoice->customer->name}}
</div>
</div>
<div class="row">
<div class="col">
{{__("ID")}}: {{$invoice->hash}} ({{$invoice->status}})
</div>
<div class="col-7 text-center">
{{__("Customer mobile")}}: {{$invoice->customer->mobile}}
</div>
</div>
</div>
<div class="col-2 text-center">
<img src="{{$qr->render(route('client.invoice',$invoice->hash))}}" alt="qr code"
class="qr-code">
</div>
</div>
<table class="table table-striped align-middle table-bordered text-center">
<tr>
<th>
#
</th>
<th>
{{__("Product")}}
</th>
<th>
{{__("Count")}}
</th>
<th>
{{__("Quantity")}}
</th>
<th>
{{__("Price")}}
</th>
</tr>
@foreach($invoice->orders as $k => $order)
<tr>
<td>
{{$k + 1}}
</td>
<td>
{{$order->product->name}}
</td>
<td>
{{number_format($order->count)}}
</td>
<td>
@if( ($order->quantity->meta??null) == null)
-
@else
@foreach($order->quantity->meta as $m)
<span>
{{$m->human_value}}
</span>
@endforeach
@endif
</td>
<td>
{{number_format($order->price_total)}}
</td>
</tr>
@endforeach
<tr>
<td>
-
</td>
<td>
{{__("Transport")}}
{{number_format($invoice->transport_price)}}
</td>
<td colspan="2">
{{__("Total price")}}
{{number_format($invoice->total_price)}}
</td>
<td colspan="2">
{{__("Orders count")}}: ({{number_format($invoice->count)}})
</td>
</tr>
</table>
<div class="inv-footer">
<p>
{{$invoice->desc}}
</p>
<hr>
{{__("Address")}}:
{{$invoice->address->state->name}}, {{$invoice->address->city->name}}, {{$invoice->address->address}}
, {{$invoice->address->zip}}
@if(trim(getSetting($data->area->name.'_'.$data->part.'_desc')) != '')
<hr>
{!! getSetting($data->area->name.'_'.$data->part.'_desc') !!}
@endif
</div>
<div class="no-print btn btn-primary mt-2 w-100" onclick="window.print()">
{{__("Print")}}
</div>
</div>
</section>

@ -0,0 +1,10 @@
{
"name": "LianaInvoice",
"version": "1.0",
"author": "xStack",
"email": "xshop@xstack.ir",
"license": "GPL-3.0-or-later",
"url": "https:\/\/xstack.ir",
"author_url": "https:\/\/4xmen.ir",
"packages": []
}

@ -0,0 +1,30 @@
<?php
namespace Resources\Views\Segments;
use App\Models\Part;
use App\Models\Setting;
class LianaInvoice
{
public static function onAdd(Part $part = null)
{
$setting = new Setting();
$setting->section = 'theme';
$setting->key = $part->area->name . '_' . $part->part.'_desc';
$setting->value = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus aliquid consequuntur culpa cupiditate dignissimos dolor doloremque error facilis ipsum iure officia quam qui, tempora! Fuga harum impedit iusto magnam veniam.';
$setting->size = 12;
$setting->title = $part->area->name . ' ' . $part->part. ' invoice footer description';
$setting->type = 'EDITOR';
$setting->save();
}
public static function onRemove(Part $part = null)
{
Setting::where('key',$part->area->name . '_' . $part->part.'_desc')->first()?->delete();
}
public static function onMount(Part $part = null)
{
return $part;
}
}

@ -0,0 +1,31 @@
.LianaInvoice {
.inv-footer{
border: 1px solid gray;
padding: 1rem;
border-radius: var(--xshop-border-radius);
}
.liana-logo{
height: 64px;
margin-top: 2rem;
}
.qr-code{
max-width: 150px;
}
@media print {
&{
font-size: 90%;
}
.qr-code{
max-width: 100%;
}
.liana-logo{
width: 64px;
margin-top: 0;
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

Loading…
Cancel
Save