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 build.zip
places.xml places.xml
*.log *.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\Dishes;
use App\Component\Models\Folders; use App\Component\Models\Folders;
use App\Component\Models\OrderBot; use App\Component\Models\OrderBotStorage;
use App\Component\Models\Settings; use App\Component\Models\Settings;
use App\Component\Models\Tasks; use App\Component\Models\Tasks;
use App\Console\Commands\HRCCommand; use App\Console\Commands\HRCCommand;
@@ -25,11 +25,11 @@ class GETBot extends HRCCommand implements HRCCommandInterface
Folders::where('is_bot_export', '=', 0) Folders::where('is_bot_export', '=', 0)
->update(['is_bot_export' => 1]); ->update(['is_bot_export' => 1]);
} }
$ordersinfo = Tasks::where('method', 'orderinfo') $orders_info = Tasks::where('method', 'orderinfo')
->get(); ->get();
$delete_params = ['closed', 'deleted']; $delete_params = ['closed', 'deleted'];
foreach ($ordersinfo as $more) { foreach ($orders_info as $more) {
$order = OrderBot::where('id', intval($more['more'])) $order = OrderBotStorage::where('id', intval($more['more']))
->whereIn('status', $delete_params) ->whereIn('status', $delete_params)
->get(); ->get();
foreach ($order as $value) { 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_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_count = $orders_count_exchange + $orders_count_current;
$orders_sum = $orders_sum_exchange + $orders_sum_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( $result = array(
'id' => $client['id'], 'id' => $client['id'],
'name' => $client['name'], 'name' => $client['name'],
@@ -41,6 +57,10 @@ class GETClientInfo extends HRCCommand implements HRCCommandInterface
'order_sum' => round($orders_sum, 2), 'order_sum' => round($orders_sum, 2),
'presale' => $presale, 'presale' => $presale,
'bonus' => intval($bonus), 'bonus' => intval($bonus),
'barcode' => $barcode,
'special_price' => $special_price,
'employee' => $employee,
'is_block' => $is_block,
) )
); );
return [ return [

View File

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

View File

@@ -3,17 +3,9 @@
namespace App\Commands; namespace App\Commands;
use App\Component\Models\Client; 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\ClientsGroup;
use App\Component\Models\ClientsPhone;
use App\Component\Models\ClientsPresale;
use App\Console\Commands\HRCCommand; use App\Console\Commands\HRCCommand;
use App\Console\Commands\HRCCommandInterface; use App\Console\Commands\HRCCommandInterface;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
class GETClients extends HRCCommand implements HRCCommandInterface class GETClients extends HRCCommand implements HRCCommandInterface
{ {
@@ -21,99 +13,6 @@ class GETClients extends HRCCommand implements HRCCommandInterface
public function command($input, $output = null) 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) { if (ClientsGroup::where('code', '0')->count() == 0) {
$group = new ClientsGroup([ $group = new ClientsGroup([
'code' => '0', 'code' => '0',
@@ -145,12 +44,33 @@ class GETClients extends HRCCommand implements HRCCommandInterface
$phone = Client::getPhone($client['user_code']); $phone = Client::getPhone($client['user_code']);
$email = Client::getEmail($client['user_code']); $email = Client::getEmail($client['user_code']);
$address = Client::getAddress($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( $out[] = array(
'id' => $client['id'], 'id' => $client['id'],
'name' => $client['name'], 'name' => $client['name'],
'phone' => $phone, 'phone' => $phone,
'email' => $email, 'email' => $email,
'address' => $address, 'address' => $address,
'barcode' => $barcode,
'special_price' => $special_price,
'employee' => $employee,
'is_block' => $is_block,
); );
} }
return [ 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; namespace App\Commands;
use App\Component\Models\ExchangeShifts; use App\Component\Models\ExchangeShifts;
use App\Component\Models\OrderBot; use App\Component\Models\OrderBotStorage;
use App\Component\Models\Report; use App\Component\Models\Report;
use App\Console\Commands\HRCCommand; use App\Console\Commands\HRCCommand;
use App\Console\Commands\HRCCommandInterface; 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']); $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; $count_items = 0;
if (is_array($orders) || is_object($orders)) { if (is_array($orders) || is_object($orders)) {
foreach ($orders as $order) { foreach ($orders as $order) {
@@ -73,7 +73,7 @@ class GETOutOrders extends HRCCommand implements HRCCommandInterface {
$end_t = strtotime($input['end_date']) - 1; $end_t = strtotime($input['end_date']) - 1;
$start = date('Y-m-d H:i:s', $start_t); $start = date('Y-m-d H:i:s', $start_t);
$end = date('Y-m-d H:i:s', $end_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; $count_items = 0;
if (is_array($orders) || is_object($orders)) { if (is_array($orders) || is_object($orders)) {
foreach ($orders as $order) { foreach ($orders as $order) {

View File

@@ -10,7 +10,7 @@ class GETReports extends HRCCommand implements HRCCommandInterface {
protected $signature = 'getreports'; protected $signature = 'getreports';
public function command($input, $output = null) { 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) { if ($reports) {
foreach ($reports as $key => $report) { foreach ($reports as $key => $report) {
$data[] = array( $data[] = array(

View File

@@ -3,6 +3,8 @@
namespace App\Commands; namespace App\Commands;
use App\Component\Models\Settings; 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\HRCCommand;
use App\Console\Commands\HRCCommandInterface; use App\Console\Commands\HRCCommandInterface;
@@ -12,6 +14,34 @@ class GETSettings extends HRCCommand implements HRCCommandInterface
public function command($input, $output = null) 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'])) { if (isset($input['code'])) {
$setting = Settings::where('code', $input['code']) $setting = Settings::where('code', $input['code'])
->first(); ->first();

View File

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

View File

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

View File

@@ -12,119 +12,295 @@ use App\Console\Commands\HRCCommand;
use App\Console\Commands\HRCCommandInterface; use App\Console\Commands\HRCCommandInterface;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
class POSTClient extends HRCCommand implements HRCCommandInterface { class POSTClient extends HRCCommand implements HRCCommandInterface
protected $signature = 'postclient'; {
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') { if ($input['task'] == 'update') {
$phone = urldecode($input['phone']); log::debug($input);
$client = Client::find($input['id']); if (isset($input['id'])) {
$client->name = urldecode($input['name']); $id = $input['id'];
$client->unloaded = 0; } else if (isset($input['client_guid'])) {
$clientGroup = ClientsGroup::where('id', $input['group_id'])->first(); $fClient = Client::where('user_code', $input['client_guid'])->first();
$client->group_id = urldecode($clientGroup['code']); if (!isset($fClient)) {
$clientPhone = ClientsPhone::where('client_guid', $client->user_code)->first(); return [
if ($clientPhone) { 'status' => 'success',
$clientPhone = ClientsPhone::find($clientPhone['id']); 'error_message' => 'Клиент не найден',
if ($phone !== '' && $phone !== '+375 ( ) - -') { ];
if (substr($phone, 0, 1) == '+') { }
$phoneData = urldecode($input['phone']); $id = $fClient['id'];
} else { } else {
$phoneData = urldecode($input['phone']); return [
$clientPhone->phone = '+375 (' . substr($phoneData, 0, 2) . ') ' . substr($phoneData, 2, 3) . '-' . substr($phoneData, 5, 2) . '-' . substr($phoneData, 7, 2); 'status' => 'success',
} 'error_message' => 'Проверьте введенные данные',
} else { ];
$clientPhone->phone = '+375 ( ) - -'; }
} if (isset($input['group_id']) && !isset($input['group_guid'])) {
$clientPhone->save(); $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', $group_id)->first();
$client->group_id = $clientGroup['code'];
$clientEmail = ClientsEmail::where('client_guid', $client->user_code)->first(); if (isset($input['phone'])) {
if ($clientEmail) { $phone = $input['phone'];
$clientEmail = ClientsEmail::find($clientEmail['id']); Log::debug($phone);
if ($input['email'] !== '') { $clientPhone = ClientsPhone::where('client_guid', $client->user_code)->first();
$clientEmail->email = urldecode($input['email']); Log::debug($clientPhone);
} else { if (isset($clientPhone)) {
$clientEmail->email = ''; $clientPhone = ClientsPhone::find($clientPhone['id']);
} if ($phone !== '' && $phone !== '+375 ( ) - -') {
$clientEmail->save(); 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('UPD Substr true: ' . $phone);
} else {
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();
}
$clientAddress = ClientsAddress::where('client_guid', $client->user_code)->first(); if (isset($input['email'])) {
if ($clientAddress) { $clientEmail = ClientsEmail::where('client_guid', $client->user_code)->first();
$clientAddress = ClientsAddress::find($clientAddress['id']); if ($clientEmail) {
if ($input['address'] !== '') { $clientEmail = ClientsEmail::find($clientEmail['id']);
$clientAddress->address = urldecode($input['address']); if (isset($input['email']) && $input['email'] !== '') {
} else { $clientEmail->email = urldecode($input['email']);
$clientAddress->address = ''; } else {
} $clientEmail->email = '';
$clientAddress->save(); }
} } else {
$clientEmail = new ClientsEmail;
$clientEmail->email = urldecode($input['email']);
}
$clientEmail->client_guid = $client->user_code;
$clientEmail->save();
} else {
$clientEmail = '';
}
$clientBarcode = ClientsBarcode::where('client_guid', $client->user_code)->first(); if (isset($input['address'])) {
if ($clientBarcode) { $clientAddress = ClientsAddress::where('client_guid', $client->user_code)->first();
$clientBarcode = ClientsBarcode::find($clientBarcode['id']); if ($clientAddress) {
if ($input['barcode'] !== '') { $clientAddress = ClientsAddress::find($clientAddress['id']);
$clientBarcode->code_id = urldecode($input['barcode']); if ($input['address'] !== '') {
} else { $clientAddress->address = urldecode($input['address']);
$clientBarcode->code_id = ''; } else {
} $clientAddress->address = '';
$clientBarcode->save(); }
} } else {
$clientAddress = new ClientsAddress;
$clientAddress->address = urldecode($input['address']);
}
$clientAddress->client_guid = $client->user_code;
$clientAddress->save();
}
$clientBarcodeStart = 0;
$clientBarcodeEnd = 0;
if (isset($input['barcode'])) {
if ($input['barcode'] !== '') {
$client->barcode_type = 2;
$client->barcode_start = $clientBarcodeStart = urldecode($input['barcode']);
$client->barcode_end = $clientBarcodeEnd = urldecode($input['barcode']);
} else {
$client->barcode_type = 1;
$client->barcode_start = $clientBarcodeStart;
$client->barcode_end = $clientBarcodeEnd;
}
}
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(); $client->save();
return [ return [
'status' => 'success', 'status' => 'success',
'client' => $client, 'client' => $client,
'phone' => $clientPhone, 'phone' => $clientPhone,
'email' => $clientEmail, 'email' => $clientEmail,
'address' => $clientAddress, 'address' => $clientAddress,
'barcode' => $clientBarcode, 'barcode' => $clientBarcodeStart,
'message' => 'Клиент обновлен', 'message' => 'Клиент обновлен',
]; ];
} }
if ($input['task'] == 'delete') { if ($input['task'] == 'delete') {
$client = Client::find($input['id']); $client = Client::find($input['id']);
$clientGroup = ClientsGroup::where('code', $client->group_id)->first(); $clientGroup = ClientsGroup::where('code', $client->group_id)->first();
$clientPhone = ClientsPhone::where('client_guid', $client->user_code)->first(); $clientPhone = ClientsPhone::where('client_guid', $client->user_code)->first();
$clientPhone = ClientsPhone::find($clientPhone['id']); $clientPhone = ClientsPhone::find($clientPhone['id']);
$clientEmail = ClientsEmail::where('client_guid', $client->user_code)->first(); $clientEmail = ClientsEmail::where('client_guid', $client->user_code)->first();
$clientEmail = ClientsEmail::find($clientEmail['id']); $clientEmail = ClientsEmail::find($clientEmail['id']);
$clientAddress = ClientsAddress::where('client_guid', $client->user_code)->first(); $clientAddress = ClientsAddress::where('client_guid', $client->user_code)->first();
$clientAddress = ClientsAddress::find($clientAddress['id']); $clientAddress = ClientsAddress::find($clientAddress['id']);
$clientBarcode = ClientsBarcode::where('client_guid', $client->user_code)->first(); $clientBarcode = ClientsBarcode::where('client_guid', $client->user_code)->first();
$clientBarcode = ClientsBarcode::find($clientBarcode['id']); $clientBarcode = ClientsBarcode::find($clientBarcode['id']);
if ($clientPhone) { if ($clientPhone) {
$clientPhone->delete(); $clientPhone->delete();
} }
if ($clientEmail) { if ($clientEmail) {
$clientEmail->delete(); $clientEmail->delete();
} }
if ($clientAddress) { if ($clientAddress) {
$clientAddress->delete(); $clientAddress->delete();
} }
if ($clientBarcode) { if ($clientBarcode) {
$clientBarcode->delete(); $clientBarcode->delete();
} }
if ($client) { if ($client) {
$client->delete(); $client->delete();
} }
return [ return [
'status' => 'success', 'status' => 'success',
'message' => 'Клиент удален', 'message' => 'Клиент удален',
'currentGroup' => $clientGroup['id'], 'currentGroup' => $clientGroup['id'],
]; ];
} }
} else {
return [ if ($input['task'] == 'lock') {
'status' => 'success', if (isset($input['id'])) {
'error_message' => 'Проверьте введенные данные', $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',
'error_message' => 'Проверьте введенные данные',
];
}
}
} }

View File

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

View File

@@ -2,11 +2,16 @@
namespace App\Commands; namespace App\Commands;
use App\Component\Models\Base;
use App\Component\Models\Dishes; use App\Component\Models\Dishes;
use App\Component\Models\OrderBot;
use App\Component\Models\OrderBotStorage;
use App\Component\Models\OrderItems; use App\Component\Models\OrderItems;
use App\Component\Models\Orders; use App\Component\Models\Orders;
use App\Component\Models\TerminalUpdate;
use App\Console\Commands\HRCCommand; use App\Console\Commands\HRCCommand;
use App\Console\Commands\HRCCommandInterface; use App\Console\Commands\HRCCommandInterface;
use Carbon\Carbon;
class POSTOrder extends HRCCommand implements HRCCommandInterface { class POSTOrder extends HRCCommand implements HRCCommandInterface {
protected $signature = 'postorder'; 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 { } else {
return [ return [
'status' => 'success', 'status' => 'success',

View File

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

View File

@@ -1,10 +1,12 @@
{ {
"name": "hrc-admin/hello-world", "name": "hrc-admin/hello-world",
"version": "2.26", "version": "2.27",
"require": { "require": {
"horeca/admin-php-module-core": "dev-master", "horeca/admin-php-module-core": "dev-master",
"guzzlehttp/guzzle": "^7.4", "guzzlehttp/guzzle": "^7.4",
"phpmailer/phpmailer": "^6.6" "phpmailer/phpmailer": "^6.6",
"ext-openssl": "*",
"ext-json": "*"
}, },
"repositories": [ "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", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "c03123a7ef4b356dbbe431d73497088d", "content-hash": "a8af6b76ceb6599b09c480a9985c90b3",
"packages": [ "packages": [
{ {
"name": "brick/math", "name": "brick/math",
@@ -5896,7 +5896,10 @@
}, },
"prefer-stable": false, "prefer-stable": false,
"prefer-lowest": false, "prefer-lowest": false,
"platform": [], "platform": {
"ext-openssl": "*",
"ext-json": "*"
},
"platform-dev": [], "platform-dev": [],
"plugin-api-version": "2.0.0" "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="../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="../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 --> <!-- build:css ../assets/styles/app.min.css -->
<link rel="stylesheet" href="../assets/styles/app.css" type="text/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" /> <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> </head>
@@ -52,6 +42,17 @@
<!-- build:js scripts/app.angular.js --> <!-- build:js scripts/app.angular.js -->
<!-- jQuery --> <!-- jQuery -->
<script src="../libs/jquery/jquery/dist/jquery.js"></script> <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 --> <!-- Bootstrap -->
<script src="scripts/config.js"></script> <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; use Illuminate\Database\Eloquent\Model;
class Client extends Model { class Client extends Model
protected $table = 'clients'; {
protected $table = 'clients';
/** /**
* Get clients phone. * Get clients phone.
*/ */
public function clientPhone() { public function clientPhone()
return $this->belongsTo('App\Component\Models\ClientsPhone', 'user_code', 'client_guid'); {
} 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(); $phone = ClientsPhone::where('client_guid', $guid)->first();
if (isset($phone)) { if (isset($phone)) {
$phone = $phone['phone']; $phone = $phone['phone'];
@@ -24,7 +27,8 @@ class Client extends Model {
return $phone; return $phone;
} }
public static function getEmail($guid) { public static function getEmail($guid)
{
$email = ClientsEmail::where('client_guid', $guid)->first(); $email = ClientsEmail::where('client_guid', $guid)->first();
if (isset($email)) { if (isset($email)) {
$email = $email['email']; $email = $email['email'];
@@ -34,7 +38,8 @@ class Client extends Model {
return $email; return $email;
} }
public static function getAddress($guid) { public static function getAddress($guid)
{
$address = ClientsAddress::where('client_guid', $guid)->first(); $address = ClientsAddress::where('client_guid', $guid)->first();
if (isset($address)) { if (isset($address)) {
$address = $address['address']; $address = $address['address'];
@@ -44,17 +49,19 @@ class Client extends Model {
return $address; return $address;
} }
public static function getBarcode($guid) { public static function getBarcode($guid)
$barcode = ClientsBarcode::where('client_guid', $guid)->first(); {
$barcode = Client::where('user_code', $guid)->first();
if (isset($barcode)) { if (isset($barcode)) {
$barcode = $barcode['value']; $barcode = $barcode['barcode_start'];
} else { } else {
$barcode = ''; $barcode = '';
} }
return $barcode; return $barcode;
} }
public static function getID($guid) { public static function getID($guid)
{
$id = Client::where('client_guid', $guid)->first(); $id = Client::where('client_guid', $guid)->first();
if (isset($id)) { if (isset($id)) {
$id = $id['id']; $id = $id['id'];
@@ -64,4 +71,16 @@ class Client extends Model {
return $id; 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 { class ClientsGroup extends Model {
protected $table = 'client_groups'; 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. * 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_type = $type;
$action_name = 'Внесение аванса'; if ($action_type == 21) {
} else { $action_name = 'Поступил предварительный платеж через скидку в размере ' . $value . ' BYN через заказ №' . $order_id;
$action_name = 'Зачет аванса';
} }
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 = new ClientsActions();
$action->action = $action_name; $action->action = $action_name;
$action->created = Carbon::createFromTimestampUTC($time)->timezone('Europe/Minsk'); $action->created = Carbon::createFromTimestampUTC($time)->timezone('Europe/Minsk');
$action->user_id = $guid; $action->user_id = $guid;
$action->action_value = abs($value); $action->action_value = abs($value);
$action->action_type = 2; $action->action_type = $action_type;
$action->order_id = $order_id;
$action->who = $staff_id; $action->who = $staff_id;
$action->save(); $action->save();
return $action_name;
} }
} }

View File

@@ -25,6 +25,19 @@ class Dishes extends Model {
$dish_name = 'Связанный товар удален'; $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; return $dish_name;
} }
@@ -59,4 +72,19 @@ class Dishes extends Model {
} }
return $isServing; 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 { class ExchangeActions extends Model {
protected $table = 'exchange_actions'; protected $table = 'exchange_actions';
} }

View File

@@ -6,4 +6,9 @@ use Illuminate\Database\Eloquent\Model;
class ExchangeDeleted extends Model { class ExchangeDeleted extends Model {
protected $table = 'exchange_deleted'; 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'], 'cof' => $item['cof'],
'unit' => Units::getName($item['units_id']), 'unit' => Units::getName($item['units_id']),
'amount' => round($item['sale_price'] * $item['count'], 2), 'amount' => round($item['sale_price'] * $item['count'], 2),
'discount' => round($discount, 2) 'discount' => round($discount)
); );
$amount += round($item['sale_price'] * $item['count'], 2); $amount += round($item['sale_price'] * $item['count'], 2);
$full_price += round($realPrice,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; use Illuminate\Database\Eloquent\Model;
class OrderBot extends 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 * @var array
*/ */
protected $guarded = []; 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'], 'cof' => $item['cof'],
'unit' => Units::getName($item['units_id']), 'unit' => Units::getName($item['units_id']),
'amount' => round($item['sale_price'] * $item['count'], 2), 'amount' => round($item['sale_price'] * $item['count'], 2),
'discount' => round($discount, 0) 'discount' => round($discount)
); );
$amount += round($item['sale_price'] * $item['count'], 2); $amount += round($item['sale_price'] * $item['count'], 2);
$full_price += round($realPrice,2); $full_price += round($realPrice,2);

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -1,150 +1,248 @@
(function() { (function () {
'use strict'; 'use strict';
angular angular
.module('app') .module('app', ['ui.bootstrap', 'ui.utils'])
.controller('ReportsCtrl', ReportsCtrl); .controller('ReportsCtrl', ReportsCtrl);
ReportsCtrl.$inject = ['$scope', 'smartRequest', 'Notification']; ReportsCtrl.$inject = ['$scope', 'smartRequest', 'Notification'];
function ReportsCtrl($scope, smartRequest, Notification) {
var date = new Date();
var formatted = ('0' + date.getDate()).slice(-2) + '.' + ('0' + (date.getMonth() + 1)).slice(-2) + '.' + date.getFullYear(); 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 = '';
date.setDate(date.getDate() - 1); for (var i = float.length - 1; i >= 0; i--) {
if (space == 3) {
number = ' ' + number;
space = 0;
}
number = float.charAt(i) + number;
space++;
}
var formatted_yesterday = ('0' + date.getDate()).slice(-2) + '.' + ('0' + (date.getMonth() + 1)).slice(-2) + '.' + date.getFullYear(); return number;
};
var date = new Date();
$scope.report_delete = []; var formatted = ('0' + date.getDate()).slice(-2) + '.' + ('0' + (date.getMonth() + 1)).slice(-2) + '.' + date.getFullYear();
$scope.report_realisation = [];
$scope.start_date = formatted_yesterday;
$scope.end_date = formatted;
$scope.report_id = 'realisation';
$scope.history = [];
$scope.statistic = {};
$scope.staffs = [];
$scope.printers = [];
$scope.update = function() { date.setDate(date.getDate() - 1);
smartRequest.get('v1/reports', function(data) {
$scope.history = data.reports;
});
smartRequest.get('v1/settings?code=11', function (data) {
$scope.delete_shift_value = data.value;
});
};
$scope.deleteReport = function (report) { var formatted_yesterday = ('0' + date.getDate()).slice(-2) + '.' + ('0' + (date.getMonth() + 1)).slice(-2) + '.' + date.getFullYear();
$('#preload-modal').modal();
Notification.primary('Дождитесь удаления! Страница обновится автоматически.');
smartRequest.post('v1/deletedata', {
value: 'delete_report',
report_id: report.id
}, function (data) {
$scope.status = data.status;
$scope.message = data.message;
if (data.status == 'success') {
Notification.success(data.message);
setTimeout(function() {
//location.reload();
$scope.update();
$('#preload-modal').modal('hide');
}, 1000);
}
if ($scope.status == 'error') {
Notification.error(data.message);
}
});
};
$scope.reportDelete = function() { $scope.report_delete = [];
smartRequest.get('v1/datareport?type=deleted&start_date=' + encodeURIComponent($scope.start_date) + '&end_date=' + encodeURIComponent($scope.end_date), function(data) { $scope.report_realisation = [];
$scope.report_delete = data.deleted; $scope.start_date = formatted_yesterday;
$scope.report_delete.total_sum = data.total_sum; $scope.end_date = formatted;
$scope.report_delete.total_count = data.total_count; $scope.report_id = 'realisation';
$('#report-delete').modal(); $scope.history = [];
}, function(data) { $scope.statistic = {};
$scope.update(); $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;
});
};
$scope.reportRealisation = function() { $scope.deleteReport = function (report) {
smartRequest.get('report/realisation?start_date=' + encodeURIComponent($scope.start_date) + '&end_date=' + encodeURIComponent($scope.end_date), function(data) { $('#preload-modal').modal();
$scope.report_realisation = data.printers; Notification.primary('Дождитесь удаления! Страница обновится автоматически.');
$scope.return_printers = data.ret_prints; smartRequest.post('v1/deletedata', {
$scope.report_realisation.total_count = data.total_count; value: 'delete_report',
$scope.report_realisation.total_sum = data.total_sum; report_id: report.id
$('#report-realisation').modal(); }, function (data) {
}, function(data) { $scope.status = data.status;
$scope.update(); $scope.message = data.message;
}); if (data.status == 'success') {
}; Notification.success(data.message);
setTimeout(function () {
//location.reload();
$scope.update();
$('#preload-modal').modal('hide');
}, 1000);
}
if ($scope.status == 'error') {
Notification.error(data.message);
}
});
};
$scope.reportStatistic = function() { $scope.closeModal = function (modalName) {
smartRequest.get('report/statistics?start_date=' + encodeURIComponent($scope.start_date) + '&end_date=' + encodeURIComponent($scope.end_date), function(data) { $scope.modalName = '#' + modalName;
$scope.statistic = data.statistic; $('.modal-body').scrollTop(0);
$('#report-statistic').modal(); $($scope.modalName).modal('dispose');
}, function(data) { return true;
$scope.update(); };
});
};
$scope.reportStaff = function() { $scope.prevModal = function (modalFromName, modalToName) {
smartRequest.get('v1/datareport?type=staff&start_date=' + encodeURIComponent($scope.start_date) + '&end_date=' + encodeURIComponent($scope.end_date), function(data) { $scope.modal_from = '#' + modalFromName;
$scope.staffs = data.staffs; $scope.modal_to = '#' + modalToName;
$('#report-staff').modal(); $($scope.modal_from).modal('hide');
}, function(data) { $($scope.modal_to).modal('toggle');
$scope.update(); };
});
};
$scope.reportPay = function() { $scope.nextModal = function (modalFromName, modalToName) {
smartRequest.get('report/payment?start_date=' + encodeURIComponent($scope.start_date) + '&end_date=' + encodeURIComponent($scope.end_date), function(data) { $scope.modal_from = '#' + modalFromName;
$scope.printers = data.printers; $scope.modal_to = '#' + modalToName;
$('#report-payment').modal(); $($scope.modal_from).modal('hide');
}, function(data) { $($scope.modal_to).modal('toggle');
$scope.update(); };
});
};
$scope.reportOut = function () {
smartRequest.get('v1/outorders?start_date=' + encodeURIComponent($scope.start_date) + '&end_date=' + encodeURIComponent($scope.end_date), function (data) {
$scope.orders = data.orders;
$scope.total = data.total;
$('#report-out').modal();
}, function (data) {
$scope.update();
});
};
$scope.createReport = function() { $scope.getOrders = function (discount_id, modalFromName, modalToName) {
switch ($scope.report_id) { $scope.discount_id = discount_id;
case 'deleted': $scope.reportDelete(); break; $scope.orders_list = $scope.orders_info[discount_id].orders;
case 'realisation': $scope.reportRealisation(); break; $scope.nextModal(modalFromName, modalToName);
case 'statistics': $scope.reportStatistic(); break; };
case 'staff': $scope.reportStaff(); break;
case 'pay': $scope.reportPay(); break;
case 'out': $scope.reportOut(); break;
}
};
$scope.archiveReport = function(type, start_date, end_date) { $scope.getItems = function (order_id, opened, closed, modalFromName, modalToName) {
$scope.report_id = type; smartRequest.get('v1/clientorderinfo?order_id=' + order_id + '&opened=' + opened + '&closed=' + closed, function (data) {
$scope.start_date = start_date; $scope.order_info = data.info;
$scope.end_date = end_date; $scope.nextModal(modalFromName, modalToName);
$scope.createReport(); });
}; };
$scope.popup = function(data) { $scope.reportDiscounts = function () {
var mywindow = window.open(); $('#preload-modal').modal();
mywindow.document.write(data); Notification.primary('Отчет формируется. Ожидайте.');
mywindow.print(); smartRequest.get('v1/datareport?type=discounts&start_date=' + encodeURIComponent($scope.start_date) + '&end_date=' + encodeURIComponent($scope.end_date), function (data) {
mywindow.close(); $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.printElem = function(elem) { $scope.reportDelete = function () {
$scope.popup($('<div/>').append($(elem).clone()).html()); $('#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.orders;
$scope.totalSum = data.totalSum;
$scope.totalCount = data.totalCount;
$('#preload-modal').modal('hide');
$('#report-delete').modal();
$scope.update();
});
};
$scope.update(); $scope.reportRealisation = function () {
} 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();
});
};
$scope.reportStatistic = function () {
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();
$scope.update();
});
};
$scope.reportStaff = function () {
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();
$scope.update();
});
};
$scope.reportPay = function () {
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();
$scope.update();
});
};
$scope.reportOut = function () {
smartRequest.get('v1/outorders?start_date=' + encodeURIComponent($scope.start_date) + '&end_date=' + encodeURIComponent($scope.end_date), function (data) {
$scope.orders = data.orders;
$scope.total = data.total;
$('#report-out').modal();
$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 'discounts':
$scope.reportDiscounts();
break;
}
};
$scope.archiveReport = function (type, start_date, end_date) {
$scope.report_id = type;
$scope.start_date = start_date;
$scope.end_date = end_date;
$scope.createReport();
};
$scope.popup = function (data) {
var mywindow = window.open();
mywindow.document.write(data);
mywindow.print();
mywindow.close();
};
$scope.printElem = function (elem) {
console.log(elem);
$scope.popup($('<div/>').append($(elem).clone()).html());
};
$scope.update();
}
})(); })();

View File

@@ -1,246 +1,345 @@
(function () { (function () {
'use strict'; 'use strict';
angular angular
.module('app') .module('app')
.controller('ShiftsCtrl', ShiftsCtrl); .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']; ShiftsCtrl.$inject = ['$scope', '$filter', 'smartRequest', 'Notification'];
function ShiftsCtrl($scope, $filter, smartRequest, Notification) {
var date = new Date();
var formatted = ('0' + date.getDate()).slice(-2) + '.' + ('0' + (date.getMonth() + 1)).slice(-2) + '.' + date.getFullYear();
date.setDate(date.getDate() - 1);
var formatted_yesterday = ('0' + date.getDate()).slice(-2) + '.' + ('0' + (date.getMonth() + 1)).slice(-2) + '.' + date.getFullYear();
$scope.start_date = formatted; function ShiftsCtrl($scope, $filter, smartRequest, Notification) {
$scope.end_date = formatted_yesterday; Number.prototype.toDivide = function() {
$scope.response = false; var float = String(this.toFixed(2));
$scope.shifts = []; if(float.length <= 6) return float;
$scope.report_delete = []; var space = 0;
$scope.countOfPages = 1; var number = '';
$scope.currentPage = 1;
$scope.statistic = {};
$scope.staffs = [];
$scope.parseFloat = parseFloat;
$scope.add = function() { for(var i = float.length - 1; i >= 0; i--) {
$scope.reImport = {}; if(space == 3) {
$('#reImport').modal(); number = ' ' + number;
}; space = 0;
}
number = float.charAt(i) + number;
space++;
}
$scope.create = function() { return number;
var start_date = document.getElementById("startDate").value; };
var end_date = document.getElementById("endDate").value; var date = new Date();
console.log(start_date, end_date); var formatted = ('0' + date.getDate()).slice(-2) + '.' + ('0' + (date.getMonth() + 1)).slice(-2) + '.' + date.getFullYear();
smartRequest.get('v1/import?start_date=' + encodeURIComponent(start_date) + '&end_date=' + encodeURIComponent(end_date), function(data) { date.setDate(date.getDate() - 1);
$scope.response = data.message; var formatted_yesterday = ('0' + date.getDate()).slice(-2) + '.' + ('0' + (date.getMonth() + 1)).slice(-2) + '.' + date.getFullYear();
if (data.message == 'shifts not found') {
Notification.error('Смены не найдены');
} else {
Notification.success('Задача создана');
$scope.update();
}
});
$('#reImport').modal('toggle');
};
$scope.update = function () {
smartRequest.get('shift/list?page=' + $scope.currentPage, function (data) {
$scope.shifts = data.shifts;
$scope.countOfPages = data.pages;
$scope.pages = $scope.makePages();
});
smartRequest.get('v1/settings?code=11', function (data) {
$scope.delete_shift_value = data.value;
});
};
$scope.deleteShift = function (shift) { $scope.start_date = formatted;
$('#preload-modal').modal(); $scope.end_date = formatted_yesterday;
Notification.primary('Дождитесь удаления! Страница обновится автоматически.'); $scope.response = false;
smartRequest.post('v1/deletedata', { $scope.shifts = [];
value: 'delete_shift', $scope.report_delete = [];
shift_id: shift.id $scope.countOfPages = 1;
}, function (data) { $scope.currentPage = 1;
$scope.status = data.status; $scope.statistic = {};
$scope.message = data.message; $scope.staffs = [];
if (data.status == 'success') { $scope.parseFloat = parseFloat;
Notification.success(data.message); $scope.dataTableOpt = {
setTimeout(function() { "aoSearchCols": [
//location.reload(); null
$scope.update(); ],
$('#preload-modal').modal('hide'); "oLanguage": {
}, 1000); "sUrl": 'https://cdn.datatables.net/plug-ins/1.13.3/i18n/ru.json'
} },
if ($scope.status == 'error') { "searching": false,
Notification.error(data.message); "paging": false,
} "info": false,
}); "order": [[1, 'desc']],
}; };
$scope.reportMerged = function (shift) { $scope.add = function () {
smartRequest.get('v1/datareport?type=merge&shift_id=' + shift.id, function (data) { $scope.reImport = {};
$scope.report_merge = data.data; $('#reImport').modal();
$scope.report_merge.count = data.count; };
$scope.report_merge.shift_id = data.shift_id;
$scope.start_date = shift.opened; $scope.create = function () {
$scope.end_date = shift.closed; var start_date = document.getElementById("startDate").value;
$('#report-merge').modal(); var end_date = document.getElementById("endDate").value;
}); console.log(start_date, end_date);
}; smartRequest.get('v1/import?start_date=' + encodeURIComponent(start_date) + '&end_date=' + encodeURIComponent(end_date), function (data) {
$scope.response = data.message;
if (data.message == 'shifts not found') {
Notification.error('Смены не найдены');
} else {
Notification.success('Задача создана');
$scope.update();
}
});
$('#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;
});
};
$scope.deleteShift = function (shift) {
$('#preload-modal').modal();
Notification.primary('Дождитесь удаления! Страница обновится автоматически.');
smartRequest.post('v1/deletedata', {
value: 'delete_shift',
shift_id: shift.id
}, function (data) {
$scope.status = data.status;
$scope.message = data.message;
if (data.status == 'success') {
Notification.success(data.message);
setTimeout(function () {
//location.reload();
$scope.update();
$('#preload-modal').modal('hide');
}, 1000);
}
if ($scope.status == 'error') {
Notification.error(data.message);
}
});
};
$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;
$scope.report_merge.count = data.count;
$scope.report_merge.shift_id = data.shift_id;
$scope.start_date = shift.opened;
$scope.end_date = shift.closed;
$('#report-merge').modal();
});
};
$scope.reportMoved = function (shift) { $scope.reportMoved = function (shift) {
smartRequest.get('v1/datareport?type=move&shift_id=' + shift.id, function (data) { smartRequest.get('v1/datareport?type=move&shift_id=' + shift.id, function (data) {
$scope.report_move = data.data; $scope.report_move = data.data;
$scope.report_move.count = data.count; $scope.report_move.count = data.count;
$scope.start_date = shift.opened; $scope.start_date = shift.opened;
$scope.end_date = shift.closed; $scope.end_date = shift.closed;
$('#report-move').modal(); $('#report-move').modal();
}); });
}; };
$scope.reportSliced = function (shift) { $scope.reportSliced = function (shift) {
smartRequest.get('v1/datareport?type=slice&shift_id=' + shift.id, function (data) { smartRequest.get('v1/datareport?type=slice&shift_id=' + shift.id, function (data) {
$scope.report_slice = data.data; $scope.report_slice = data.data;
$scope.report_slice.count = data.count; $scope.report_slice.count = data.count;
$scope.report_slice.shift_id = data.shift_id; $scope.report_slice.shift_id = data.shift_id;
$scope.start_date = shift.opened; $scope.start_date = shift.opened;
$scope.end_date = shift.closed; $scope.end_date = shift.closed;
$('#report-slice').modal(); $('#report-slice').modal();
}); });
}; };
$scope.reportDelete = function (shift) { $scope.reportDelete = function (shift) {
smartRequest.get('v1/datareport?type=deleted&shift_id=' + shift.id, function (data) { smartRequest.get('v1/datareport?type=deleted&shift_id=' + shift.id, function (data) {
$scope.report_delete = data.deleted; if (data.totalCount > 0) {
$scope.report_delete.total_sum = data.total_sum; $scope.report_delete = data.orders;
$scope.report_delete.total_count = data.total_count; $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;
$scope.start_date = shift.opened; $scope.update();
$scope.end_date = shift.closed; $('#shift-delete').modal();
$('#report-delete').modal(); } else {
}); Notification.error(data.message);
}; }
$scope.reportRealisation = function (shift) { });
smartRequest.get('report/realisation?shift_id=' + shift.id, function (data) { };
$scope.report_realisation = data.printers; $scope.reportRealisation = function (shift) {
$scope.return_printers = data.ret_prints; 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.report_realisation.total_count = data.total_count; $scope.start_date = shift.opened;
$scope.report_realisation.total_sum = data.total_sum; $scope.end_date = shift.closed;
$scope.start_date = shift.opened; $scope.update();
$scope.end_date = shift.closed; $('#report-realisation').modal();
});
};
$('#report-realisation').modal(); $scope.reportStatistic = function (shift) {
}); 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();
});
};
$scope.reportStatistic = function (shift) { $scope.reportStaff = function (shift) {
smartRequest.get('report/statistics?shift_id=' + shift.id, function (data) { smartRequest.get('v1/datareport?type=staff&shift_id=' + shift.id, function (data) {
$scope.statistic = data.statistic; $scope.staffs = data.staffs;
$scope.start_date = shift.opened; $scope.start_date = shift.opened;
$scope.end_date = shift.closed; $scope.end_date = shift.closed;
$('#report-statistic').modal(); $scope.update();
}); $('#report-staff').modal();
}; });
};
$scope.reportStaff = function (shift) { $scope.reportPay = function (shift) {
smartRequest.get('v1/datareport?type=staff&shift_id=' + shift.id, function (data) { smartRequest.get('report/payment?shift_id=' + shift.id, function (data) {
$scope.staffs = data.staffs; $scope.printers = data.printers;
$scope.start_date = shift.opened; $scope.start_date = shift.opened;
$scope.end_date = shift.closed; $scope.end_date = shift.closed;
$('#report-staff').modal(); $scope.update();
}); $('#report-payment').modal();
}; });
};
$scope.reportPay = function (shift) { $scope.reportOut = function (shift) {
smartRequest.get('report/payment?shift_id=' + shift.id, function (data) { smartRequest.get('v1/outorders?shift_id=' + shift.id, function (data) {
$scope.response = data.message;
if (data.message == 'false') {
Notification.error('Внешние заказы не найдены');
} else {
$scope.orders = data.orders;
$scope.shift = data.shift;
$scope.total = data.total;
$scope.printers = data.printers; $scope.update();
$scope.start_date = shift.opened; $('#report-out').modal();
$scope.end_date = shift.closed; }
});
};
$('#report-payment').modal(); $scope.restoreShift = function (shift) {
}, function (data) { $('#preload-modal').modal();
$scope.update(); Notification.primary('Дождитесь загрузки! Страница обновится автоматически.');
}); smartRequest.post('v1/restoreshift', {
}; shift_id: shift.id
}, function (data) {
$scope.reportOut = function (shift) { $scope.status = data.status;
smartRequest.get('v1/outorders?shift_id=' + shift.id, function (data) { $scope.response = data.message;
$scope.response = data.message; if (data.status == 'success') {
if (data.message == 'false') { Notification.success(data.message);
Notification.error('Внешние заказы не найдены'); setTimeout(function () {
} else { location.reload();
$scope.orders = data.orders; }, 1000);
$scope.shift = data.shift; }
$scope.total = data.total; if ($scope.status == 'error') {
Notification.error(data.message);
}
});
};
$('#report-out').modal(); $scope.popup = function (data) {
} var mywindow = window.open();
mywindow.document.write(data);
}, function (data) { mywindow.print();
$scope.update(); mywindow.close();
}); };
};
$scope.restoreShift = function (shift) { $scope.printElem = function (elem) {
$('#preload-modal').modal(); $scope.popup($('<div/>').append($(elem).clone()).html());
Notification.primary('Дождитесь загрузки! Страница обновится автоматически.'); };
smartRequest.post('v1/restoreshift', {
shift_id: shift.id
}, function (data) {
$scope.status = data.status;
$scope.response = data.message;
if (data.status == 'success') {
Notification.success(data.message);
setTimeout(function() {
location.reload();
}, 1000);
}
if ($scope.status == 'error') {
Notification.error(data.message);
}
});
};
$scope.popup = function(data) { $scope.makePages = function () {
var mywindow = window.open(); return Array.from({length: $scope.countOfPages}, (v, k) => k + 1);
mywindow.document.write(data); };
mywindow.print(); $scope.showPage = function (index) {
mywindow.close(); $scope.currentPage = index;
}; $scope.update();
};
$scope.printElem = function(elem) { $scope.nextPage = function () {
$scope.popup($('<div/>').append($(elem).clone()).html()); $scope.currentPage++;
}; $scope.update();
};
$scope.makePages = function () { $scope.prevPage = function () {
return Array.from({ length: $scope.countOfPages }, (v, k) => k + 1); $scope.currentPage--;
}; $scope.update();
};
$scope.showPage = function (index) { $scope.update();
$scope.currentPage = index; }
$scope.update();
};
$scope.nextPage = function () {
$scope.currentPage++;
$scope.update();
};
$scope.prevPage = function () {
$scope.currentPage--;
$scope.update();
};
$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.terminalLogs = [];
$scope.update = function () { $scope.update = function () {
smartRequest.get('settings/terminals', function (data) { smartRequest.get('v1/settings?method=terminals', function (data) {
$scope.terminals = data.terminals; $scope.terminals = data.terminals;
}); });
}; };

View File

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

View File

@@ -46,6 +46,14 @@
controller: 'ClientsCtrl', controller: 'ClientsCtrl',
resolve: ['scripts/controllers/clients.js'] 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', code: 'app.shifts',
url: '/shifts', url: '/shifts',

View File

@@ -4,26 +4,49 @@
<h5 class="modal-title">Редактирование клиента</h5> <h5 class="modal-title">Редактирование клиента</h5>
</div> </div>
<div class="modal-body p-lg"> <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="form-group row">
<div class="col-sm-12"> <div class="col-sm-12">
<span>Группа: </span> <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> <select name="group" class="form-control input-c"
<span>Имя: </span><input class="form-control" placeholder="Название" type="text" ng-model="contextElement.name"> ng-options="opt.id as opt.name for opt in groups" ng-model="contextGroup"></select>
<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="Название" type="text"
<span>Адрес: </span><input class="form-control" placeholder="Введите email" type="text" ng-model="contextElement.address"> ng-model="contextElement.name">
<span>Email: </span><input class="form-control" placeholder="Введите адрес" type="text" ng-model="contextElement.email"> <span>Телефон: </span><input class="form-control" type="text" ng-model="contextElement.phone"
<span>Штрих код: </span><input class="form-control" placeholder="Введите штрих код" type="text" ng-model="contextElement.barcode"> ui-mask="+375 (99) 999-99-99">
</div> <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> </div>
</form> </form>
</div> </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>
</div> </div>

View File

@@ -103,44 +103,57 @@
<div class="p-a-md"> <div class="p-a-md">
<div class="row m-t"> <div class="row m-t">
<div class="col-sm-12"> <div class="col-sm-12">
<a href="" class="pull-left m-r-md"> <div class="col-sm-11">
<a href="" class="pull-left m-r-md">
<span class="avatar w-96"> <span class="avatar w-96">
<img src="../views/clients/images/client.png"> <img src="../views/clients/images/client.png">
<i class="on b-white"></i> <i class="on b-white"></i>
</span> </span>
</a> </a>
<div class="clear m-b"> <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"> <p class="text-muted">
<span class="m-r"> <span class="m-r">
<i class="fa fa-phone m-r-sm text-muted"></i>{{currentClient.info.phone}} <i class="fa fa-phone m-r-sm text-muted"></i>{{currentClient.info.phone}}
</span> </span>
<small> <small>
<i class="fa fa-map-marker m-r-xs"></i>{{currentClient.info.address}} <i class="fa fa-map-marker m-r-xs"></i>{{currentClient.info.address}}
</small> </small>
</p> </p>
</div>
</div> </div>
<div class="col-sm-1">
<div class="p-y text-center text-sm-center col-sm-12"> <div class="dropdown inline">
<a href="" class="inline p-x text-center"> <button class="btn white dropdown-toggle" data-toggle="dropdown"
<span class="h5 block m-0">{{currentClient.info.order_sum | curr}} BYN</span> aria-expanded="true"><i class="fa fa-bars"></i></button>
<small class="text-xs text-muted">Сумма заказов</small> <div class="dropdown-menu dropdown-menu-scale pull-right">
</a> <a class="dropdown-item" href="" ng-if="!currentClient.info.is_block" ng-click="lockClient(currentClient)">Заблокировать</a>
<a href="" class="inline p-x b-l text-center"> <a class="dropdown-item" href="" ng-if="currentClient.info.is_block" ng-click="unlockClient(currentClient)">Разблокировать</a>
<span class="h5 block m-0">{{currentClient.info.order_count}}</span> <a class="dropdown-item" data-toggle="modal"
<small class="text-xs text-muted">Кол-во заказов</small> data-target="#client-confirm-delete">Удалить</a>
</a> </div>
<a href="" class="inline p-x b-l b-r text-center" </div>
ng-if="currentClient.info.presale > 0">
<span class="h5 block m-0">{{currentClient.info.presale | curr}} BYN</span>
<small class="text-xs text-muted">Аванс</small>
</a>
<a href="" class="inline p-x text-center" ng-if="currentClient.info.bonus > 0">
<span class="h5 block m-0">{{currentClient.info.bonus}}</span>
<small class="text-xs text-muted">Бонусы</small>
</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>
<small class="text-xs text-muted">Сумма заказов</small>
</a>
<a href="" class="inline p-x b-l text-center">
<span class="h5 block m-0">{{currentClient.info.order_count}}</span>
<small class="text-xs text-muted">Кол-во заказов</small>
</a>
<a href="" class="inline p-x b-l b-r text-center"
ng-if="currentClient.info.presale > 0">
<span class="h5 block m-0">{{currentClient.info.presale | curr}} BYN</span>
<small class="text-xs text-muted">Аванс</small>
</a>
<a href="" class="inline p-x text-center" ng-if="currentClient.info.bonus > 0">
<span class="h5 block m-0">{{currentClient.info.bonus}}</span>
<small class="text-xs text-muted">Бонусы</small>
</a>
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -148,17 +161,17 @@
<div class="row"> <div class="row">
<div class="col-lg-12 col-sm-9"> <div class="col-lg-12 col-sm-9">
<div class="p-y-md clearfix nav-active-primary"> <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"> <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> aria-expanded="true">Журнал действий</a>
</li> </li>
<li class="nav-item"> <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> aria-expanded="false" ng-click="getOrders(currentClient.id)">Заказы</a>
</li> </li>
<li class="nav-item"> <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> aria-expanded="false">Информация</a>
</li> </li>
</ul> </ul>
@@ -170,19 +183,14 @@
<div class="row"> <div class="row">
<div class="col-sm-8 col-lg-12"> <div class="col-sm-8 col-lg-12">
<div class="tab-content"> <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" <div class="streamline b-l m-b m-l"
style="width:auto;max-height:350px;overflow-y: auto;" style="width:auto;max-height:350px;overflow-y: auto;"
ng-if="clientLogs.length > 0"> ng-if="clientLogs.length > 0">
<div class="sl-item b-success" ng-repeat="clientLog in clientLogs"> <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> <div class="sl-date text-muted">{{clientLog.time}}</div>
<p>{{clientLog.action}} на сумму {{clientLog.value | curr}} BYN <p>{{clientLog.action}}</p>
пользователем {{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>
</div> </div>
</div> </div>
</div> </div>
@@ -195,7 +203,7 @@
</div> </div>
</div> </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" <div class="streamline b-l m-b m-l"
style="width:auto;max-height:350px;overflow-y: auto;" style="width:auto;max-height:350px;overflow-y: auto;"
ng-if="orders.length > 0"> ng-if="orders.length > 0">
@@ -231,7 +239,7 @@
</div> </div>
</div> </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="row m-b">
<div class="col-xs-10"> <div class="col-xs-10">
<small class="text-muted">Телефон:</small> <small class="text-muted">Телефон:</small>
@@ -418,6 +426,14 @@
ng-model="newClient.special_price"> ng-model="newClient.special_price">
</div> </div>
</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>
<div class="dker p-a"> <div class="dker p-a">
@@ -466,7 +482,7 @@
<div class="confirm-box-footer"> <div class="confirm-box-footer">
<button type="button" class="btn dark-white p-x-md" data-dismiss="modal">Нет</button> <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> </div>
</div> </div>

View File

@@ -16,12 +16,29 @@
<div class="padding"> <div class="padding">
<div class="margin"> <div class="margin">
<h5 class="m-b-0 _300">{{update_time}} <div class="row">
<i title="Данные о текущей смене скоро обновятся. Обновите страницу через несколько минут" class="fa fa-spinner fa-spin text-success" ng-if="need_update"></i> <div class="col-sm-9">
</h5> <h5 id="currentTime" class="m-b-0 _300">{{ currentDate | date:'dd.MM.yyyy HH:mm:ss' }}
<small class="text-muted">Данные по филиалу </h5>
<strong>{{globals.currentUser.organization.name}}</strong> <small class="text-muted">Данные по филиалу
</small> <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>
<div class="row"> <div class="row">
@@ -113,7 +130,7 @@
<div class="box-tool box-tool-white"> <div class="box-tool box-tool-white">
<ul class="nav"> <ul class="nav">
<li class="nav-item"> <li class="nav-item">
<a ng-click="getMore('delete')"> <a ng-click="getMoreDeleted()">
<i class="fa fa-eye"></i> <i class="fa fa-eye"></i>
</a> </a>
</li> </li>
@@ -171,7 +188,7 @@
<div class="box-tool box-tool-white"> <div class="box-tool box-tool-white">
<ul class="nav"> <ul class="nav">
<li class="nav-item"> <li class="nav-item">
<a ng-click="getMore('guests')"> <a ng-click="getMoreGuests()">
<i class="fa fa-eye"></i> <i class="fa fa-eye"></i>
</a> </a>
</li> </li>
@@ -402,7 +419,7 @@
</div> </div>
<div class="row"> <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">
<div class="box-header"> <div class="box-header">
<h3>Топ продаваемых товаров</h3> <h3>Топ продаваемых товаров</h3>
@@ -548,13 +565,13 @@
<div ui-include="'../views/dashboard/add.html'"></div> <div ui-include="'../views/dashboard/add.html'"></div>
</div> </div>
<div class="modal fade" id="get-more-delete"> <div class="modal fade" id="get-more-deleted">
<div ui-include="'../views/dashboard/items/more-delete.html'"></div> <div ui-include="'../views/dashboard/items/more-deleted.html'"></div>
</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 ui-include="'../views/dashboard/items/more-newyear.html'"></div>
</div> </div>-->
<div class="modal fade" id="get-more-guests"> <div class="modal fade" id="get-more-guests">
<div ui-include="'../views/dashboard/items/more-guests.html'"></div> <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 ui-include="'../views/dashboard/items/items-staff.html'"></div>
</div> </div>
<div class="modal fade" id="items-delete"> <div class="modal fade" id="items-deleted">
<div ui-include="'../views/dashboard/items/items-delete.html'"></div> <div ui-include="'../views/dashboard/items/items-deleted.html'"></div>
</div> </div>
<div class="modal fade" id="preload-modal" data-backdrop="true"> <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-dialog modal-lg">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <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> <i class="material-icons md-24">arrow_back</i>
</button> </button>
<h5 class="modal-title">Подробнее об удалениях в заказе № {{ order.code }}</h5> <h5 class="modal-title">Подробнее об удалениях в заказе № {{ order.code }}</h5>

View File

@@ -17,7 +17,7 @@
</thead> </thead>
<tbody> <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.number }}</td>
<td class="text-right">{{ deleted_order.opened }}</td> <td class="text-right">{{ deleted_order.opened }}</td>
<td class="text-right">{{ getClosedDate(deleted_order.closed) }}</td> <td class="text-right">{{ getClosedDate(deleted_order.closed) }}</td>
@@ -36,4 +36,5 @@
<div class="text-muted">Удаленных позиций нет</div> <div class="text-muted">Удаленных позиций нет</div>
</div> </div>
</div> </div>
</div> </div>
</div>

View File

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

View File

@@ -15,12 +15,13 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody ng-repeat="order in client.orders">
<tr ng-click="getItems('guests', client)"> <tr ng-click="getItems('guests', order)">
<td class="text-right" style="width: 20%;">Заказ № {{ client.number }}</td> <td class="text-right" style="width: 20%;">Заказ № {{ order.number }}</td>
<td class="text-right" style="width: 30%;">Открыт {{ client.opened }}</td> <td class="text-right" style="width: 30%;">Открыт {{ order.opened }}</td>
<td class="text-right" style="width: 30%;">{{ client.closed }}</td> <td ng-if="order.closed" class="text-right" style="width: 30%;">Закрыт {{ order.closed }}</td>
<td class="text-right" style="width: 20%;">{{ client.sum | curr }} BYN</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> </tr>
</tbody> </tbody>
</table> </table>
@@ -31,4 +32,5 @@
<div class="text-muted">Заказов от именованных гостей нет</div> <div class="text-muted">Заказов от именованных гостей нет</div>
</div> </div>
</div> </div>
</div> </div>
</div>

View File

@@ -24,7 +24,7 @@
</div> </div>
</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"> <div class="col-sm-6">
<input placeholder="Имя" ng-model="client_name" class="form-control" value="client_name" disabled></input> <input placeholder="Имя" ng-model="client_name" class="form-control" value="client_name" disabled></input>
<p> <p>

View File

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

View File

@@ -10,56 +10,84 @@
<span class="text-muted">{{start_date}} - {{end_date}}</span> <span class="text-muted">{{start_date}} - {{end_date}}</span>
</div> </div>
<div class="modal-body p-lg"> <div class="modal-body p-lg">
<div class="table-responsive" ng-if="report_delete.length > 0"> <div ng-if="report_delete.length > 0">
<table class="table table-bordered" ng-repeat="report in report_delete"> <div class="m-b" id="shiftsAccordion">
<thead> <div class="panel box" ng-repeat="reportShift in report_delete">
<th>Смена#{{ report.shift_id }} Заказ #{{ report.order_code }}</th> <div class="box-header">
</thead> <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}}"
<tbody> class="collapsed" aria-expanded="false">
<tr ng-repeat="item in report.items"> <h2>Смена №{{reportShift.shift_id}}</h2>
<td> </a>
<h6>{{ item.dish_name }} </div>
<small> <div class="m-b" id="ordersAccordion">
<p>Время удаления: <strong>{{item.time}}</strong></p> <div id="c_{{reportShift.shift_id}}" class="panel box collapse" aria-expanded="false">
<p>Цена товара: <strong>{{item.price}} BYN</strong></p> <div ng-repeat="reportOrder in reportShift.orders">
<p>Количество: <strong>{{item.count}} шт</strong></p> <div id="c_{{reportShift.shift_id}}_{{reportOrder.order_id}}" class="box-header">
<p>На сумму: <strong>{{item.sum}} BYN</strong></p> <span class="pull-right label text-sm">Удалено: {{reportOrder.totalCount}} позиций. На сумму {{reportOrder.totalSum | curr}} BYN</span>
</small> <a data-toggle="collapse" data-parent="#ordersAccordion"
</h6> data-target="#co_{{reportShift.shift_id}}_{{reportOrder.order_id}}"
class="collapsed" aria-expanded="false">
<p> <h2>Заказ №{{reportOrder.order_id}}</h2>
Удалил: </a>
<strong>{{ item.who }}</strong> </div>
<br/> Подтвердил: <div id="co_{{reportShift.shift_id}}_{{reportOrder.order_id}}" class="collapse" aria-expanded="false">
<strong>{{ item.approved }}</strong> <div class="box-body">
<br/> Причина: <div class="table-responsive-xl">
<strong>{{ item.reason }}</strong> <table class="table table-bordered m-0">
</p> <thead>
</td> <tr>
</tr> <th>Имя</th>
</tbody> <th>Время/Причина</th>
<hr> <th>Товар/цена</th>
</table> <th>Кол-во</th>
<th>Итог</th>
<hr> </tr>
</thead>
<table class="table table-bordered"> <tbody>
<tbody> <tr ng-repeat="item in reportOrder.items">
<tr> <td>{{ item.who }}</td>
<td> <td>
<strong>Итого</strong> <ul class="list-unstyled">
</td> <li>{{ item.time }}</li>
<td style="text-align: right"> <li><small>{{ item.reason }}</small></li>
<strong>{{ report_delete.total_count }}</strong> удалений</td> </ul>
<td style="text-align: right">на сумму </td>
<strong>{{ report_delete.total_sum | curr }} BYN</strong> <td>
</td> <ul class="list-unstyled">
</tr> <li>{{ item.dish }}</li>
</tbody> <li><small>{{ item.price | curr }} BYN</small></li>
</table> </ul>
</td>
<td>{{ item.count }}</td>
<td>{{ item.total | curr}} BYN</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div> </div>
<table class="table table-bordered">
<tbody>
<tr>
<td>
<strong>Итого</strong>
</td>
<td style="text-align: right">
<strong>{{ totalCount }}</strong> удалений
</td>
<td style="text-align: right">на сумму
<strong>{{ totalSum | curr }} BYN</strong>
</td>
</tr>
</tbody>
</table>
<div ng-if="report_delete.length == 0"> <div ng-if="report_delete.length == 0">
<p>Удаления отсутствуют</p> <p>Удаления отсутствуют</p>
</div> </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-dialog modal-lg">
<div class="modal-content" id="reportRealisation"> <div class="modal-content" id="reportRealisation">
<div class="modal-header"> <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')"> <button class="btn btn-icon white" ng-click="printElem('#reportRealisation')">
<i class="fa fa-print"></i> <i class="fa fa-print"></i>
</button> </button>
@@ -9,9 +9,9 @@
<h5 class="modal-title">Отчет по реализации</h5> <h5 class="modal-title">Отчет по реализации</h5>
<span class="text-muted">{{start_date}} - {{end_date}}</span> <span class="text-muted">{{start_date}} - {{end_date}}</span>
</div> </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"> <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> <thead>
<th style="width: 70%">{{ printer.name }}</th> <th style="width: 70%">{{ printer.name }}</th>
<th style="width: 10%; text-align: right">{{ printer.count }}</th> <th style="width: 10%; text-align: right">{{ printer.count }}</th>
@@ -26,9 +26,7 @@
</tr> </tr>
</tbody> </tbody>
</table> </table>
<div ng-if="return_printers.length > 0"> <div ng-if="return_printers.length > 0">
<hr>
<table class="table table-bordered" ng-repeat="ret_print in return_printers"> <table class="table table-bordered" ng-repeat="ret_print in return_printers">
<thead> <thead>
<th style="width: 70%">{{ ret_print.name }} (возврат)</th> <th style="width: 70%">{{ ret_print.name }} (возврат)</th>
@@ -46,8 +44,6 @@
</table> </table>
</div> </div>
<hr>
<table class="table table-bordered"> <table class="table table-bordered">
<tbody> <tbody>
<tr> <tr>

View File

@@ -13,120 +13,171 @@
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-bordered"> <table class="table table-bordered">
<tbody> <tbody>
<tr> <tr>
<td colspan="2"> <td colspan="2">
<strong>Реализация</strong> <strong>Операции внесения/изъятия</strong>
</td> </td>
</tr> </tr>
<tr> <tr>
<td>Количество заказов</td> <td>Внесено наличными</td>
<td style="text-align: right">{{ statistic.orders_count }}</td> <td style="text-align: right">{{ fiscal.income_sum | curr }} BYN</td>
</tr> </tr>
<tr> <tr>
<td>Сумма заказов (без скидки) <strong>BYN</strong></td> <td>Выплачено наличными</td>
<td style="text-align: right">{{ statistic.total_sum | curr}}</td> <td style="text-align: right">{{ fiscal.outcome_sum | curr }} BYN</td>
</tr> </tr>
<tr> <tr>
<td>Скидка <strong>BYN</strong></td> <td colspan="2">
<td style="text-align: right">{{ statistic.discount_sum | curr}}</td> <strong>Реализация</strong>
</tr> </td>
</tr>
<tr>
<td>Количество заказов</td>
<td style="text-align: right">{{ realisation.orders_count }}</td>
</tr>
<tr>
<td>Сумма заказов (без скидки)</td>
<td style="text-align: right">{{ realisation.orders_sum_without_sales | curr}} BYN</td>
</tr>
<tr>
<td>Скидка</td>
<td style="text-align: right">{{ realisation.sale_sum | curr}} BYN</td>
</tr>
<tr> <tr>
<td>Итоговоя сумма <strong>BYN</strong></td> <td>Итоговоя сумма</td>
<td style="text-align: right">{{ statistic.orders_sum | curr}}</td> <td style="text-align: right">{{ realisation.orders_sum_with_sales | curr}} BYN</td>
</tr> </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>
</tr>
<tr> <tr>
<td colspan="2"> <td colspan="2">
<strong>Возвраты</strong> <strong>Возвраты</strong>
</td> </td>
</tr> </tr>
<tr> <tr>
<td>Количество возвратов</td> <td>Количество возвратов</td>
<td style="text-align: right">{{ statistic.return_count }}</td> <td style="text-align: right">{{ returns.returned_orders_count }}</td>
</tr> </tr>
<tr> <tr>
<td>Сумма возвратов <strong>BYN</strong></td> <td>Сумма возвратов</td>
<td style="text-align: right">{{ statistic.return_sum | curr }}</td> <td style="text-align: right">{{ returns.returned_items_sum | curr }} BYN</td>
</tr> </tr>
<tr> <tr>
<td colspan="2"> <td colspan="2">
<strong>Статистика</strong> <strong>Аннулирования</strong>
</td> </td>
</tr> </tr>
<tr> <tr>
<td>Количество гостей</td> <td>Количество аннулирований</td>
<td style="text-align: right">{{ statistic.clients_count }}</td> <td style="text-align: right">{{ cancellations.cancellations_count }}</td>
</tr> </tr>
<tr> <tr>
<td>Средний чек <strong>BYN</strong></td> <td>Сумма аннулирований</td>
<td style="text-align: right">{{ statistic.avg_order_sum | curr}}</td> <td style="text-align: right">{{ cancellations.cancellations_sum | curr }} BYN</td>
</tr> </tr>
<tr>
<td>Средний чек на 1-го гостя <strong>BYN</strong></td>
<td style="text-align: right">{{ statistic.avg_order_client_sum | curr}}</td>
</tr>
<tr> <tr>
<td colspan="2"> <td colspan="2">
<strong>Авансы</strong> <strong>Статистика</strong>
</td> </td>
</tr> </tr>
<tr> <tr>
<td>Количество авансов полученных</td> <td>Количество гостей</td>
<td style="text-align: right">{{ statistic.in_presale_count }}</td> <td style="text-align: right">{{ statistic.clients_count }}</td>
</tr> </tr>
<tr> <tr>
<td>Сумма авансов полученных <strong>BYN</strong></td> <td>Средний чек</td>
<td style="text-align: right">{{ statistic.in_presale_sum | curr}}</td> <td style="text-align: right">{{ statistic.clients_average_sum | curr}} BYN</td>
</tr> </tr>
<tr> <tr>
<td>Количество авансов возвращенных</td> <td>Средний чек на 1-го гостя</td>
<td style="text-align: right">{{ statistic.out_presale_count }}</td> <td style="text-align: right">{{ statistic.clients_average_sum_one | curr}} BYN</td>
</tr> </tr>
<tr>
<td>Сумма авансов возвращенных <strong>BYN</strong></td>
<td style="text-align: right">{{ statistic.out_presale_sum | curr}}</td>
</tr>
<tr> <tr>
<td colspan="2"> <td colspan="2">
<strong>Формы оплаты</strong> <strong>Авансы</strong>
</td> </td>
</tr> </tr>
<tr> <tr>
<td>Наличный расчет <strong>BYN</strong></td> <td>Количество авансов полученных</td>
<td style="text-align: right">{{ statistic.cash | curr}}</td> <td style="text-align: right">{{ presales.presales_income_count }}</td>
</tr> </tr>
<tr> <tr ng-if="presales.presales_income_cash_sum > 0">
<td>Наличный расчет (отложенные) <strong>BYN</strong></td> <td>Сумма авансов полученных наличными</td>
<td style="text-align: right">{{ statistic.wait_sum | curr}}</td> <td style="text-align: right">{{ presales.presales_income_cash_sum | curr}} BYN</td>
</tr> </tr>
<tr> <tr ng-if="presales.presales_income_credit_sum > 0">
<td>Безналичный расчет <strong>BYN</strong></td> <td>Сумма авансов полученных кредитной картой</td>
<td style="text-align: right">{{ statistic.clearing | curr}}</td> <td style="text-align: right">{{ presales.presales_income_credit_sum | curr}} BYN</td>
</tr> </tr>
<tr> <tr ng-if="presales.presales_income_clearing_sum > 0">
<td>Кредитными картами <strong>BYN</strong></td> <td>Сумма авансов полученных безналичным расчетом</td>
<td style="text-align: right">{{ statistic.credit | curr}}</td> <td style="text-align: right">{{ presales.presales_income_clearing_sum | curr}} BYN</td>
</tr> </tr>
<tr> <tr ng-if="presales.presales_income_discount_sum > 0">
<td>Питание штата <strong>BYN</strong></td> <td>Сумма авансов полученных через скидку</td>
<td style="text-align: right">{{ statistic.self | curr}}</td> <td style="text-align: right">{{ presales.presales_income_discount_sum | curr}} BYN</td>
</tr> </tr>
<tr> <tr>
<td>По ранее полученному авансу <strong>BYN</strong></td> <td>Количество авансов возвращенных</td>
<td style="text-align: right">{{ statistic.presale | curr}}</td> <td style="text-align: right">{{ presales.presales_outcome_count }}</td>
</tr> </tr>
<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>
<td colspan="2">
<strong>Формы оплаты</strong>
</td>
</tr>
<tr>
<td>Наличный расчет</td>
<td style="text-align: right">{{ payments.pay_cash | curr}} BYN</td>
</tr>
<tr>
<td>Кредитными картами</td>
<td style="text-align: right">{{ payments.pay_credit | curr}} BYN</td>
</tr>
<tr>
<td>Безналичный расчет</td>
<td style="text-align: right">{{ payments.pay_clearing | curr}} BYN</td>
</tr>
<tr>
<td>Питание штата</td>
<td style="text-align: right">{{ payments.pay_self | curr}} BYN</td>
</tr>
<tr>
<td>По ранее полученному авансу</td>
<td style="text-align: right">{{ payments.pay_presale | curr}} BYN</td>
</tr>
<tr>
<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> </tbody>
</table> </table>

View File

@@ -57,6 +57,7 @@
<a class="dropdown-item" ng-click="reportDelete(shift)">По удалениям</a> <a class="dropdown-item" ng-click="reportDelete(shift)">По удалениям</a>
<a class="dropdown-item" ng-click="reportStaff(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="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="reportOrders(shift)">По заказам</a> -->
<a class="dropdown-item" ng-click="reportMerged(shift)">По объединениям</a> <a class="dropdown-item" ng-click="reportMerged(shift)">По объединениям</a>
<a class="dropdown-item" ng-click="reportSliced(shift)">По разбиениям</a> <a class="dropdown-item" ng-click="reportSliced(shift)">По разбиениям</a>
@@ -95,8 +96,8 @@
</div> </div>
</div> </div>
<div class="modal fade" id="report-delete" data-backdrop="true"> <div class="modal fade" id="shift-delete" data-backdrop="true">
<div ui-include="'../views/reports/items/deleted.html'"></div> <div ui-include="'../views/shifts/items/deleted.html'"></div>
</div> </div>
<div class="modal fade" id="report-realisation" data-backdrop="true"> <div class="modal fade" id="report-realisation" data-backdrop="true">
@@ -137,4 +138,16 @@
<div class="modal fade" id="preload-modal" data-backdrop="true"> <div class="modal fade" id="preload-modal" data-backdrop="true">
<div ui-include="'../views/shifts/preload.html'"></div> <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> </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>