1914 行
86 KiB
PHP
可执行文件
1914 行
86 KiB
PHP
可执行文件
<?php
|
|
|
|
namespace Retail\Controller;
|
|
|
|
use Common\Business\Inventory;
|
|
use Common\Business\SerialNumberGoods;
|
|
use Common\Business\Store;
|
|
use Common\Model\RetailGuideModel;
|
|
use Common\Model\RetailSellModel;
|
|
use Common\Model\RetailVipModel;
|
|
use Common\Order\BillOrder;
|
|
use Think\Controller;
|
|
|
|
//[1.9.20]
|
|
|
|
/**
|
|
* Class StatisticsController
|
|
* @package Retail\Controller
|
|
*/
|
|
class StatisticsController extends BaseController
|
|
{
|
|
/**
|
|
* 商户统计报表(加载模板)
|
|
*/
|
|
public function index()
|
|
{
|
|
// 操作权限
|
|
$arr = array(
|
|
'goods_statistics' => '/index.php/Retail/Statistics/goods_statistics',
|
|
'stocks' => '/index.php/Retail/Statistics/stocks',
|
|
'sell_statistics' => '/index.php/Retail/Statistics/sell_statistics',
|
|
'sell_order' => '/index.php/Retail/Statistics/sell_order',
|
|
'inventoryList' => '/index.php/Retail/Statistics/getGoodsInventoryList',
|
|
'inventoryInfo' => '/index.php/Retail/Statistics/getGoodsInventoryInfo',
|
|
);
|
|
$authArr = checkFunction($arr);
|
|
$this->assign('authArr', json_encode($authArr));
|
|
$result = $this->getStoreList();
|
|
$this->assign('storeList', json_encode($result['store_list']));
|
|
$this->assign('platform_type', $this->role_info['platform_type']);
|
|
$this->display();
|
|
}
|
|
|
|
/**
|
|
* 获取门店列表
|
|
* @return array
|
|
*/
|
|
protected function getStoreList()
|
|
{
|
|
$merchant_id = session('merchant_userinfo')['id'];
|
|
$store = new Store();
|
|
$storeList = $store->getStoreList(['merchant_id' => $merchant_id]); //获取门店列表
|
|
$res = array('status' => 1, 'store_list' => $storeList, 'merchant_id' => $merchant_id);
|
|
return $res;
|
|
}
|
|
|
|
/**
|
|
* 展示门店库存统计
|
|
* 获取普通商品库存
|
|
* @return array $res
|
|
*/
|
|
public function getGoodsStock()
|
|
{
|
|
// 获取门店
|
|
$result = $this->getStoreList();
|
|
if ($result['status'] == 0) {
|
|
$this->ajaxReturn($result);
|
|
}
|
|
$store_list = $result['store_list'];
|
|
$merchant_id = $result['merchant_id'];
|
|
// 门店商品条件
|
|
$map = array(
|
|
'g.merchant_id' => $merchant_id,
|
|
'g.status' => array('in', array(0, 1)),
|
|
'g.attribute_state' => 1,
|
|
);
|
|
// 处理数据
|
|
foreach ($store_list as &$val) {
|
|
$map1 = $map;
|
|
$map1['g.store_id'] = $val['id'];
|
|
// 合计
|
|
$result2 = $this->merchantTotalStoreGoodsStock($map1);
|
|
$val['count'] = floatval(round($result2['count'], 2));
|
|
$val['all_purchase'] = floatval(round($result2['all_purchase'], 2));
|
|
$val['piece_stock'] = floatval(round($result2['piece_stock'], 2));
|
|
$val['pricing_stock'] = floatval(round($result2['pricing_stock'], 2));
|
|
$val['sell_retail_total'] = floatval(round($result2['sell_retail_total'], 2));
|
|
$val['sell_online_total'] = floatval(round($result2['sell_online_total'], 2));
|
|
unset($map1);
|
|
unset($result2);
|
|
}
|
|
$res['status'] = 1;
|
|
$res['goods_statistics'] = $store_list;
|
|
$this->ajaxReturn($res);
|
|
}
|
|
|
|
/**
|
|
* 商户统计门店普通商品库存
|
|
* @param array $map 查询条件
|
|
* @return array $res
|
|
*/
|
|
protected function merchantTotalStoreGoodsStock($map)
|
|
{
|
|
// 定义返回值
|
|
$res = array(
|
|
'count' => 0, // 商品合计
|
|
'all_purchase' => 0, // 进价合计
|
|
'piece_stock' => 0, // 计件库存合计
|
|
'pricing_stock' => 0, // 计量库存合计
|
|
'sell_retail_total' => 0, // 店内售出合计
|
|
'sell_online_total' => 0, // 商城售出合计
|
|
);
|
|
// 查询门店商品
|
|
$goods_list = M('retail_goods as g')
|
|
->join('ls_retail_store_sale_goods as a on g.id=a.goods_id')
|
|
->field('g.purchase_price,g.retail_price,g.online_price,g.pricing_method,a.goods_num')
|
|
->where($map)
|
|
->select();
|
|
foreach ($goods_list as &$val) {
|
|
$res['count']++;
|
|
$res['all_purchase'] += floatval($val['goods_num']) * floatval($val['purchase_price']);
|
|
$res['sell_retail_total'] += floatval($val['goods_num']) * floatval($val['retail_price']);
|
|
$res['sell_online_total'] += floatval($val['goods_num']) * floatval($val['online_price']);
|
|
if ($val['pricing_method'] == 1) { // 计件商品
|
|
$res['piece_stock'] += floatval($val['goods_num']);
|
|
} else { // 计量商品
|
|
$res['pricing_stock'] += floatval($val['goods_num']);
|
|
}
|
|
}
|
|
return $res;
|
|
}
|
|
|
|
/**
|
|
* 展示门店库存统计
|
|
* 获取规格商品库存
|
|
* @return array $res
|
|
*/
|
|
public function getSkuGoodsStock()
|
|
{
|
|
// 获取门店
|
|
$result = $this->getStoreList();
|
|
if ($result['status'] == 0) {
|
|
$this->ajaxReturn($result);
|
|
}
|
|
$store_list = $result['store_list'];
|
|
$merchant_id = $result['merchant_id'];
|
|
// 门店商品条件
|
|
$map = array(
|
|
'merchant_id' => $merchant_id,
|
|
'status' => array('in', array(0, 1)),
|
|
'attribute_state' => 2,
|
|
);
|
|
// 处理数据
|
|
foreach ($store_list as &$val) {
|
|
$map1 = $map;
|
|
$map1['store_id'] = $val['id'];
|
|
$result2 = $this->merchantTotalStoreSkuGoodsStock($map1);
|
|
$val['count'] = floatval(round($result2['count'], 2));
|
|
$val['all_purchase'] = floatval(round($result2['all_purchase'], 2));
|
|
$val['piece_stock'] = floatval(round($result2['piece_stock'], 2));
|
|
$val['pricing_stock'] = floatval(round($result2['pricing_stock'], 2));
|
|
$val['sell_retail_total'] = floatval(round($result2['sell_retail_total'], 2));
|
|
$val['sell_online_total'] = floatval(round($result2['sell_online_total'], 2));
|
|
unset($map1);
|
|
unset($result2);
|
|
}
|
|
$res['status'] = 1;
|
|
$res['sku_statistics'] = $store_list;
|
|
$this->ajaxReturn($res);
|
|
}
|
|
|
|
/**
|
|
* 商户统计门店规格商品库存
|
|
* @param array $map 查询条件
|
|
* @return array $res
|
|
*/
|
|
protected function merchantTotalStoreSkuGoodsStock($map)
|
|
{
|
|
// 定义返回值
|
|
$res = array(
|
|
'count' => 0, // 商品合计
|
|
'all_purchase' => 0, // 进价合计
|
|
'piece_stock' => 0, // 计件库存合计
|
|
'pricing_stock' => 0, // 计量库存合计
|
|
'sell_retail_total' => 0, // 店内售出合计
|
|
'sell_online_total' => 0, // 商城售出合计
|
|
);
|
|
// 查询门店商品id
|
|
$goods_ids = M('retail_goods')->where($map)->getField('id', true);
|
|
if (empty($goods_ids)) {
|
|
return $res;
|
|
}
|
|
// 查询规格商品
|
|
$map2 = array(
|
|
's.goods_id' => array('in', $goods_ids),
|
|
's.store_id' => $map['store_id'],
|
|
's.status' => 1,
|
|
's.state' => 0
|
|
);
|
|
$sku_list = M('retail_sku_goods as s')
|
|
->join('ls_retail_store_sale_goods as a on a.sku_id=s.id')
|
|
->field('s.purchase_price,s.retail_price,s.online_price,a.pricing_method,a.goods_num')
|
|
->where($map2)
|
|
->select();
|
|
foreach ($sku_list as &$val) {
|
|
$res['count']++;
|
|
$res['all_purchase'] += floatval($val['goods_num']) * floatval($val['purchase_price']);
|
|
$res['sell_retail_total'] += floatval($val['goods_num']) * floatval($val['retail_price']);
|
|
$res['sell_online_total'] += floatval($val['goods_num']) * floatval($val['online_price']);
|
|
if ($val['pricing_method'] == 1) { // 计件商品
|
|
$res['piece_stock'] += floatval($val['goods_num']);
|
|
} else { // 计量商品
|
|
$res['pricing_stock'] += floatval($val['goods_num']);
|
|
}
|
|
}
|
|
return $res;
|
|
}
|
|
|
|
/**
|
|
* 获取销售统计
|
|
* @return array $res
|
|
*/
|
|
public function getSellTotal()
|
|
{
|
|
$result = $this->getStoreList();
|
|
if ($result['status'] == 0) {
|
|
$this->ajaxReturn($result);
|
|
}
|
|
$store_list = $result['store_list'];
|
|
$merchant_id = $result['merchant_id'];
|
|
// 定义公共查询条件
|
|
$map = array(
|
|
'b.merchant_id' => $merchant_id,
|
|
'b.pay_state' => 1,
|
|
'b.pay_type' => array('neq', 0),
|
|
);
|
|
foreach ($store_list as &$val) {
|
|
$map1 = $map;
|
|
$map1['b.store_id'] = $val['id'];
|
|
$result2 = $this->merchantGetStoreSellTotal($map1);
|
|
$val['sell_num'] = floatval($result2['sell_num']);
|
|
$val['refund_num'] = floatval($result2['refund_num']);
|
|
$val['sell_money'] = floatval($result2['sell_money']);
|
|
$val['refund_money'] = floatval($result2['refund_money']);
|
|
$val['income'] = floatval($result2['income']);
|
|
$val['cost'] = floatval($result2['cost']);
|
|
$val['profit'] = floatval($result2['profit']);
|
|
$val['profit_margin'] = floatval($result2['profit_margin']) . '%';
|
|
unset($map1);
|
|
unset($result2);
|
|
}
|
|
$res['status'] = 1;
|
|
$res['sell_statistics'] = $store_list;
|
|
$this->ajaxReturn($res);
|
|
}
|
|
|
|
/**
|
|
* 统计金额(公共方法)
|
|
* @param array $map 查询条件
|
|
* @return array $res
|
|
*/
|
|
protected function merchantGetStoreSellTotal($map)
|
|
{
|
|
// 销售
|
|
$map['b.order_type'] = 1;
|
|
// 笔数
|
|
$sell_num = M('retail_bill_order as b')
|
|
->join('ls_retail_bill_discount as d on b.id=d.bill_id')
|
|
->join('ls_retail_bill_online as o on b.id=o.bill_id', 'LEFT')
|
|
->where($map)
|
|
->count();
|
|
// 金额
|
|
$sell_money = M('retail_bill_order as b')
|
|
->join('ls_retail_bill_discount as d on b.id=d.bill_id')
|
|
->join('ls_retail_bill_online as o on b.id=o.bill_id', 'LEFT')
|
|
->where($map)
|
|
->sum('all_money');
|
|
// 所有销售成本
|
|
$sell_ids = M('retail_bill_order as b')
|
|
->join('ls_retail_bill_discount as d on b.id=d.bill_id')
|
|
->join('ls_retail_bill_online as o on b.id=o.bill_id', 'LEFT')
|
|
->field('b.id')
|
|
->where($map)
|
|
->select();
|
|
$sell_ids = array_column($sell_ids, 'id');
|
|
$sell_cost = 0;
|
|
if ($sell_ids) {
|
|
// 销售成本
|
|
$all_sell = M('retail_sell')->field('num,purchase_price')->where(array('bill_id' => array('in', $sell_ids), 'purchase_price' => array('gt', 0)))->select();
|
|
foreach ($all_sell as &$v1) {
|
|
$sell_cost += floatval(round($v1['num'] * $v1['purchase_price'], 2));
|
|
}
|
|
}
|
|
// 退款
|
|
unset($map['b.order_type']);
|
|
$map['b.order_type'] = 2;
|
|
// 笔数
|
|
$refund_num = M('retail_bill_order as b')
|
|
->join('ls_retail_bill_discount as d on b.id=d.bill_id')
|
|
->join('ls_retail_bill_online as o on b.id=o.bill_id', 'LEFT')
|
|
->where($map)
|
|
->count();
|
|
// 金额
|
|
$refund_money = M('retail_bill_order as b')
|
|
->join('ls_retail_bill_discount as d on b.id=d.bill_id')
|
|
->join('ls_retail_bill_online as o on b.id=o.bill_id', 'LEFT')
|
|
->where($map)
|
|
->sum('all_money');
|
|
// 所有退款成本
|
|
$refund_ids = M('retail_bill_order as b')
|
|
->join('ls_retail_bill_discount as d on b.id=d.bill_id')
|
|
->join('ls_retail_bill_online as o on b.id=o.bill_id', 'LEFT')
|
|
->field('b.id')
|
|
->where($map)
|
|
->select();
|
|
$refund_ids = $refund_ids ? array_column($refund_ids, 'id') : '0';
|
|
// 销售成本
|
|
$refund_cost = 0;
|
|
if ($refund_ids) {
|
|
$all_refund = M('retail_sell')->field('num,purchase_price')->where(array('bill_id' => array('in', $refund_ids), 'purchase_price' => array('gt', 0)))->select();
|
|
foreach ($all_refund as &$v2) {
|
|
$refund_cost += floatval(round($v2['num'] * $v2['purchase_price'], 2));
|
|
}
|
|
}
|
|
// 计算成本 (销售成本 - 退款成本)
|
|
$cost = floatval(round($sell_cost - $refund_cost, 2));
|
|
// 实际金额 (销售金额 - 退款金额)
|
|
$income = floatval(round($sell_money - $refund_money, 2));
|
|
// 计算盈利,利润()
|
|
$profit = floatval(round($income - $cost, 2));
|
|
$profit_margin = floatval(round($profit / $income * 100, 2)) . '%';
|
|
$res = array(
|
|
'sell_num' => $sell_num ? $sell_num : 0,
|
|
'refund_num' => $refund_num ? $refund_num : 0,
|
|
'sell_money' => $sell_money ? $sell_money : 0,
|
|
'refund_money' => $refund_money ? $refund_money : 0,
|
|
'income' => $income ? $income : 0,
|
|
'cost' => $cost ? $cost : 0,
|
|
'profit' => $profit ? $profit : 0,
|
|
'profit_margin' => $profit_margin ? $profit_margin : '0%'
|
|
);
|
|
return $res;
|
|
}
|
|
|
|
/**
|
|
* 商品库存统计(加载模板)
|
|
* @param int $storeid
|
|
*/
|
|
public function stocks()
|
|
{
|
|
// 操作权限
|
|
$arr = array(
|
|
'stock_export' => '/index.php/Retail/Statistics/stock_export',
|
|
);
|
|
$authArr = checkFunction($arr);
|
|
// 接受参数
|
|
$store_id = I('get.store_id');
|
|
$this->assign('authArr', $authArr);
|
|
$this->assign('store_id', $store_id ? $store_id : 0);
|
|
$this->display();
|
|
}
|
|
|
|
/**
|
|
* 获取分类 品牌 供货商(公共方法)
|
|
* @return array $res
|
|
*/
|
|
public function get_seek_list()
|
|
{
|
|
$user = I('session.ls_userinfo');
|
|
$store_id = I('post.store_id');
|
|
if (!$store_id) {
|
|
$res = array('status' => 0, 'msg' => '参数缺失');
|
|
$this->ajaxReturn($res);
|
|
}
|
|
// 商品分类
|
|
$class_data = M('retail_goods_class')->field('id,class_name')->where(array('pid' => 0, 'status' => 0, 'merchantid' => $user['merchantid'], 'type' => 1))->order('id asc')->select();
|
|
if ($class_data) {
|
|
foreach ($class_data as &$val) {
|
|
$children1 = M('retail_goods_class')->field('id,class_name')->where(array('pid' => $val['id'], 'status' => 0, 'merchantid' => $user['merchantid'], 'type' => 2))->order('id asc')->select();
|
|
if ($children1) {
|
|
foreach ($children1 as &$value) {
|
|
$children2 = M('retail_goods_class')->field('id,class_name')->where(array('pid' => $value['id'], 'status' => 0, 'merchantid' => $user['merchantid'], 'type' => 3))->order('id asc')->select();
|
|
$value['children'] = $children2;
|
|
}
|
|
}
|
|
$val['children'] = $children1;
|
|
}
|
|
}
|
|
// 供货商
|
|
$res['supplier'] = M('retail_supplier')->field('id,supplier_name')->where(array('merchantid' => $user['merchantid'], 'status' => 1))->select();
|
|
// 品牌
|
|
$res['goods_brand'] = M('retail_goods_brand')->field('id,name')->where(array('merchantid' => $user['merchantid'], 'state' => 0))->select();
|
|
// 导购员
|
|
$res['guide'] = M('retail_guide')->field('id,guidename')->where(array('merchantid' => $user['merchantid'], 'storeid' => $store_id, 'status' => 1))->select();
|
|
$res['class_data'] = $class_data;
|
|
$this->ajaxReturn($res);
|
|
}
|
|
|
|
/**
|
|
* 获取普通商品库存展示
|
|
* @param int $page 分页
|
|
* @param int $limit 每页数量
|
|
* @param array $seek_data 搜索条件
|
|
* @return array $res
|
|
*/
|
|
public function getGoodsList()
|
|
{
|
|
// 获取session
|
|
$user = I('session.ls_userinfo');
|
|
$store_id = I('post.store_id');
|
|
// 接收数据
|
|
$page = (int)I('post.page');
|
|
$limit = (int)I('post.limit');
|
|
$seek_data = I('post.seek_data');
|
|
// 分类搜索
|
|
$class_id = array_pop($seek_data['class_ids']);
|
|
if ($class_id) {
|
|
$class1 = M('retail_goods_class')->field('id,pid')->where(array('id' => $class_id))->find();
|
|
if ($class1['pid'] == 0) { // 一级分类
|
|
$class = M('retail_goods_class as c1')
|
|
->join('ls_retail_goods_class as c2 on c1.id=c2.pid')
|
|
->join('ls_retail_goods_class as c3 on c2.id=c3.pid AND c3.status=0', 'LEFT')
|
|
->where(array('c1.id' => $class_id, 'c2.status' => 0))
|
|
->field('c2.id,c3.id as c3_id')
|
|
->select();
|
|
if ($class) {
|
|
$arr = array();
|
|
$arr[] = $class_id;
|
|
foreach ($class as &$val) {
|
|
if (!in_array($val['id'], $arr)) {
|
|
$arr[] = $val['id'];
|
|
}
|
|
if ($val['c3_id']) {
|
|
if (!in_array($val['c3_id'], $arr)) {
|
|
$arr[] = $val['c3_id'];
|
|
}
|
|
}
|
|
}
|
|
$map['g.goods_class_id'] = array('in', $arr);
|
|
} else {
|
|
$map['g.goods_class_id'] = $class_id;
|
|
}
|
|
} else {
|
|
$class2 = M('retail_goods_class')->field('id,pid')->where(array('id' => $class1['pid']))->find();
|
|
if ($class2['pid'] == 0) { // 二级分类
|
|
$class = M('retail_goods_class as c1')
|
|
->join('ls_retail_goods_class as c2 on c1.id=c2.pid')
|
|
->where(array('c1.id' => $class_id, 'c2.status' => 0))
|
|
->field('c2.id')
|
|
->select();
|
|
if ($class) {
|
|
$arr = array();
|
|
$arr[] = $class_id;
|
|
foreach ($class as &$val) {
|
|
if (!in_array($val['id'], $arr)) {
|
|
$arr[] = $val['id'];
|
|
}
|
|
}
|
|
$map['g.goods_class_id'] = array('in', $arr);
|
|
} else {
|
|
$map['g.goods_class_id'] = $class_id;
|
|
}
|
|
} else { // 三级分类
|
|
$map['g.goods_class_id'] = $class_id;
|
|
}
|
|
}
|
|
}
|
|
// 商品名称搜索
|
|
if (trim($seek_data['goods_name'], '')) {
|
|
$map['g.goods_name'] = array('like', '%' . $seek_data['goods_name'] . '%');
|
|
}
|
|
// 商品货号、条码搜索
|
|
if (trim($seek_data['keyword'], '')) {
|
|
$map['g.goods_number|goods_code'] = array('like', '%' . $seek_data['keyword'] . '%');
|
|
}
|
|
// 供货商搜索
|
|
if ($seek_data['supplier_id']) {
|
|
$map['g.supplier_id'] = $seek_data['supplier_id'];
|
|
}
|
|
// 品牌搜索
|
|
if ($seek_data['goods_brand_id']) {
|
|
$map['g.goods_brand_id'] = $seek_data['goods_brand_id'];
|
|
}
|
|
// 称重类型搜索
|
|
if ($seek_data['pricing_method']) {
|
|
$map['g.pricing_method'] = $seek_data['pricing_method'];
|
|
}
|
|
$map['g.store_id'] = $store_id;
|
|
$map['g.merchant_id'] = $user['merchantid'];
|
|
$map['g.status'] = array('in', "0,1");
|
|
$map['g.attribute_state'] = 1;
|
|
$goods_list = M('retail_goods as g')
|
|
->join('ls_retail_store_sale_goods as a on g.id=a.goods_id')
|
|
->field('g.id as goods_id,g.goods_class_id,g.goods_name,g.goods_number,g.goods_code,g.purchase_price,g.retail_price,g.online_price,g.company,g.pricing_method,g.source_type,g.shop_mem_status,g.shop_mem_price,g.store_mem_status,g.store_mem_price,g.goods_brand_id,g.supplier_id,g.serial_number_state,a.goods_num')
|
|
->where($map)
|
|
->page($page, $limit)
|
|
->order('g.id desc')
|
|
->select();
|
|
$total = M('retail_goods as g')
|
|
->join('ls_retail_store_sale_goods as a on g.id=a.goods_id')
|
|
->where($map)->count();
|
|
foreach ($goods_list as &$val) {
|
|
// 获取商品分类
|
|
$class1 = M('retail_goods_class')->field('id,class_name,pid')->where(array('id' => $val['goods_class_id']))->find();
|
|
if ($class1['pid'] == 0) {
|
|
$val['class_name'] = '/' . $class1['class_name'];
|
|
} else {
|
|
$class2 = M('retail_goods_class')->field('id,class_name,pid')->where(array('id' => $class1['pid']))->find();
|
|
if ($class2['pid'] == 0) {
|
|
$val['class_name'] = '/' . $class2['class_name'] . '/' . $class1['class_name'];
|
|
} else {
|
|
$class3 = M('retail_goods_class')->field('id,class_name,pid')->where(array('id' => $class2['pid']))->find();
|
|
$val['class_name'] = '/' . $class3['class_name'] . '/' . $class2['class_name'] . '/' . $class1['class_name'];
|
|
}
|
|
}
|
|
// 处理货号
|
|
$val['goods_number'] = $val['goods_number'] ? $val['goods_number'] : '未设置';
|
|
// 进价合计
|
|
$val['all_purchase'] = floatval(round($val['goods_num'] * $val['purchase_price'], 2));
|
|
// 处理进价
|
|
$val['purchase_price'] = floatval($val['purchase_price']);
|
|
// 处理库存(加上单位)
|
|
$val['goods_num'] = $val['goods_num'] ? floatval($val['goods_num']) : 0;
|
|
$val['stock'] = floatval($val['goods_num']) . $val['company'];
|
|
// 处理店内价
|
|
$val['retail_price'] = floatval($val['retail_price']);
|
|
// 处理商城价
|
|
$val['online_price'] = floatval($val['online_price']);
|
|
// 店内售出合计
|
|
$val['sell_retail_total'] = floatval(round($val['retail_price'] * $val['goods_num'], 2));
|
|
// 商城售出合计
|
|
$val['sell_online_total'] = floatval(round($val['online_price'] * $val['goods_num'], 2));
|
|
// 店内会员价
|
|
$val['store_mem_price'] = $val['store_mem_status'] == 1 && $val['store_mem_price'] > 0 ? $val['store_mem_price'] : '关闭';
|
|
// 商城会员价
|
|
$val['shop_mem_price'] = $val['shop_mem_status'] == 1 && $val['shop_mem_price'] > 0 ? $val['shop_mem_price'] : '关闭';
|
|
// 称重类型
|
|
$val['exchange_weigh_type'] = $val['pricing_method'] == 1 ? '非称重' : '称重';
|
|
// 供货商
|
|
if ($val['supplier_id']) {
|
|
$supplier_name = M('retail_supplier')->where(array('id' => $val['supplier_id'], 'merchantid' => $user['merchantid'], 'status' => 1))->getField('supplier_name');
|
|
$val['supplier_name'] = $supplier_name ? $supplier_name : '无';
|
|
} else {
|
|
$val['supplier_name'] = '无';
|
|
}
|
|
// 商品品牌
|
|
if ($val['goods_brand_id']) {
|
|
$goods_brand_name = M('retail_goods_brand')->where(array('id' => $val['goods_brand_id'], 'merchantid' => $user['merchantid'], 'state' => 0))->getField('name');
|
|
$val['goods_brand_name'] = $goods_brand_name ? $goods_brand_name : '无';
|
|
} else {
|
|
$val['goods_brand_name'] = '无';
|
|
}
|
|
// 商品来源
|
|
switch ($val['source_type']) {
|
|
case 1:
|
|
$val['source_name'] = '店长添加';
|
|
break;
|
|
case 2:
|
|
$val['source_name'] = '同步商户';
|
|
break;
|
|
case 3:
|
|
$val['source_name'] = '收银员添加';
|
|
break;
|
|
default:
|
|
$val['source_name'] = '未知来源';
|
|
}
|
|
}
|
|
$res = $this->goodsStatistics($map);
|
|
$res['status'] = $goods_list ? 1 : 0;
|
|
$res['goods_list'] = $goods_list;
|
|
$res['total'] = $total ? (int)$total : 0;
|
|
$this->ajaxReturn($res);
|
|
}
|
|
|
|
/**
|
|
* 统计普通商品数据
|
|
* @param array $map 搜索条件
|
|
* @return array $res
|
|
*/
|
|
protected function goodsStatistics($map)
|
|
{
|
|
$goods = M('retail_goods as g')
|
|
->join('ls_retail_store_sale_goods as a on g.id=a.goods_id')
|
|
->field('g.purchase_price,g.retail_price,g.online_price,g.pricing_method,a.goods_num')
|
|
->where($map)
|
|
->order('g.id desc')
|
|
->select();
|
|
$weigh_stock = 0; // 称重总库存
|
|
$not_weigh_stock = 0; // 非承重总库存
|
|
$purchase_price = 0; // 总进价
|
|
$retail_price_total = 0; // 店内售出合计
|
|
$online_price_total = 0; // 商城售出合计
|
|
foreach ($goods as &$val) {
|
|
if ($val['pricing_method'] == 1) { // 称重
|
|
$not_weigh_stock += $val['goods_num'];
|
|
} else { // 非称重
|
|
$weigh_stock += $val['goods_num'];
|
|
}
|
|
$purchase_price += $val['goods_num'] * $val['purchase_price'];
|
|
$retail_price_total += $val['goods_num'] * $val['retail_price'];
|
|
$online_price_total += $val['goods_num'] * $val['online_price'];
|
|
}
|
|
$res['purchase_price'] = $purchase_price ? floatval(round($purchase_price, 2)) : 0;
|
|
$res['weigh_stock'] = $weigh_stock ? floatval($weigh_stock) : 0;
|
|
$res['not_weigh_stock'] = $not_weigh_stock ? floatval($not_weigh_stock) : 0;
|
|
$res['retail_price_total'] = $retail_price_total ? floatval(round($retail_price_total, 2)) : 0;
|
|
$res['online_price_total'] = $online_price_total ? floatval(round($online_price_total, 2)) : 0;
|
|
return $res;
|
|
}
|
|
|
|
/**
|
|
* 获取规格商品库存展示
|
|
* @param int $page 分页
|
|
* @param int $limit 每页数量
|
|
* @param array $seek_data 搜索条件
|
|
* @return array $res
|
|
*/
|
|
public function getSkuGoodsList()
|
|
{
|
|
$user = I('session.ls_userinfo');
|
|
$store_id = I('post.store_id');
|
|
$page = (int)I('post.page');
|
|
$limit = (int)I('post.limit');
|
|
$seek_data = I('post.seek_data');
|
|
// 分类搜索
|
|
$class_id = array_pop($seek_data['class_ids']);
|
|
if ($class_id) {
|
|
$class1 = M('retail_goods_class')->field('id,pid')->where(array('id' => $class_id))->find();
|
|
if ($class1['pid'] == 0) { // 一级分类
|
|
$class = M('retail_goods_class as c1')
|
|
->join('ls_retail_goods_class as c2 on c1.id=c2.pid')
|
|
->join('ls_retail_goods_class as c3 on c2.id=c3.pid AND c3.status=0', 'LEFT')
|
|
->where(array('c1.id' => $class_id, 'c2.status' => 0))
|
|
->field('c2.id,c3.id as c3_id')
|
|
->select();
|
|
if ($class) { // 一级分类有子分类
|
|
$arr = array();
|
|
$arr[] = $class_id;
|
|
foreach ($class as &$val) {
|
|
if (!in_array($val['id'], $arr)) {
|
|
$arr[] = $val['id'];
|
|
}
|
|
if ($val['c3_id']) {
|
|
if (!in_array($val['c3_id'], $arr)) {
|
|
$arr[] = $val['c3_id'];
|
|
}
|
|
}
|
|
}
|
|
$map['goods_class_id'] = array('in', $arr);
|
|
} else { // 一级分类无子分类
|
|
$map['goods_class_id'] = $class_id;
|
|
}
|
|
} else {
|
|
$class2 = M('retail_goods_class')->field('id,pid')->where(array('id' => $class1['pid']))->find();
|
|
if ($class2['pid'] == 0) { // 二级分类
|
|
$class = M('retail_goods_class as c1')
|
|
->join('ls_retail_goods_class as c2 on c1.id=c2.pid')
|
|
->where(array('c1.id' => $class_id, 'c2.status' => 0))
|
|
->field('c2.id')
|
|
->select();
|
|
if ($class) {
|
|
$arr = array();
|
|
$arr[] = $class_id;
|
|
foreach ($class as &$val) {
|
|
if (!in_array($val['id'], $arr)) {
|
|
$arr[] = $val['id'];
|
|
}
|
|
}
|
|
$map['goods_class_id'] = array('in', $arr);
|
|
} else {
|
|
$map['goods_class_id'] = $class_id;
|
|
}
|
|
} else { // 三级分类
|
|
$map['goods_class_id'] = $class_id;
|
|
}
|
|
}
|
|
}
|
|
// 商品名称搜索
|
|
if (trim($seek_data['goods_name'], '')) {
|
|
$map['goods_name'] = array('like', '%' . $seek_data['goods_name'] . '%');
|
|
}
|
|
// 商品货号、条码搜索
|
|
if (trim($seek_data['keyword'], '')) {
|
|
$map['goods_number|goods_code'] = array('like', '%' . $seek_data['keyword'] . '%');
|
|
}
|
|
// 供货商搜索
|
|
if ($seek_data['supplier_id']) {
|
|
$map['supplier_id'] = $seek_data['supplier_id'];
|
|
}
|
|
// 品牌搜索
|
|
if ($seek_data['goods_brand_id']) {
|
|
$map['goods_brand_id'] = $seek_data['goods_brand_id'];
|
|
}
|
|
// 称重类型搜索
|
|
if ($seek_data['pricing_method']) {
|
|
$map['pricing_method'] = $seek_data['pricing_method'];
|
|
}
|
|
$map['store_id'] = $store_id;
|
|
$map['merchant_id'] = $user['merchantid'];
|
|
$map['status'] = array('in', "0,1");
|
|
$map['attribute_state'] = 2;
|
|
$goods_ids = M('retail_goods')->where($map)->getField('id', true);
|
|
if (!$goods_ids) {
|
|
$res['status'] = 0;
|
|
$res['msg'] = '暂无商品';
|
|
$this->ajaxReturn($res);
|
|
}
|
|
$where['sk.goods_id'] = array('in', $goods_ids);
|
|
$where['sk.store_id'] = $store_id;
|
|
$where['sk.status'] = 1;
|
|
$where['sk.state'] = 0;
|
|
$sku_list = M('retail_sku_goods as sk')
|
|
->join('ls_retail_store_sale_goods as a on a.sku_id=sk.id')
|
|
->join('ls_retail_goods as g on g.id=a.goods_id')
|
|
->field('sk.goods_id,sk.purchase_price,sk.sku_code as goods_code,sk.retail_price,sk.online_price,sk.sku_id_list,sk.shop_mem_price,sk.store_mem_price,g.goods_class_id,g.goods_name,g.goods_number,g.company,g.pricing_method,g.source_type,g.shop_mem_status,g.store_mem_status,g.goods_brand_id,g.supplier_id,a.goods_num')
|
|
->where($where)
|
|
->page($page, $limit)
|
|
->order('sk.id desc')
|
|
->select();
|
|
$total = M('retail_sku_goods as sk')
|
|
->join('ls_retail_store_sale_goods as a on a.sku_id=sk.id')
|
|
->join('ls_retail_goods as g on g.id=a.goods_id')
|
|
->where($where)->count();
|
|
$RSLModel = D('RetailSkuList');
|
|
foreach ($sku_list as &$val) {
|
|
// 获取商品分类
|
|
$class1 = M('retail_goods_class')->field('id,class_name,pid')->where(array('id' => $val['goods_class_id']))->find();
|
|
if ($class1['pid'] == 0) {
|
|
$val['class_name'] = '/' . $class1['class_name'];
|
|
} else {
|
|
$class2 = M('retail_goods_class')->field('id,class_name,pid')->where(array('id' => $class1['pid']))->find();
|
|
if ($class2['pid'] == 0) {
|
|
$val['class_name'] = '/' . $class2['class_name'] . '/' . $class1['class_name'];
|
|
} else {
|
|
$class3 = M('retail_goods_class')->field('id,class_name,pid')->where(array('id' => $class2['pid']))->find();
|
|
$val['class_name'] = '/' . $class3['class_name'] . '/' . $class2['class_name'] . '/' . $class1['class_name'];
|
|
}
|
|
}
|
|
// 处理规格名称
|
|
$sku_name = $RSLModel->getFindField(array($RSLModel::ID => array('in', $val['sku_id_list'])), $RSLModel::NAME, true);
|
|
$val['goods_name'] = $val['goods_name'] . '(' . implode(',', $sku_name) . ')';
|
|
// 处理货号
|
|
$val['goods_number'] = $val['goods_number'] ? $val['goods_number'] : '未设置';
|
|
// 进价合计
|
|
$val['all_purchase'] = round($val['goods_num'] * $val['purchase_price'], 2);
|
|
// 处理进价
|
|
$val['purchase_price'] = floatval($val['purchase_price']);
|
|
// 处理库存(加上单位)
|
|
$val['goods_num'] = $val['goods_num'] ? floatval($val['goods_num']) : 0;
|
|
$val['stock'] = $val['goods_num'] . $val['company'];
|
|
// 处理店内售价
|
|
$val['retail_price'] = floatval($val['retail_price']);
|
|
// 处理商城售价
|
|
$val['online_price'] = floatval($val['online_price']);
|
|
// 店内售出合计
|
|
$val['sell_retail_total'] = floatval(round($val['retail_price'] * $val['goods_num'], 2));
|
|
// 商城售出合计
|
|
$val['sell_online_total'] = floatval(round($val['online_price'] * $val['goods_num'], 2));
|
|
// 店内会员价
|
|
$val['store_mem_price'] = $val['store_mem_status'] == 1 && $val['store_mem_price'] > 0 ? floatval($val['store_mem_price']) : ' 关闭 ';
|
|
// 商城会员价
|
|
$val['shop_mem_price'] = $val['shop_mem_status'] == 1 && $val['shop_mem_price'] > 0 ? floatval($val['shop_mem_price']) : ' 关闭 ';
|
|
// 商品称重类型
|
|
$val['exchange_weigh_type'] = $val['pricing_method'] == 1 ? '非称重' : '称重';
|
|
// 供货商
|
|
if ($val['supplier_id']) {
|
|
$supplier_name = M('retail_supplier')->where(array('id' => $val['supplier_id'], 'merchantid' => $user['merchantid'], 'status' => 1))->getField('supplier_name');
|
|
$val['supplier_name'] = $supplier_name ? $supplier_name : '无';
|
|
} else {
|
|
$val['supplier_name'] = '无';
|
|
}
|
|
// 商品品牌
|
|
if ($val['goods_brand_id']) {
|
|
$goods_brand_name = M('retail_goods_brand')->where(array('id' => $val['goods_brand_id'], 'merchantid' => $user['merchantid'], 'state' => 0))->getField('name');
|
|
$val['goods_brand_name'] = $goods_brand_name ? $goods_brand_name : '无';
|
|
} else {
|
|
$val['goods_brand_name'] = '无';
|
|
}
|
|
// 商品来源
|
|
switch ($val['source_type']) {
|
|
case 1:
|
|
$val['source_name'] = '店长添加';
|
|
break;
|
|
case 2:
|
|
$val['source_name'] = '同步商户';
|
|
break;
|
|
case 3:
|
|
$val['source_name'] = '收银员添加';
|
|
break;
|
|
default:
|
|
$val['source_name'] = '未知来源';
|
|
}
|
|
}
|
|
$res = $this->skuStatistics($where);
|
|
$res['status'] = $sku_list ? 1 : 0;
|
|
$res['goods_list'] = $sku_list ? $sku_list : array();
|
|
$res['total'] = $total ? (int)$total : 0;
|
|
$this->ajaxReturn($res);
|
|
}
|
|
|
|
/**
|
|
* 统计规格商品数据
|
|
* @param array $map 搜索条件
|
|
* @return array $res
|
|
*/
|
|
protected function skuStatistics($where)
|
|
{
|
|
$sku = M('retail_sku_goods as sk')
|
|
->join('ls_retail_store_sale_goods as a on a.sku_id=sk.id')
|
|
->field('sk.purchase_price,sk.retail_price,sk.online_price,a.pricing_method,a.goods_num')
|
|
->where($where)
|
|
->select();
|
|
$weigh_stock = 0; // 称重总库存
|
|
$not_weigh_stock = 0; // 非承重总库存
|
|
$purchase_price = 0; // 总进价
|
|
$retail_price_total = 0; // 店内售出合计
|
|
$online_price_total = 0; // 商城售出合计
|
|
foreach ($sku as &$val) {
|
|
if ($val['pricing_method'] == 1) { // 非称重
|
|
$not_weigh_stock += $val['goods_num'];
|
|
} else { // 称重
|
|
$weigh_stock += $val['goods_num'];
|
|
}
|
|
$purchase_price += $val['goods_num'] * $val['purchase_price'];
|
|
$retail_price_total += $val['goods_num'] * $val['retail_price'];
|
|
$online_price_total += $val['goods_num'] * $val['online_price'];
|
|
}
|
|
$res['purchase_price'] = $purchase_price ? round($purchase_price, 2) : 0;
|
|
$res['weigh_stock'] = $weigh_stock ? floatval($weigh_stock) : 0;
|
|
$res['not_weigh_stock'] = $not_weigh_stock ? floatval($not_weigh_stock) : 0;
|
|
$res['retail_price_total'] = $retail_price_total ? floatval(round($retail_price_total, 2)) : 0;
|
|
$res['online_price_total'] = $online_price_total ? floatval(round($online_price_total, 2)) : 0;
|
|
return $res;
|
|
}
|
|
|
|
/**
|
|
* 门店库存统计展示
|
|
* 规格
|
|
* @param int $storeid
|
|
* @param int $page 分页
|
|
* @param int $limit 每页数量
|
|
* @param array seek_data 搜索条件
|
|
* @return array $res
|
|
*/
|
|
public function get_sku_list()
|
|
{
|
|
$user = I('session.ls_userinfo');
|
|
$storeid = I('post.storeid');
|
|
$page = (int)I('post.page');
|
|
$limit = (int)I('post.limit');
|
|
$seek_data = I('post.seek_data');
|
|
/* 分类搜索 */
|
|
$class_id = array_pop($seek_data['class_ids']);
|
|
if ($class_id) {
|
|
$class1 = M('retail_goods_class')->field('id,pid')->where(array('id' => $class_id))->find();
|
|
if ($class1['pid'] == 0) { // 一级分类
|
|
$class = M('retail_goods_class as c1')
|
|
->join('ls_retail_goods_class as c2 on c1.id=c2.pid')
|
|
->join('ls_retail_goods_class as c3 on c2.id=c3.pid AND c3.status=0', 'LEFT')
|
|
->where(array('c1.id' => $class_id, 'c2.status' => 0))
|
|
->field('c2.id,c3.id as c3_id')
|
|
->select();
|
|
if ($class) {
|
|
$arr = array();
|
|
$arr[] = $class_id;
|
|
foreach ($class as &$val) {
|
|
if (!in_array($val['id'], $arr)) {
|
|
$arr[] = $val['id'];
|
|
}
|
|
if ($val['c3_id']) {
|
|
if (!in_array($val['c3_id'], $arr)) {
|
|
$arr[] = $val['c3_id'];
|
|
}
|
|
}
|
|
}
|
|
$map['goods_class_id'] = array('in', $arr);
|
|
}
|
|
} else {
|
|
$class2 = M('retail_goods_class')->field('id,pid')->where(array('id' => $class1['pid']))->find();
|
|
if ($class2['pid'] == 0) { // 二级分类
|
|
$class = M('retail_goods_class as c1')
|
|
->join('ls_retail_goods_class as c2 on c1.id=c2.pid')
|
|
->where(array('c1.id' => $class_id, 'c2.status' => 0))
|
|
->field('c2.id')
|
|
->select();
|
|
if ($class) {
|
|
$arr = array();
|
|
$arr[] = $class_id;
|
|
foreach ($class as &$val) {
|
|
if (!in_array($val['id'], $arr)) {
|
|
$arr[] = $val['id'];
|
|
}
|
|
}
|
|
$map['goods_class_id'] = array('in', $arr);
|
|
}
|
|
} else { // 三级分类
|
|
$map['goods_class_id'] = $class_id;
|
|
}
|
|
}
|
|
}
|
|
/* 商品名称搜索 */
|
|
if (trim($seek_data['goods_name'], '')) {
|
|
$map['goods_name'] = array('like', '%' . $seek_data['goods_name'] . '%');
|
|
}
|
|
/* 商品货号、条码搜索 */
|
|
if (trim($seek_data['keyword'], '')) {
|
|
$map['goods_number|goods_code'] = array('like', '%' . $seek_data['keyword'] . '%');
|
|
}
|
|
/* 供货商搜索 */
|
|
if ($seek_data['supplier_id']) {
|
|
$map['supplier_id'] = $seek_data['supplier_id'];
|
|
}
|
|
/* 品牌搜索 */
|
|
if ($seek_data['goods_brand_id']) {
|
|
$map['goods_brand_id'] = $seek_data['goods_brand_id'];
|
|
}
|
|
/* 称重类型搜索 */
|
|
if ($seek_data['can_exchange_weigh']) {
|
|
$map['pricing_method'] = $seek_data['can_exchange_weigh'];
|
|
}
|
|
$map['store_id'] = $storeid;
|
|
$map['merchant_id'] = $user['merchantid'];
|
|
$map['status'] = array('in', "0,1");
|
|
$map['attribute_state'] = 2;
|
|
$goods_ids = M('retail_goods')->where($map)->getField('id', true);
|
|
if (!$goods_ids) {
|
|
$res['goods_list'] = array();
|
|
$res['total'] = 0;
|
|
$this->ajaxReturn($res);
|
|
}
|
|
$where['sk.goods_id'] = array('in', $goods_ids);
|
|
$where['sk.store_id'] = $storeid;
|
|
$where['sk.status'] = 1;
|
|
$where['sk.state'] = 0;
|
|
$sku_list = M('retail_sku_goods as sk')
|
|
->join('ls_retail_store_sale_goods as a on a.sku_id=sk.id')
|
|
->join('ls_retail_goods as g on g.id=a.goods_id')
|
|
->field('sk.goods_id,sk.sku_code as goods_code,sk.purchase_price,sk.retail_price,sk.online_price,sk.sku_id_list,sk.shop_mem_price,sk.store_mem_price,g.goods_class_id,g.goods_name,g.goods_number,g.company,g.pricing_method,g.source_type,g.shop_mem_status,g.store_mem_status,g.goods_brand_id,g.supplier_id,a.goods_num')
|
|
->where($where)
|
|
->page($page, $limit)
|
|
->order('sk.id desc')
|
|
->select();
|
|
$total = M('retail_sku_goods as sk')
|
|
->join('ls_retail_store_sale_goods as a on a.sku_id=sk.id')
|
|
->join('ls_retail_goods as g on g.id=a.goods_id')
|
|
->where($where)->count();
|
|
$res = $this->statistics_sku($where);
|
|
foreach ($sku_list as &$val) {
|
|
$class1 = M('retail_goods_class')->field('id,class_name,pid')->where(array('id' => $val['goods_class_id']))->find();
|
|
if ($class1['pid'] == 0) {
|
|
$val['class_name'] = '/' . $class1['class_name'];
|
|
} else {
|
|
$class2 = M('retail_goods_class')->field('id,class_name,pid')->where(array('id' => $class1['pid']))->find();
|
|
if ($class2['pid'] == 0) {
|
|
$val['class_name'] = '/' . $class2['class_name'] . '/' . $class1['class_name'];
|
|
} else {
|
|
$class3 = M('retail_goods_class')->field('id,class_name,pid')->where(array('id' => $class2['pid']))->find();
|
|
$val['class_name'] = '/' . $class3['class_name'] . '/' . $class2['class_name'] . '/' . $class1['class_name'];
|
|
}
|
|
}
|
|
$sku_name = M('retail_sku_list')->where(array('id' => array('in', $val['sku_id_list'])))->getField('name', true);
|
|
$val['goods_name'] = $val['goods_name'] . '(' . implode(',', $sku_name) . ')';
|
|
$val['goods_num'] = floatval($val['goods_num']);
|
|
$val['stock'] = $val['goods_num'] . $val['company'];
|
|
$val['purch_price'] = floatval($val['purchase_price']);
|
|
$val['all_purch'] = round($val['goods_num'] * $val['purchase_price'], 2);
|
|
$val['retail_price'] = floatval($val['retail_price']);
|
|
$val['online_price'] = floatval($val['online_price']);
|
|
$val['retail_price_total'] = floatval(round($val['retail_price'] * $val['goods_num'], 2));
|
|
$val['online_price_total'] = floatval(round($val['online_price'] * $val['goods_num'], 2));
|
|
$val['shop_mem_price'] = $val['shop_mem_status'] == 1 && $val['shop_mem_price'] > 0 ? floatval($val['shop_mem_price']) : '关闭';
|
|
$val['store_mem_price'] = $val['store_mem_status'] == 1 && $val['store_mem_price'] > 0 ? floatval($val['store_mem_price']) : '关闭';
|
|
$val['source_name'] = $val['source_type'] == 3 ? '调拨' : '进货';
|
|
$val['pricing_method'] = $val['pricing_method'] == 1 ? '非称重' : '称重';
|
|
if ($val['supplier_id'] && $val['supplier_id'] == -1) {
|
|
$val['supplier_name'] = '自采/其他';
|
|
} else if ($val['supplier_id'] && $val['supplier_id'] != -1) {
|
|
$supplier_name = M('retail_supplier')->where(array('id' => $val['supplier_id'], 'merchantid' => $map['merchantid'], 'status' => 1))->getField('supplier_name');
|
|
$val['supplier_name'] = $supplier_name ? $supplier_name : '无';
|
|
} else {
|
|
$val['supplier_name'] = '无';
|
|
}
|
|
if ($val['goods_brand_id']) {
|
|
$goods_brand_name = M('retail_goods_brand')->where(array('id' => $val['goods_brand_id'], 'merchantid' => $map['merchantid'], 'state' => 0))->getField('name');
|
|
$val['goods_brand_name'] = $goods_brand_name ? $goods_brand_name : '无';
|
|
} else {
|
|
$val['goods_brand_name'] = '无';
|
|
}
|
|
$val['goods_code'] = $val['goods_code'] ? $val['goods_code'] : '无';
|
|
$val['good_number'] = $val['goods_number'] ? $val['goods_number'] : '无';
|
|
}
|
|
$res['status'] = 1;
|
|
$res['goods_list'] = $sku_list ? $sku_list : array();
|
|
$res['total'] = $total ? (int)$total : 0;
|
|
$this->ajaxReturn($res);
|
|
}
|
|
|
|
/**
|
|
* 统计金额(公共方法)
|
|
* @param array $map 查询条件
|
|
* @return array $res
|
|
*/
|
|
protected function statistics_sell($map)
|
|
{
|
|
// 销售
|
|
$map['b.order_type'] = 1;
|
|
// 笔数
|
|
$sell_num = M('retail_bill_order as b')
|
|
->join('ls_retail_bill_discount as d on b.id=d.bill_id')
|
|
->join('ls_retail_bill_online as o on b.id=o.bill_id', 'LEFT')
|
|
->where($map)
|
|
->count();
|
|
// 金额
|
|
$sell_money = M('retail_bill_order as b')
|
|
->join('ls_retail_bill_discount as d on b.id=d.bill_id')
|
|
->join('ls_retail_bill_online as o on b.id=o.bill_id', 'LEFT')
|
|
->where($map)
|
|
->sum('all_money');
|
|
// 退款
|
|
unset($map['b.order_type']);
|
|
$map['b.order_type'] = 2;
|
|
// 笔数
|
|
$refund_num = M('retail_bill_order as b')
|
|
->join('ls_retail_bill_discount as d on b.id=d.bill_id')
|
|
->join('ls_retail_bill_online as o on b.id=o.bill_id', 'LEFT')
|
|
->where($map)
|
|
->count();
|
|
// 金额
|
|
$refund_money = M('retail_bill_order as b')
|
|
->join('ls_retail_bill_discount as d on b.id=d.bill_id')
|
|
->join('ls_retail_bill_online as o on b.id=o.bill_id', 'LEFT')
|
|
->where($map)
|
|
->sum('all_money');
|
|
// 所有订单
|
|
unset($map['b.order_type']);
|
|
$map['b.order_type'] = 1; // 销售成本
|
|
// 获取销售
|
|
$all_bill_ids = M('retail_bill_order as b')
|
|
->join('ls_retail_bill_discount as d on b.id=d.bill_id')
|
|
->join('ls_retail_bill_online as o on b.id=o.bill_id', 'LEFT')
|
|
->field('b.id')
|
|
->where($map)
|
|
->select();
|
|
$bill_ids = $all_bill_ids ? array_column($all_bill_ids, 'id') : '0';
|
|
// 销售成本
|
|
$all_sell = M('retail_sell')->field('num,purchase_price')->where(array('bill_id' => array('in', $bill_ids), 'purchase_price' => array('gt', 0)))->select();
|
|
$cost = 0;
|
|
foreach ($all_sell as &$val) {
|
|
$cost += floatval(round($val['num'] * $val['purchase_price'], 2));
|
|
}
|
|
// 实收金额(总金额 - 退款金额)
|
|
$income = floatval(round($sell_money - $refund_money, 2));
|
|
// 计算盈利,利润()
|
|
$profit = floatval(round($income - $cost, 2));
|
|
$profit_margin = floatval(round($profit / $income * 100, 2)) . '%';
|
|
$res['sell_num'] = $sell_num ? $sell_num : 0;
|
|
$res['refund_num'] = $refund_num ? $refund_num : 0;
|
|
$res['sell_money'] = $sell_money ? $sell_money : 0;
|
|
$res['refund_money'] = $refund_money ? $refund_money : 0;
|
|
$res['income'] = $income ? $income : 0;
|
|
$res['cost'] = $cost ? $cost : 0;
|
|
$res['profit'] = $profit ? $profit : 0;
|
|
$res['profit_margin'] = $profit_margin ? $profit_margin : '0%';
|
|
return $res;
|
|
}
|
|
|
|
/* 库存统计导出
|
|
* */
|
|
public function stock_export()
|
|
{
|
|
$user = I('session.ls_userinfo');
|
|
$store_id = I('get.store_id');
|
|
$type = I('get.type'); // 类型
|
|
$seek_data = json_decode($_GET['seek_data'], true); // 搜索条件
|
|
/* 分类搜索 */
|
|
$class_id = array_pop($seek_data['class_ids']);
|
|
if ($class_id) {
|
|
$class1 = M('retail_goods_class')->field('id,pid')->where(array('id' => $class_id))->find();
|
|
if ($class1['pid'] == 0) { // 一级分类
|
|
$class = M('retail_goods_class as c1')
|
|
->join('ls_retail_goods_class as c2 on c1.id=c2.pid')
|
|
->join('ls_retail_goods_class as c3 on c2.id=c3.pid AND c3.status=0', 'LEFT')
|
|
->where(array('c1.id' => $class_id, 'c2.status' => 0))
|
|
->field('c2.id,c3.id as c3_id')
|
|
->select();
|
|
if ($class) {
|
|
$arr = array();
|
|
$arr[] = $class_id;
|
|
foreach ($class as &$val) {
|
|
if (!in_array($val['id'], $arr)) {
|
|
$arr[] = $val['id'];
|
|
}
|
|
if ($val['c3_id']) {
|
|
if (!in_array($val['c3_id'], $arr)) {
|
|
$arr[] = $val['c3_id'];
|
|
}
|
|
}
|
|
}
|
|
$map['g.goods_class_id'] = array('in', $arr);
|
|
} else {
|
|
$map['g.goods_class_id'] = $class_id;
|
|
}
|
|
} else {
|
|
$class2 = M('retail_goods_class')->field('id,pid')->where(array('id' => $class1['pid']))->find();
|
|
if ($class2['pid'] == 0) { // 二级分类
|
|
$class = M('retail_goods_class as c1')
|
|
->join('ls_retail_goods_class as c2 on c1.id=c2.pid')
|
|
->where(array('c1.id' => $class_id, 'c2.status' => 0))
|
|
->field('c2.id')
|
|
->select();
|
|
if ($class) {
|
|
$arr = array();
|
|
$arr[] = $class_id;
|
|
foreach ($class as &$val) {
|
|
if (!in_array($val['id'], $arr)) {
|
|
$arr[] = $val['id'];
|
|
}
|
|
}
|
|
$map['g.goods_class_id'] = array('in', $arr);
|
|
} else {
|
|
$map['g.goods_class_id'] = $class_id;
|
|
}
|
|
} else { // 三级分类
|
|
$map['g.goods_class_id'] = $class_id;
|
|
}
|
|
}
|
|
}
|
|
/* 商品名称搜索 */
|
|
if (trim($seek_data['goods_name'], '')) {
|
|
$map['g.goods_name'] = array('like', '%' . $seek_data['goods_name'] . '%');
|
|
}
|
|
// 商品货号、条码搜索
|
|
if (trim($seek_data['keyword'], '')) {
|
|
$map['g.goods_number|g.goods_code'] = array('like', '%' . $seek_data['keyword'] . '%');
|
|
}
|
|
/* 供货商搜索 */
|
|
if ($seek_data['supplier_id']) {
|
|
$map['g.supplier_id'] = $seek_data['supplier_id'];
|
|
}
|
|
/* 品牌搜索 */
|
|
if ($seek_data['goods_brand_id']) {
|
|
$map['g.goods_brand_id'] = $seek_data['goods_brand_id'];
|
|
}
|
|
/* 称重类型搜索 */
|
|
if ($seek_data['pricing_method']) {
|
|
$map['g.pricing_method'] = $seek_data['pricing_method'];
|
|
}
|
|
$map['g.store_id'] = $store_id;
|
|
$map['g.merchant_id'] = $user['merchantid'];
|
|
$map['g.status'] = array('in', "0,1");
|
|
if ($type == 1) {
|
|
$map['g.attribute_state'] = 1;
|
|
$result = $this->goods_export($map);
|
|
if ($result['status'] == 1) {
|
|
$store_list = $result['goods_list'];
|
|
}
|
|
} else {
|
|
$map['g.attribute_state'] = 2;
|
|
$result = $this->sku_export($map);
|
|
if ($result['status'] == 1) {
|
|
$store_list = $result['sku_list'];
|
|
}
|
|
}
|
|
$store_list = $store_list ? $store_list : array();
|
|
$name = $type == 1 ? '普通商品库存统计报表' : '规格商品库存统计报表';
|
|
$headArr = array(
|
|
array('index', '序号'),
|
|
array('goods_name', '商品名称'),
|
|
array('class_name', '商品分类'),
|
|
array('goods_number', '商品货号'),
|
|
array('stock', '库存'),
|
|
array('purchase_price', '进价(单个)'),
|
|
array('all_purchase', '进价(合计)'),
|
|
array('retail_price', '售价(店内)'),
|
|
array('online_price', '售价(商城)'),
|
|
array('sell_retail_total', '售出合计(店内)'),
|
|
array('sell_online_total', '售出合计(商城)'),
|
|
array('store_mem_price', '会员价(店内)'),
|
|
array('shop_mem_price', '会员价(商城)'),
|
|
array('source_name', '渠道'),
|
|
array('pricing_method', '类型'),
|
|
array('supplier_name', '供货商'),
|
|
array('goods_brand_name', '品牌')
|
|
);
|
|
$str = $name . '导出时间' . date('Y-m-d H:i:s', time());
|
|
getExcel($name, $headArr, $store_list, $str);
|
|
}
|
|
|
|
/* 普通商品导出
|
|
* @return array()
|
|
* */
|
|
protected function goods_export($map)
|
|
{
|
|
$goods_list = M('retail_goods as g')
|
|
->join('ls_retail_store_sale_goods as a on a.goods_id=g.id')
|
|
->field('g.id as goods_id,g.goods_class_id,g.goods_name,g.goods_number,g.goods_code,g.purchase_price,g.retail_price,g.online_price,g.company,g.pricing_method,g.shop_mem_status,g.shop_mem_price,g.store_mem_status,g.source_type,g.store_mem_price,g.goods_brand_id,g.supplier_id,a.goods_num')
|
|
->where($map)
|
|
->order('g.id desc')
|
|
->select();
|
|
if (!$goods_list) {
|
|
$res['status'] = 0;
|
|
$res['msg'] = '暂无数据';
|
|
return $res;
|
|
}
|
|
foreach ($goods_list as $key => &$val) {
|
|
$val['index'] = $key + 1;
|
|
// 获取商品分类
|
|
$class1 = M('retail_goods_class')->field('id,class_name,pid')->where(array('id' => $val['goods_class_id']))->find();
|
|
if ($class1['pid'] == 0) {
|
|
$val['class_name'] = '/' . $class1['class_name'];
|
|
} else {
|
|
$class2 = M('retail_goods_class')->field('id,class_name,pid')->where(array('id' => $class1['pid']))->find();
|
|
if ($class2['pid'] == 0) {
|
|
$val['class_name'] = '/' . $class2['class_name'] . '/' . $class1['class_name'];
|
|
} else {
|
|
$class3 = M('retail_goods_class')->field('id,class_name,pid')->where(array('id' => $class2['pid']))->find();
|
|
$val['class_name'] = '/' . $class3['class_name'] . '/' . $class2['class_name'] . '/' . $class1['class_name'];
|
|
}
|
|
}
|
|
$val['all_purchase'] = strval(floatval(round($val['goods_num'] * $val['purchase_price'], 2)));
|
|
$val['goods_num'] = floatval($val['goods_num']);
|
|
$val['stock'] = $val['goods_num'] . $val['company'];
|
|
$val['purchase_price'] = strval(floatval($val['purchase_price']));
|
|
$val['retail_price'] = strval(floatval($val['retail_price']));
|
|
$val['online_price'] = strval(floatval($val['online_price']));
|
|
$val['sell_retail_total'] = strval(floatval(round($val['retail_price'] * $val['goods_num'], 2)));
|
|
$val['sell_online_total'] = strval(floatval(round($val['online_price'] * $val['goods_num'], 2)));
|
|
$val['shop_mem_price'] = $val['shop_mem_status'] == 1 && $val['shop_mem_price'] > 0 ? strval(floatval($val['shop_mem_price'])) : '关闭';
|
|
$val['store_mem_price'] = $val['store_mem_status'] == 1 && $val['store_mem_price'] > 0 ? strval(floatval($val['store_mem_price'])) : '关闭';
|
|
$val['pricing_method'] = $val['pricing_method'] == 1 ? '非称重' : '称重';
|
|
if ($val['supplier_id']) {
|
|
$supplier_name = M('retail_supplier')->where(array('id' => $val['supplier_id'], 'merchantid' => $map['merchant_id'], 'status' => 1))->getField('supplier_name');
|
|
$val['supplier_name'] = $supplier_name ? $supplier_name : '无';
|
|
} else {
|
|
$val['supplier_name'] = '无';
|
|
}
|
|
if ($val['goods_brand_id']) {
|
|
$goods_brand_name = M('retail_goods_brand')->where(array('id' => $val['goods_brand_id'], 'merchantid' => $map['merchant_id'], 'state' => 0))->getField('name');
|
|
$val['goods_brand_name'] = $goods_brand_name ? $goods_brand_name : '无';
|
|
} else {
|
|
$val['goods_brand_name'] = '无';
|
|
}
|
|
// 商品来源
|
|
switch ($val['source_type']) {
|
|
case 1:
|
|
$val['source_name'] = '店长添加';
|
|
break;
|
|
case 2:
|
|
$val['source_name'] = '同步商户';
|
|
break;
|
|
case 3:
|
|
$val['source_name'] = '收银员添加';
|
|
break;
|
|
default:
|
|
$val['source_name'] = '未知来源';
|
|
}
|
|
}
|
|
$res['status'] = 1;
|
|
$res['goods_list'] = $goods_list;
|
|
return $res;
|
|
}
|
|
|
|
/* 普通商品导出
|
|
* @return array()
|
|
* */
|
|
protected function sku_export($map)
|
|
{
|
|
/* 查看进价权限 */
|
|
$show_purch_price = I('session.global_store_jurisdiction')['showpurch_price'];
|
|
$goods_ids = M('retail_goods as g')->field('g.id')->where($map)->select();
|
|
// 处理二位数组
|
|
$goods_ids = array_column($goods_ids, 'id');
|
|
if (empty($goods_ids)) {
|
|
$res['status'] = 0;
|
|
$res['msg'] = '暂无商品数据';
|
|
return $res;
|
|
}
|
|
$where['sk.goods_id'] = array('in', $goods_ids);
|
|
$where['sk.store_id'] = $map['g.store_id'];
|
|
$where['sk.status'] = 1;
|
|
$where['sk.state'] = 0;
|
|
$sku_list = M('retail_sku_goods as sk')
|
|
->join('ls_retail_store_sale_goods as a on a.sku_id=sk.id')
|
|
->join('ls_retail_goods as g on g.id=a.goods_id')
|
|
->field('sk.goods_id,sk.purchase_price,sk.sku_code as goods_code,sk.retail_price,sk.online_price,sk.sku_id_list,sk.shop_mem_price,sk.store_mem_price,g.goods_class_id,g.goods_name,g.goods_number,g.company,g.pricing_method,g.source_type,g.shop_mem_status,g.store_mem_status,g.goods_brand_id,g.supplier_id,a.goods_num')
|
|
->where($where)
|
|
->order('sk.id desc')
|
|
->select();
|
|
if (!$sku_list) {
|
|
$res['status'] = 0;
|
|
$res['msg'] = '暂无规格商品';
|
|
return $res;
|
|
}
|
|
foreach ($sku_list as $key => &$val) {
|
|
$val['index'] = $key + 1;
|
|
$class1 = M('retail_goods_class')->field('id,class_name,pid')->where(array('id' => $val['goods_class_id']))->find();
|
|
if ($class1['pid'] == 0) {
|
|
$val['class_name'] = '/' . $class1['class_name'];
|
|
} else {
|
|
$class2 = M('retail_goods_class')->field('id,class_name,pid')->where(array('id' => $class1['pid']))->find();
|
|
if ($class2['pid'] == 0) {
|
|
$val['class_name'] = '/' . $class2['class_name'] . '/' . $class1['class_name'];
|
|
} else {
|
|
$class3 = M('retail_goods_class')->field('id,class_name,pid')->where(array('id' => $class2['pid']))->find();
|
|
$val['class_name'] = '/' . $class3['class_name'] . '/' . $class2['class_name'] . '/' . $class1['class_name'];
|
|
}
|
|
}
|
|
$sku_name = M('retail_sku_list')->where(array('id' => array('in', $val['sku_id_list'])))->getField('name', true);
|
|
$val['goods_name'] = $val['goods_name'] . '(' . implode(',', $sku_name) . ')';
|
|
$val['all_purchase'] = strval(floatval(round($val['goods_num'] * $val['purchase_price'], 2)));
|
|
$val['goods_num'] = floatval($val['goods_num']);
|
|
$val['stock'] = strval($val['goods_num'] . $val['company']);
|
|
$val['purchase_price'] = strval(floatval($val['purchase_price']));
|
|
$val['retail_price'] = strval(floatval($val['retail_price']));
|
|
$val['online_price'] = strval(floatval($val['online_price']));
|
|
$val['sell_retail_total'] = strval(floatval(round($val['retail_price'] * $val['goods_num'], 2)));
|
|
$val['sell_online_total'] = strval(floatval(round($val['retail_price'] * $val['goods_num'], 2)));
|
|
$val['shop_mem_status'] = $val['shop_mem_status'] == 1 && $val['shop_mem_price'] > 0 ? strval(floatval($val['shop_mem_price'])) : ' 关闭 ';
|
|
$val['store_mem_status'] = $val['store_mem_status'] == 1 && $val['store_mem_price'] > 0 ? strval(floatval($val['store_mem_price'])) : ' 关闭 ';
|
|
$val['pricing_method'] = $val['pricing_method'] == 1 ? '非称重' : '称重';
|
|
if ($val['supplier_id']) {
|
|
$supplier_name = M('retail_supplier')->where(array('id' => $val['supplier_id'], 'merchantid' => $map['merchant_id'], 'status' => 1))->getField('supplier_name');
|
|
$val['supplier_name'] = $supplier_name ? $supplier_name : '无';
|
|
} else {
|
|
$val['supplier_name'] = '无';
|
|
}
|
|
if ($val['goods_brand_id']) {
|
|
$goods_brand_name = M('retail_goods_brand')->where(array('id' => $val['goods_brand_id'], 'merchantid' => $map['merchant_id'], 'state' => 0))->getField('name');
|
|
$val['goods_brand_name'] = $goods_brand_name ? $goods_brand_name : '无';
|
|
} else {
|
|
$val['goods_brand_name'] = '无';
|
|
}
|
|
// 商品来源
|
|
switch ($val['source_type']) {
|
|
case 1:
|
|
$val['source_name'] = '店长添加';
|
|
break;
|
|
case 2:
|
|
$val['source_name'] = '同步商户';
|
|
break;
|
|
case 3:
|
|
$val['source_name'] = '收银员添加';
|
|
break;
|
|
default:
|
|
$val['source_name'] = '未知来源';
|
|
}
|
|
}
|
|
$res['status'] = 1;
|
|
$res['sku_list'] = $sku_list;
|
|
return $res;
|
|
}
|
|
|
|
/**
|
|
* 销售订单统计(加载模板)
|
|
* @param int $storeid
|
|
*/
|
|
public function sell_order()
|
|
{
|
|
// 操作权限
|
|
$arr = array(
|
|
'sell_export' => '/index.php/Retail/Statistics/sell_export',
|
|
);
|
|
$authArr = checkFunction($arr);
|
|
// 接受参数
|
|
$store_id = I('get.store_id');
|
|
$this->assign('authArr', $authArr);
|
|
$this->assign('store_id', $store_id ? $store_id : 0);
|
|
$this->display();
|
|
}
|
|
|
|
/**
|
|
* 获取销售数据展示
|
|
* @param int $page 分页
|
|
* @param int $limit 每页数量
|
|
* @param array $seek_data 搜索条件
|
|
* @return array $res
|
|
*/
|
|
public function getBillList()
|
|
{
|
|
// 获取session
|
|
$user = I('session.ls_userinfo');
|
|
$store_id = I('post.store_id');
|
|
// 接收数据
|
|
$page = (int)I('post.page');
|
|
$limit = (int)I('post.limit');
|
|
$seek_data = I('post.seek_data');
|
|
/* 时间搜索 */
|
|
$start_time = $seek_data['start_time'];
|
|
$end_time = $seek_data['end_time'];
|
|
if ($start_time && $end_time) {
|
|
$start_time = strtotime($start_time);
|
|
$end_time = strtotime($end_time);
|
|
$map['b.add_time'] = array('between', array($start_time, $end_time));
|
|
} else if ($start_time && !$end_time) {
|
|
$start_time = strtotime($start_time);
|
|
$map['b.add_time'] = array('egt', $start_time);
|
|
} else if (!$start_time && $end_time) {
|
|
$end_time = strtotime($end_time);
|
|
$map['b.add_time'] = array('elt', $end_time);
|
|
}
|
|
/* 订单号搜索 */
|
|
if (trim($seek_data['order_id'], '')) {
|
|
$map['b.order_no'] = array('like', '%' . $seek_data['order_id'] . '%');
|
|
}
|
|
/* 导购员搜索 */
|
|
if ($seek_data['guide_id']) {
|
|
$map['b.guide_id'] = $seek_data['guide_id'];
|
|
}
|
|
$map[] = array(
|
|
'b.order_type' => 1,
|
|
array(
|
|
'b.order_type' => array('in', '2,3'),
|
|
'b.refund_status' => 2,
|
|
),
|
|
'_logic' => 'OR',
|
|
);
|
|
/* 类型搜索 */
|
|
if ($seek_data['order_mold']) {
|
|
switch ($seek_data['order_mold']) {
|
|
case 1:
|
|
$map['b.type'] = 2;
|
|
break;
|
|
case 2:
|
|
$map['b.type'] = 1;
|
|
break;
|
|
case 3:
|
|
$map['b.type'] = 2;
|
|
$map['b.order_type'] = 1;
|
|
break;
|
|
case 4:
|
|
$map['b.type'] = 1;
|
|
$map['b.order_type'] = 1;
|
|
break;
|
|
case 5:
|
|
$map['b.type'] = 2;
|
|
$map['b.order_type'] = 2;
|
|
break;
|
|
case 6:
|
|
$map['b.type'] = 1;
|
|
$map['b.order_type'] = 2;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
$map['b.merchant_id'] = $user['merchantid'];
|
|
$map['b.store_id'] = $store_id;
|
|
$map['b.pay_state'] = 1;
|
|
$map['b.pay_type'] = array('neq', 0);
|
|
|
|
$bill_list = M('retail_bill_order as b')
|
|
->join('ls_retail_bill_discount as d on b.id=d.bill_id')
|
|
->join('ls_retail_bill_online as o on b.id=o.bill_id', 'LEFT')
|
|
->where($map)
|
|
->page($page, $limit)
|
|
->order('b.add_time desc')
|
|
->select();
|
|
|
|
$total = M('retail_bill_order as b')
|
|
->join('ls_retail_bill_discount as d on b.id=d.bill_id')
|
|
->join('ls_retail_bill_online as o on b.id=o.bill_id', 'LEFT')
|
|
->where($map)
|
|
->count();
|
|
$BillOrder = new BillOrder();
|
|
foreach ($bill_list as &$val) {
|
|
$val['add_time'] = date('Y-m-d H:i:s', $val['add_time']);
|
|
|
|
$val['pay_name'] = $BillOrder->getPayType($val['pay_type'], $val['id']);
|
|
|
|
/* 消费对象 */
|
|
if ($val['vid']) {
|
|
$vip = M('retail_vip')->field('name,nickname')->where(array('id' => $val['vid']))->find();
|
|
if ($vip) {
|
|
if ($vip['name']) {
|
|
$val['consumer_object'] = $vip['name'];
|
|
} else if ($vip['nickname']) {
|
|
$val['consumer_object'] = $vip['nickname'];
|
|
} else {
|
|
$val['consumer_object'] = '未设置';
|
|
}
|
|
} else {
|
|
$val['consumer_object'] = '散客';
|
|
}
|
|
} else if ($val['third_vip_code']) {
|
|
$val['consumer_object'] = $val['third_vip_name'];
|
|
} else {
|
|
$val['consumer_object'] = '散客';
|
|
}
|
|
/* 统计成本 */
|
|
$val['purchase_price'] = 0;
|
|
$sell_list = M('retail_sell')->field('num,purchase_price')->where(array('bill_id' => $val['id']))->select();
|
|
foreach ($sell_list as &$v) {
|
|
$val['purchase_price'] += floatval(round($v['num'] * $v['purchase_price'], 2));
|
|
}
|
|
$val['delivery_fee'] = $val['delivery_fee'] ? floatval($val['delivery_fee']) : 0;
|
|
$val['profit'] = floatval(round($val['all_money'] - $val['purchase_price'] - $val['delivery_fee'], 2));
|
|
$val['profit_margin'] = floatval(round($val['profit'] / ($val['all_money'] - $val['delivery_fee']) * 100, 2)) . '%';
|
|
$val['dismoney'] = $val['vip_dis_money'] && $val['vip_dis_money'] > 0 ? floatval($val['vip_dis_money']) : '无';
|
|
$val['coupon_money'] = $val['coupon_money'] && $val['coupon_money'] > 0 ? floatval($val['coupon_money']) : '无';
|
|
$val['delivery_fee'] = $val['delivery_fee'] && $val['delivery_fee'] > 0 ? floatval($val['delivery_fee']) : '无';
|
|
$val['small_changes_money'] = $val['small_changes_money'] && $val['small_changes_money'] > 0 ? floatval($val['small_changes_money']) : '无';
|
|
if ($val['discount'] > 0 && $val['discount'] < 1 && $val['cashier_dis_money']) {
|
|
$val['discount_remark'] = floatval($val['discount']) . '折金额:' . floatval($val['cashier_dis_money']);
|
|
} else {
|
|
$val['discount_remark'] = '未打折金额:无';
|
|
}
|
|
/* 查询导购员 */
|
|
if ($val['guide_id']) {
|
|
$guide_name = M('retail_guide')->where(array('id' => $val['guide_id']))->getField('guidename');
|
|
$val['guide_name'] = $guide_name ? $guide_name : '未设置';
|
|
} else {
|
|
$val['guide_name'] = '自购';
|
|
}
|
|
/* 类型 */
|
|
$type_name = $val['type'] == 1 ? '商城' : '店内';
|
|
$order_type_name = $val['order_type'] == 1 ? '销售' : '退款';
|
|
$val['order_mold'] = $type_name . $order_type_name;
|
|
/* 退款订单加负号 */
|
|
if ($val['order_type'] != 1) {
|
|
$val['all_money'] = '-' . $val['all_money'];
|
|
$val['profit'] = 0;
|
|
$val['profit_margin'] = '0%';
|
|
}
|
|
}
|
|
/* 统计 */
|
|
$res = $this->sellStatistics($map);
|
|
$res['status'] = 1;
|
|
$res['bill_list'] = $bill_list;
|
|
$res['total'] = $total ? (int)$total : 0;
|
|
$this->ajaxReturn($res);
|
|
}
|
|
|
|
/**
|
|
* 统计金额(公共方法)
|
|
* @param array $map 查询条件
|
|
* @return array $res
|
|
*/
|
|
protected function sellStatistics($map)
|
|
{
|
|
// 销售
|
|
$map['b.order_type'] = 1;
|
|
// 笔数
|
|
$sell_num = M('retail_bill_order as b')
|
|
->join('ls_retail_bill_discount as d on b.id=d.bill_id')
|
|
->join('ls_retail_bill_online as o on b.id=o.bill_id', 'LEFT')
|
|
->where($map)
|
|
->count();
|
|
// 金额
|
|
$sell_money = M('retail_bill_order as b')
|
|
->join('ls_retail_bill_discount as d on b.id=d.bill_id')
|
|
->join('ls_retail_bill_online as o on b.id=o.bill_id', 'LEFT')
|
|
->where($map)
|
|
->sum('all_money');
|
|
// 所有销售成本
|
|
$sell_ids = M('retail_bill_order as b')
|
|
->join('ls_retail_bill_discount as d on b.id=d.bill_id')
|
|
->join('ls_retail_bill_online as o on b.id=o.bill_id', 'LEFT')
|
|
->field('b.id')
|
|
->where($map)
|
|
->select();
|
|
$sell_ids = array_column($sell_ids, 'id');
|
|
$sell_cost = 0;
|
|
if ($sell_ids) {
|
|
// 销售成本
|
|
$all_sell = M('retail_sell')->field('num,purchase_price')->where(array('bill_id' => array('in', $sell_ids), 'purchase_price' => array('gt', 0)))->select();
|
|
foreach ($all_sell as &$v1) {
|
|
$sell_cost += floatval(round($v1['num'] * $v1['purchase_price'], 2));
|
|
}
|
|
}
|
|
// 退款
|
|
unset($map['b.order_type']);
|
|
$map['b.order_type'] = 2;
|
|
// 笔数
|
|
$refund_num = M('retail_bill_order as b')
|
|
->join('ls_retail_bill_discount as d on b.id=d.bill_id')
|
|
->join('ls_retail_bill_online as o on b.id=o.bill_id', 'LEFT')
|
|
->where($map)
|
|
->count();
|
|
// 金额
|
|
$refund_money = M('retail_bill_order as b')
|
|
->join('ls_retail_bill_discount as d on b.id=d.bill_id')
|
|
->join('ls_retail_bill_online as o on b.id=o.bill_id', 'LEFT')
|
|
->where($map)
|
|
->sum('all_money');
|
|
// 所有退款成本
|
|
$refund_ids = M('retail_bill_order as b')
|
|
->join('ls_retail_bill_discount as d on b.id=d.bill_id')
|
|
->join('ls_retail_bill_online as o on b.id=o.bill_id', 'LEFT')
|
|
->field('b.id')
|
|
->where($map)
|
|
->select();
|
|
$refund_ids = $refund_ids ? array_column($refund_ids, 'id') : '0';
|
|
// 销售成本
|
|
$refund_cost = 0;
|
|
if ($refund_ids) {
|
|
$all_refund = M('retail_sell')->field('num,purchase_price')->where(array('bill_id' => array('in', $refund_ids), 'purchase_price' => array('gt', 0)))->select();
|
|
foreach ($all_refund as &$v2) {
|
|
$refund_cost += floatval(round($v2['num'] * $v2['purchase_price'], 2));
|
|
}
|
|
}
|
|
// 计算成本 (销售成本 - 退款成本)
|
|
$cost = floatval(round($sell_cost - $refund_cost, 2));
|
|
// 实际金额 (销售金额 - 退款金额)
|
|
$income = floatval(round($sell_money - $refund_money, 2));
|
|
// 计算盈利,利润()
|
|
$profit = floatval(round($income - $cost, 2));
|
|
$profit_margin = floatval(round($profit / $income * 100, 2)) . '%';
|
|
$res['sell_num'] = $sell_num ? $sell_num : 0;
|
|
$res['refund_num'] = $refund_num ? $refund_num : 0;
|
|
$res['sell_money'] = $sell_money ? $sell_money : 0;
|
|
$res['refund_money'] = $refund_money ? $refund_money : 0;
|
|
$res['income'] = $income ? $income : 0;
|
|
$res['cost'] = $cost ? $cost : 0;
|
|
$res['profit'] = $profit ? $profit : 0;
|
|
$res['profit_margin'] = $profit_margin ? $profit_margin : '0%';
|
|
return $res;
|
|
}
|
|
|
|
|
|
/**
|
|
* 普通商品库存报表
|
|
*/
|
|
public function getGoodsInventoryList()
|
|
{
|
|
$data = I('post.');
|
|
$data['merchant_id'] = $this->merchant_id;
|
|
$inventory = new Inventory();
|
|
$result = $inventory->getStoreSyncGoodsInventoryList($data);
|
|
$this->ajaxReturn($result);
|
|
}
|
|
|
|
|
|
/**
|
|
* 普通商品库存报表详情
|
|
*/
|
|
public function getGoodsInventoryInfo()
|
|
{
|
|
$data = I('post.');
|
|
$data['merchant_id'] = $this->merchant_id;
|
|
$inventory = new Inventory();
|
|
$result = $inventory->getSyncGoodsInfo($data);
|
|
$this->ajaxReturn($result);
|
|
}
|
|
|
|
/**
|
|
* 规格商品库存报表
|
|
*/
|
|
public function getGoodsSkuInventoryList()
|
|
{
|
|
$data = I('post.');
|
|
$data['merchant_id'] = $this->merchant_id;
|
|
$inventory = new Inventory();
|
|
$result = $inventory->getStoreSyncGoodsSkuInventoryList($data);
|
|
$this->ajaxReturn($result);
|
|
}
|
|
|
|
/**
|
|
* 规格商品库存报表详情
|
|
*/
|
|
public function getGoodsSkuInventoryInfo()
|
|
{
|
|
$data = I('post.');
|
|
$data['merchant_id'] = $this->merchant_id;
|
|
$inventory = new Inventory();
|
|
$result = $inventory->getSyncGoodsSkuInfo($data);
|
|
$this->ajaxReturn($result);
|
|
}
|
|
|
|
|
|
//串号列表
|
|
public function serialList()
|
|
{
|
|
$data = I('post.');
|
|
$data['user_type'] = 4;
|
|
$data['merchant_id'] = $this->merchant_id;
|
|
$SerialClass = new SerialNumberGoods();
|
|
$result = $SerialClass->warehouseSerialList($data);
|
|
$this->ajaxReturn($result);
|
|
}
|
|
|
|
/**
|
|
* 销售报表导出
|
|
* @throws \PHPExcel_Exception
|
|
* @throws \PHPExcel_Reader_Exception
|
|
* @throws \PHPExcel_Writer_Exception
|
|
*/
|
|
public function sell_export()
|
|
{
|
|
if (IS_POST) {
|
|
$ExporttableController = new ExporttableController();
|
|
$RetailGuideModel = new RetailGuideModel();
|
|
$RetailVipModel = new RetailVipModel();
|
|
|
|
ini_set('memory_limit', '64M');
|
|
$user = I('session.ls_userinfo');
|
|
$store_id = I('post.store_id') ? I('post.store_id') : $this->store_id;
|
|
//搜索条件
|
|
$seek_data = I('post.seek_data') ? I('post.seek_data') : [];
|
|
$directory_name = I('post.directory_name');
|
|
$page = I('post.page') ? I('post.page') : 1;
|
|
$limit = I('post.limit') ? I('post.limit') : 500;
|
|
/* 时间搜索 */
|
|
$start_time = $seek_data['start_time'];
|
|
$end_time = $seek_data['end_time'];
|
|
if ($start_time && $end_time) {
|
|
$start_time = strtotime($start_time);
|
|
$end_time = strtotime($end_time);
|
|
$map['b.add_time'] = ['between', [$start_time, $end_time]];
|
|
} else if ($start_time && !$end_time) {
|
|
$start_time = strtotime($start_time);
|
|
$map['b.add_time'] = ['egt', $start_time];
|
|
} else if (!$start_time && $end_time) {
|
|
$start_time = strtotime($start_time);
|
|
$map['b.add_time'] = ['elt', $start_time];
|
|
}
|
|
/* 订单号搜索 */
|
|
if (trim($seek_data['order_id'], '')) {
|
|
$map['b.order_no'] = ['like', '%' . $seek_data['order_id'] . '%'];
|
|
}
|
|
/* 导购员搜索 */
|
|
if ($seek_data['guide_id']) {
|
|
$map['b.guide_id'] = $seek_data['guide_id'];
|
|
}
|
|
$map[] = [
|
|
'b.order_type' => 1,
|
|
[
|
|
'b.order_type' => ['in', '2,3'],
|
|
'b.refund_status' => 2,
|
|
],
|
|
'_logic' => 'OR',
|
|
];
|
|
/* 类型搜索 */
|
|
if ($seek_data['order_mold']) {
|
|
switch ($seek_data['order_mold']) {
|
|
case 1:
|
|
$map['b.type'] = 2;
|
|
break;
|
|
case 2:
|
|
$map['b.type'] = 1;
|
|
break;
|
|
case 3:
|
|
$map['b.type'] = 2;
|
|
$map['b.order_type'] = 1;
|
|
break;
|
|
case 4:
|
|
$map['b.type'] = 1;
|
|
$map['b.order_type'] = 1;
|
|
break;
|
|
case 5:
|
|
$map['b.type'] = 2;
|
|
$map['b.order_type'] = 2;
|
|
break;
|
|
case 6:
|
|
$map['b.type'] = 1;
|
|
$map['b.order_type'] = 2;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
$map['b.merchant_id'] = $user['merchantid'];
|
|
$map['b.store_id'] = $store_id;
|
|
$map['b.pay_state'] = 1;
|
|
$map['b.pay_type'] = ['neq', 0];
|
|
$bill_list = M('retail_bill_order as b')
|
|
->join('ls_retail_bill_discount as d on b.id=d.bill_id')
|
|
->join('ls_retail_bill_online as o on b.id=o.bill_id', 'LEFT')
|
|
->field('id,order_no,all_money,pay_type,type,order_type,b.add_time,vid,guide_id,vip_dis_money,coupon_money,small_changes_money,delivery_fee,discount,cashier_dis_money,third_vip_code,third_vip_name')
|
|
->where($map)
|
|
->page((int)$page, (int)$limit)
|
|
->order('b.add_time desc')
|
|
->select();
|
|
$BillOrder = new BillOrder();
|
|
foreach ($bill_list as $key => &$val) {
|
|
$val['index'] = $key + 1;
|
|
$val['add_time'] = date('Y-m-d H:i:s', $val['add_time']);
|
|
|
|
$val['pay_name'] = $BillOrder->getPayType($val['pay_type'], $val['id']);
|
|
|
|
/* 消费对象 */
|
|
if ($val['vid']) {
|
|
$vip = $RetailVipModel->getFind(['id' => $val['vid']], 'name,nickname');
|
|
if ($vip) {
|
|
if ($vip['name']) {
|
|
$val['consumer_object'] = $vip['name'];
|
|
} else if ($vip['nickname']) {
|
|
$val['consumer_object'] = $vip['nickname'];
|
|
} else {
|
|
$val['consumer_object'] = '未设置';
|
|
}
|
|
} else {
|
|
$val['consumer_object'] = '散客';
|
|
}
|
|
} else if ($val['third_vip_code']) {
|
|
$val['consumer_object'] = $val['third_vip_name'];
|
|
} else {
|
|
$val['consumer_object'] = '散客';
|
|
}
|
|
/* 统计成本 */
|
|
$val['purchase_price'] = 0;
|
|
$sell_list = M('retail_sell')->field('num,purchase_price')->where(array('bill_id' => $val['id']))->select();
|
|
foreach ($sell_list as &$v) {
|
|
$val['purchase_price'] += floatval(round($v['num'] * $v['purchase_price'], 2));
|
|
}
|
|
$val['delivery_fee'] = $val['delivery_fee'] ? floatval($val['delivery_fee']) : 0;
|
|
$val['profit'] = floatval(round($val['all_money'] - $val['purchase_price'] - $val['delivery_fee'], 2));
|
|
$val['profit_margin'] = floatval(round($val['profit'] / ($val['all_money'] - $val['delivery_fee']) * 100, 2)) . '%';
|
|
$val['dismoney'] = $val['vip_dis_money'] && $val['vip_dis_money'] > 0 ? floatval($val['vip_dis_money']) : '无';
|
|
$val['coupon_money'] = $val['coupon_money'] && $val['coupon_money'] > 0 ? floatval($val['coupon_money']) : '无';
|
|
$val['delivery_fee'] = $val['delivery_fee'] && $val['delivery_fee'] > 0 ? floatval($val['delivery_fee']) : '无';
|
|
$val['small_changes_money'] = $val['small_changes_money'] && $val['small_changes_money'] > 0 ? floatval($val['small_changes_money']) : '无';
|
|
if ($val['discount'] > 0 && $val['discount'] < 1 && $val['cashier_dis_money']) {
|
|
$val['discount_remark'] = floatval($val['discount']) . '折金额:' . floatval($val['cashier_dis_money']);
|
|
} else {
|
|
$val['discount_remark'] = '未打折金额:无';
|
|
}
|
|
/* 查询导购员 */
|
|
if ($val['guide_id']) {
|
|
$guide_name = $RetailGuideModel->getFindField(['id' => $val['guideid']], 'guidename');
|
|
$val['guide_name'] = $guide_name ? $guide_name : '未设置';
|
|
} else {
|
|
$val['guide_name'] = '自购';
|
|
}
|
|
/* 类型 */
|
|
$type_name = $val['type'] == 1 ? '商城' : '店内';
|
|
$order_type_name = $val['order_type'] == 1 ? '销售' : '退款';
|
|
$val['order_mold'] = $type_name . $order_type_name;
|
|
/* 退款订单加负号 */
|
|
if ($val['order_type'] != 1) {
|
|
$val['all_money'] = '-' . $val['all_money'];
|
|
$val['profit'] = 0;
|
|
$val['profit_margin'] = '0%';
|
|
}
|
|
}
|
|
import("Vendor.PHPExcel.PHPExcel");
|
|
import("Vendor.PHPExcel.Writer.Excel5");
|
|
import("Vendor.PHPExcel.IOFactory.php");
|
|
$filename = 'SellListReport' . date("ymdHis", time());
|
|
$headArr = [
|
|
['index', '序号'],
|
|
['order_mold', '类型'],
|
|
['order_no', '订单号'],
|
|
['add_time', '售出时间'],
|
|
['consumer_object', '消费对象'],
|
|
['guide_name', '导购'],
|
|
['pay_name', '支付方式'],
|
|
['all_money', '支付金额'],
|
|
['purchase_price', '成本合计'],
|
|
['coupon_money', '优惠券'],
|
|
['small_changes_money', '抹零'],
|
|
['vip_dis_money', '会员折扣'],
|
|
['discount_remark', '收银折扣'],
|
|
['delivery_fee', '费送费'],
|
|
['profit', '利润'],
|
|
['profit_margin', '利润率'],
|
|
];
|
|
$str = $filename . '表格生成时间:' . date('Y-m-d H:i:s');
|
|
if (!$directory_name) {
|
|
$num = createKey();
|
|
$directory_name = "./Uploads/storeGoodsExcel/{$store_id}/{$num}";
|
|
}
|
|
$ExporttableController->setExcel($filename, $headArr, $bill_list, $str, $directory_name);
|
|
$result = array(
|
|
'status' => 1,
|
|
'type' => 1,
|
|
'directory_name' => $directory_name,
|
|
'msg' => '请继续生成文件'
|
|
);
|
|
if (count($bill_list) < $limit) {
|
|
$result['type'] = 2;
|
|
$result['msg'] = '数据生成完毕';
|
|
}
|
|
$this->ajaxReturn($result);
|
|
} else if (IS_GET) {
|
|
$directory_name = I('get.directory_name');
|
|
$ExporttalController = new ExporttableController();
|
|
$res = $ExporttalController->fileZipAddToDel($directory_name, 'SellList');
|
|
$this->ajaxReturn($res);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 获取商户概况数据统计
|
|
*/
|
|
public function getMerchantStatisticsList()
|
|
{
|
|
$Statistics = new \Common\Order\Statistics();
|
|
|
|
if (!$this->merchant_id) {
|
|
$this->ajaxReturn(['status' => 0, 'msg' => '登录超时,请重新登录']);
|
|
}
|
|
|
|
$result = $Statistics->getMerchantStatisticsList($this->merchant_id);
|
|
|
|
$this->ajaxReturn($result);
|
|
}
|
|
|
|
/**
|
|
* 获取门店概况数据统计
|
|
*/
|
|
public function getStoreStatisticsList()
|
|
{
|
|
$Statistics = new \Common\Order\Statistics();
|
|
|
|
if (!$this->merchant_id || !$this->store_id) {
|
|
$this->ajaxReturn(['status' => 0, 'msg' => '登录超时,请重新登录']);
|
|
}
|
|
|
|
$result = $Statistics->getStoreStatisticsList($this->merchant_id, $this->store_id);
|
|
|
|
$this->ajaxReturn($result);
|
|
}
|
|
}
|