Fixed reports
This commit is contained in:
miroman-afk
2023-05-02 15:21:54 +03:00
parent 70120653f7
commit fb46c8e739
78 changed files with 21233 additions and 1892 deletions

1
.gitignore vendored
View File

@@ -4,3 +4,4 @@ vendor/
build.zip
places.xml
*.log
*.log

View File

@@ -1 +0,0 @@
{"status":"success","version":"2.13","file":"http:\/\/portal.hrc.by\/uploads\/modules\/v1\/2.13\/build.zip","name":"v1"}

View File

@@ -4,7 +4,7 @@ namespace App\Commands;
use App\Component\Models\Dishes;
use App\Component\Models\Folders;
use App\Component\Models\OrderBot;
use App\Component\Models\OrderBotStorage;
use App\Component\Models\Settings;
use App\Component\Models\Tasks;
use App\Console\Commands\HRCCommand;
@@ -25,11 +25,11 @@ class GETBot extends HRCCommand implements HRCCommandInterface
Folders::where('is_bot_export', '=', 0)
->update(['is_bot_export' => 1]);
}
$ordersinfo = Tasks::where('method', 'orderinfo')
$orders_info = Tasks::where('method', 'orderinfo')
->get();
$delete_params = ['closed', 'deleted'];
foreach ($ordersinfo as $more) {
$order = OrderBot::where('id', intval($more['more']))
foreach ($orders_info as $more) {
$order = OrderBotStorage::where('id', intval($more['more']))
->whereIn('status', $delete_params)
->get();
foreach ($order as $value) {

View File

@@ -0,0 +1,30 @@
<?php
namespace App\Commands;
use App\Component\Models\Filesystem;
use App\Console\Commands\HRCCommand;
use App\Console\Commands\HRCCommandInterface;
class GETClearCache extends HRCCommand implements HRCCommandInterface
{
protected $signature = 'getclearcache';
const cacheFolder = CORE_PATH . '/../../Cache/';
public function command($input, $output = null)
{
$code = Filesystem::GetCode($input['token']);
if (isset($input['folder'])) {
Filesystem::ClearFolder(self::cacheFolder . $code . '/' . $input['folder']);
return [
'status' => 'success',
];
}
if (!isset($input['folder'])) {
Filesystem::ClearFolder(self::cacheFolder . $code . '/');
return [
'status' => 'success',
];
}
}
}

View File

@@ -30,6 +30,22 @@ class GETClientInfo extends HRCCommand implements HRCCommandInterface
$orders_sum_current = ShiftOnlineOrders::where('client_code', $client_guid)->where('is_returned', 0)->where('is_deleted', 0)->sum('full_sum');
$orders_count = $orders_count_exchange + $orders_count_current;
$orders_sum = $orders_sum_exchange + $orders_sum_current;
$barcode = Client::getBarcode($client_guid);
if ($client['is_special_price'] == 0) {
$special_price = false;
} else {
$special_price = true;
}
if ($client['is_employee'] == 0) {
$employee = false;
} else {
$employee = true;
}
if ($client['is_block'] == 0) {
$is_block = false;
} else {
$is_block = true;
}
$result = array(
'id' => $client['id'],
'name' => $client['name'],
@@ -41,6 +57,10 @@ class GETClientInfo extends HRCCommand implements HRCCommandInterface
'order_sum' => round($orders_sum, 2),
'presale' => $presale,
'bonus' => intval($bonus),
'barcode' => $barcode,
'special_price' => $special_price,
'employee' => $employee,
'is_block' => $is_block,
)
);
return [

View File

@@ -35,6 +35,7 @@ class GETClientOrders extends HRCCommand implements HRCCommandInterface
return [
'status' => 'success',
'orders' => $orders,
'count' => count($orders)
];
} else {
return [

View File

@@ -3,17 +3,9 @@
namespace App\Commands;
use App\Component\Models\Client;
use App\Component\Models\ClientsAddress;
use App\Component\Models\ClientsBarcode;
use App\Component\Models\ClientsBonus;
use App\Component\Models\ClientsEmail;
use App\Component\Models\ClientsGroup;
use App\Component\Models\ClientsPhone;
use App\Component\Models\ClientsPresale;
use App\Console\Commands\HRCCommand;
use App\Console\Commands\HRCCommandInterface;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
class GETClients extends HRCCommand implements HRCCommandInterface
{
@@ -21,99 +13,6 @@ class GETClients extends HRCCommand implements HRCCommandInterface
public function command($input, $output = null)
{
if (isset($input['type']) && $input['type'] == 'loyalty') {
$last_update = Carbon::createFromTimestampUTC($input['last_update'])->timezone('Europe/Minsk');
$phones = ClientsPhone::where('updated_at', '>=', $last_update)->get();
$addresses = ClientsAddress::where('updated_at', '>=', $last_update)->get();
$barcodes = ClientsBarcode::where('updated_at', '>=', $last_update)->get();
$emails = ClientsEmail::where('updated_at', '>=', $last_update)->get();
$presales = ClientsPresale::where('updated_at', '>=', $last_update)->get();
$bonuses = ClientsBonus::where('updated_at', '>=', $last_update)->get();
$clients = Client::where('updated_at', '>=', $last_update)->get();
$info = [];
foreach ($phones as $phone) {
$info[] = $phone['client_guid'];
}
foreach ($addresses as $address) {
$info[] = $address['client_guid'];
}
foreach ($barcodes as $barcode) {
$info[] = $barcode['client_guid'];
}
foreach ($emails as $email) {
$info[] = $email['client_guid'];
}
foreach ($presales as $presale) {
$info[] = $presale['client_guid'];
}
foreach ($bonuses as $bonus) {
$info[] = $bonus['client_guid'];
}
foreach ($clients as $client) {
$info[] = $client['user_code'];
}
$guides = array_values(array_unique($info));
$email = $phone = $client = [];
foreach ($guides as $guid) {
$email_address = Client::getEmail($guid);
$phone_number = Client::getPhone($guid);
$client_info = Client::where('user_code', $guid)->first();
$email[] = array(
'email' => $email_address
);
$phone[] = array(
'phone' => $phone_number
);
$badge[] = array(
'name' => 'Test',
'code' => 1
);
$bonus_dishes[] = array(
'code' => ''
);
if (ClientsBonus::getBonus($guid) > 0) {
$bonus_info[] = array(
'amount' => ClientsBonus::getBonus($guid),
'dishes' => $bonus_dishes
);
} else {
$bonus_info[] = array(
'amount' => ClientsBonus::getBonus($guid)
);
}
$group_info = ClientsGroup::where('code', $client_info['group_id'])->first();
$client[] = array(
'id' => $client_info['id'],
'name' => $client_info['name'],
'guid' => $guid,
'presale' => ClientsPresale::getPresale($guid),
'bonuses' => $bonus_info,
'barcode' => Client::getBarcode($guid),
'group_id' => $client_info['group_id'],
'emails' => $email,
'phones' => $phone,
'badges' => $badge
);
$groups[] = $group_info['code'];
$email = $phone = $badge = $bonus_dishes = $bonus_info = [];
}
$groups_guides = array_values(array_unique($groups));
foreach ($groups_guides as $group) {
$group_info = ClientsGroup::where('code', $group)->first();
$groups_info[] = array(
'id' => $group_info['id'],
'name' => $group_info['name'],
'guid' => $group_info['code'],
);
}
return [
'status' => 'success',
'clients' => $client,
'groups' => $groups_info,
];
}
if (ClientsGroup::where('code', '0')->count() == 0) {
$group = new ClientsGroup([
'code' => '0',
@@ -145,12 +44,33 @@ class GETClients extends HRCCommand implements HRCCommandInterface
$phone = Client::getPhone($client['user_code']);
$email = Client::getEmail($client['user_code']);
$address = Client::getAddress($client['user_code']);
$barcode = Client::getBarcode($client['user_code']);
if ($client['is_special_price'] == 0) {
$special_price = false;
} else {
$special_price = true;
}
if ($client['is_employee'] == 0) {
$employee = false;
} else {
$employee = true;
}
if ($client['is_block'] == 0) {
$is_block = false;
} else {
$is_block = true;
}
$out[] = array(
'id' => $client['id'],
'name' => $client['name'],
'phone' => $phone,
'email' => $email,
'address' => $address,
'barcode' => $barcode,
'special_price' => $special_price,
'employee' => $employee,
'is_block' => $is_block,
);
}
return [

View File

@@ -0,0 +1,95 @@
<?php
namespace App\Commands;
use App\Component\Models\Client;
use App\Component\Models\ClientsAddress;
use App\Component\Models\ClientsBarcode;
use App\Component\Models\ClientsBonus;
use App\Component\Models\ClientsEmail;
use App\Component\Models\ClientsGroup;
use App\Component\Models\ClientsPhone;
use App\Component\Models\ClientsPresale;
use App\Console\Commands\HRCCommand;
use App\Console\Commands\HRCCommandInterface;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
class GETCompanyClients extends HRCCommand implements HRCCommandInterface
{
protected $signature = 'getcompanyclients';
public function command($input, $output = null)
{
$dt = Carbon::createFromTimestamp($input['last_update'])->subHours(3);
$last_update = $dt->format('Y-m-d H:i:s');
$clients = Client::select('id', 'name', 'user_code', 'group_id', 'last_change', 'updated_at')
->where('updated_at', '>', $last_update)
->get();
if (count($clients) < 1) {
return [
'status' => 'success',
'clients' => [],
'groups' => [],
];
}
foreach ($clients as $client) {
$email_address = Client::getEmail($client['user_code']);
$phone_number = Client::getPhone($client['user_code']);
$email[] = array(
'email' => $email_address
);
$phone[] = array(
'phone' => $phone_number
);
$badge[] = array(
'name' => 'Test',
'code' => 1
);
$bonus_dishes[] = array(
'code' => ''
);
if (ClientsBonus::getBonus($client['user_code']) > 0) {
$bonus_info[] = array(
'amount' => ClientsBonus::getBonus($client['user_code']),
'dishes' => $bonus_dishes
);
} else {
$bonus_info = array(
'amount' => ClientsBonus::getBonus($client['user_code']),
'dishes' => []
);
}
$group_info = ClientsGroup::where('code', $client['group_id'])->first();
$clients_info[] = array(
'id' => $client['id'],
'name' => $client['name'],
'guid' => $client['user_code'],
'presale' => ClientsPresale::getPresale($client['user_code']),
'bonuses' => $bonus_info,
'barcode' => Client::getBarcode($client['user_code']),
'group_id' => ClientsGroup::getID($client['group_id']),
'emails' => $email,
'phones' => $phone,
'badges' => []
);
$groups[] = $group_info['code'];
$email = $phone = $badge = $bonus_dishes = $bonus_info = [];
}
$groups_guides = array_values(array_unique($groups));
foreach ($groups_guides as $group) {
$group_info = ClientsGroup::where('code', $group)->first();
$groups_info[] = array(
'id' => $group_info['id'],
'name' => $group_info['name'],
'guid' => $group_info['code'],
);
}
return [
'status' => 'success',
'clients' => $clients_info,
'groups' => $groups_info,
];
}
}

256
commands/GETDashboard.php Normal file
View File

@@ -0,0 +1,256 @@
<?php
namespace App\Commands;
use App\Component\Models\Client;
use App\Component\Models\Dishes;
use App\Component\Models\Reasons;
use App\Component\Models\ShiftOnlineActions;
use App\Component\Models\ShiftOnlineDeleted;
use App\Component\Models\ShiftOnlineOrders;
use App\Component\Models\Shifts;
use App\Component\Models\Staff;
use App\Console\Commands\HRCCommand;
use App\Console\Commands\HRCCommandInterface;
use Carbon\Carbon;
class GETDashboard extends HRCCommand implements HRCCommandInterface
{
protected $signature = 'getdashboard';
public function command($input, $output = null)
{
if (isset($input['method'])) {
if (isset($input['more'])) {
$more = $input['more'];
} else {
$more = false;
}
if (isset($input['items'])) {
if (isset($input['order_id'])) {
$order_id = $input['order_id'];
} else {
return [
'status' => 'success',
'message' => 'Проверьте введенные данные'
];
}
$items = $input['items'];
} else {
$items = false;
}
if (isset($input['type'])) {
$type = $input['type'];
} else {
$type = false;
}
$method = $input['method'];
} else {
return [
'status' => 'success',
'message' => 'Проверьте введенные данные'
];
}
if ($method == "deleted") {
$count = ShiftOnlineDeleted::count();
if ($count < 1) {
$count = 0;
}
$sum = ShiftOnlineDeleted::selectRaw('SUM(count * sale_price) as sum')->first();
if (isset($sum) && !is_null($sum['sum'])) {
$sum = $sum['sum'];
} else {
$sum = 0;
}
if ($more) {
$deleted_items = ShiftOnlineDeleted::select('order_code')
->selectRaw('SUM(count * sale_price) as sum')
->groupBy('order_code')
->get();
if ($count > 0) {
foreach ($deleted_items as $deleted_item) {
$order = ShiftOnlineOrders::select('opened', 'closed')
->where('code', $deleted_item['order_code'])
->first();
$closed = $order['closed'];
if ($closed == '0000-00-00 00:00:00') {
$closed = '30.12.1899';
}
$orders[] = array(
'number' => $deleted_item['order_code'],
'opened' => $order['opened'],
'closed' => $closed,
'deleted_sum' => round($deleted_item['sum'], 2)
);
}
} else {
$orders = [];
}
return [
'status' => 'success',
'title' => 'Подробнее об удаленных',
'total_sum' => round($sum, 2),
'total_count' => $count,
'deleted_orders' => $orders
];
}
if ($items) {
$all_sum = $all_count = 0;
$deleted_items = ShiftOnlineDeleted::where('order_code', $order_id)
->get();
if ($count > 0) {
foreach ($deleted_items as $deleted_item) {
$order = ShiftOnlineActions::where('order_code', $deleted_item['order_code'])
->where('type_action', 5)
->first();
$out_items[] = array(
'dish' => Dishes::getName($deleted_item['menu_code']),
'time' => $order['time'],
'reason' => Reasons::getName($order['reason']),
'count' => $deleted_item['count'],
'sale_price' => $deleted_item['count'] * $deleted_item['sale_price'],
'who_deleted' => Staff::getName($order['who'])
);
$all_sum += $deleted_item['count'] * $deleted_item['sale_price'];
$all_count += $deleted_item['count'];
}
} else {
$out_items = [];
}
return [
'status' => 'success',
'code' => $order_id,
'all_sum' => round($all_sum, 2),
'all_count' => round($all_count, 3),
'items' => $out_items
];
}
return [
'status' => 'success',
'sum' => round($sum, 2),
'count' => $count
];
}
if ($method == 'guests') {
if ($type == 'median') {
$data = [];
$orders = ShiftOnlineOrders::where('is_waited', 1)
->where('is_deleted', 0)
->get();
if (isset($orders)) {
foreach ($orders as $order) {
$originalTime = $order['opened'];
$newTime = Carbon::createFromFormat('Y-m-d H:i:s', $originalTime)->format('d.m.Y H:i:s');
$data[] = array(
'time' => $newTime,
'count' => $order['client_count']
);
}
}
return [
'status' => 'success',
'data' => $data
];
}
if ($type == 'more') {
$clientsIDS = ShiftOnlineOrders::select('client_code')
->where('is_deleted', 0)
->where('is_returned', 0)
->where('who_open', '<>', 0)
->where('client_code', '<>', '')
->groupBy('client_code')
->get();
$clientsOrdersCount = ShiftOnlineOrders::select('client_code')
->where('is_deleted', 0)
->where('is_returned', 0)
->where('who_open', '<>', 0)
->where('client_code', '<>', '')
->groupBy('client_code')
->count();
if ($clientsOrdersCount > 0) {
foreach ($clientsIDS as $clientsID) {
$orders_info = ShiftOnlineOrders::where('client_code', $clientsID['client_code'])
->where('is_deleted', 0)
->where('is_returned', 0)
->where('who_open', '<>', 0)
->get();
$clientName = Client::getName($clientsID['client_code']);
$clientOrder[$clientName] = [];
foreach ($orders_info as $order_info) {
if ($order_info['closed'] == '0000-00-00 00:00:00') {
$closed = false;
} else {
$closed = $order_info['closed'];
}
$order = array(
'number' => $order_info['code'],
'opened' => $order_info['opened'],
'closed' => $closed,
'sum' => $order_info['order_sum']
);
array_push($clientOrder[$clientName], $order);
}
}
foreach ($clientOrder as $key => $oInfo) {
$out[] = array(
'name' => $key,
'orders' => $oInfo
);
}
return [
'status' => 'success',
'title' => 'Подробнее о заказах гостей',
'clients' => $out
];
} else {
return [
'status' => 'success',
'title' => 'Подробнее о заказах гостей',
'clients' => []
];
}
}
$guests = $namedGuests = $totalSum = 0;
$orders = ShiftOnlineOrders::where('is_waited', 1)
->where('is_deleted', 0)
->get();
if (isset($orders)) {
foreach ($orders as $order) {
$guests += $order['client_count'];
$totalSum += $order['order_sum'];
if ($order['client_code'] != '') {
$namedGuests += 1;
}
}
}
return [
'status' => 'success',
'namedGuests' => $namedGuests,
'guestsCount' => $guests,
'totalSum' => round($totalSum, 2)
];
}
if ($method == 'info') {
$response['status'] = 'success';
$response['exists'] = 'false';
$shifts = Shifts::first();
if (isset($shifts)) {
$response['exists'] = true;
$response['opened'] = $shifts['opened'];
$response['open'] = Staff::getName($shifts['who_open']);
$response['z_number'] = $shifts['z_number'];
if ($shifts['who_close'] > 0) {
$response['closed'] = $shifts['closed'];
$response['close'] = Staff::getName($shifts['who_close']);
}
}
return $response;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,20 +0,0 @@
<?php
namespace App\Commands;
use App\Component\Models\User;
use App\Console\Commands\HRCCommand;
use App\Console\Commands\HRCCommandInterface;
class GETHelloWorld extends HRCCommand implements HRCCommandInterface {
protected $signature = 'gethello';
public function command($input, $output = null) {
$users = User::all();
return [
'status' => 'success',
'users' => $users,
];
}
}

39
commands/GETKeyInfo.php Normal file
View File

@@ -0,0 +1,39 @@
<?php
namespace App\Commands;
use App\Component\Models\Cache;
use App\Console\Commands\HRCEncryptor;
use App\Console\Commands\HRCCommand;
use App\Console\Commands\HRCCommandInterface;
use Illuminate\Support\Facades\Log;
class GETKeyInfo extends HRCCommand implements HRCCommandInterface
{
protected $signature = 'getkeyinfo';
public function command($input, $output = null)
{
$cache = Cache::get(245817422, 'v1', $input);
if ($cache) {
return [
'status' => 'success',
'info' => $cache,
'input' => $input
];
}
$info_file = __DIR__ . "\\..\\..\\..\\info.ini";
$key_file = __DIR__ . "\\..\\..\\..\\Key.key";
$unn = parse_ini_file($info_file);
$unn = intval($unn['unn']);
$info = json_decode(HRCEncryptor::decrypt(file_get_contents($key_file), $unn), true);
if (!$cache) {
$cache = Cache::store(245817422, 'v1', $input, $info);
}
return [
'status' => 'success',
'info' => $cache,
'input' => $input
];
}
}

View File

@@ -3,7 +3,7 @@
namespace App\Commands;
use App\Component\Models\ExchangeShifts;
use App\Component\Models\OrderBot;
use App\Component\Models\OrderBotStorage;
use App\Component\Models\Report;
use App\Console\Commands\HRCCommand;
use App\Console\Commands\HRCCommandInterface;
@@ -19,7 +19,7 @@ class GETOutOrders extends HRCCommand implements HRCCommandInterface {
$out = array('id' => $shift['id'], 'opened' => $shift['opened'], 'closed' => $shift['closed']);
}
}
$orders = OrderBot::select('id', 'order', 'created_at')->where('created_at', '>', $out['opened'])->where('created_at', '<=', $out['closed'])->get();
$orders = OrderBotStorage::select('id', 'order', 'created_at')->where('created_at', '>', $out['opened'])->where('created_at', '<=', $out['closed'])->get();
$count_items = 0;
if (is_array($orders) || is_object($orders)) {
foreach ($orders as $order) {
@@ -73,7 +73,7 @@ class GETOutOrders extends HRCCommand implements HRCCommandInterface {
$end_t = strtotime($input['end_date']) - 1;
$start = date('Y-m-d H:i:s', $start_t);
$end = date('Y-m-d H:i:s', $end_t);
$orders = OrderBot::select('id', 'order', 'created_at')->where('created_at', '>', $start)->where('created_at', '<=', $end)->get();
$orders = OrderBotStorage::select('id', 'order', 'created_at')->where('created_at', '>', $start)->where('created_at', '<=', $end)->get();
$count_items = 0;
if (is_array($orders) || is_object($orders)) {
foreach ($orders as $order) {

View File

@@ -10,7 +10,7 @@ class GETReports extends HRCCommand implements HRCCommandInterface {
protected $signature = 'getreports';
public function command($input, $output = null) {
$reports = Report::all();
$reports = Report::select('id', 'name', 'report_type', 'start_date', 'end_date')->orderBy('id', 'desc')->get();
if ($reports) {
foreach ($reports as $key => $report) {
$data[] = array(

View File

@@ -3,6 +3,8 @@
namespace App\Commands;
use App\Component\Models\Settings;
use App\Component\Commands\Methods\Cache;
use App\Component\Models\Terminal;
use App\Console\Commands\HRCCommand;
use App\Console\Commands\HRCCommandInterface;
@@ -12,6 +14,34 @@ class GETSettings extends HRCCommand implements HRCCommandInterface
public function command($input, $output = null)
{
if (isset($input['method'])) {
$method = $input['method'];
if ($method == 'terminals') {
$out = [];
$terminals = Terminal::get();
foreach ($terminals as $terminal) {
if ($terminal['is_active'] === 1) {
$is_active = true;
} else {
$is_active = false;
}
$out[] = array(
'work_code' => $terminal['work_code'],
'work_group' => $terminal['work_group'],
'soft' => $terminal['soft'],
'is_active' => $is_active,
'key' => $terminal['key'],
'last_activity' => $terminal['last_activity'],
);
}
return [
'status' => 'success',
'terminals' => $out,
];
}
}
if (isset($input['code'])) {
$setting = Settings::where('code', $input['code'])
->first();

View File

@@ -3,7 +3,8 @@
namespace App\Commands;
use App\Component\Models\Dishes;
use App\Component\Models\OnlineItems;
use App\Component\Models\ShiftOnlineItems;
use App\Component\Models\ShiftOnlineOrders;
use App\Component\Models\Terminal;
use App\Console\Commands\HRCCommand;
use App\Console\Commands\HRCCommandInterface;
@@ -18,8 +19,21 @@ class GETTopDishes extends HRCCommand implements HRCCommandInterface {
} else {
$terminalKey = 0;
}
$info = OnlineItems::where('menu_code', '>', 0)->get()->unique('menu_code');
$count = OnlineItems::where('menu_code', '>', 0)->count();
$allOrders = ShiftOnlineOrders::select('code')
->where('is_closed', 1)
->where('is_returned', 0)
->where('is_deleted', 0)
->get();
foreach ($allOrders as $order) {
$orders[] = array($order['code']);
}
$info = ShiftOnlineItems::where('menu_code', '>', 0)
->whereIn('order_code', $orders)
->get()
->unique('menu_code');
$count = ShiftOnlineItems::where('menu_code', '>', 0)
->whereIn('order_code', $orders)
->count();
if ($count > 0) {
foreach ($info as $key => $value) {
$out[] = $value;
@@ -29,18 +43,22 @@ class GETTopDishes extends HRCCommand implements HRCCommandInterface {
->where('legacy_code', '=', $item['dish_code'])
->where('is_history', '=', 0)
->first();
$onlineDishInfo = OnlineItems::where('menu_code', '=', $item['menu_code'])
$onlineDishInfo = ShiftOnlineItems::where('menu_code', '=', $item['menu_code'])
->where('dish_code', '=', $item['dish_code'])
->whereIn('order_code', $orders)
->first();
if ($dishInfo['name'] == '') {
$dishHistInfo = Dishes::where('code', '=', $item['menu_code'])
->where('legacy_code', '=', $item['dish_code'])
->whereIn('order_code', $orders)
->first();
$dishName = $dishHistInfo['name'];
} else {
$dishName = $dishInfo['name'];
}
$dishCount = OnlineItems::where('menu_code', '=', $item['menu_code'])->sum('count');
$dishCount = ShiftOnlineItems::where('menu_code', '=', $item['menu_code'])
->whereIn('order_code', $orders)
->sum('count');
$dishSum = $onlineDishInfo['real_price'] * $dishCount;
if ($dishSum > 0) {
$dishTotalCost = round(($onlineDishInfo['special_price'] * $dishCount), 2);

View File

@@ -2,9 +2,11 @@
namespace App\Commands;
use App\Component\Models\Client;
use App\Component\Models\ClientsBonus;
use App\Console\Commands\HRCCommand;
use App\Console\Commands\HRCCommandInterface;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
class POSTBonus extends HRCCommand implements HRCCommandInterface
@@ -13,13 +15,17 @@ class POSTBonus extends HRCCommand implements HRCCommandInterface
public function command($input, $output = null)
{
$client_guid = $input['client_id'];
$client_guid = $input['client_guid'];
$bonus_amount = abs($input['amount']);
$staff_id = $input['who'];
$staff_id = $input['who_id'];
$bonus_time = $input['date_transaction'];
$type = $input['type'];
ClientsBonus::bonusReg($client_guid, $bonus_amount, $type);
ClientsBonus::bonusLog($client_guid, $bonus_amount, $bonus_time, $staff_id);
$client = Client::where('user_code', $client_guid)->first();
$client = Client::find($client['id']);
$client->updated_at = Carbon::createFromTimestampUTC($bonus_time)->timezone('Europe/Minsk');
$client->save();
if ($type == 'in') {
$message = 'Начислено ' . $bonus_amount . ' бонусов';
} elseif ($type == 'out') {

View File

@@ -12,46 +12,124 @@ use App\Console\Commands\HRCCommand;
use App\Console\Commands\HRCCommandInterface;
use Illuminate\Support\Facades\Log;
class POSTClient extends HRCCommand implements HRCCommandInterface {
class POSTClient extends HRCCommand implements HRCCommandInterface
{
protected $signature = 'postclient';
public function command($input, $output = null) {
public function command($input, $output = null)
{
if (isset($input['task']) && isset($input['id'])) {
if (isset($input['task'])) {
if ($input['task'] == 'update') {
$phone = urldecode($input['phone']);
$client = Client::find($input['id']);
log::debug($input);
if (isset($input['id'])) {
$id = $input['id'];
} else if (isset($input['client_guid'])) {
$fClient = Client::where('user_code', $input['client_guid'])->first();
if (!isset($fClient)) {
return [
'status' => 'success',
'error_message' => 'Клиент не найден',
];
}
$id = $fClient['id'];
} else {
return [
'status' => 'success',
'error_message' => 'Проверьте введенные данные',
];
}
if (isset($input['group_id']) && !isset($input['group_guid'])) {
$group_id = $input['group_id'];
} else if (isset($input['group_guid']) && !isset($input['group_id'])) {
$fGroup = ClientsGroup::where('code', $input['group_guid'])->first();
if (!isset($fGroup)) {
return [
'status' => 'success',
'error_message' => 'Группа не найдена',
];
}
$group_id = $fGroup['id'];
} else if (isset($input['group_id']) && isset($input['group_guid'])) {
$fGroup = ClientsGroup::where('code', $input['group_guid'])->first();
if (!isset($fGroup)) {
$fGroup = ClientsGroup::where('id', isset($input['group_id']))->first();
if (!isset($fGroup)) {
return [
'status' => 'success',
'error_message' => 'Группа не найдена',
];
}
}
$group_id = $fGroup['id'];
} else {
return [
'status' => 'success',
'error_message' => 'Проверьте введенные данные',
];
}
$client = Client::find($id);
$client->name = urldecode($input['name']);
$client->unloaded = 0;
$clientGroup = ClientsGroup::where('id', $input['group_id'])->first();
$client->group_id = urldecode($clientGroup['code']);
$clientGroup = ClientsGroup::where('id', $group_id)->first();
$client->group_id = $clientGroup['code'];
if (isset($input['phone'])) {
$phone = $input['phone'];
Log::debug($phone);
$clientPhone = ClientsPhone::where('client_guid', $client->user_code)->first();
if ($clientPhone) {
Log::debug($clientPhone);
if (isset($clientPhone)) {
$clientPhone = ClientsPhone::find($clientPhone['id']);
if ($phone !== '' && $phone !== '+375 ( ) - -') {
if (substr($phone, 0, 1) == '+') {
$phoneData = urldecode($input['phone']);
$clientPhone->phone = '+375 (' . substr($phone, 4, 2) . ') ' . substr($phone, 6, 3) . '-' . substr($phone, 9, 2) . '-' . substr($phone, 11, 2);
log::debug('UPD Substr true: ' . $phone);
} else {
$phoneData = urldecode($input['phone']);
$clientPhone->phone = '+375 (' . substr($phoneData, 0, 2) . ') ' . substr($phoneData, 2, 3) . '-' . substr($phoneData, 5, 2) . '-' . substr($phoneData, 7, 2);
log::debug('UPD Substr false: ' . $phone);
$clientPhone->phone = '+375 (' . substr($phone, 0, 2) . ') ' . substr($phone, 2, 3) . '-' . substr($phone, 5, 2) . '-' . substr($phone, 7, 2);
}
} else {
$clientPhone->phone = '+375 ( ) - -';
}
} else {
$clientPhone = new ClientsPhone;
if ($phone !== '' && $phone !== '+375 ( ) - -') {
if (substr($phone, 0, 1) == '+') {
$clientPhone->phone = '+375 (' . substr($phone, 4, 2) . ') ' . substr($phone, 6, 3) . '-' . substr($phone, 9, 2) . '-' . substr($phone, 11, 2);
log::debug('CR Substr true: ' . $phone);
} else {
log::debug('CR Substr false: ' . $phone);
$clientPhone->phone = '+375 (' . substr($phone, 0, 2) . ') ' . substr($phone, 2, 3) . '-' . substr($phone, 5, 2) . '-' . substr($phone, 7, 2);
}
} else {
$clientPhone->phone = '+375 ( ) - -';
}
}
$clientPhone->client_guid = $client->user_code;
$clientPhone->save();
}
if (isset($input['email'])) {
$clientEmail = ClientsEmail::where('client_guid', $client->user_code)->first();
if ($clientEmail) {
$clientEmail = ClientsEmail::find($clientEmail['id']);
if ($input['email'] !== '') {
if (isset($input['email']) && $input['email'] !== '') {
$clientEmail->email = urldecode($input['email']);
} else {
$clientEmail->email = '';
}
} else {
$clientEmail = new ClientsEmail;
$clientEmail->email = urldecode($input['email']);
}
$clientEmail->client_guid = $client->user_code;
$clientEmail->save();
} else {
$clientEmail = '';
}
if (isset($input['address'])) {
$clientAddress = ClientsAddress::where('client_guid', $client->user_code)->first();
if ($clientAddress) {
$clientAddress = ClientsAddress::find($clientAddress['id']);
@@ -60,20 +138,42 @@ class POSTClient extends HRCCommand implements HRCCommandInterface {
} else {
$clientAddress->address = '';
}
} else {
$clientAddress = new ClientsAddress;
$clientAddress->address = urldecode($input['address']);
}
$clientAddress->client_guid = $client->user_code;
$clientAddress->save();
}
$clientBarcode = ClientsBarcode::where('client_guid', $client->user_code)->first();
if ($clientBarcode) {
$clientBarcode = ClientsBarcode::find($clientBarcode['id']);
$clientBarcodeStart = 0;
$clientBarcodeEnd = 0;
if (isset($input['barcode'])) {
if ($input['barcode'] !== '') {
$clientBarcode->code_id = urldecode($input['barcode']);
$client->barcode_type = 2;
$client->barcode_start = $clientBarcodeStart = urldecode($input['barcode']);
$client->barcode_end = $clientBarcodeEnd = urldecode($input['barcode']);
} else {
$clientBarcode->code_id = '';
$client->barcode_type = 1;
$client->barcode_start = $clientBarcodeStart;
$client->barcode_end = $clientBarcodeEnd;
}
$clientBarcode->save();
}
if (isset($input['is_special_price']) && $input['is_special_price'] == 'true') {
$specialPrice = 1;
} else {
$specialPrice = 0;
}
if (isset($input['is_employee']) && $input['is_employee'] == 'true') {
$employee = 1;
} else {
$employee = 0;
}
$client->is_special_price = $specialPrice;
$client->is_employee = $employee;
$client->save();
return [
@@ -82,7 +182,7 @@ class POSTClient extends HRCCommand implements HRCCommandInterface {
'phone' => $clientPhone,
'email' => $clientEmail,
'address' => $clientAddress,
'barcode' => $clientBarcode,
'barcode' => $clientBarcodeStart,
'message' => 'Клиент обновлен',
];
}
@@ -120,6 +220,82 @@ class POSTClient extends HRCCommand implements HRCCommandInterface {
'currentGroup' => $clientGroup['id'],
];
}
if ($input['task'] == 'lock') {
if (isset($input['id'])) {
$id = $input['id'];
} else if (isset($input['client_guid'])) {
$fClient = Client::where('user_code', $input['client_guid'])->first();
if (!isset($fClient)) {
return [
'status' => 'success',
'error_message' => 'Клиент не найден',
];
}
$id = $fClient['id'];
} else {
return [
'status' => 'success',
'error_message' => 'Проверьте введенные данные',
];
}
$client = Client::find($id);
$clientGroup = ClientsGroup::where('code', $client->group_id)->first();
$client->is_block = 1;
$client->save();
return [
'status' => 'success',
'message' => 'Клиент заблокирован',
'currentGroup' => $clientGroup['id'],
];
}
if ($input['task'] == 'unlock') {
if (isset($input['id'])) {
$id = $input['id'];
} else if (isset($input['client_guid'])) {
$fClient = Client::where('user_code', $input['client_guid'])->first();
if (!isset($fClient)) {
return [
'status' => 'success',
'error_message' => 'Клиент не найден',
];
}
$id = $fClient['id'];
} else {
return [
'status' => 'success',
'error_message' => 'Проверьте введенные данные',
];
}
$client = Client::find($id);
$clientGroup = ClientsGroup::where('code', $client->group_id)->first();
$client->is_block = 0;
$client->save();
return [
'status' => 'success',
'message' => 'Клиент разблокирован',
'currentGroup' => $clientGroup['id'],
];
}
if ($input['task'] == 'search' && isset($input['name'])) {
$client = Client::where('name', 'like', '%' . urldecode($input['name']) . '%')->get();
if (count($client) > 0) {
$message = 'Клиенты найдены!';
} else {
$message = 'Клиенты с именем ' . urldecode($input['name']) . ' не найдены!';
}
return [
'status' => 'success',
'message' => $message,
'clients' => $client
];
}
} else {
return [
'status' => 'success',

View File

@@ -30,11 +30,26 @@ class POSTCreateClient extends HRCCommand implements HRCCommandInterface {
}
$total = Client::where('name', '=', $input['name'])->count();
if (isset($input['client_guid'])) {
$check_guid = Client::where('user_code', $input['client_guid'])->count();
if ($check_guid > 0) {
return [
'status' => 'success',
'message' => 'Клиент уже существует'
];
}
}
$client_code = Client::max('code') + 1;
if (isset($input['is_special_price']) && $input['is_special_price'] == 'true') {
$specialPrice = 1;
} else {
$specialPrice = 0;
}
if (isset($input['is_employee']) && $input['is_employee'] == 'true') {
$employee = 1;
} else {
$employee = 0;
}
$client = new Client;
if ($total >= 1) {
$total = $total + 1;
@@ -42,10 +57,17 @@ class POSTCreateClient extends HRCCommand implements HRCCommandInterface {
} else {
$client->name = urldecode($input['name']);
}
if (!isset($input['client_guid'])) {
$client->user_code = strtoupper(md5(time()));
} else {
$client->user_code = $input['client_guid'];
}
$client->code = $client_code;
$client->group_id = $group['code'];
$client->is_special_price = $specialPrice;
$client->is_employee = $employee;
$client->last_change = date("Ymd");
$clientEmail = new ClientsEmail;
$clientEmail->email = urldecode($input['email']);
$clientEmail->client_guid = $client->user_code;
@@ -55,7 +77,7 @@ class POSTCreateClient extends HRCCommand implements HRCCommandInterface {
$clientAddress->client_guid = $client->user_code;
$clientPhone = new ClientsPhone;
if ($input['phone'] !== '') {
if ($input['phone'] !== '' && isset($input['phone'])) {
$phoneData = urldecode($input['phone']);
$phone = '+375 (' . substr($phoneData, 0, 2) . ') ' . substr($phoneData, 2, 3) . '-' . substr($phoneData, 5, 2) . '-' . substr($phoneData, 7, 2);
} else {
@@ -65,7 +87,7 @@ class POSTCreateClient extends HRCCommand implements HRCCommandInterface {
$clientPhone->client_guid = $client->user_code;
if (isset($input['barcode']) && $input['barcode'] > 0) {
$client->barcode_type = 1;
$client->barcode_type = 2;
$clientBarcode = new ClientsBarcode;
$clientBarcode->code_id = urldecode($input['barcode']);
$clientBarcode->name = '';
@@ -73,13 +95,15 @@ class POSTCreateClient extends HRCCommand implements HRCCommandInterface {
$clientBarcode->value = urldecode($input['barcode']);
$clientBarcode->block = 0;
$clientBarcode->symptom_block = 0;
$client->barcode_start = urldecode($input['barcode']);
$client->barcode_end = urldecode($input['barcode']);
$client->save();
$clientPhone->save();
$clientEmail->save();
$clientAddress->save();
$clientBarcode->save();
} else {
$client->barcode_type = 0;
$client->barcode_type = 1;
$client->save();
$clientPhone->save();
$clientEmail->save();

View File

@@ -2,11 +2,16 @@
namespace App\Commands;
use App\Component\Models\Base;
use App\Component\Models\Dishes;
use App\Component\Models\OrderBot;
use App\Component\Models\OrderBotStorage;
use App\Component\Models\OrderItems;
use App\Component\Models\Orders;
use App\Component\Models\TerminalUpdate;
use App\Console\Commands\HRCCommand;
use App\Console\Commands\HRCCommandInterface;
use Carbon\Carbon;
class POSTOrder extends HRCCommand implements HRCCommandInterface {
protected $signature = 'postorder';
@@ -97,6 +102,132 @@ class POSTOrder extends HRCCommand implements HRCCommandInterface {
];
}
if ($input['task'] == 'pay' && isset($input['info'])) {
$test_json = Base::validate_json(urldecode($input['info']));
if (!$test_json) {
return [
'status' => 'fail',
'message' => 'Ошибка обработки JSON',
];
}
$order_info = json_decode(urldecode($input['info']), true);
if (isset($order_info['order_id'])) {
$order_id = intval($order_info['order_id']);
$order = OrderBotStorage::where('id', $order_id)->first();
if (!isset($order)) {
return [
'status' => 'fail',
'message' => 'Заказ с данным ID не найден',
];
}
} else {
return [
'status' => 'fail',
'message' => 'Отсутствует ID заказа',
];
}
if (isset($order_info['transaction_id'])) {
$transaction_id = intval($order_info['transaction_id']);
$order_data = json_decode(base64_decode($order['order']), true);
if ($transaction_id != $order_data['id']) {
return [
'status' => 'fail',
'message' => 'ID заказа не соответствует ID транзакции',
];
}
} else {
return [
'status' => 'fail',
'message' => 'Отсутствует ID транзакции',
];
}
if (isset($order_info['time'])) {
$pay_time = $order_info['time'];
if ($pay_time < $order['created_at']) {
return [
'status' => 'fail',
'message' => 'Время создания заказа больше чем время оплаты',
];
}
} else {
return [
'status' => 'fail',
'message' => 'Отсутствует время оплаты заказа',
];
}
if (isset($order_info['amount'])) {
$amount = floatval($order_info['amount']);
if ($amount != floatval($order_data['price'])) {
return [
'status' => 'fail',
'message' => 'Сумма оплаты не соответствует сумме заказа',
];
}
} else {
return [
'status' => 'fail',
'message' => 'Отсутствует сумма оплаты',
];
}
if (isset($order_info['is_print'])) {
$is_print = $order_info['is_print'];
} else {
$is_print = false;
}
if (isset($order_info['is_closed'])) {
$is_closed = $order_info['is_closed'];
} else {
$is_closed = false;
}
if ($order['is_send'] === 0) {
return [
'status' => 'fail',
'message' => 'Заказ ещё не отправлен',
];
} else {
$pay_task = array(
'order_id' => $order_id,
'transaction_id' => $transaction_id,
'time' => $pay_time,
'amount' => $amount,
'is_print' => $is_print,
'is_closed' => $is_closed
);
$todayDate = Carbon::now('Europe/Minsk')->format('Y-m-d H:i:m');
$bot_info = OrderBot::first();
$terminal_id = $bot_info['terminal_id'];
$check_order = TerminalUpdate::where('method', 'payorder')
->where('more', base64_encode(json_encode($pay_task)))
->count();
if ($check_order > 0) {
return [
'status' => 'fail',
'message' => 'Задача оплаты в обработке',
];
}
$task = new TerminalUpdate;
$task->terminal_id = $terminal_id;
$task->next_at = $todayDate;
$task->method = 'payorder';
$task->period = 1;
$task->is_cycle = 0;
$task->more = base64_encode(json_encode($pay_task));
$task->save();
}
return [
'status' => 'success',
'message' => 'Информация об оплате отправлена',
];
}
} else {
return [
'status' => 'success',

View File

@@ -2,9 +2,11 @@
namespace App\Commands;
use App\Component\Models\Client;
use App\Component\Models\ClientsPresale;
use App\Console\Commands\HRCCommand;
use App\Console\Commands\HRCCommandInterface;
use Carbon\Carbon;
class POSTPresale extends HRCCommand implements HRCCommandInterface
{
@@ -12,18 +14,19 @@ class POSTPresale extends HRCCommand implements HRCCommandInterface
public function command($input, $output = null)
{
$client_guid = $input['client_id'];
$client_guid = $input['client_guid'];
$presale_amount = abs($input['amount']);
$staff_id = $input['who'];
$staff_id = $input['who_id'];
$presale_time = $input['date_transaction'];
$type = $input['type'];
$action_type = intval($input['action_type']);
$code_order = intval($input['code_order']);
ClientsPresale::presaleReg($client_guid, $presale_amount, $type);
ClientsPresale::presaleLog($client_guid, $presale_amount, $presale_time, $staff_id);
if ($type == 'in') {
$message = 'Внесен аванс на сумму ' . $presale_amount . ' BYN';
} elseif ($type == 'out') {
$message = 'Зачтен аванс на сумму ' . $presale_amount . ' BYN';
}
$message = ClientsPresale::presaleLog($client_guid, $presale_amount, $presale_time, $staff_id, $action_type, $code_order);
$client = Client::where('user_code', $client_guid)->first();
$client = Client::find($client['id']);
$client->updated_at = Carbon::createFromTimestampUTC($presale_time)->timezone('Europe/Minsk');
$client->save();
$presale_result = ClientsPresale::getPresale($client_guid);
return [
'status' => 'success',

View File

@@ -1,10 +1,12 @@
{
"name": "hrc-admin/hello-world",
"version": "2.26",
"version": "2.27",
"require": {
"horeca/admin-php-module-core": "dev-master",
"guzzlehttp/guzzle": "^7.4",
"phpmailer/phpmailer": "^6.6"
"phpmailer/phpmailer": "^6.6",
"ext-openssl": "*",
"ext-json": "*"
},
"repositories": [
{

7
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "c03123a7ef4b356dbbe431d73497088d",
"content-hash": "a8af6b76ceb6599b09c480a9985c90b3",
"packages": [
{
"name": "brick/math",
@@ -5896,7 +5896,10 @@
},
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform": {
"ext-openssl": "*",
"ext-json": "*"
},
"platform-dev": [],
"plugin-api-version": "2.0.0"
}

View File

@@ -0,0 +1,31 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddOrderIdColumnInClientsActions extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up() {
if (!Schema::hasColumn('clients_actions', 'order_id')) {
Schema::table('clients_actions', function (Blueprint $table) {
$table->integer('order_id')->nullable();
});
}
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down() {
Schema::table('clients_actions', function (Blueprint $table) {
$table->dropColumn('order_id');
});
}
}

View File

@@ -0,0 +1,70 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class UpdateCoreInterface227 extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
$directivesUpd = CORE_PATH . '/../V1/forUpdate/toDirectives/';
$indexUpd = CORE_PATH . '/../V1/forUpdate/toWebApp/';
$servicesUpd = CORE_PATH . '/../V1/forUpdate/toServices/';
$libsUpd = CORE_PATH . '/../V1/forUpdate/toLibs/datatables/';
if (is_dir($directivesUpd)) {
$files = array_diff(scandir($directivesUpd), array('.', '..'));
foreach ($files as $file) {
if (file_exists(CORE_PATH . '/../../web/app/scripts/directives/' . $file)) {
copy(CORE_PATH . '/../../web/app/scripts/directives/' . $file, CORE_PATH . '/../../web/app/scripts/directives/' . $file . '.bak');
}
copy($directivesUpd . $file, CORE_PATH . '/../../web/app/scripts/directives/' . $file);
}
}
if (is_dir($indexUpd)) {
$files = array_diff(scandir($indexUpd), array('.', '..'));
foreach ($files as $file) {
if (file_exists(CORE_PATH . '/../../web/app/' . $file)) {
copy(CORE_PATH . '/../../web/app/' . $file, CORE_PATH . '/../../web/app/' . $file . '.bak');
}
copy($indexUpd . $file, CORE_PATH . '/../../web/app/' . $file);
}
}
if (is_dir($servicesUpd)) {
$files = array_diff(scandir($servicesUpd), array('.', '..'));
foreach ($files as $file) {
if (file_exists(CORE_PATH . '/../../web/app/scripts/services/' . $file)) {
copy(CORE_PATH . '/../../web/app/scripts/services/' . $file, CORE_PATH . '/../../web/app/scripts/services/' . $file . '.bak');
}
copy($servicesUpd . $file, CORE_PATH . '/../../web/app/scripts/services/' . $file);
}
}
if (is_dir($libsUpd)) {
$files = array_diff(scandir($libsUpd), array('.', '..'));
if (!is_dir(CORE_PATH . '/../../web/libs/datatables/')) {
mkdir(CORE_PATH . '/../../web/libs/datatables/', 0777);
}
foreach ($files as $file) {
if (file_exists(CORE_PATH . '/../../web/libs/datatables/' . $file)) {
copy(CORE_PATH . '/../../web/libs/datatables/' . $file, CORE_PATH . '/../../web/libs/datatables//' . $file . '.bak');
}
copy($libsUpd . $file, CORE_PATH . '/../../web/libs/datatables/' . $file);
}
}
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
}
}

View File

@@ -0,0 +1,29 @@
<?php
use App\Component\Models\Filesystem;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\Log;
class DeleteFrontendFolders227 extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up() {
if (file_exists(CORE_PATH . '/../Staff/web/')) {
Filesystem::ClearFolder((CORE_PATH . '/../Staff/web/'));
} else {
Log::debug('Staff frontend already deleted!');
}
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down() {
//
}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,5 @@
/*!
* Print button for Buttons and DataTables.
* 2016 SpryMedia Ltd - datatables.net/license
*/
!function(n){"function"==typeof define&&define.amd?define(["jquery","datatables.net","datatables.net-buttons"],function(t){return n(t,window,document)}):"object"==typeof exports?module.exports=function(t,e){return t=t||window,(e=e||("undefined"!=typeof window?require("jquery"):require("jquery")(t))).fn.dataTable||require("datatables.net")(t,e),e.fn.dataTable.Buttons||require("datatables.net-buttons")(t,e),n(e,t,t.document)}:n(jQuery,window,document)}(function(m,b,t,p){"use strict";function h(t){return n.href=t,-1===(t=n.host).indexOf("/")&&0!==n.pathname.indexOf("/")&&(t+="/"),n.protocol+"//"+t+n.pathname+n.search}var e=m.fn.dataTable,n=t.createElement("a");return e.ext.buttons.print={className:"buttons-print",text:function(t){return t.i18n("buttons.print","Print")},action:function(t,e,n,o){function r(t,e){for(var n="<tr>",o=0,r=t.length;o<r;o++){var i=null===t[o]||t[o]===p?"":t[o];n+="<"+e+" "+(s[o]?'class="'+s[o]+'"':"")+">"+i+"</"+e+">"}return n+"</tr>"}var i=e.buttons.exportData(m.extend({decodeEntities:!1},o.exportOptions)),a=e.buttons.exportInfo(o),s=e.columns(o.exportOptions.columns).flatten().map(function(t){return e.settings()[0].aoColumns[e.column(t).index()].sClass}).toArray(),u='<table class="'+e.table().node().className+'">';o.header&&(u+="<thead>"+r(i.header,"th")+"</thead>"),u+="<tbody>";for(var d=0,c=i.body.length;d<c;d++)u+=r(i.body[d],"td");u+="</tbody>",o.footer&&i.footer&&(u+="<tfoot>"+r(i.footer,"th")+"</tfoot>"),u+="</table>";var l=b.open("","");if(l){l.document.close();var f="<title>"+a.title+"</title>";m("style, link").each(function(){f+=function(t){t=m(t).clone()[0];return"link"===t.nodeName.toLowerCase()&&(t.href=h(t.href)),t.outerHTML}(this)});try{l.document.head.innerHTML=f}catch(t){m(l.document.head).html(f)}l.document.body.innerHTML="<h1>"+a.title+"</h1><div>"+(a.messageTop||"")+"</div>"+u+"<div>"+(a.messageBottom||"")+"</div>",m(l.document.body).addClass("dt-print-view"),m("img",l.document.body).each(function(t,e){e.setAttribute("src",h(e.getAttribute("src")))}),o.customize&&o.customize(l,o,e);a=function(){o.autoPrint&&(l.print(),l.close())};navigator.userAgent.match(/Trident\/\d.\d/)?a():l.setTimeout(a,1e3)}else e.buttons.info(e.i18n("buttons.printErrorTitle","Unable to open print view"),e.i18n("buttons.printErrorMsg","Please allow popups in your browser for this site to be able to view the print view."),5e3)},title:"*",messageTop:"*",messageBottom:"*",exportOptions:{},header:!0,footer:!1,autoPrint:!0,customize:null},e});

View File

@@ -0,0 +1,4 @@
/*! DataTables Bootstrap 3 integration
* ©2011-2015 SpryMedia Ltd - datatables.net/license
*/
!function(t){"function"==typeof define&&define.amd?define(["jquery","datatables.net"],function(e){return t(e,window,document)}):"object"==typeof exports?module.exports=function(e,a){return e=e||window,(a=a||("undefined"!=typeof window?require("jquery"):require("jquery")(e))).fn.dataTable||require("datatables.net")(e,a),t(a,0,e.document)}:t(jQuery,window,document)}(function(x,e,n,r){"use strict";var i=x.fn.dataTable;return x.extend(!0,i.defaults,{dom:"<'row'<'col-sm-6'l><'col-sm-6'f>><'row'<'col-sm-12'tr>><'row'<'col-sm-5'i><'col-sm-7'p>>",renderer:"bootstrap"}),x.extend(i.ext.classes,{sWrapper:"dataTables_wrapper form-inline dt-bootstrap",sFilterInput:"form-control input-sm",sLengthSelect:"form-control input-sm",sProcessing:"dataTables_processing panel panel-default"}),i.ext.renderer.pageButton.bootstrap=function(d,e,o,a,l,u){function c(e,a){for(var t,n,r=function(e){e.preventDefault(),x(e.currentTarget).hasClass("disabled")||b.page()==e.data.action||b.page(e.data.action).draw("page")},i=0,s=a.length;i<s;i++)if(t=a[i],Array.isArray(t))c(e,t);else{switch(f=p="",t){case"ellipsis":p="&#x2026;",f="disabled";break;case"first":p=m.sFirst,f=t+(0<l?"":" disabled");break;case"previous":p=m.sPrevious,f=t+(0<l?"":" disabled");break;case"next":p=m.sNext,f=t+(l<u-1?"":" disabled");break;case"last":p=m.sLast,f=t+(l<u-1?"":" disabled");break;default:p=t+1,f=l===t?"active":""}p&&(n=-1!==f.indexOf("disabled"),n=x("<li>",{class:g.sPageButton+" "+f,id:0===o&&"string"==typeof t?d.sTableId+"_"+t:null}).append(x("<a>",{href:n?null:"#","aria-controls":d.sTableId,"aria-disabled":n?"true":null,"aria-label":w[t],"aria-role":"link","aria-current":"active"===f?"page":null,"data-dt-idx":t,tabindex:d.iTabIndex}).html(p)).appendTo(e),d.oApi._fnBindAction(n,{action:t},r))}}var p,f,t,b=new i.Api(d),g=d.oClasses,m=d.oLanguage.oPaginate,w=d.oLanguage.oAria.paginate||{};try{t=x(e).find(n.activeElement).data("dt-idx")}catch(e){}c(x(e).empty().html('<ul class="pagination"/>').children("ul"),a),t!==r&&x(e).find("[data-dt-idx="+t+"]").trigger("focus")},i});

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,85 @@
(function ($, oldFunction) {
$.param = function (a, traditional) {
var s = oldFunction.apply(oldFunction, [a, traditional]);
return s.replace(/\+/g, '%20');
};
})(jQuery, jQuery.param);
(function () {
'use strict';
angular
.module('smart.request', [])
.service('smartRequest', smartRequest);
smartRequest.$inject = ['$http', 'Notification', '$rootScope'];
function smartRequest($http, Notification, $rootScope) {
this.post = function (method, data, callback, error_callback, server_error_callback) {
var xsrf = $.param(data, true);
$http({
method: 'POST',
url: $rootScope.apiUrl + method,
timeout: 10 * 60 * 1000,
data: xsrf,
headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Token': $rootScope.globals.currentUser ? $rootScope.globals.currentUser.token : '' }
}).then(function successCallback(response) {
if (response.data.status !== 'success') {
if (response.data.more) {
Notification.error(response.data.more);
}
if (response.data.message) {
Notification.error(response.data.message);
}
if (typeof error_callback !== typeof undefined) {
error_callback(response.data);
}
}
else {
if (typeof callback !== typeof undefined) {
callback(response.data);
}
}
}, function errorCallback(response) {
if (typeof server_error_callback !== typeof undefined) {
server_error_callback(response);
}
else {
Notification.error('Сервер недоступен');
}
});
};
this.get = function (method, callback, error_callback, server_error_callback) {
$http({
method: 'GET',
url: $rootScope.apiUrl + method,
timeout: 10 * 60 * 1000,
headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Token': $rootScope.globals.currentUser ? $rootScope.globals.currentUser.token : '' }
}).then(function successCallback(response) {
if (response.data.status !== 'success') {
Notification.error(response.data.more);
if (typeof error_callback !== typeof undefined) {
error_callback(response.data);
}
}
else {
if (typeof callback !== typeof undefined) {
callback(response.data);
}
}
}, function errorCallback(response) {
if (typeof server_error_callback !== typeof undefined) {
server_error_callback(response);
}
else {
Notification.error('Сервер недоступен');
}
});
};
}
})();

View File

@@ -22,6 +22,10 @@
<link rel="stylesheet" href="../libs/angular/angular-ui-notification/dist/angular-ui-notification.min.css" />
<link rel="stylesheet" href="../assets/bootstrap/dist/css/bootstrap.min.css" type="text/css" />
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.3/css/dataTables.bootstrap.min.css" type="text/css" />
<link rel="stylesheet" href="https://cdn.datatables.net/buttons/2.3.5/css/buttons.dataTables.min.css" type="text/css" />
<!-- build:css ../assets/styles/app.min.css -->
<link rel="stylesheet" href="../assets/styles/app.css" type="text/css" />
@@ -29,21 +33,7 @@
<link rel="stylesheet" href="../assets/styles/font.css" type="text/css" />
<!-- Matomo -->
<script type="text/javascript">
var _paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="//analytics.hrc.by/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '1']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script>
<!-- End Matomo Code -->
</head>
@@ -52,6 +42,17 @@
<!-- build:js scripts/app.angular.js -->
<!-- jQuery -->
<script src="../libs/jquery/jquery/dist/jquery.js"></script>
<!-- DataTables -->
<script src="../libs/datatables/jquery.dataTables.min.js"></script>
<script src="../libs/datatables/dataTables.buttons.min.js"></script>
<script src="../libs/datatables/buttons.print.min.js"></script>
<script src="../libs/datatables/pdfmake.min.js"></script>
<script src="../libs/datatables/vfs_fonts.js"></script>
<script src="../libs/datatables/buttons.html5.min.js"></script>
<script src="../libs/datatables/jszip.min.js"></script>
<script src="../libs/datatables/dataTables.bootstrap.min.js"></script>
<!-- Bootstrap -->
<script src="scripts/config.js"></script>

73
models/Base.php Normal file
View File

@@ -0,0 +1,73 @@
<?php
namespace App\Component\Models;
class Base
{
public static function tofloat($num) {
$dotPos = strrpos($num, '.');
$commaPos = strrpos($num, ',');
$sep = (($dotPos > $commaPos) && $dotPos) ? $dotPos :
((($commaPos > $dotPos) && $commaPos) ? $commaPos : false);
if (!$sep) {
return floatval(preg_replace("/[^0-9]/", "", $num));
}
return floatval(
preg_replace("/[^0-9]/", "", substr($num, 0, $sep)) . '.' .
preg_replace("/[^0-9]/", "", substr($num, $sep+1, strlen($num)))
);
}
public static function validate_json($string)
{
// decode the JSON data
$result = json_decode(utf8_encode($string), true, JSON_INVALID_UTF8_SUBSTITUTE);
// switch and check possible JSON errors
switch (json_last_error()) {
case JSON_ERROR_NONE:
$error = ''; // JSON is valid // No error has occurred
break;
case JSON_ERROR_DEPTH:
$error = 'The maximum stack depth has been exceeded.';
break;
case JSON_ERROR_STATE_MISMATCH:
$error = 'Invalid or malformed JSON.';
break;
case JSON_ERROR_CTRL_CHAR:
$error = 'Control character error, possibly incorrectly encoded.';
break;
case JSON_ERROR_SYNTAX:
$error = 'Syntax error, malformed JSON.';
break;
// PHP >= 5.3.3
case JSON_ERROR_UTF8:
$error = 'Malformed UTF-8 characters, possibly incorrectly encoded.';
break;
// PHP >= 5.5.0
case JSON_ERROR_RECURSION:
$error = 'One or more recursive references in the value to be encoded.';
break;
// PHP >= 5.5.0
case JSON_ERROR_INF_OR_NAN:
$error = 'One or more NAN or INF values in the value to be encoded.';
break;
case JSON_ERROR_UNSUPPORTED_TYPE:
$error = 'A value of a type that cannot be encoded was given.';
break;
default:
$error = 'Unknown JSON error occured.';
break;
}
if ($error !== '') {
// throw the Exception or exit // or whatever :)
return false;
}
// everything is OK
return true;
}
}

104
models/Cache.php Normal file
View File

@@ -0,0 +1,104 @@
<?php
namespace App\Component\Models;
class Cache
{
public static function get($code, $plugin, $input)
{
unset($input['ip']);
unset($input['token']);
unset($input['admin_user_id']);
unset($input['host']);
$method = $input['method_name'];
unset($input['method_name']);
$dirname = CORE_PATH . '/../../Cache/' . $code . '/' . $plugin . '/';
if (!is_dir($dirname)) {
mkdir($dirname, 0777);
}
$filename = $method . ".tmp";
if (file_exists($dirname . $filename)) {
$caches = json_decode(file_get_contents($dirname . $filename), true);
foreach ($caches as $key => $cache) {
if ($cache['input'] == $input) {
return $cache['result'];
}
}
} else {
return false;
}
}
public static function store($code, $plugin, $input, $result)
{
unset($input['ip']);
unset($input['token']);
unset($input['admin_user_id']);
unset($input['host']);
$method = $input['method_name'];
unset($input['method_name']);
$data = [];
$info = array('input' => $input, 'result' => $result);
array_push($data, $info);
$dirname = CORE_PATH . '/../../Cache/' . $code . '/' . $plugin . '/';
if (!is_dir($dirname)) {
mkdir($dirname, 0777);
}
$filename = $method . ".tmp";
if (!file_exists($dirname . $filename)) {
$handle = fopen($dirname . $filename, 'w');
fputs($handle, json_encode($data));
fclose($handle);
return $result;
} else {
$handle = fopen($dirname . $filename, 'r');
$caches = fgets($handle);
fclose($handle);
$caches = json_decode($caches, true);
foreach ($caches as $key => $cache) {
if ($cache == $info) {
return $info['result'];
} else {
array_push($caches, $info);
$handle = fopen($dirname . $filename, 'w');
fputs($handle, json_encode($caches));
fclose($handle);
return $info['result'];
}
}
}
}
public static function clear($code, $plugin, $input, $type)
{
$dirname = CORE_PATH . '/../../Cache/' . $code . '/' . $plugin . '/';
if ($type == 'single') {
$method = $input['method_name'];
if (is_dir($dirname)) {
$filename = $method . ".tmp";
if (file_exists($dirname . $filename)) {
unlink($dirname . $filename);
return true;
} else {
return false;
}
} else {
return false;
}
}
if ($type == 'full') {
$files = glob($dirname."/*");
if (count($files) > 0) {
foreach ($files as $file) {
if (file_exists($file)) {
unlink($file);
}
}
return true;
} else {
return false;
}
}
}
}

View File

@@ -4,17 +4,20 @@ namespace App\Component\Models;
use Illuminate\Database\Eloquent\Model;
class Client extends Model {
class Client extends Model
{
protected $table = 'clients';
/**
* Get clients phone.
*/
public function clientPhone() {
public function clientPhone()
{
return $this->belongsTo('App\Component\Models\ClientsPhone', 'user_code', 'client_guid');
}
public static function getPhone($guid) {
public static function getPhone($guid)
{
$phone = ClientsPhone::where('client_guid', $guid)->first();
if (isset($phone)) {
$phone = $phone['phone'];
@@ -24,7 +27,8 @@ class Client extends Model {
return $phone;
}
public static function getEmail($guid) {
public static function getEmail($guid)
{
$email = ClientsEmail::where('client_guid', $guid)->first();
if (isset($email)) {
$email = $email['email'];
@@ -34,7 +38,8 @@ class Client extends Model {
return $email;
}
public static function getAddress($guid) {
public static function getAddress($guid)
{
$address = ClientsAddress::where('client_guid', $guid)->first();
if (isset($address)) {
$address = $address['address'];
@@ -44,17 +49,19 @@ class Client extends Model {
return $address;
}
public static function getBarcode($guid) {
$barcode = ClientsBarcode::where('client_guid', $guid)->first();
public static function getBarcode($guid)
{
$barcode = Client::where('user_code', $guid)->first();
if (isset($barcode)) {
$barcode = $barcode['value'];
$barcode = $barcode['barcode_start'];
} else {
$barcode = '';
}
return $barcode;
}
public static function getID($guid) {
public static function getID($guid)
{
$id = Client::where('client_guid', $guid)->first();
if (isset($id)) {
$id = $id['id'];
@@ -64,4 +71,16 @@ class Client extends Model {
return $id;
}
public static function getName($guid)
{
$client_name = Client::where('user_code', $guid)
->first();
if (isset($client_name)) {
$client_name = $client_name['name'];
} else {
$client_name = 'Связанный персонал не найден';
}
return $client_name;
}
}

View File

@@ -6,4 +6,14 @@ use Illuminate\Database\Eloquent\Model;
class ClientsGroup extends Model {
protected $table = 'client_groups';
public static function getID($guid) {
$id = ClientsGroup::where('code', $guid)->first();
if (isset($id)) {
$id = $id['id'];
} else {
$id = 0;
}
return $id;
}
}

View File

@@ -46,20 +46,44 @@ class ClientsPresale extends Model
/**
* Presale log.
*/
public static function presaleLog($guid, $value, $time, $staff_id)
public static function presaleLog($guid, $value, $time, $staff_id, $type, $order_id)
{
if ($value > 0) {
$action_name = 'Внесение аванса';
} else {
$action_name = 'Зачет аванса';
$action_type = $type;
if ($action_type == 21) {
$action_name = 'Поступил предварительный платеж через скидку в размере ' . $value . ' BYN через заказ №' . $order_id;
}
if ($action_type == 11) {
$action_name = 'Поступил предварительный платеж наличными в размере ' . $value . ' BYN';
}
if ($action_type == 13) {
$action_name = 'Поступил предварительный платеж безналичными в размере ' . $value . ' BYN';
}
if ($action_type == 12) {
$action_name = 'Поступил предварительный платеж кредитной картой в размере ' . $value . ' BYN';
}
if ($action_type == 14) {
$action_name = 'Возврат предварительного платежа наличными в размере ' . $value . ' BYN';
}
if ($action_type == 16) {
$action_name = 'Возврат предварительного платежа безналичными в размере ' . $value . ' BYN';
}
if ($action_type == 15) {
$action_name = 'Возврат предварительного платежа кредитной картой в размере ' . $value . ' BYN';
}
if ($action_type == 2) {
$action_name = 'Зачтен предварительный платеж в размере ' . $value . ' BYN через заказ №' . $order_id;
}
$action = new ClientsActions();
$action->action = $action_name;
$action->created = Carbon::createFromTimestampUTC($time)->timezone('Europe/Minsk');
$action->user_id = $guid;
$action->action_value = abs($value);
$action->action_type = 2;
$action->action_type = $action_type;
$action->order_id = $order_id;
$action->who = $staff_id;
$action->save();
return $action_name;
}
}

View File

@@ -25,6 +25,19 @@ class Dishes extends Model {
$dish_name = 'Связанный товар удален';
}
}
if ($dish_name == 'Связанный товар удален') {
$dish_name = Dishes::where('legacy_code', $data)->where('is_history', 0)->first();
if ($dish_name) {
$dish_name = $dish_name['name'];
} else {
$dish_name = Dishes::where('legacy_code', $data)->where('is_history', 1)->first();
if ($dish_name) {
$dish_name = $dish_name['name'];
} else {
$dish_name = 'Связанный товар удален';
}
}
}
return $dish_name;
}
@@ -59,4 +72,19 @@ class Dishes extends Model {
}
return $isServing;
}
public static function GetPrinterCode($data) {
$dish = Dishes::where('legacy_code', $data)->where('is_history', 0)->first();
if ($dish) {
$printer_code = $dish['printer_code'];
} else {
$dish = Dishes::where('legacy_code', $data)->where('is_history', 1)->first();
if ($dish) {
$printer_code = $dish['printer_code'];
} else {
$printer_code = 0;
}
}
return $printer_code;
}
}

View File

@@ -6,4 +6,6 @@ use Illuminate\Database\Eloquent\Model;
class ExchangeActions extends Model {
protected $table = 'exchange_actions';
}

View File

@@ -6,4 +6,9 @@ use Illuminate\Database\Eloquent\Model;
class ExchangeDeleted extends Model {
protected $table = 'exchange_deleted';
public function deletedActions() {
return $this->hasMany('App\Component\Models\ExchangeActions', 'order_position', 'item_id')
->where('exchange_actions.action_type', '=', 5);
}
}

View File

@@ -54,7 +54,7 @@ class ExchangeOrders extends Model
'cof' => $item['cof'],
'unit' => Units::getName($item['units_id']),
'amount' => round($item['sale_price'] * $item['count'], 2),
'discount' => round($discount, 2)
'discount' => round($discount)
);
$amount += round($item['sale_price'] * $item['count'], 2);
$full_price += round($realPrice,2);

36
models/Filesystem.php Normal file
View File

@@ -0,0 +1,36 @@
<?php
namespace App\Component\Models;
class Filesystem
{
public static function GetCode($token)
{
$code = json_decode(base64_decode(urldecode($token)), true);
$unn = $code['unn'];
if ($code == '') {
$session_file = __DIR__ . "\\..\\..\\..\\Sessions\\" . $token . ".ini";
$session_data = parse_ini_file($session_file);
$unn = intval($session_data['unn']);
}
return $unn;
}
public static function ClearFolder($dir)
{
$d = opendir($dir);
while (($entry = readdir($d)) !== false) {
if ($entry != "." && $entry != "..") {
if (is_dir($dir . "/" . $entry)) {
self::ClearFolder($dir . "/" . $entry);
} else {
unlink($dir . "/" . $entry);
}
}
}
closedir($d);
rmdir($dir);
return true;
}
}

View File

@@ -5,5 +5,5 @@ namespace App\Component\Models;
use Illuminate\Database\Eloquent\Model;
class OrderBot extends Model {
protected $table = 'orderbot_storage';
protected $table = 'order_bot';
}

View File

@@ -0,0 +1,9 @@
<?php
namespace App\Component\Models;
use Illuminate\Database\Eloquent\Model;
class OrderBotStorage extends Model {
protected $table = 'orderbot_storage';
}

View File

@@ -12,4 +12,19 @@ class Printer extends Model {
* @var array
*/
protected $guarded = [];
public static function getName($data) {
$printer_name = Printer::where('code', $data)->where('is_history', 0)->first();
if ($printer_name) {
$printer_name = $printer_name['name'];
} else {
$printer_name = Printer::where('code', $data)->where('is_history', 1)->first();
if ($printer_name) {
$printer_name = $printer_name['name'];
} else {
$printer_name = 'Связанный принтер удален';
}
}
return $printer_name;
}
}

View File

@@ -59,7 +59,7 @@ class ShiftOnlineOrders extends Model
'cof' => $item['cof'],
'unit' => Units::getName($item['units_id']),
'amount' => round($item['sale_price'] * $item['count'], 2),
'discount' => round($discount, 0)
'discount' => round($discount)
);
$amount += round($item['sale_price'] * $item['count'], 2);
$full_price += round($realPrice,2);

View File

@@ -1,5 +1,5 @@
[info]
name=V1
version=2.26
version=2.27
[build]
version=2.26
version=2.27

View File

@@ -116,12 +116,10 @@
};
$scope.editClient = function (client, group) {
$scope.contextElement = client;
$scope.contextGroup = group;
$('#edit-client').modal('toggle');
console.log(client);
console.log($scope.contextGroup);
};
$scope.updateClient = function (group) {
@@ -135,6 +133,8 @@
address: $scope.contextElement.address,
email: $scope.contextElement.email,
barcode: $scope.contextElement.barcode,
is_special_price: $scope.contextElement.special_price,
is_employee: $scope.contextElement.employee,
task: 'update'
}, function (data) {
if (data.status == 'success') {
@@ -147,12 +147,11 @@
});
};
$scope.removeClient = function () {
$scope.removeClient = function (client) {
$('#client-confirm-delete').modal('toggle');
$('#edit-client').modal('toggle');
smartRequest.post('v1/client', {
id: $scope.contextElement.id,
id: client.id,
task: 'delete'
}, function (data) {
$scope.getGroups();
@@ -166,6 +165,40 @@
});
};
$scope.lockClient = function (client) {
smartRequest.post('v1/client', {
id: client.id,
task: 'lock'
}, function (data) {
//$scope.getGroups();
//$scope.openGroup($scope.currentGroup);
if (data.message) {
Notification.success(data.message);
$scope.openClientInfo(client);
}
if (data.error_message) {
Notification.error(data.error_message);
}
});
};
$scope.unlockClient = function (client) {
smartRequest.post('v1/client', {
id: client.id,
task: 'unlock'
}, function (data) {
//$scope.getGroups();
//$scope.openGroup($scope.currentGroup);
if (data.message) {
Notification.success(data.message);
$scope.openClientInfo(client);
}
if (data.error_message) {
Notification.error(data.error_message);
}
});
};
$scope.pager = function (currentPage) {
smartRequest.get('v1/clients?group_id=' + $scope.currentGroup + '&page=' + $scope.currentPage, function (data) {
$scope.clients = data.clients;
@@ -179,11 +212,17 @@
if ($scope.search.query.length === 0) {
$scope.openGroup({id: $scope.currentGroupId});
} else {
smartRequest.post('client/search', {
smartRequest.post('v1/client', {
task: 'search',
name: $scope.search.query
},
function (data) {
$scope.clients = data.clients;
if (data.clients.length > 0) {
Notification.success(data.message);
} else {
Notification.error(data.message);
}
});
}
};
@@ -229,7 +268,8 @@
address: $scope.newClient.address,
email: $scope.newClient.email,
barcode: $scope.newClient.barcode,
is_special_price: $scope.newClient.special_price
is_special_price: $scope.newClient.special_price,
is_employee: $scope.newClient.employee
}, function (data) {
$scope.pager($scope.currentGroup);
$scope.closeCard();
@@ -256,6 +296,7 @@
};
$scope.openClientInfo = function (client) {
$('#actions_tab').tab('show')
$scope.currentClientId = client.id;
$scope.isCreateNewGroup = false;
$scope.isCreateNewClient = false;

View File

@@ -22,9 +22,10 @@
.controller('DashboardCtrl', DashboardCtrl);
DashboardCtrl.inject = ['$scope', 'smartRequest', '$interval', '$location', 'Notification'];
function DashboardCtrl($scope, smartRequest, $interval, $location, Notification) {
$(document).ready(function() {
if (moment(moment().format('YYYY-MM-DD')).isAfter('2021-12-25')) {
/*$(document).ready(function () {
/!*if (moment(moment().format('YYYY-MM-DD')).isAfter('2021-12-25')) {
if (moment(moment().format('YYYY-MM-DD')).isBefore('2022-01-10')) {
smartRequest.get('v1/topdishesnewyear', function (data) {
$scope.year_count = data.count;
@@ -65,8 +66,15 @@
}
});
}
}
});
}*!/
*/
//Отображение текущего времени
$scope.currentDate = new Date();
var timer = $interval(function() {
$scope.currentDate = new Date();
}, 1000);
$scope.nextImage = function () {
$('.carousel').carousel('next');
@@ -75,6 +83,50 @@
$('.carousel').carousel('prev');
};
//Автоматическое обновление данных
$scope.timerEnabled = false;
$scope.timeRemaining = new Date(0, 0, 0, 0, 2, 0);
var updateTimer = null;
$scope.toggleTimer = function() {
if ($scope.timerEnabled) {
startTimer();
} else {
stopTimer();
}
};
function startTimer() {
if (updateTimer === null) {
updateTimer = $interval(function() {
$scope.timeRemaining.setSeconds($scope.timeRemaining.getSeconds() - 1);
console.log($scope.timeRemaining.getSeconds());
if ($scope.timeRemaining.getMinutes() === 0 && $scope.timeRemaining.getSeconds() === 0) {
stopTimer();
$scope.timeRemaining = new Date(0, 0, 0, 0, 2, 0);
console.log('Данные обновлены');
smartRequest.get('v1/clearcache?folder=dashboard', function (data) {
});
$scope.update();
startTimer();
}
}, 1000);
}
}
function stopTimer() {
if (updateTimer !== null) {
$interval.cancel(updateTimer);
updateTimer = null;
}
}
//Остановка таймеров
$scope.$on('$destroy', function() {
$interval.cancel(timer);
$interval.cancel(updateTimer);
});
$scope.orders_closed = {
percent: 0,
total: 0,
@@ -277,16 +329,17 @@
});
};
$scope.clearCache = function () {
smartRequest.get('v1/clearcache?folder=dashboard', function (data) {
});
};
$scope.updateData = function () {
smartRequest.get('dashboard/online/updatetime', function (data) {
$scope.update_time = data.updated;
});
smartRequest.get('dashboard/online/updatetime', function (data) {
$scope.update_time = data.updated;
});
smartRequest.get('dashboard/online/info', function (data) {
smartRequest.get('v1/dashboard?method=info', function (data) {
$scope.shiftInfo = data;
});
@@ -347,7 +400,6 @@
});
smartRequest.get('dashboard/online/folders', function (data) {
$scope.folders.labels = data.folders.map(folder => folder.name);
$scope.folders.data = data.folders.map(folder => Math.roundClearNG(folder.count));
@@ -381,13 +433,13 @@
$scope.profit = data.profit;
});
smartRequest.get('dashboard/online/guests', function (data) {
smartRequest.get('v1/dashboard?method=guests', function (data) {
$scope.guests = data.guestsCount;
$scope.namedGuests = data.namedGuests;
$scope.sumNamedGuests = data.totalSum;
});
smartRequest.get('dashboard/online/deleted', function (data) {
smartRequest.get('v1/dashboard?method=deleted', function (data) {
$scope.deleted = Math.roundNG(data.count, -2);
$scope.deleted_sum = Math.roundNG(data.sum, -2);
});
@@ -398,7 +450,7 @@
$scope.tot_disc_sum = Math.roundNG(data.total_sum, -2);
});
smartRequest.get('dashboard/online/guests/median', function (data) {
smartRequest.get('v1/dashboard?method=guests&type=median', function (data) {
$scope.medianGuests.labels = [];
$scope.medianGuests.data = [[]];
@@ -462,11 +514,7 @@
$scope.update_time = data.updated;
});
smartRequest.get('dashboard/online/updatetime', function (data) {
$scope.update_time = data.updated;
});
smartRequest.get('dashboard/online/info', function (data) {
smartRequest.get('v1/dashboard?method=info', function (data) {
$scope.shiftInfo = data;
});
@@ -544,13 +592,13 @@
$scope.profit = data.profit;
});
smartRequest.get('dashboard/online/guests', function (data) {
smartRequest.get('v1/dashboard?method=guests', function (data) {
$scope.guests = data.guestsCount;
$scope.namedGuests = data.namedGuests;
$scope.sumNamedGuests = data.totalSum;
});
smartRequest.get('dashboard/online/deleted', function (data) {
smartRequest.get('v1/dashboard?method=deleted', function (data) {
$scope.deleted = Math.roundNG(data.count, -2);
$scope.deleted_sum = Math.roundNG(data.sum, -2);
});
@@ -561,7 +609,7 @@
$scope.tot_disc_sum = Math.roundNG(data.total_sum, -2);
});
smartRequest.get('dashboard/online/guests/median', function (data) {
smartRequest.get('v1/dashboard?method=guests&type=median', function (data) {
$scope.medianGuests.labels = [];
$scope.medianGuests.data = [[]];
@@ -569,12 +617,10 @@
var tempTime = [];
for (var i = 0; i < data.data.length; i++) {
var newDate = $scope.getMomentDate(data.data[i].time);
tempData.push(parseInt(data.data[i].count));
tempTime.push(newDate);
var indexTime = $scope.getIntervals(tempTime[i], $scope.medianGuests.labels);
if (indexTime == -1) {
$scope.medianGuests.labels.push(tempTime[i]);
$scope.medianGuests.data[0].push(tempData[i]);
@@ -637,7 +683,6 @@
};
$scope.ping();
$scope.all_widgets = [];
$scope.add = function () {
smartRequest.get('settings/widgets/all', function (data) {
@@ -671,9 +716,14 @@
};
$scope.getMomentDate = function (date_str) {
var date = moment(date_str, 'DD.MM.YYYY HH:mm:ss');
var remainder = 30 - (date.minute() % 30);
return moment(date).add(remainder, 'minutes').set('second', 0);
var momentTime = moment(date_str, 'DD.MM.YYYY HH:mm:ss'); // Создаем объект Moment из строки времени
var minutes = momentTime.minute(); // Получаем количество минут в объекте Moment
if (minutes > 30) {
minutes = 30;
} else {
minutes = 0;
}
return moment(momentTime).set('minutes', minutes).set('second', 0);
};
$scope.getIntervals = function (momentTime, array) {
@@ -715,6 +765,20 @@
});
};
$scope.getMoreGuests = function (code) {
smartRequest.get('v1/dashboard?method=guests&type=more', function (data) {
$scope.moreData = data;
$('#get-more-guests').modal();
});
};
$scope.getMoreDeleted = function () {
smartRequest.get('v1/dashboard?method=deleted&more=true', function (data) {
$scope.moreData = data;
$('#get-more-deleted').modal();
});
};
$scope.getMoreDiscount = function () {
smartRequest.get('v1/morediscount/', function (data) {
$scope.moreData = data;
@@ -730,6 +794,14 @@
});
};
$scope.getItemsDeleted = function (order) {
$('#get-more-deleted').modal('toggle');
smartRequest.get('v1/dashboard?method=deleted&items=true&order_id=' + order.number, function (data) {
$scope.order = data;
$('#items-deleted').modal('toggle');
});
};
$scope.getItemsStaff = function (order) {
$('#get-more-staff').modal('toggle');
smartRequest.get('v1/onlinestaff?method=items&order=' + order.number, function (data) {

View File

@@ -1,11 +1,29 @@
(function () {
'use strict';
angular
.module('app')
.module('app', ['ui.bootstrap', 'ui.utils'])
.controller('ReportsCtrl', ReportsCtrl);
ReportsCtrl.$inject = ['$scope', 'smartRequest', 'Notification'];
function ReportsCtrl($scope, smartRequest, Notification) {
Number.prototype.toDivide = function () {
var float = String(this.toFixed(2));
if (float.length <= 6) return float;
var space = 0;
var number = '';
for (var i = float.length - 1; i >= 0; i--) {
if (space == 3) {
number = ' ' + number;
space = 0;
}
number = float.charAt(i) + number;
space++;
}
return number;
};
var date = new Date();
var formatted = ('0' + date.getDate()).slice(-2) + '.' + ('0' + (date.getMonth() + 1)).slice(-2) + '.' + date.getFullYear();
@@ -23,10 +41,22 @@
$scope.statistic = {};
$scope.staffs = [];
$scope.printers = [];
$scope.dataTableOpt = {
"aoSearchCols": [
null
],
"oLanguage": {
"sUrl": 'https://cdn.datatables.net/plug-ins/1.13.3/i18n/ru.json'
},
"searching": false,
"paging": false,
"info": false,
"order": [[1, 'desc']],
};
$scope.update = function () {
smartRequest.get('v1/reports', function (data) {
$scope.history = data.reports;
$('.modal-body').scrollTop(0);
});
smartRequest.get('v1/settings?code=11', function (data) {
$scope.delete_shift_value = data.value;
@@ -56,34 +86,89 @@
});
};
$scope.closeModal = function (modalName) {
$scope.modalName = '#' + modalName;
$('.modal-body').scrollTop(0);
$($scope.modalName).modal('dispose');
return true;
};
$scope.prevModal = function (modalFromName, modalToName) {
$scope.modal_from = '#' + modalFromName;
$scope.modal_to = '#' + modalToName;
$($scope.modal_from).modal('hide');
$($scope.modal_to).modal('toggle');
};
$scope.nextModal = function (modalFromName, modalToName) {
$scope.modal_from = '#' + modalFromName;
$scope.modal_to = '#' + modalToName;
$($scope.modal_from).modal('hide');
$($scope.modal_to).modal('toggle');
};
$scope.getOrders = function (discount_id, modalFromName, modalToName) {
$scope.discount_id = discount_id;
$scope.orders_list = $scope.orders_info[discount_id].orders;
$scope.nextModal(modalFromName, modalToName);
};
$scope.getItems = function (order_id, opened, closed, modalFromName, modalToName) {
smartRequest.get('v1/clientorderinfo?order_id=' + order_id + '&opened=' + opened + '&closed=' + closed, function (data) {
$scope.order_info = data.info;
$scope.nextModal(modalFromName, modalToName);
});
};
$scope.reportDiscounts = function () {
$('#preload-modal').modal();
Notification.primary('Отчет формируется. Ожидайте.');
smartRequest.get('v1/datareport?type=discounts&start_date=' + encodeURIComponent($scope.start_date) + '&end_date=' + encodeURIComponent($scope.end_date), function (data) {
$scope.orders_info = data.orders_info;
$scope.orders_count = data.orders_count;
$scope.orders_full_sum = data.orders_full_sum;
$scope.orders_sale_sum = data.orders_sale_sum;
$scope.orders_order_sum = data.orders_order_sum;
$('#preload-modal').modal('hide');
$('#report-discounts').modal();
$scope.update();
});
};
$scope.reportDelete = function () {
$('#preload-modal').modal();
Notification.primary('Отчет формируется. Ожидайте.');
smartRequest.get('v1/datareport?type=deleted&start_date=' + encodeURIComponent($scope.start_date) + '&end_date=' + encodeURIComponent($scope.end_date), function (data) {
$scope.report_delete = data.deleted;
$scope.report_delete.total_sum = data.total_sum;
$scope.report_delete.total_count = data.total_count;
$scope.report_delete = data.orders;
$scope.totalSum = data.totalSum;
$scope.totalCount = data.totalCount;
$('#preload-modal').modal('hide');
$('#report-delete').modal();
}, function(data) {
$scope.update();
});
};
$scope.reportRealisation = function () {
smartRequest.get('report/realisation?start_date=' + encodeURIComponent($scope.start_date) + '&end_date=' + encodeURIComponent($scope.end_date), function(data) {
smartRequest.get('v1/datareport?type=realisation&start_date=' + encodeURIComponent($scope.start_date) + '&end_date=' + encodeURIComponent($scope.end_date), function (data) {
$scope.update();
$scope.report_realisation = data.printers;
$scope.return_printers = data.ret_prints;
$scope.report_realisation.total_count = data.total_count;
$scope.report_realisation.total_sum = data.total_sum;
$('#report-realisation').modal();
}, function(data) {
$scope.update();
});
};
$scope.reportStatistic = function () {
smartRequest.get('report/statistics?start_date=' + encodeURIComponent($scope.start_date) + '&end_date=' + encodeURIComponent($scope.end_date), function(data) {
smartRequest.get('v1/datareport?type=statistic&start_date=' + encodeURIComponent($scope.start_date) + '&end_date=' + encodeURIComponent($scope.end_date), function (data) {
$scope.fiscal = data.fiscal;
$scope.realisation = data.realisation;
$scope.returns = data.returns;
$scope.cancellations = data.cancellations;
$scope.statistic = data.statistic;
$scope.presales = data.presales;
$scope.payments = data.payments;
$('#report-statistic').modal();
}, function(data) {
$scope.update();
});
};
@@ -92,7 +177,6 @@
smartRequest.get('v1/datareport?type=staff&start_date=' + encodeURIComponent($scope.start_date) + '&end_date=' + encodeURIComponent($scope.end_date), function (data) {
$scope.staffs = data.staffs;
$('#report-staff').modal();
}, function(data) {
$scope.update();
});
};
@@ -101,7 +185,6 @@
smartRequest.get('report/payment?start_date=' + encodeURIComponent($scope.start_date) + '&end_date=' + encodeURIComponent($scope.end_date), function (data) {
$scope.printers = data.printers;
$('#report-payment').modal();
}, function(data) {
$scope.update();
});
};
@@ -111,19 +194,33 @@
$scope.orders = data.orders;
$scope.total = data.total;
$('#report-out').modal();
}, function (data) {
$scope.update();
});
};
$scope.createReport = function () {
switch ($scope.report_id) {
case 'deleted': $scope.reportDelete(); break;
case 'realisation': $scope.reportRealisation(); break;
case 'statistics': $scope.reportStatistic(); break;
case 'staff': $scope.reportStaff(); break;
case 'pay': $scope.reportPay(); break;
case 'out': $scope.reportOut(); break;
case 'deleted':
$scope.reportDelete();
break;
case 'realisation':
$scope.reportRealisation();
break;
case 'statistics':
$scope.reportStatistic();
break;
case 'staff':
$scope.reportStaff();
break;
case 'pay':
$scope.reportPay();
break;
case 'out':
$scope.reportOut();
break;
case 'discounts':
$scope.reportDiscounts();
break;
}
};
@@ -142,6 +239,7 @@
};
$scope.printElem = function (elem) {
console.log(elem);
$scope.popup($('<div/>').append($(elem).clone()).html());
};

View File

@@ -2,10 +2,41 @@
'use strict';
angular
.module('app')
.filter('curr', function () { //maybe we should take it to the filter folder
return function (input) {
if (typeof input == 'string') {
input = parseFloat(input.replace(/,/g, '.'));
}
var outputValue = input;
if (typeof outputValue !== 'undefined') {
return outputValue.toFixed(2);
} else {
return 0.00;
}
};
})
.controller('ShiftsCtrl', ShiftsCtrl);
ShiftsCtrl.$inject = ['$scope', '$filter', 'smartRequest', 'Notification'];
function ShiftsCtrl($scope, $filter, smartRequest, Notification) {
Number.prototype.toDivide = function() {
var float = String(this.toFixed(2));
if(float.length <= 6) return float;
var space = 0;
var number = '';
for(var i = float.length - 1; i >= 0; i--) {
if(space == 3) {
number = ' ' + number;
space = 0;
}
number = float.charAt(i) + number;
space++;
}
return number;
};
var date = new Date();
var formatted = ('0' + date.getDate()).slice(-2) + '.' + ('0' + (date.getMonth() + 1)).slice(-2) + '.' + date.getFullYear();
date.setDate(date.getDate() - 1);
@@ -21,6 +52,18 @@
$scope.statistic = {};
$scope.staffs = [];
$scope.parseFloat = parseFloat;
$scope.dataTableOpt = {
"aoSearchCols": [
null
],
"oLanguage": {
"sUrl": 'https://cdn.datatables.net/plug-ins/1.13.3/i18n/ru.json'
},
"searching": false,
"paging": false,
"info": false,
"order": [[1, 'desc']],
};
$scope.add = function () {
$scope.reImport = {};
@@ -43,11 +86,17 @@
$('#reImport').modal('toggle');
};
$scope.closeModal = function (modalName) {
$scope.modalName = '#' + modalName;
$($scope.modalName).modal('dispose');
};
$scope.update = function () {
smartRequest.get('shift/list?page=' + $scope.currentPage, function (data) {
$scope.shifts = data.shifts;
$scope.countOfPages = data.pages;
$scope.pages = $scope.makePages();
$('.modal-body').scrollTop(0);
});
smartRequest.get('v1/settings?code=11', function (data) {
$scope.delete_shift_value = data.value;
@@ -77,6 +126,47 @@
});
};
$scope.prevModal = function (modalFromName, modalToName) {
$scope.modal_from = '#' + modalFromName;
$scope.modal_to = '#' + modalToName;
$($scope.modal_from).modal('hide');
$($scope.modal_to).modal('toggle');
};
$scope.nextModal = function (modalFromName, modalToName) {
$scope.modal_from = '#' + modalFromName;
$scope.modal_to = '#' + modalToName;
$($scope.modal_from).modal('hide');
$($scope.modal_to).modal('toggle');
};
$scope.getOrders = function (discount_id, modalFromName, modalToName) {
$scope.discount_id = discount_id;
$scope.orders_list = $scope.orders_info[discount_id].orders;
$scope.nextModal(modalFromName, modalToName);
};
$scope.getItems = function (order_id, opened, closed, modalFromName, modalToName) {
smartRequest.get('v1/clientorderinfo?order_id=' + order_id + '&opened=' + opened + '&closed=' + closed, function (data) {
$scope.order_info = data.info;
$scope.nextModal(modalFromName, modalToName);
});
};
$scope.reportDiscounts = function (shift) {
smartRequest.get('v1/datareport?type=discounts&shift_id=' + shift.id, function (data) {
$scope.orders_info = data.orders_info;
$scope.orders_count = data.orders_count;
$scope.orders_full_sum = data.orders_full_sum;
$scope.orders_sale_sum = data.orders_sale_sum;
$scope.orders_order_sum = data.orders_order_sum;
$scope.start_date = shift.opened;
$scope.end_date = shift.closed;
$('#report-discounts').modal();
$scope.update();
});
};
$scope.reportMerged = function (shift) {
smartRequest.get('v1/datareport?type=merge&shift_id=' + shift.id, function (data) {
$scope.report_merge = data.data;
@@ -112,39 +202,51 @@
$scope.reportDelete = function (shift) {
smartRequest.get('v1/datareport?type=deleted&shift_id=' + shift.id, function (data) {
$scope.report_delete = data.deleted;
$scope.report_delete.total_sum = data.total_sum;
$scope.report_delete.total_count = data.total_count;
if (data.totalCount > 0) {
$scope.report_delete = data.orders;
$scope.total_sum = data.totalSum;
$scope.total_count = data.totalCount;
$scope.shift_id = shift.id;
$scope.start_date = shift.opened;
$scope.end_date = shift.closed;
$('#report-delete').modal();
$scope.update();
$('#shift-delete').modal();
} else {
Notification.error(data.message);
}
});
};
$scope.reportRealisation = function (shift) {
smartRequest.get('report/realisation?shift_id=' + shift.id, function (data) {
smartRequest.get('v1/datareport?type=realisation&shift_id=' + shift.id, function (data) {
$scope.report_realisation = data.printers;
$scope.return_printers = data.ret_prints;
$scope.report_realisation.total_count = data.total_count;
$scope.report_realisation.total_sum = data.total_sum;
$scope.start_date = shift.opened;
$scope.end_date = shift.closed;
$scope.update();
$('#report-realisation').modal();
});
};
$scope.reportStatistic = function (shift) {
smartRequest.get('report/statistics?shift_id=' + shift.id, function (data) {
smartRequest.get('v1/datareport?type=statistic&shift_id=' + shift.id, function (data) {
$scope.fiscal = data.fiscal;
$scope.realisation = data.realisation;
$scope.returns = data.returns;
$scope.cancellations = data.cancellations;
$scope.statistic = data.statistic;
$scope.presales = data.presales;
$scope.payments = data.payments;
$scope.start_date = shift.opened;
$scope.end_date = shift.closed;
$scope.update();
$('#report-statistic').modal();
});
};
@@ -155,20 +257,19 @@
$scope.start_date = shift.opened;
$scope.end_date = shift.closed;
$scope.update();
$('#report-staff').modal();
});
};
$scope.reportPay = function (shift) {
smartRequest.get('report/payment?shift_id=' + shift.id, function (data) {
$scope.printers = data.printers;
$scope.start_date = shift.opened;
$scope.end_date = shift.closed;
$('#report-payment').modal();
}, function (data) {
$scope.update();
$('#report-payment').modal();
});
};
@@ -182,11 +283,9 @@
$scope.shift = data.shift;
$scope.total = data.total;
$scope.update();
$('#report-out').modal();
}
}, function (data) {
$scope.update();
});
};

271
web/controllers/staff.js Normal file
View File

@@ -0,0 +1,271 @@
(function() {
'use strict';
angular
.module('app')
.controller('StaffCtrl', StaffCtrl);
StaffCtrl.$inject = ['$scope', 'smartRequest', 'Notification', '$timeout'];
function StaffCtrl($scope, smartRequest, Notification, $timeout) {
$scope.groups = [];
$scope.personals = [];
$scope.parentGroup = 0;
$scope.parentGroupCode = '';
$scope.search = {
query: ''
};
$scope.interfaces = [];
$scope.rights = [];
$scope.currentPersonalObject = {
id: 0
};
$scope.currentGroupObject = {
id: 0
};
var promise = 0;
smartRequest.get('v1/clearcache?folder=staff', function () {});
$scope.update = function() {
smartRequest.get('staff/group/list', function(data) {
$scope.groups = data.groups;
});
};
$scope.updateGroups = function (callback, id) {
smartRequest.get('staff/group/list', function(data) {
$scope.groups = data.groups;
if (callback) {
var newGroup = $scope.getItemById($scope.groups, id);
callback(newGroup);
}
});
};
$scope.updatePersonals = function (callback, id) {
smartRequest.get('staff/list?group_code=' + $scope.parentGroupCode, function(data) {
$scope.personals = data.staff;
if (callback) {
var newStaff = $scope.getItemById($scope.personals, id);
callback(newStaff);
}
});
};
$scope.addGroup = function() {
smartRequest.post('staff/group/store', {
name: 'Новая группа'
}, function(data) {
var groupId = data.group_id;
$scope.updateGroups($scope.showGroup, groupId);
});
};
$scope.addPersonal = function() {
smartRequest.post('staff/store', {
name: 'Новый персонал',
group_code: $scope.parentGroupCode
}, function(data) {
var staffId = data.staff_id;
$scope.updatePersonals($scope.showPersonal, staffId);
});
};
$scope.openGroup = function(group) {
$scope.currentGroupObject = {
id: 0
};
$scope.parentGroup = group.id;
$scope.parentGroupCode = group.code;
$scope.personals = [];
$scope.updatePersonal();
};
$scope.showPersonal = function(personal) {
$scope.currentGroupObject = {
id: 0
};
$scope.currentPersonalObject = personal;
};
$scope.showGroup = function(group) {
$scope.currentPersonalObject = {
id: 0
};
$scope.currentGroupObject = group;
for(var i = 0; i < $scope.rights.length; i++) {
$scope.rights[i].is_active = false;
}
smartRequest.get('staff/right/list?group_code=' + $scope.currentGroupObject.code, function(data) {
for(var i = 0; i < data.rights.length; i++) {
for(var j = 0; j < $scope.rights.length; j++) {
if(data.rights[i].code === $scope.rights[j].code) {
$scope.rights[j].is_active = true;
break;
}
}
}
});
};
$scope.updatePersonal = function() {
smartRequest.get('staff/list?group_code=' + $scope.parentGroupCode, function(data) {
$scope.personals = data.staff;
});
};
$scope.closeCard = function() {
$scope.currentPersonalObject = {
id: 0
};
$scope.currentGroupObject = {
id: 0
};
};
$scope.getItemById = function(list, id) {
var res;
list.forEach(function (item) {
if (item.id == id) {
res = item;
return;
}
});
return res;
};
$scope.savePersonal = function() {
smartRequest.post('staff/update', {
id: $scope.currentPersonalObject.id,
name: $scope.currentPersonalObject.name,
password: $scope.currentPersonalObject.password,
interface_code: $scope.currentPersonalObject.interface_code,
group_code: $scope.currentPersonalObject.group_code
},
function(data) {
Notification.success('Персонал сохранен');
$scope.closeCard();
});
};
$scope.saveGroup = function() {
var activeRights = $scope.rights.filter(right => right.is_active);
smartRequest.post('staff/group/update', {
id: $scope.currentGroupObject.id,
name: $scope.currentGroupObject.name,
interface_code: $scope.currentGroupObject.interface_code,
sub_interface_code: $scope.currentGroupObject.sub_interface_code,
rights: JSON.stringify(activeRights.map(activeRight => activeRight.code))
}, function(data) {
Notification.success('Группа сохранена');
$scope.closeCard();
});
};
$scope.upFolder = function() {
$scope.currentPersonalObject = {
id: 0
};
$scope.currentGroupObject = {
id: 0
};
$scope.parentGroup = 0;
$scope.update();
};
$scope.removePersonal = function() {
$('#personal-confirm-delete').modal('toggle');
smartRequest.post('staff/delete', {
id: $scope.currentPersonalObject.id
}, function(data) {
$scope.currentPersonalObject = {
id: 0
};
$scope.updatePersonal();
});
};
$scope.removeGroup = function() {
$('#group-confirm-delete').modal('toggle');
smartRequest.post('staff/group/delete', {
id: $scope.currentGroupObject.id
}, function(data) {
$scope.currentGroupObject = {
id: 0
};
$scope.update();
});
};
$scope.personalSearch = function() {
if(promise){
$timeout.cancel(promise);
}
promise = $timeout(function() {
if($scope.search.query.length > 0) {
smartRequest.post('staff/search', {
name: $scope.search.query
},
function (data) {
$scope.personals = data.staff;
});
}
else {
$scope.upFolder();
}
}, 300);
};
$scope.setRights = function() {
$scope.removeActiveToggle();
$scope.onRightsByTemplate();
};
$scope.removeActiveToggle = function() {
$scope.rights.forEach(function (item) {
if (item.is_active) {
item.is_active = false;
}
});
};
$scope.onRightsByTemplate = function() {
smartRequest.get('staff/rights/template?code=' + $scope.currentGroupObject.interface_code + '&sub_code=' + $scope.currentGroupObject.sub_interface_code, function (data) {
for(var i = 0; i < data.rights.length; i++) {
for(var j = 0; j < $scope.rights.length; j++) {
if(data.rights[i].code === $scope.rights[j].code) {
$scope.rights[j].is_active = true;
break;
}
}
}
});
};
$scope.update();
smartRequest.get('staff/interface/list', function(data) {
$scope.interfaces = data.interfaces;
});
smartRequest.get('staff/right/all', function(data) {
$scope.rights = data.rights;
});
}
})();

View File

@@ -23,7 +23,7 @@
$scope.terminalLogs = [];
$scope.update = function () {
smartRequest.get('settings/terminals', function (data) {
smartRequest.get('v1/settings?method=terminals', function (data) {
$scope.terminals = data.terminals;
});
};

View File

@@ -35,6 +35,13 @@ item: [
order: 40
},
{
name: 'Персонал',
acl: 'staff',
url: 'app.staff',
icon: 'business',
order: 50
},
{
name: 'Реализация',
acl: 'shifts,report',
icon: 'library_books',

View File

@@ -46,6 +46,14 @@
controller: 'ClientsCtrl',
resolve: ['scripts/controllers/clients.js']
},
{
code: 'app.staff',
url: '/staff',
templateUrl: '../views/staff/index.html',
data: {title: 'Персонал'},
controller: 'StaffCtrl',
resolve: ['scripts/controllers/staff.js']
},
{
code: 'app.shifts',
url: '/shifts',

View File

@@ -4,26 +4,49 @@
<h5 class="modal-title">Редактирование клиента</h5>
</div>
<div class="modal-body p-lg">
<form role="form" class="ng-pristine ng-valid container">
<form role="form" class="ng-pristine ng-valid container" ng-submit="updateClient(contextGroup)">
<div class="form-group row">
<div class="col-sm-12">
<span>Группа: </span>
<select name="group" class="form-control input-c" ng-options="opt.id as opt.name for opt in groups" ng-model="contextGroup"></select>
<span>Имя: </span><input class="form-control" placeholder="Название" type="text" ng-model="contextElement.name">
<span>Телефон: </span><input class="form-control" type="text" ng-model="contextElement.phone" ui-mask="+375 (99) 999-99-99">
<span>Адрес: </span><input class="form-control" placeholder="Введите email" type="text" ng-model="contextElement.address">
<span>Email: </span><input class="form-control" placeholder="Введите адрес" type="text" ng-model="contextElement.email">
<span>Штрих код: </span><input class="form-control" placeholder="Введите штрих код" type="text" ng-model="contextElement.barcode">
<select name="group" class="form-control input-c"
ng-options="opt.id as opt.name for opt in groups" ng-model="contextGroup"></select>
<span>Имя: </span><input class="form-control" placeholder="Название" type="text"
ng-model="contextElement.name">
<span>Телефон: </span><input class="form-control" type="text" ng-model="contextElement.phone"
ui-mask="+375 (99) 999-99-99">
<span>Адрес: </span><input class="form-control" placeholder="Введите email" type="text"
ng-model="contextElement.address">
<span>Email: </span><input class="form-control" placeholder="Введите адрес" type="text"
ng-model="contextElement.email">
<span>Штрих код: </span><input class="form-control" placeholder="Введите штрих код" type="text"
ng-model="contextElement.barcode">
<p>
<div class="form-group form-group-inline row">
<label class="col-sm-3 form-group-label" for="specialPriceCheck">Скидка по
себестоимости </label>
<div class="col-sm-9">
<input class="form-group-input" type="checkbox" value="" id="specialPriceCheck"
ng-model="contextElement.special_price" ng-checked="contextElement.special_price">
</div>
</div>
<div class="form-group form-group-inline row">
<label class="col-sm-3 form-group-label" for="employeeCheck">Сотрудник</label>
<div class="col-sm-9">
<input class="form-group-input" type="checkbox" value="" id="employeeCheck"
ng-model="contextElement.employee" ng-checked="contextElement.employee">
</div>
</div>
</p>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn dark-white p-x-md" data-dismiss="modal">Отмена</button>
<button type="submit" class="btn success p-x-md">Сохранить</button>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn danger p-x-md pull-left" data-toggle="modal" data-target="#client-confirm-delete"><i class="material-icons">&#xE872;</i></button>
<button type="button" class="btn dark-white p-x-md" data-dismiss="modal">Отмена</button>
<button type="button" class="btn success p-x-md" ng-click="updateClient(contextGroup)">Сохранить</button>
</div>
</div>
</div>

View File

@@ -103,6 +103,7 @@
<div class="p-a-md">
<div class="row m-t">
<div class="col-sm-12">
<div class="col-sm-11">
<a href="" class="pull-left m-r-md">
<span class="avatar w-96">
<img src="../views/clients/images/client.png">
@@ -110,7 +111,7 @@
</span>
</a>
<div class="clear m-b">
<h3 class="m-0 m-b-xs">{{currentClient.name}}</h3>
<h3 class="m-0 m-b-xs">{{currentClient.name}} <span ng-if="currentClient.info.is_block">(КЛИЕНТ ЗАБЛОКИРОВАН)</span></h3>
<p class="text-muted">
<span class="m-r">
<i class="fa fa-phone m-r-sm text-muted"></i>{{currentClient.info.phone}}
@@ -120,7 +121,20 @@
</small>
</p>
</div>
</div>
<div class="col-sm-1">
<div class="dropdown inline">
<button class="btn white dropdown-toggle" data-toggle="dropdown"
aria-expanded="true"><i class="fa fa-bars"></i></button>
<div class="dropdown-menu dropdown-menu-scale pull-right">
<a class="dropdown-item" href="" ng-if="!currentClient.info.is_block" ng-click="lockClient(currentClient)">Заблокировать</a>
<a class="dropdown-item" href="" ng-if="currentClient.info.is_block" ng-click="unlockClient(currentClient)">Разблокировать</a>
<a class="dropdown-item" data-toggle="modal"
data-target="#client-confirm-delete">Удалить</a>
</div>
</div>
</div>
</div>
<div class="p-y text-center text-sm-center col-sm-12">
<a href="" class="inline p-x text-center">
<span class="h5 block m-0">{{currentClient.info.order_sum | curr}} BYN</span>
@@ -143,22 +157,21 @@
</div>
</div>
</div>
</div>
<div class="dker p-x">
<div class="row">
<div class="col-lg-12 col-sm-9">
<div class="p-y-md clearfix nav-active-primary">
<ul class="nav nav-pills nav-sm">
<ul class="nav nav-pills nav-sm" id="client_tab">
<li class="nav-item">
<a class="nav-link active" href="" data-toggle="tab" data-target="#tab_1"
<a class="nav-link active" id="actions_tab" href="" data-toggle="tab" data-target="#actions"
aria-expanded="true">Журнал действий</a>
</li>
<li class="nav-item">
<a class="nav-link" href="" data-toggle="tab" data-target="#tab_2"
<a class="nav-link" id="orders_tab" href="" data-toggle="tab" data-target="#orders"
aria-expanded="false" ng-click="getOrders(currentClient.id)">Заказы</a>
</li>
<li class="nav-item">
<a class="nav-link" href="" data-toggle="tab" data-target="#tab_3"
<a class="nav-link" id="info_tab" href="" data-toggle="tab" data-target="#info"
aria-expanded="false">Информация</a>
</li>
</ul>
@@ -170,19 +183,14 @@
<div class="row">
<div class="col-sm-8 col-lg-12">
<div class="tab-content">
<div class="tab-pane p-v-sm active" id="tab_1" aria-expanded="true">
<div class="tab-pane p-v-sm active" id="actions" aria-expanded="true">
<div class="streamline b-l m-b m-l"
style="width:auto;max-height:350px;overflow-y: auto;"
ng-if="clientLogs.length > 0">
<div class="sl-item b-success" ng-repeat="clientLog in clientLogs">
<div class="sl-content" ng-if="clientLog.type == 2">
<div class="sl-content">
<div class="sl-date text-muted">{{clientLog.time}}</div>
<p>{{clientLog.action}} на сумму {{clientLog.value | curr}} BYN
пользователем {{clientLog.who}}</p>
</div>
<div class="sl-content" ng-if="clientLog.type == 1">
<div class="sl-date text-muted">{{clientLog.time}}</div>
<p>{{clientLog.action}} в количестве {{clientLog.value}} шт</p>
<p>{{clientLog.action}}</p>
</div>
</div>
</div>
@@ -195,7 +203,7 @@
</div>
</div>
</div>
<div class="tab-pane p-v-sm" id="tab_2" aria-expanded="true">
<div class="tab-pane p-v-sm" id="orders" aria-expanded="true">
<div class="streamline b-l m-b m-l"
style="width:auto;max-height:350px;overflow-y: auto;"
ng-if="orders.length > 0">
@@ -231,7 +239,7 @@
</div>
</div>
</div>
<div class="tab-pane p-v-sm" id="tab_3">
<div class="tab-pane p-v-sm" id="info">
<div class="row m-b">
<div class="col-xs-10">
<small class="text-muted">Телефон:</small>
@@ -418,6 +426,14 @@
ng-model="newClient.special_price">
</div>
</div>
<div class="form-group form-group-inline row">
<label class="col-sm-3 form-group-label" for="employeeCheck">Сотрудник</label>
<div class="col-sm-9">
<input class="form-group-input" type="checkbox" value="" id="employeeCheck"
ng-model="newClient.employee">
</div>
</div>
</div>
<div class="dker p-a">
@@ -466,7 +482,7 @@
<div class="confirm-box-footer">
<button type="button" class="btn dark-white p-x-md" data-dismiss="modal">Нет</button>
<button type="button" class="btn danger p-x-md" ng-click="removeClient()">Да</button>
<button type="button" class="btn danger p-x-md" ng-click="removeClient(currentClient)">Да</button>
</div>
</div>
</div>

View File

@@ -16,13 +16,30 @@
<div class="padding">
<div class="margin">
<h5 class="m-b-0 _300">{{update_time}}
<i title="Данные о текущей смене скоро обновятся. Обновите страницу через несколько минут" class="fa fa-spinner fa-spin text-success" ng-if="need_update"></i>
<div class="row">
<div class="col-sm-9">
<h5 id="currentTime" class="m-b-0 _300">{{ currentDate | date:'dd.MM.yyyy HH:mm:ss' }}
</h5>
<small class="text-muted">Данные по филиалу
<strong>{{globals.currentUser.organization.name}}</strong>
</small>
</div>
<div class="col-sm-3">
<label class="md-switch">
<input id="timerCheckbox" type="checkbox" ng-model="timerEnabled" ng-change="toggleTimer()">
<i class="blue"></i>
<span ng-show="timerEnabled">
Автоматическое обновление через: {{ timeRemaining | date:'mm:ss' }}
</span>
<span ng-show="!timerEnabled">
Обновление данных отключено!
</span>
</label>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12 col-md-3">
@@ -113,7 +130,7 @@
<div class="box-tool box-tool-white">
<ul class="nav">
<li class="nav-item">
<a ng-click="getMore('delete')">
<a ng-click="getMoreDeleted()">
<i class="fa fa-eye"></i>
</a>
</li>
@@ -171,7 +188,7 @@
<div class="box-tool box-tool-white">
<ul class="nav">
<li class="nav-item">
<a ng-click="getMore('guests')">
<a ng-click="getMoreGuests()">
<i class="fa fa-eye"></i>
</a>
</li>
@@ -402,7 +419,7 @@
</div>
<div class="row">
<div class="col-md-12 col-xl-8" style="max-height: 620px; overflow-y: hidden;">
<div class="col-md-12 col-xl-8" style="max-height: 620px; "><!--overflow-y: hidden;-->
<div class="box">
<div class="box-header">
<h3>Топ продаваемых товаров</h3>
@@ -548,13 +565,13 @@
<div ui-include="'../views/dashboard/add.html'"></div>
</div>
<div class="modal fade" id="get-more-delete">
<div ui-include="'../views/dashboard/items/more-delete.html'"></div>
<div class="modal fade" id="get-more-deleted">
<div ui-include="'../views/dashboard/items/more-deleted.html'"></div>
</div>
<div class="modal my-modal fade" id="get-more-newyear">
<!--<div class="modal my-modal fade" id="get-more-newyear">
<div ui-include="'../views/dashboard/items/more-newyear.html'"></div>
</div>
</div>-->
<div class="modal fade" id="get-more-guests">
<div ui-include="'../views/dashboard/items/more-guests.html'"></div>
@@ -592,8 +609,8 @@
<div ui-include="'../views/dashboard/items/items-staff.html'"></div>
</div>
<div class="modal fade" id="items-delete">
<div ui-include="'../views/dashboard/items/items-delete.html'"></div>
<div class="modal fade" id="items-deleted">
<div ui-include="'../views/dashboard/items/items-deleted.html'"></div>
</div>
<div class="modal fade" id="preload-modal" data-backdrop="true">

View File

@@ -1,7 +1,7 @@
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-toggle="modal" data-target="#items-delete" ng-click="returnModal('delete')">
<button type="button" class="close" data-toggle="modal" data-target="#items-deleted" ng-click="returnModal('deleted')">
<i class="material-icons md-24">arrow_back</i>
</button>
<h5 class="modal-title">Подробнее об удалениях в заказе № {{ order.code }}</h5>

View File

@@ -17,7 +17,7 @@
</thead>
<tbody>
<tr ng-repeat="deleted_order in moreData.deleted_orders" ng-click="getItems('delete', deleted_order)">
<tr ng-repeat="deleted_order in moreData.deleted_orders" ng-click="getItemsDeleted(deleted_order)">
<td class="text-right">{{ deleted_order.number }}</td>
<td class="text-right">{{ deleted_order.opened }}</td>
<td class="text-right">{{ getClosedDate(deleted_order.closed) }}</td>
@@ -37,3 +37,4 @@
</div>
</div>
</div>
</div>

View File

@@ -27,8 +27,8 @@
<thead>
<tr>
<th>Всего: {{ discounts }} {{ GetCountTotalOrders(discounts) }}</th>
<th class="text-right">на сумму {{ moreData.amount | curr }}</th>
<th class="text-right">со скидой в: {{discounts_sum | curr }}</th>
<th class="text-right">на сумму: {{ moreData.amount | curr }}</th>
<th class="text-right">со скидкой: {{discounts_sum | curr }}</th>
<th class="text-right">Итого: {{ moreData.total_sum | curr }} BYN</th>
</tr>
</thead>
@@ -41,3 +41,4 @@
</div>
</div>
</div>

View File

@@ -15,12 +15,13 @@
</tr>
</thead>
<tbody>
<tr ng-click="getItems('guests', client)">
<td class="text-right" style="width: 20%;">Заказ № {{ client.number }}</td>
<td class="text-right" style="width: 30%;">Открыт {{ client.opened }}</td>
<td class="text-right" style="width: 30%;">{{ client.closed }}</td>
<td class="text-right" style="width: 20%;">{{ client.sum | curr }} BYN</td>
<tbody ng-repeat="order in client.orders">
<tr ng-click="getItems('guests', order)">
<td class="text-right" style="width: 20%;">Заказ № {{ order.number }}</td>
<td class="text-right" style="width: 30%;">Открыт {{ order.opened }}</td>
<td ng-if="order.closed" class="text-right" style="width: 30%;">Закрыт {{ order.closed }}</td>
<td ng-if="!order.closed" class="text-right" style="width: 30%;">Не закрыт</td>
<td class="text-right" style="width: 20%;">{{ order.sum | curr }} BYN</td>
</tr>
</tbody>
</table>
@@ -32,3 +33,4 @@
</div>
</div>
</div>
</div>

View File

@@ -24,7 +24,7 @@
</div>
</div>
<div ng-if="client_name && client_address" class="form-group row">
<div ng-if="client_name" class="form-group row">
<div class="col-sm-6">
<input placeholder="Имя" ng-model="client_name" class="form-control" value="client_name" disabled></input>
<p>

View File

@@ -12,6 +12,7 @@
<option value="deleted">По удалениям</option>
<option value="pay">По отделам и видам оплат</option>
<option value="staff">По персоналу</option>
<option value="discounts">По скидкам</option>
<option value="out">По внешним заказам</option>
</optgroup>
</select>
@@ -130,6 +131,10 @@
<div ui-include="'../views/reports/items/deleted.html'"></div>
</div>
<div class="modal fade" id="report-discounts" data-backdrop="true">
<div ui-include="'../views/reports/items/discounts.html'"></div>
</div>
<div class="modal fade" id="report-realisation" data-backdrop="true">
<div ui-include="'../views/reports/items/realisation.html'"></div>
</div>
@@ -154,6 +159,14 @@
<div ui-include="'../views/shifts/preload.html'"></div>
</div>
<div class="modal fade" id="report-order-info" data-backdrop="true">
<div ui-include="'../views/reports/items/order-info.html'"></div>
</div>
<div class="modal fade" id="report-orders-list" data-backdrop="true">
<div ui-include="'../views/reports/items/orders-list.html'"></div>
</div>
<script type="text/javascript" src="/libs/js/moment/locale/ru.js"></script>
<script type="text/javascript">

View File

@@ -10,40 +10,69 @@
<span class="text-muted">{{start_date}} - {{end_date}}</span>
</div>
<div class="modal-body p-lg">
<div class="table-responsive" ng-if="report_delete.length > 0">
<table class="table table-bordered" ng-repeat="report in report_delete">
<div ng-if="report_delete.length > 0">
<div class="m-b" id="shiftsAccordion">
<div class="panel box" ng-repeat="reportShift in report_delete">
<div class="box-header">
<span class="pull-right label text-sm">Удалено: {{reportShift.totalCount}} позиций. На сумму {{reportShift.totalSum | curr}} BYN</span>
<a data-toggle="collapse" data-parent="#accordion" data-target="#c_{{reportShift.shift_id}}"
class="collapsed" aria-expanded="false">
<h2>Смена №{{reportShift.shift_id}}</h2>
</a>
</div>
<div class="m-b" id="ordersAccordion">
<div id="c_{{reportShift.shift_id}}" class="panel box collapse" aria-expanded="false">
<div ng-repeat="reportOrder in reportShift.orders">
<div id="c_{{reportShift.shift_id}}_{{reportOrder.order_id}}" class="box-header">
<span class="pull-right label text-sm">Удалено: {{reportOrder.totalCount}} позиций. На сумму {{reportOrder.totalSum | curr}} BYN</span>
<a data-toggle="collapse" data-parent="#ordersAccordion"
data-target="#co_{{reportShift.shift_id}}_{{reportOrder.order_id}}"
class="collapsed" aria-expanded="false">
<h2>Заказ №{{reportOrder.order_id}}</h2>
</a>
</div>
<div id="co_{{reportShift.shift_id}}_{{reportOrder.order_id}}" class="collapse" aria-expanded="false">
<div class="box-body">
<div class="table-responsive-xl">
<table class="table table-bordered m-0">
<thead>
<th>Смена#{{ report.shift_id }} Заказ #{{ report.order_code }}</th>
<tr>
<th>Имя</th>
<th>Время/Причина</th>
<th>Товар/цена</th>
<th>Кол-во</th>
<th>Итог</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in report.items">
<tr ng-repeat="item in reportOrder.items">
<td>{{ item.who }}</td>
<td>
<h6>{{ item.dish_name }}
<small>
<p>Время удаления: <strong>{{item.time}}</strong></p>
<p>Цена товара: <strong>{{item.price}} BYN</strong></p>
<p>Количество: <strong>{{item.count}} шт</strong></p>
<p>На сумму: <strong>{{item.sum}} BYN</strong></p>
</small>
</h6>
<p>
Удалил:
<strong>{{ item.who }}</strong>
<br/> Подтвердил:
<strong>{{ item.approved }}</strong>
<br/> Причина:
<strong>{{ item.reason }}</strong>
</p>
<ul class="list-unstyled">
<li>{{ item.time }}</li>
<li><small>{{ item.reason }}</small></li>
</ul>
</td>
<td>
<ul class="list-unstyled">
<li>{{ item.dish }}</li>
<li><small>{{ item.price | curr }} BYN</small></li>
</ul>
</td>
<td>{{ item.count }}</td>
<td>{{ item.total | curr}} BYN</td>
</tr>
</tbody>
<hr>
</table>
<hr>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<table class="table table-bordered">
<tbody>
<tr>
@@ -51,15 +80,14 @@
<strong>Итого</strong>
</td>
<td style="text-align: right">
<strong>{{ report_delete.total_count }}</strong> удалений</td>
<strong>{{ totalCount }}</strong> удалений
</td>
<td style="text-align: right">на сумму
<strong>{{ report_delete.total_sum | curr }} BYN</strong>
<strong>{{ totalSum | curr }} BYN</strong>
</td>
</tr>
</tbody>
</table>
</div>
<div ng-if="report_delete.length == 0">
<p>Удаления отсутствуют</p>
</div>

View File

@@ -0,0 +1,49 @@
<div class="modal-dialog modal-lg">
<div class="modal-content" id="report-discounts">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">&times;</button>
<button class="btn btn-icon white" ng-click="printElem('#report-discounts')">
<i class="fa fa-print"></i>
</button>
<h4 class="modal-title">{{globals.currentUser.organization.name}}</h4>
<h5 class="modal-title">Отчет по скидкам</h5>
<span class="text-muted">{{start_date}} - {{end_date}}</span>
</div>
<div class="modal-body p-lg">
<div class="table-responsive" ng-if="orders_count > 0">
<div class="table-responsive">
<p>Количество заказов со скидками: <strong>{{orders_count}}</strong><br>
Сумма заказов без скидок: <strong>{{orders_full_sum.toDivide()}} BYN</strong><br>
Сумма заказов со скидками: <strong>{{orders_order_sum.toDivide()}} BYN</strong><br>
Сумма скидок: <strong>{{orders_sale_sum.toDivide()}} BYN</strong>
</p>
<table class="table table-striped table-hover white b-a" ng-repeat="(discount_value, orders) in orders_info">
<thead>
<th>Скидка {{discount_value}}%</th>
</thead>
<thead>
<tr>
<th>Количество</th>
<th>Сумма заказов без скидки</th>
<th>Сумма заказов со скидкой</th>
<th>Сумма скидок</th>
</tr>
</thead>
<tbody>
<tr ng-click="getOrders(discount_value, 'report-discounts', 'report-orders-list')" data-toggle="tooltip" data-placement="bottom" title="Нажмите для просмотра списка заказов">
<td>{{orders.info.orders_count}}</td>
<td>{{orders.info.full_sum.toDivide()}} BYN</td>
<td>{{orders.info.order_sum.toDivide()}} BYN</td>
<td>{{orders.info.sale_sum.toDivide()}} BYN</td>
</tr>
</tbody>
</table>
</div>
</div>
<div ng-if="orders_count == 0">
<p>Заказы со скидками отсутствуют</p>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,78 @@
<div class="modal-dialog modal-lg">
<div class="modal-content" id="report-order-info">
<div class="modal-header">
<button type="button" class="close" ng-click="prevModal('report-order-info', 'report-orders-list')">
<i class="material-icons md-24">arrow_back</i>
</button>
<p>
Номер заказа: <strong>#{{order_info.order_id}}</strong><br>
Время закрытия: <strong>{{order_info.closed}}</strong><br>
Персонал: <strong>{{order_info.who_close}}</strong><br>
Статус заказа: <span class="label success">{{order_info.order_status}}</span><br>
</p>
</div>
<div class="modal-body p-lg">
<div class="table-responsive">
<table class="table table-striped white b-a">
<thead>
<tr>
<th>ID</th>
<th>Блюдо</th>
<th style="width: 80px">Кол-во</th>
<th style="width: 140px">Стоимость</th>
<th style="width: 180px">Итог</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in order_info.items">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.count * item.cof}}</td>
<td>{{item.price | curr}} BYN</td>
<td>{{item.amount | curr}} BYN <p ng-if="item.discount > 0">
<span>(Скидка: {{item.discount}}%)</span></p></td>
</tr>
<tr>
<td colspan="4" class="text-right"><strong>Итого</strong></td>
<td>{{order_info.amount | curr}} BYN</td>
</tr>
<tr>
<td colspan="4" class="text-right no-border"
ng-if="order_info.full_price - order_info.amount > 0">
<strong>Сумма скидки</strong></td>
<td ng-if="order_info.full_price - order_info.amount > 0">{{order_info.full_price -
order_info.amount | curr}} BYN
</td>
</tr>
<tr>
<td colspan="4" class="text-right no-border"><strong>Оплачено:</strong></td>
</tr>
<tr ng-if="order_info.cash > 0">
<td colspan="5" class="text-right no-border">Наличные: <strong>{{order_info.cash
| curr}} BYN</strong></td>
</tr>
<tr ng-if="order_info.credit > 0">
<td colspan="5" class="text-right no-border">Кред. карта: <strong>{{order_info.credit | curr}}
BYN</strong></td>
</tr>
<tr ng-if="order_info.clearing > 0">
<td colspan="5" class="text-right no-border">Питание штата: <strong>{{order_info.clearing |
curr}}
BYN</strong>
</tr>
<tr ng-if="order_info.presale > 0">
<td colspan="5" class="text-right no-border">Зачтен аванс: <strong>{{order_info.presale | curr}}
BYN</strong></td>
</tr>
<tr ng-if="order_info.self > 0">
<td colspan="5" class="text-right no-border">Безнал: <strong>{{order_info.self | curr}}
BYN</strong>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,44 @@
<div class="modal-dialog modal-lg">
<div class="modal-content" id="report-orders-list">
<div class="modal-header">
<button type="button" class="close" ng-click="prevModal('report-orders-list', 'report-discounts')">
<i class="material-icons md-24">arrow_back</i>
</button>
<h5 class="modal-title">Список заказов со скидкой {{discount_id}}%:</h5>
</div>
<div class="modal-body p-lg">
<div class="table-responsive" ng-if="orders_count > 0">
<div class="table-responsive">
<table class="table table-striped table-hover white b-a">
<thead>
<tr>
<th>Смена №</th>
<th>Заказ №</th>
<th>Сумма без скидки</th>
<th>Сумма со скидкой</th>
<th>Сумма скидки</th>
<th>Открыт</th>
<th>Закрыт</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="order in orders_list" ng-click="getItems(order.code, order.opened, order.closed, 'report-orders-list', 'report-order-info')" data-toggle="tooltip" data-placement="bottom" title="Нажмите для просмотра информации о заказе">
<td>{{order.shift_id}}</td>
<td>{{order.code}}</td>
<td>{{order.full_sum | curr}} BYN</td>
<td>{{order.order_sum | curr}} BYN</td>
<td>{{order.sale_sum | curr}} BYN</td>
<td>{{order.opened}}</td>
<td>{{order.closed}}</td>
</tr>
</tbody>
</table>
</div>
</div>
<div ng-if="orders_count == 0">
<p>Заказы со скидками отсутствуют</p>
</div>
</div>
</div>
</div>

View File

@@ -1,7 +1,7 @@
<div class="modal-dialog modal-lg">
<div class="modal-content" id="reportRealisation">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">&times;</button>
<button type="button" class="close" data-dismiss="modal" ng-click="closeModal('reportRealisation')">&times;</button>
<button class="btn btn-icon white" ng-click="printElem('#reportRealisation')">
<i class="fa fa-print"></i>
</button>
@@ -9,9 +9,9 @@
<h5 class="modal-title">Отчет по реализации</h5>
<span class="text-muted">{{start_date}} - {{end_date}}</span>
</div>
<div class="modal-body p-lg">
<div id="tableRealisation" class="modal-body p-lg">
<div class="table-responsive" ng-if="report_realisation.length > 0">
<table class="table table-bordered" ng-repeat="printer in report_realisation">
<table class="table table-bordered table-striped datatable" ui-jq="dataTable" ui-options="dataTableOpt" ng-repeat="printer in report_realisation">
<thead>
<th style="width: 70%">{{ printer.name }}</th>
<th style="width: 10%; text-align: right">{{ printer.count }}</th>
@@ -26,9 +26,7 @@
</tr>
</tbody>
</table>
<div ng-if="return_printers.length > 0">
<hr>
<table class="table table-bordered" ng-repeat="ret_print in return_printers">
<thead>
<th style="width: 70%">{{ ret_print.name }} (возврат)</th>
@@ -46,8 +44,6 @@
</table>
</div>
<hr>
<table class="table table-bordered">
<tbody>
<tr>

View File

@@ -13,6 +13,19 @@
<div class="table-responsive">
<table class="table table-bordered">
<tbody>
<tr>
<td colspan="2">
<strong>Операции внесения/изъятия</strong>
</td>
</tr>
<tr>
<td>Внесено наличными</td>
<td style="text-align: right">{{ fiscal.income_sum | curr }} BYN</td>
</tr>
<tr>
<td>Выплачено наличными</td>
<td style="text-align: right">{{ fiscal.outcome_sum | curr }} BYN</td>
</tr>
<tr>
<td colspan="2">
<strong>Реализация</strong>
@@ -20,28 +33,20 @@
</tr>
<tr>
<td>Количество заказов</td>
<td style="text-align: right">{{ statistic.orders_count }}</td>
<td style="text-align: right">{{ realisation.orders_count }}</td>
</tr>
<tr>
<td>Сумма заказов (без скидки) <strong>BYN</strong></td>
<td style="text-align: right">{{ statistic.total_sum | curr}}</td>
<td>Сумма заказов (без скидки)</td>
<td style="text-align: right">{{ realisation.orders_sum_without_sales | curr}} BYN</td>
</tr>
<tr>
<td>Скидка <strong>BYN</strong></td>
<td style="text-align: right">{{ statistic.discount_sum | curr}}</td>
<td>Скидка</td>
<td style="text-align: right">{{ realisation.sale_sum | curr}} BYN</td>
</tr>
<tr>
<td>Итоговоя сумма <strong>BYN</strong></td>
<td style="text-align: right">{{ statistic.orders_sum | curr}}</td>
</tr>
<tr>
<td>Отложенных заказы</td>
<td style="text-align: right">{{ statistic.wait_count }}</td>
</tr>
<tr>
<td>Отложено на сумму <strong>BYN</strong></td>
<td style="text-align: right">{{ statistic.wait_sum | curr}}</td>
<td>Итоговоя сумма</td>
<td style="text-align: right">{{ realisation.orders_sum_with_sales | curr}} BYN</td>
</tr>
<tr>
@@ -51,11 +56,25 @@
</tr>
<tr>
<td>Количество возвратов</td>
<td style="text-align: right">{{ statistic.return_count }}</td>
<td style="text-align: right">{{ returns.returned_orders_count }}</td>
</tr>
<tr>
<td>Сумма возвратов <strong>BYN</strong></td>
<td style="text-align: right">{{ statistic.return_sum | curr }}</td>
<td>Сумма возвратов</td>
<td style="text-align: right">{{ returns.returned_items_sum | curr }} BYN</td>
</tr>
<tr>
<td colspan="2">
<strong>Аннулирования</strong>
</td>
</tr>
<tr>
<td>Количество аннулирований</td>
<td style="text-align: right">{{ cancellations.cancellations_count }}</td>
</tr>
<tr>
<td>Сумма аннулирований</td>
<td style="text-align: right">{{ cancellations.cancellations_sum | curr }} BYN</td>
</tr>
<tr>
@@ -68,12 +87,12 @@
<td style="text-align: right">{{ statistic.clients_count }}</td>
</tr>
<tr>
<td>Средний чек <strong>BYN</strong></td>
<td style="text-align: right">{{ statistic.avg_order_sum | curr}}</td>
<td>Средний чек</td>
<td style="text-align: right">{{ statistic.clients_average_sum | curr}} BYN</td>
</tr>
<tr>
<td>Средний чек на 1-го гостя <strong>BYN</strong></td>
<td style="text-align: right">{{ statistic.avg_order_client_sum | curr}}</td>
<td>Средний чек на 1-го гостя</td>
<td style="text-align: right">{{ statistic.clients_average_sum_one | curr}} BYN</td>
</tr>
<tr>
@@ -83,19 +102,39 @@
</tr>
<tr>
<td>Количество авансов полученных</td>
<td style="text-align: right">{{ statistic.in_presale_count }}</td>
<td style="text-align: right">{{ presales.presales_income_count }}</td>
</tr>
<tr>
<td>Сумма авансов полученных <strong>BYN</strong></td>
<td style="text-align: right">{{ statistic.in_presale_sum | curr}}</td>
<tr ng-if="presales.presales_income_cash_sum > 0">
<td>Сумма авансов полученных наличными</td>
<td style="text-align: right">{{ presales.presales_income_cash_sum | curr}} BYN</td>
</tr>
<tr ng-if="presales.presales_income_credit_sum > 0">
<td>Сумма авансов полученных кредитной картой</td>
<td style="text-align: right">{{ presales.presales_income_credit_sum | curr}} BYN</td>
</tr>
<tr ng-if="presales.presales_income_clearing_sum > 0">
<td>Сумма авансов полученных безналичным расчетом</td>
<td style="text-align: right">{{ presales.presales_income_clearing_sum | curr}} BYN</td>
</tr>
<tr ng-if="presales.presales_income_discount_sum > 0">
<td>Сумма авансов полученных через скидку</td>
<td style="text-align: right">{{ presales.presales_income_discount_sum | curr}} BYN</td>
</tr>
<tr>
<td>Количество авансов возвращенных</td>
<td style="text-align: right">{{ statistic.out_presale_count }}</td>
<td style="text-align: right">{{ presales.presales_outcome_count }}</td>
</tr>
<tr>
<td>Сумма авансов возвращенных <strong>BYN</strong></td>
<td style="text-align: right">{{ statistic.out_presale_sum | curr}}</td>
<tr ng-if="presales.presales_outcome_cash_sum > 0">
<td>Сумма авансов возвращенных наличными</td>
<td style="text-align: right">{{ presales.presales_outcome_cash_sum | curr}} BYN</td>
</tr>
<tr ng-if="presales.presales_outcome_credit_sum > 0">
<td>Сумма авансов возвращенных на кредитную карту</td>
<td style="text-align: right">{{ presales.presales_outcome_credit_sum | curr}} BYN</td>
</tr>
<tr ng-if="presales.presales_outcome_clearing_sum > 0">
<td>Сумма авансов возвращенных безналичным расчетом</td>
<td style="text-align: right">{{ presales.presales_outcome_clearing_sum | curr}} BYN</td>
</tr>
<tr>
@@ -104,28 +143,40 @@
</td>
</tr>
<tr>
<td>Наличный расчет <strong>BYN</strong></td>
<td style="text-align: right">{{ statistic.cash | curr}}</td>
<td>Наличный расчет</td>
<td style="text-align: right">{{ payments.pay_cash | curr}} BYN</td>
</tr>
<tr>
<td>Наличный расчет (отложенные) <strong>BYN</strong></td>
<td style="text-align: right">{{ statistic.wait_sum | curr}}</td>
<td>Кредитными картами</td>
<td style="text-align: right">{{ payments.pay_credit | curr}} BYN</td>
</tr>
<tr>
<td>Безналичный расчет <strong>BYN</strong></td>
<td style="text-align: right">{{ statistic.clearing | curr}}</td>
<td>Безналичный расчет</td>
<td style="text-align: right">{{ payments.pay_clearing | curr}} BYN</td>
</tr>
<tr>
<td>Кредитными картами <strong>BYN</strong></td>
<td style="text-align: right">{{ statistic.credit | curr}}</td>
<td>Питание штата</td>
<td style="text-align: right">{{ payments.pay_self | curr}} BYN</td>
</tr>
<tr>
<td>Питание штата <strong>BYN</strong></td>
<td style="text-align: right">{{ statistic.self | curr}}</td>
<td>По ранее полученному авансу</td>
<td style="text-align: right">{{ payments.pay_presale | curr}} BYN</td>
</tr>
<tr>
<td>По ранее полученному авансу <strong>BYN</strong></td>
<td style="text-align: right">{{ statistic.presale | curr}}</td>
<td>Онлайн</td>
<td style="text-align: right">{{ payments.pay_online | curr}} BYN</td>
</tr>
<tr>
<td>Иные способы оплаты</td>
<td style="text-align: right">{{ payments.pay_another | curr}} BYN</td>
</tr>
<tr ng-if="pay_delivery > 0">
<td>Доставка</td>
<td style="text-align: right">{{ payments.pay_delivery | curr}} BYN</td>
</tr>
<tr ng-if="pay_echeck > 0">
<td>Электронный чек</td>
<td style="text-align: right">{{ payments.pay_echeck | curr}} BYN</td>
</tr>
</tbody>

View File

@@ -57,6 +57,7 @@
<a class="dropdown-item" ng-click="reportDelete(shift)">По удалениям</a>
<a class="dropdown-item" ng-click="reportStaff(shift)">По персоналу</a>
<a class="dropdown-item" ng-click="reportPay(shift)">По отделам</a>
<a class="dropdown-item" ng-click="reportDiscounts(shift)">По скидкам</a>
<!-- <a class="dropdown-item" ng-click="reportOrders(shift)">По заказам</a> -->
<a class="dropdown-item" ng-click="reportMerged(shift)">По объединениям</a>
<a class="dropdown-item" ng-click="reportSliced(shift)">По разбиениям</a>
@@ -95,8 +96,8 @@
</div>
</div>
<div class="modal fade" id="report-delete" data-backdrop="true">
<div ui-include="'../views/reports/items/deleted.html'"></div>
<div class="modal fade" id="shift-delete" data-backdrop="true">
<div ui-include="'../views/shifts/items/deleted.html'"></div>
</div>
<div class="modal fade" id="report-realisation" data-backdrop="true">
@@ -138,3 +139,15 @@
<div class="modal fade" id="preload-modal" data-backdrop="true">
<div ui-include="'../views/shifts/preload.html'"></div>
</div>
<div class="modal fade" id="report-discounts" data-backdrop="true">
<div ui-include="'../views/reports/items/discounts.html'"></div>
</div>
<div class="modal fade" id="report-order-info" data-backdrop="true">
<div ui-include="'../views/reports/items/order-info.html'"></div>
</div>
<div class="modal fade" id="report-orders-list" data-backdrop="true">
<div ui-include="'../views/reports/items/orders-list.html'"></div>
</div>

View File

@@ -0,0 +1,83 @@
<div class="modal-dialog modal-lg">
<div class="modal-content" id="reportDeleted">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">&times;</button>
<button class="btn btn-icon white" ng-click="printElem('#reportDeleted')">
<i class="fa fa-print"></i>
</button>
<h4 class="modal-title">{{globals.currentUser.organization.name}}</h4>
<h5 class="modal-title">Отчет по удалениям</h5>
<span class="text-muted">{{start_date}} - {{end_date}}</span>
</div>
<div class="modal-body p-lg">
<div ng-if="report_delete.length > 0">
<div class="m-b" id="accordion">
<div class="panel box" ng-repeat="report in report_delete">
<div class="box-header">
<span class="pull-right label text-sm">Удалено: {{report.orderTotalCount}} позиций. На сумму {{report.orderTotalSum | curr}} BYN</span>
<a data-toggle="collapse" data-parent="#accordion" data-target="#c_{{report.order_id}}"
class="collapsed" aria-expanded="false">
<h2>Заказ №{{report.order_id}}</h2>
</a>
</div>
<div id="c_{{report.order_id}}" class="collapse" aria-expanded="false">
<div class="box-body">
<div class="table-responsive-xl">
<table class="table table-bordered m-0">
<thead>
<tr>
<th>Имя</th>
<th>Время/Причина</th>
<th>Товар/цена</th>
<th>Кол-во</th>
<th>Итог</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in report.items">
<td>{{ item.who }}</td>
<td>
<ul class="list-unstyled">
<li>{{ item.time }}</li>
<li><small>{{ item.reason }}</small></li>
</ul>
</td>
<td>
<ul class="list-unstyled">
<li>{{ item.dish }}</li>
<li><small>{{ item.price | curr }} BYN</small></li>
</ul>
</td>
<td>{{ item.count }}</td>
<td>{{ item.total | curr}} BYN</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
<table class="table table-bordered">
<tbody>
<tr>
<td>
<strong>Итого</strong>
</td>
<td style="text-align: right">
<strong>{{ total_count }}</strong> удалений
</td>
<td style="text-align: right">на сумму
<strong>{{ total_sum | curr }} BYN</strong>
</td>
</tr>
</tbody>
</table>
<div ng-if="report_delete.length == 0">
<p>Удаления отсутствуют</p>
</div>
</div>
</div>
</div>

237
web/views/staff/index.html Normal file
View File

@@ -0,0 +1,237 @@
<div class="app-body-inner">
<div class="row-col row-col-xs b-b">
<div class="col-sm-3 col-md-2 light bg b-r">
<div class="row-col">
<div class="p-a-xs b-b">
<div class="input-group">
<span class="input-group-addon no-border no-bg">
<i class="fa fa-search"></i>
</span>
<input type="text" class="form-control no-border no-bg" placeholder="Поиск персонала..." ng-keyup="personalSearch()" ng-model="search.query">
<span class="input-group-addon no-border no-bg search-clear" ng-click="search.query = ''">
<i class="fa fa-times"></i>
</span>
</div>
</div>
<div class="row-row">
<div class="row-body scrollable hover">
<div class="row-inner">
<div class="list inset">
<div class="list-item pointer no_selection" ng-if="parentGroup > 0 && search.query.length === 0" ios-dblclick="upFolder()">
<div class="list-left">
<span class="w-30">
<i class="material-icons" style="font-size: 30px;">&#xE2C7;</i>
</span>
</div>
<div class="list-body" style="line-height: 30px">
...
</div>
</div>
<div class="list-item pointer no_selection" ng-repeat="group in groups" sglclick="showGroup(group)" ng-class="group.id == currentGroupObject.id ? 'active' : ''"
ios-dblclick="openGroup(group)" ng-if="parentGroup == 0 && search.query.length === 0">
<div class="list-left">
<span class="w-30">
<i class="material-icons" style="font-size: 30px;">&#xE2C7;</i>
</span>
</div>
<div class="list-body" style="line-height: 30px">
{{ group.name }}
</div>
</div>
<div class="list-item pointer no_selection" ng-repeat="personal in personals" ng-click="showPersonal(personal)" ng-class="personal.id == currentPersonalObject.id ? 'active' : ''"
ng-if="parentGroup > 0 || search.query.length > 0">
<div class="list-left">
<span class="w-30">
<i class="material-icons" style="font-size: 30px;">&#xE893;</i>
</span>
</div>
<div class="list-body" style="line-height: 30px">
{{ personal.name }}
</div>
</div>
</div>
</div>
</div>
</div>
<div class="p-a b-t text-center">
<a class="btn btn-md btn-outline rounded b-info text-info" ng-click="addGroup()" ng-if="parentGroup == 0 && search.query.length === 0">
<i class="fa fa-plus fa-fw m-r-xs"></i>Группа
</a>
<a class="btn btn-md btn-outline rounded b-info text-info" ng-click="addPersonal()" ng-if="parentGroup > 0 && search.query.length === 0">
<i class="fa fa-plus fa-fw m-r-xs"></i>Персонал
</a>
</div>
</div>
</div>
<div class="col-sm-8 col-md-5">
<div class="row-col" ng-class="(currentGroupObject.id == 0)?'hide-object':''">
<div class="p-a-sm">
<div>
<a class="btn btn-sm white pull-right" ng-click="closeCard()">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="row-row">
<div class="row-body">
<div class="row-inner">
<div class="padding">
<div class="form-horizontal">
<div class="form-group row">
<label class="col-sm-3 form-control-label">Название</label>
<div class="col-sm-9">
<input type="text" class="form-control" ng-model="currentGroupObject.name">
</div>
</div>
<hr/>
<div class="form-group row">
<label class="col-sm-3 form-control-label">Режим работы</label>
<div class="col-sm-9">
<select class="form-control" ng-model="currentGroupObject.interface_code" ng-change="setRights()">
<option ng-repeat="interface in interfaces" value="{{ interface.code }}">{{ interface.name }}</option>
</select>
</div>
</div>
<div class="row">
<div class="col-sm-3">
<label class="form-control-label">Шаблоны прав</label>
</div>
<div class="col-sm-9">
<label class="radio-inline ui-check ui-check-md">
<input type="radio" name="sub-interface" ng-change="setRights()" ng-model="currentGroupObject.sub_interface_code" value="1" class="has-value">
<i class="dark-white"></i>Администратор
</label>
<label class="radio-inline ui-check ui-check-md">
<input type="radio" name="sub-interface" ng-change="setRights()" ng-model="currentGroupObject.sub_interface_code" value="2" class="has-value">
<i class="dark-white"></i>Официант
</label>
</div>
</div>
<div class="table-responsive" style="background-color: #fff">
<table class="table table-bordered table-hover">
<thead>
<th>Право</th>
<th>Статус</th>
</thead>
<tbody>
<tr ng-repeat="right in rights">
<td>{{ right.name }}</td>
<td style="width: 90px">
<label class="ui-switch ui-switch-md m-t-xs">
<input type="checkbox" ng-model="right.is_active">
<i></i>
</label>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="footer-form">
<div class="padding" style="float: right; width: 100%; padding: 0.5rem 1.5rem">
<button class="btn danger p-x-md pull-left" data-toggle="modal" data-target="#group-confirm-delete">
<i class="fa fa-trash"></i>
</button>
<button class="btn success p-x-md pull-right" ng-click="saveGroup()" style="margin-right: 15px">Сохранить</button>
</div>
</div>
</div>
<div class="row-col" ng-class="(currentPersonalObject.id == 0)?'hide-object':''">
<div class="p-a-sm">
<div>
<a class="btn btn-sm white pull-right" ng-click="closeCard()">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="row-row">
<div class="row-body">
<div class="row-inner">
<div class="padding">
<div class="form-horizontal">
<div class="form-group row">
<label class="col-sm-3 form-control-label">Имя</label>
<div class="col-sm-9">
<input type="text" class="form-control" ng-model="currentPersonalObject.name">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 form-control-label">Пароль</label>
<div class="col-sm-9">
<input type="text" class="form-control" ng-model="currentPersonalObject.password">
</div>
</div>
<!-- <div class="form-group row">
<label class="col-sm-3 form-control-label">Режим работы</label>
<div class="col-sm-9">
<select class="form-control" ng-model="currentPersonalObject.interface_code">
<option ng-repeat="interface in interfaces" value="{{ interface.code }}">{{ interface.name }}</option>
</select>
</div>
</div> -->
</div>
</div>
</div>
</div>
</div>
<div class="footer-form">
<div class="padding" style="float: right; width: 100%; padding: 0.5rem 1.5rem">
<button class="btn danger p-x-md pull-left" data-toggle="modal" data-target="#personal-confirm-delete">
<i class="fa fa-trash"></i>
</button>
<button class="btn success p-x-md pull-right" ng-click="savePersonal()" style="margin-right: 15px">Сохранить</button>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="personal-confirm-delete" class="modal confirm-box" data-backdrop="true">
<div class="bottom white b-b" style="height: 90px">
<div class="confirm-box-body p-lg">
<p>Вы действительно хотите удалить персонал?</p>
</div>
<div class="confirm-box-footer">
<button type="button" class="btn dark-white p-x-md" data-dismiss="modal">Нет</button>
<button type="button" class="btn danger p-x-md" ng-click="removePersonal()">Да</button>
</div>
</div>
</div>
<div id="group-confirm-delete" class="modal confirm-box" data-backdrop="true">
<div class="bottom white b-b" style="height: 90px">
<div class="confirm-box-body p-lg">
<p>Вы действительно хотите удалить группу?</p>
</div>
<div class="confirm-box-footer">
<button type="button" class="btn dark-white p-x-md" data-dismiss="modal">Нет</button>
<button type="button" class="btn danger p-x-md" ng-click="removeGroup()">Да</button>
</div>
</div>
</div>