tradings section
This commit is contained in:
parent
591fcbee2b
commit
325740f054
|
|
@ -43,7 +43,7 @@ class GroupController extends Controller
|
|||
'title.tm' => ['required', 'min:3'],
|
||||
'title.ru' => ['required', 'min:3'],
|
||||
'title.en' => ['required', 'min:3'],
|
||||
'type' => ['string', 'in:import,export'],
|
||||
'type' => ['string', 'in:import,export,trading'],
|
||||
'is_default' => ['boolean'],
|
||||
]);
|
||||
|
||||
|
|
@ -74,7 +74,7 @@ class GroupController extends Controller
|
|||
'title.ru' => ['required', 'min:3'],
|
||||
'title.en' => ['required', 'min:3'],
|
||||
'is_default' => ['boolean'],
|
||||
'type' => ['string', 'in:import,export'],
|
||||
'type' => ['string', 'in:import,export,trading'],
|
||||
]);
|
||||
|
||||
info($request->all());
|
||||
|
|
|
|||
|
|
@ -0,0 +1,107 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Web;
|
||||
|
||||
use Inertia\Inertia;
|
||||
use App\Models\Group;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
use App\Http\Resources\SubgroupResource;
|
||||
use App\Imports\TradingsImport;
|
||||
use App\Models\Subgroup;
|
||||
|
||||
class TradingController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
if (blank(request('group'))) {
|
||||
request()->merge([
|
||||
'group' => optional(Group::whereType('trading')->where('is_default', true)->first())->id
|
||||
]);
|
||||
}
|
||||
$subgroupsWithTradings = Subgroup::with(['tradings' => function ($query) {
|
||||
$query
|
||||
->where('group_id', request('group'))
|
||||
->where('locale', app()->getLocale());
|
||||
}])
|
||||
->where('group_id', request('group'))
|
||||
->where('locale', app()->getLocale())
|
||||
->simplePaginate(50);
|
||||
|
||||
$groups = Group::whereType('trading')->get();
|
||||
|
||||
$filters = array_filter(request()->all([
|
||||
'group',
|
||||
]));
|
||||
|
||||
if (array_key_exists('category', $filters)) {
|
||||
$filters['category'] = intval($filters['category']);
|
||||
}
|
||||
|
||||
if (array_key_exists('group', $filters)) {
|
||||
$filters['group'] = intval($filters['group']);
|
||||
}
|
||||
|
||||
return Inertia::render('Tradings', [
|
||||
'text' => settings('text')[app()->getLocale()],
|
||||
'filters' => $filters,
|
||||
'subgroupsWithTradings' => SubgroupResource::collection($subgroupsWithTradings),
|
||||
'groups' => fn () => $groups,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function import()
|
||||
{
|
||||
request()->validate([
|
||||
'group' => ['exists:groups,id'],
|
||||
'file' => ['required', 'mimes:xlsx'],
|
||||
]);
|
||||
|
||||
if (!$group = Group::find(request('group'))) {
|
||||
$group = Group::create([
|
||||
'title' => 'New group',
|
||||
'type' => 'export',
|
||||
'is_default' => true
|
||||
]);
|
||||
}
|
||||
|
||||
$group->tradings()->whereLocale(app()->getLocale())->delete();
|
||||
|
||||
try {
|
||||
$id = now()->unix();
|
||||
session(['import' => $id]);
|
||||
|
||||
$file = request()->file('file')->storeAs('uploads', $filename = $group->filename);
|
||||
$group->update(['file' => $filename]);
|
||||
|
||||
Excel::queueImport(new TradingsImport($id, $group, app()->getLocale()), $file);
|
||||
} catch (\Throwable $th) {
|
||||
info('error here');
|
||||
info($th->getMessage());
|
||||
}
|
||||
|
||||
return redirect()->route('tradings');
|
||||
}
|
||||
|
||||
public function status()
|
||||
{
|
||||
$id = session('import');
|
||||
|
||||
return response([
|
||||
'started' => filled(cache("start_date_$id")),
|
||||
'finished' => filled(cache("end_date_$id")),
|
||||
'current_row' => (int) cache("current_row_$id"),
|
||||
'total_rows' => (int) cache("total_rows_$id"),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -14,5 +14,6 @@ class VerifyCsrfToken extends Middleware
|
|||
protected $except = [
|
||||
'/exports/import',
|
||||
'/imports/import',
|
||||
'/tradings/import',
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class SubgroupResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'deals_count' => $this->deals_count,
|
||||
'total_sum' => $this->total_sum,
|
||||
'tradings' => TradingResource::collection($this->tradings)
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class TradingResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return parent::toArray($request);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,206 @@
|
|||
<?php
|
||||
|
||||
namespace App\Imports;
|
||||
|
||||
use App\Models\Group;
|
||||
use App\Models\Export;
|
||||
use App\Models\Category;
|
||||
use App\Models\Subgroup;
|
||||
use App\Models\Trading;
|
||||
use Maatwebsite\Excel\Row;
|
||||
use Maatwebsite\Excel\Concerns\OnEachRow;
|
||||
use Maatwebsite\Excel\Events\AfterImport;
|
||||
use Maatwebsite\Excel\Events\BeforeImport;
|
||||
use Maatwebsite\Excel\Concerns\WithEvents;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Maatwebsite\Excel\Concerns\WithStartRow;
|
||||
use Maatwebsite\Excel\Concerns\WithChunkReading;
|
||||
use Maatwebsite\Excel\Concerns\WithMultipleSheets;
|
||||
|
||||
class TradingsImport implements OnEachRow, WithStartRow, WithMultipleSheets, WithEvents, WithChunkReading, ShouldQueue
|
||||
{
|
||||
public $id;
|
||||
public $group;
|
||||
public $subgroup;
|
||||
public $locale;
|
||||
public $category;
|
||||
public $currency;
|
||||
public $categories;
|
||||
public $tradingsInserts;
|
||||
|
||||
public function __construct(int $id, Group $group, string $locale)
|
||||
{
|
||||
$this->id = $id;
|
||||
$this->group = $group->id;
|
||||
$this->locale = $locale;
|
||||
$this->categories = Category::all();
|
||||
$this->tradingsInserts = [];
|
||||
}
|
||||
|
||||
public function sheets(): array
|
||||
{
|
||||
return [
|
||||
0 => $this,
|
||||
];
|
||||
}
|
||||
|
||||
public function startRow(): int
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
public function chunkSize(): int
|
||||
{
|
||||
return 1000;
|
||||
}
|
||||
|
||||
public function registerEvents(): array
|
||||
{
|
||||
return [
|
||||
BeforeImport::class => function (BeforeImport $event) {
|
||||
$totalRows = $event->getReader()->getTotalRows();
|
||||
|
||||
if (filled($totalRows)) {
|
||||
cache()->forever("total_rows_{$this->id}", array_values($totalRows)[0]);
|
||||
cache()->forever("start_date_{$this->id}", now()->unix());
|
||||
}
|
||||
},
|
||||
AfterImport::class => function (AfterImport $event) {
|
||||
cache(["end_date_{$this->id}" => now()], now()->addMinute());
|
||||
cache()->forget("total_rows_{$this->id}");
|
||||
cache()->forget("start_date_{$this->id}");
|
||||
cache()->forget("current_row_{$this->id}");
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
public function onRow(Row $row)
|
||||
{
|
||||
$rowIndex = $row->getIndex();
|
||||
$row = array_map('trim', $row->toArray());
|
||||
cache()->forever("current_row_{$this->id}", $rowIndex);
|
||||
|
||||
if (!empty($row[0])) {
|
||||
$this->setCategory($row);
|
||||
$this->setCurrency($row);
|
||||
$this->setType($row);
|
||||
|
||||
$this->setTradingsInSubgroup($row);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(empty($row[0]) && empty($row[1]) && empty($row[3]) && !empty($row[4])) {
|
||||
$this->setTotalSumInSubgroup($row);
|
||||
return;
|
||||
}
|
||||
|
||||
$row['group'] = $this->group;
|
||||
$row['category'] = $this->category;
|
||||
$row['currency'] = $this->currency;
|
||||
$row['locale'] = $this->locale;
|
||||
$row['type'] = $this->type;
|
||||
|
||||
/**
|
||||
* At first tradings are saved in an array, then in DB when subgroup ends
|
||||
*/
|
||||
array_push($this->tradingsInserts, [
|
||||
'locale' => $row['locale'],
|
||||
'category_id' => $row['category'],
|
||||
'group_id' => $row['group'],
|
||||
'subgroup_id' => null,
|
||||
'type' => $row['type'],
|
||||
'currency' => $row['currency'],
|
||||
'title' => $row[1],
|
||||
'unit' => $row[2],
|
||||
'amount' => $row[3],
|
||||
'price' => $row[4],
|
||||
'seller_country' => $row[7],
|
||||
'buyer_country' => $row[9],
|
||||
'point' => $row[10],
|
||||
]);
|
||||
}
|
||||
|
||||
protected function setTotalSumInSubgroup($row)
|
||||
{
|
||||
if(strripos($row[4], 'Итого сумма') !== false || strripos($row[4], 'Total sum') !== false || strripos($row[4], 'Jemi') !== false) {
|
||||
|
||||
$this->subgroup->update([
|
||||
'total_sum' => $row[4] . ' ' . $row[5]
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save all rows with tradings for one subgroup.
|
||||
* The function works, when excel parser reaches the row with `Заключено сделок`
|
||||
*/
|
||||
protected function setTradingsInSubgroup($row)
|
||||
{
|
||||
if(strripos($row[0], 'Заключено сделок') !== false || strripos($row[0], 'Deals count') !== false || strripos($row[0], 'Tm translation') !== false) {
|
||||
|
||||
$this->subgroup = Subgroup::create([
|
||||
'deals_count' => $row[0],
|
||||
'group_id' => $this->group,
|
||||
'locale' => $this->locale
|
||||
]);
|
||||
|
||||
foreach ($this->tradingsInserts as &$item) {
|
||||
$item['subgroup_id'] = $this->subgroup->id;
|
||||
}
|
||||
|
||||
$this->subgroup->tradings()->createMany($this->tradingsInserts);
|
||||
$this->tradingsInserts = [];
|
||||
}
|
||||
}
|
||||
|
||||
protected function setCategory($row)
|
||||
{
|
||||
if ($category = $this->categories->first(fn ($c) => data_get($c->getOriginal('title'), $this->locale) == $row[0])) {
|
||||
$this->category = $category->id;
|
||||
}
|
||||
}
|
||||
|
||||
protected function setCurrency($row)
|
||||
{
|
||||
if (in_array($row[0], [
|
||||
'Доллар США',
|
||||
'ABŞ-nyň dollary',
|
||||
'US dollar',
|
||||
'in US dollars',
|
||||
])) {
|
||||
$this->currency = 'USD';
|
||||
}
|
||||
|
||||
if (in_array($row[0], [
|
||||
'türkmen manady',
|
||||
'Туркменский манат',
|
||||
'turkmen manats',
|
||||
])) {
|
||||
$this->currency = 'TMT';
|
||||
}
|
||||
}
|
||||
|
||||
protected function setType($row)
|
||||
{
|
||||
if (in_array($row[0], [
|
||||
'External',
|
||||
'Foreign',
|
||||
'Внешний',
|
||||
'Daşarky',
|
||||
])) {
|
||||
$this->type = 'external';
|
||||
}
|
||||
|
||||
if (in_array($row[0], [
|
||||
'Internal',
|
||||
'internal',
|
||||
'Внутренний',
|
||||
'Içerki'
|
||||
])) {
|
||||
$this->type = 'internal';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -25,4 +25,9 @@ class Category extends Model
|
|||
{
|
||||
return $this->hasMany(Export::class);
|
||||
}
|
||||
|
||||
public function tradings()
|
||||
{
|
||||
return $this->hasMany(Trading::class);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,11 @@ class Group extends Model
|
|||
return $this->hasMany(Export::class);
|
||||
}
|
||||
|
||||
public function tradings()
|
||||
{
|
||||
return $this->hasMany(Trading::class);
|
||||
}
|
||||
|
||||
public function imports()
|
||||
{
|
||||
return $this->hasMany(Import::class);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Subgroup extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $guarded = ['id'];
|
||||
|
||||
public function tradings()
|
||||
{
|
||||
return $this->hasMany(Trading::class);
|
||||
}
|
||||
|
||||
public function group()
|
||||
{
|
||||
return $this->belongsTo(Group::class);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Laravel\Scout\Searchable;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
class Trading extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $guarded = ['id'];
|
||||
protected $casts = [
|
||||
'price' => 'float',
|
||||
'total' => 'float',
|
||||
'amount' => 'float',
|
||||
];
|
||||
protected $appends = ['total'];
|
||||
protected $with = ['category'];
|
||||
|
||||
public function scopeLines($query)
|
||||
{
|
||||
return $query->where('is_line', true);
|
||||
}
|
||||
|
||||
public function category()
|
||||
{
|
||||
return $this->belongsTo(Category::class);
|
||||
}
|
||||
|
||||
public function getTotalAttribute()
|
||||
{
|
||||
return round($this->price * $this->amount, 2);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class ChangeTypeColumnInGroupsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('groups', function (Blueprint $table) {
|
||||
DB::statement("ALTER TABLE `groups` CHANGE `type` `type` ENUM('import', 'export', 'trading') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'import';");
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('groups', function (Blueprint $table) {
|
||||
DB::statement("ALTER TABLE `groups` CHANGE `type` `type` ENUM('import', 'export') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'import';");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateSubgroupsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('subgroups', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('deals_count')->nullable();
|
||||
$table->string('total_sum')->nullable();
|
||||
|
||||
$table->unsignedBigInteger('group_id');
|
||||
$table->foreign('group_id')->references('id')->on('groups');
|
||||
|
||||
$table->enum('locale', ['en', 'ru', 'tm'])
|
||||
->default('tm')
|
||||
->index();
|
||||
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('subgroups');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateTradingsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('tradings', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('group_id')->nullable()->constrained()->onDelete('cascade');
|
||||
|
||||
$table->unsignedBigInteger('subgroup_id');
|
||||
$table->foreign('subgroup_id')->references('id')->on('subgroups');
|
||||
|
||||
$table->foreignId('category_id')->nullable()->constrained()->onDelete('cascade');
|
||||
$table->enum('type', ['internal', 'external'])->nullable();
|
||||
$table->text('title');
|
||||
$table->string('unit')->nullable();
|
||||
$table->string('amount')->nullable();
|
||||
$table->string('currency')->nullable();
|
||||
$table->string('seller_country')->nullable();
|
||||
$table->string('buyer_country')->nullable();
|
||||
$table->string('point')->nullable();
|
||||
$table->string('price')->nullable();
|
||||
$table->boolean('is_line')->default(false);
|
||||
$table->enum('locale', ['en', 'ru', 'tm'])
|
||||
->default('tm')
|
||||
->index();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('tradings');
|
||||
}
|
||||
}
|
||||
|
|
@ -55,6 +55,10 @@ export default {
|
|||
label: this.trans("Exports"),
|
||||
path: "exports",
|
||||
},
|
||||
{
|
||||
label: this.trans("Trading"),
|
||||
path: "tradings",
|
||||
},
|
||||
{
|
||||
label: this.trans("Requests"),
|
||||
path: "requests",
|
||||
|
|
|
|||
|
|
@ -12,6 +12,9 @@
|
|||
<a-radio-button value="export">
|
||||
{{ trans("Export") }}
|
||||
</a-radio-button>
|
||||
<a-radio-button value="trading">
|
||||
{{ trans("Trading") }}
|
||||
</a-radio-button>
|
||||
</a-radio-group>
|
||||
<a-button type="primary" @click="visible = true">{{
|
||||
trans("Create")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,267 @@
|
|||
<template>
|
||||
<div>
|
||||
<!-- Header -->
|
||||
<div
|
||||
class="flex bg-white p-4 text-lg border-b border-gray-300 h-20 items-center"
|
||||
>
|
||||
|
||||
<div class="flex-1 flex justify-end items-center space-x-3">
|
||||
|
||||
<a-button
|
||||
v-if="$page.props.user"
|
||||
type="primary"
|
||||
@click="importModalVisible = true"
|
||||
>{{ trans('Upload excel') }}</a-button
|
||||
>
|
||||
<a-button
|
||||
v-if="group && group.file"
|
||||
type="primary"
|
||||
@click="() => download(group.hashid)"
|
||||
>{{ trans('Download excel') }}</a-button
|
||||
>
|
||||
|
||||
<a-select
|
||||
v-model="filter.group"
|
||||
:placeholder="trans('Group')"
|
||||
class="w-48"
|
||||
show-search
|
||||
>
|
||||
<a-select-option
|
||||
v-for="group in groups"
|
||||
:key="group.id"
|
||||
:value="group.id"
|
||||
>{{ group.title[$page.props.locale || 'tm'] }}</a-select-option
|
||||
>
|
||||
</a-select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Table -->
|
||||
|
||||
<a-table
|
||||
v-for="(subgroup, index) in items"
|
||||
:key="subgroup.id"
|
||||
class="table w-full"
|
||||
:dataSource="subgroup.tradings"
|
||||
:columns="visibleColumns"
|
||||
:pagination="false"
|
||||
:showHeader="index === 0 ? true : false"
|
||||
:customRow="
|
||||
(record) => {
|
||||
let self = this;
|
||||
return {
|
||||
on: {},
|
||||
};
|
||||
}
|
||||
"
|
||||
rowKey="id"
|
||||
>
|
||||
<span
|
||||
slot="id"
|
||||
slot-scope="_, __, index"
|
||||
class="text-right"
|
||||
v-text="index + 1"
|
||||
/>
|
||||
|
||||
|
||||
|
||||
<span slot="category" slot-scope="category">
|
||||
<span>{{ category && category.title[$page.props.locale || 'tm'] }}</span>
|
||||
</span>
|
||||
<span slot="price" slot-scope="price, row" class="whitespace-nowrap">
|
||||
{{ price }} {{ row.currency }}
|
||||
</span>
|
||||
<span slot="amount" slot-scope="amount, row" class="whitespace-nowrap">
|
||||
{{ amount }} {{ row.unit }}
|
||||
</span>
|
||||
|
||||
<template #footer>
|
||||
<p class="footer-p">{{ subgroup.deals_count }}, {{ subgroup.total_sum }}</p>
|
||||
</template>
|
||||
|
||||
</a-table>
|
||||
<infinite-loading
|
||||
:identifier="infiniteScroll"
|
||||
:distance="20"
|
||||
spinner="waveDots"
|
||||
@infinite="loadMore"
|
||||
v-if="items.length >= perPage"
|
||||
>
|
||||
<div slot="no-more" class="uppercase font-bold text-gray-700 mb-6 py-5">
|
||||
{{ trans('All items loaded') }}
|
||||
</div>
|
||||
<div slot="no-results"></div>
|
||||
</infinite-loading>
|
||||
<!-- Other -->
|
||||
<import-modal
|
||||
v-if="importModalVisible"
|
||||
action="tradings"
|
||||
:group="group && group.id"
|
||||
@close="importModalVisible = false"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import columns from "@/data/trading-columns";
|
||||
import ImportModal from "@/Components/ImportModal";
|
||||
import InfiniteLoading from "vue-infinite-loading";
|
||||
|
||||
export default {
|
||||
props: [
|
||||
"subgroupsWithTradings",
|
||||
"groups",
|
||||
"filters",
|
||||
],
|
||||
|
||||
components: { ImportModal, InfiniteLoading },
|
||||
|
||||
metaInfo() {
|
||||
return {
|
||||
title: this.trans('Trading'),
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
this.loadMore = _.debounce(this.loadMore, 300);
|
||||
const showColumns = localStorage.getItem("trading-columns")
|
||||
? JSON.parse(localStorage.getItem("trading-columns"))
|
||||
: columns.filter((col) => col.visible).map((col) => col.key);
|
||||
|
||||
return {
|
||||
page: 1,
|
||||
perPage: 50,
|
||||
infiniteScroll: +new Date(),
|
||||
importModalVisible: false,
|
||||
createRequestVisible: false,
|
||||
items: this.subgroupsWithTradings.data,
|
||||
selectedRowKeys: [],
|
||||
selectedItems: [],
|
||||
showOnlySelected: false,
|
||||
showColumns,
|
||||
filter: _.assign(
|
||||
{
|
||||
title: undefined,
|
||||
category: undefined,
|
||||
group: undefined,
|
||||
currency: undefined,
|
||||
unit: undefined,
|
||||
type: undefined,
|
||||
},
|
||||
this.filters
|
||||
)
|
||||
};
|
||||
},
|
||||
|
||||
watch: {
|
||||
filter: {
|
||||
handler(value) {
|
||||
this.$inertia.get(this.route("tradings"), value, {
|
||||
preserveState: true,
|
||||
onSuccess: (response) => {
|
||||
this.page = 1;
|
||||
this.infiniteScroll = +new Date();
|
||||
this.items = response.props.subgroupsWithTradings.data;
|
||||
},
|
||||
});
|
||||
},
|
||||
deep: true,
|
||||
},
|
||||
|
||||
showColumns(value) {
|
||||
localStorage.setItem("trading-columns", JSON.stringify(value));
|
||||
},
|
||||
},
|
||||
|
||||
computed: {
|
||||
itemsFiltered() {
|
||||
return this.items.filter(
|
||||
(item) => !this.selectedRowKeys.includes(item.id)
|
||||
);
|
||||
},
|
||||
|
||||
visibleColumns() {
|
||||
return [
|
||||
...this.columns.filter((col) => this.showColumns.includes(col.key)),
|
||||
];
|
||||
},
|
||||
|
||||
group() {
|
||||
return this.groups.find((group) => group.id === this.filter.group)
|
||||
},
|
||||
|
||||
columns() {
|
||||
return columns.map((column) => {
|
||||
column.title = this.trans(column.title)
|
||||
return column
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
beforeMount() {
|
||||
if (this.$page.url.search('page') !== -1) {
|
||||
this.$inertia.get(this.route("tradings"), this.filter)
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
onSelectChange(selectedRowKeys, selectedRows) {
|
||||
const items = _.differenceBy(this.selectedItems, selectedRows, "id");
|
||||
this.selectedItems = [...items, ...selectedRows].filter((item) =>
|
||||
selectedRowKeys.includes(item.id)
|
||||
);
|
||||
|
||||
this.selectedRowKeys = selectedRowKeys;
|
||||
},
|
||||
|
||||
onCheckboxChange(value) {
|
||||
this.showColumns = [...value];
|
||||
},
|
||||
|
||||
addToLine() {
|
||||
this.$inertia.post(
|
||||
this.route("lines.store"),
|
||||
{
|
||||
ids: this.selectedRowKeys,
|
||||
},
|
||||
{
|
||||
onSuccess: (response) => {
|
||||
this.$message.success("Lines added");
|
||||
},
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
loadMore($state) {
|
||||
this.$inertia.get(
|
||||
this.route("tradings"),
|
||||
{
|
||||
...this.filter,
|
||||
page: this.page + 1,
|
||||
per_page: this.perPage,
|
||||
},
|
||||
{
|
||||
only: ["subgroupsWithTradings"],
|
||||
preserveState: true,
|
||||
preserveScroll: true,
|
||||
onSuccess: (response) => {
|
||||
if (response.props.subgroupsWithTradings.data.length) {
|
||||
this.items = this.items.concat(response.props.subgroupsWithTradings.data);
|
||||
this.page += 1;
|
||||
$state.loaded();
|
||||
} else {
|
||||
$state.complete();
|
||||
}
|
||||
},
|
||||
}
|
||||
);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.footer-p {
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
[
|
||||
{
|
||||
"key": "id",
|
||||
"title": "№",
|
||||
"align": "center",
|
||||
"visible": true,
|
||||
"scopedSlots": {
|
||||
"customRender": "id"
|
||||
},
|
||||
"width": "1%",
|
||||
"opacity": 0
|
||||
},
|
||||
{
|
||||
"dataIndex": "title",
|
||||
"key": "title",
|
||||
"title": "Title",
|
||||
"visible": true,
|
||||
"width": "30%"
|
||||
},
|
||||
{
|
||||
"dataIndex": "category",
|
||||
"key": "category",
|
||||
"title": "Category",
|
||||
"visible": true,
|
||||
"scopedSlots": {
|
||||
"customRender": "category"
|
||||
},
|
||||
"width": "9%"
|
||||
},
|
||||
{
|
||||
"dataIndex": "amount",
|
||||
"key": "amount",
|
||||
"title": "Amount",
|
||||
"scopedSlots": {
|
||||
"customRender": "amount"
|
||||
},
|
||||
"visible": true,
|
||||
"width": "9%"
|
||||
},
|
||||
{
|
||||
"dataIndex": "price",
|
||||
"key": "price",
|
||||
"title": "Price",
|
||||
"scopedSlots": {
|
||||
"customRender": "price"
|
||||
},
|
||||
"visible": true,
|
||||
"width": "9%"
|
||||
},
|
||||
{
|
||||
"dataIndex": "total",
|
||||
"key": "total",
|
||||
"title": "Total",
|
||||
"scopedSlots": {
|
||||
"customRender": "price"
|
||||
},
|
||||
"visible": true,
|
||||
"width": "9%"
|
||||
},
|
||||
{
|
||||
"dataIndex": "seller_country",
|
||||
"key": "seller_country",
|
||||
"title": "Seller country",
|
||||
"visible": true,
|
||||
"width": "7%"
|
||||
},
|
||||
{
|
||||
"dataIndex": "buyer_country",
|
||||
"key": "buyer_country",
|
||||
"title": "Buyer country",
|
||||
"visible": true,
|
||||
"width": "7%"
|
||||
},
|
||||
{
|
||||
"dataIndex": "point",
|
||||
"key": "point",
|
||||
"title": "Point",
|
||||
"visible": true,
|
||||
"width": "14%"
|
||||
}
|
||||
]
|
||||
|
|
@ -69,5 +69,8 @@
|
|||
"First name": "First name",
|
||||
"Last name": "Last name",
|
||||
"Organization type": "Organization type",
|
||||
"Unauthorized": "Unauthorized"
|
||||
"Unauthorized": "Unauthorized",
|
||||
"Seller country": "Seller country",
|
||||
"Buyer country": "Buyer country",
|
||||
"Trading": "Trading"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,5 +69,8 @@
|
|||
"First name": "Имя",
|
||||
"Last name": "Фамилия",
|
||||
"Organization type": "Тип организации",
|
||||
"Unauthorized": "Неверные данные"
|
||||
"Unauthorized": "Неверные данные",
|
||||
"Seller country": "Страна продавца",
|
||||
"Buyer country": "Страна покупателя",
|
||||
"Trading": "Торги"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,5 +69,8 @@
|
|||
"First name": "Adyňyz",
|
||||
"Last name": "Familiýaňyz",
|
||||
"Organization type": "Edaraň görnüşi",
|
||||
"Unauthorized": "Nädogry maglumat"
|
||||
"Unauthorized": "Nädogry maglumat",
|
||||
"Seller country": "Satyjynyň yurdy",
|
||||
"Buyer country": "Alyjynyň yurdy",
|
||||
"Trading": "Söwda"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ use App\Http\Controllers\Web\ImportController;
|
|||
use App\Http\Controllers\Web\RequestController;
|
||||
use App\Http\Controllers\Web\SettingController;
|
||||
use App\Http\Controllers\Web\CategoryController;
|
||||
use App\Http\Controllers\Web\TradingController;
|
||||
use App\Models\Export;
|
||||
|
||||
/*
|
||||
|
|
@ -25,6 +26,7 @@ use App\Models\Export;
|
|||
// Route::get('/', [HomeController::class, 'index'])->name('home');
|
||||
Route::group(['middleware' => 'check_october_session'], function () {
|
||||
Route::get('imports', [ImportController::class, 'index'])->name('imports');
|
||||
Route::get('tradings', [TradingController::class, 'index'])->name('tradings');
|
||||
Route::get('/', [ExportController::class, 'index'])->name('exports');
|
||||
Route::get('download/{group}', [GroupController::class, 'download'])->name('download');
|
||||
Route::post('requests', [RequestController::class, 'store'])->name('requests.store');
|
||||
|
|
@ -35,6 +37,7 @@ Route::group(['middleware' => 'check_october_session'], function () {
|
|||
Route::group(['middleware' => 'auth:sanctum'], function () {
|
||||
Route::post('imports/import', [ImportController::class, 'import'])->name('imports.import');
|
||||
Route::post('exports/import', [ExportController::class, 'import'])->name('exports.import');
|
||||
Route::post('tradings/import', [TradingController::class, 'import'])->name('tradings.import');
|
||||
Route::get('import-status', [ExportController::class, 'status'])->name('import-status');
|
||||
|
||||
Route::get('lines', [LineController::class, 'index'])->name('lines');
|
||||
|
|
|
|||
Loading…
Reference in New Issue