Files
OMS/app/inventorydepth/model/shop/adjustment.php
2026-01-04 19:08:31 +08:00

546 lines
19 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* Copyright 2012-2026 ShopeX (https://www.shopex.cn)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
*
*/
class inventorydepth_mdl_shop_adjustment extends dbeav_model
{
public $filter_use_like = false;
public $defaultOrder = 'shop_product_bn_crc32';
var $has_export_cnf = true;
var $export_name = '库存管理';
function __construct($app)
{
parent::__construct($app);
$this->app = $app;
}
public function table_name($real=false){
$table_name = 'shop_skus';
if($real){
return kernel::database()->prefix.$this->app->app_id.'_'.$table_name;
}else{
return $table_name;
}
}
function searchOptions(){
$parentOptions = parent::searchOptions();
$childOptions = array(
'shop_iid'=>app::get('base')->_('店铺商品ID'),
'shop_sku_id'=>app::get('base')->_('平台SKU ID'),
);
return array_merge($childOptions,$parentOptions);
}
/**
* 覆盖店铺库存
*
* @return void
* @author
**/
public function convert_shop_stock($filter)
{
$sql = 'UPDATE '.$this->table_name(true).' SET shop_stock=release_stock WHERE '.$this->_filter($filter);
$this->db->exec($sql);
}
/*
* “导出”相关开始
*/
public function disabled_export_cols(&$cols){
unset($cols['column_operator']);
}
private function get_export_title_by_fields($fields,&$arr_fields){
$arr_fields_titles = array(
"column_request" => "*:回写库存",
"shop_product_bn" => "*:店铺货号",
"column_bind" => "*:是否捆绑",
"shop_title" => "*:店铺货品名称",
"column_regulation" => "*:库存更新规则",
"column_shop_stock" => "*:店铺库存",
"column_actual_stock" => "*:店铺可售库存",
"column_release_stock" => "*:发布库存",
"shop_properties_name" => "*:店铺货品属性",
"shop_price" => "*:销售价",
"download_time" => "*:同步时间",
"mapping" => "*:已对映上本地货品",
"update_time" => "*:最后更新时间",
);
$title_arr = array();
$arr_fields = explode(",",$fields);
foreach($arr_fields as $var_af){
$title_arr[] = $arr_fields_titles[$var_af];
}
return mb_convert_encoding(implode(',',$title_arr), 'GBK', 'UTF-8');
}
private function get_export_row_value_by_field($field,$row_arr,$arr_shop_stock,$arr_release_stock){
$return_data = $row_arr[$field];
switch($field){
case "column_request":
$return_data = "关闭";
if($row_arr["request"] == 'true'){
$return_data = "开启";
}
break;
case "column_bind":
if($row_arr["bind"] == "1"){
$return_data = "组合";
}elseif($row_arr["bind"] == "2"){
$return_data = "多选一";
}else{
$return_data = "普通";
}
break;
case "shop_price":
$return_data = "".number_format($return_data,2,".","");
break;
case "download_time":
case "update_time":
$return_data = date("Y-m-d H:i:s",$return_data);
break;
case "mapping":
if($return_data == "1"){
$return_data = "SKU已匹配";
}else{
$return_data = "SKU未匹配";
}
break;
case "column_shop_stock":
if(!empty($arr_shop_stock)){
foreach($arr_shop_stock as $var_ass){
if($row_arr["id"] == $var_ass["id"]){
$return_data = $var_ass["num"];break;
}
}
}
break;
case "column_regulation":
if(!empty($arr_release_stock)){
foreach($arr_release_stock as $var_ars){
if($row_arr["id"] == $var_ars["id"]){
$return_data = $var_ars["rule_heading"];break;
}
}
}
break;
case "column_actual_stock":
$return_data = "0";
if(!empty($arr_release_stock)){
foreach($arr_release_stock as $var_ars){
if($row_arr["id"] == $var_ars["id"]){
$return_data = $var_ars["actual_stock"];break;
}
}
}
break;
case "column_release_stock":
$return_data = $row_arr["release_stock"];;
if(!empty($arr_release_stock)){
foreach($arr_release_stock as $var_ars){
if($row_arr["id"] == $var_ars["id"]){
$return_data = $var_ars["quantity"];break;
}
}
}
break;
}
return kernel::single('ome_func')->csv_filter($return_data);
}
//参考控制器getShopStock方法 店铺库存获取
private function get_export_shop_stock($iids,$shop_id){
if(empty($iids) || !$shop_id){
return array();
}
$shop = $this->app->model('shop')->dump(array('shop_id'=>$shop_id));
$shopfactory = inventorydepth_service_shop_factory::createFactory($shop['shop_type'],$shop['business_type']);
if ($shopfactory === false){
return array();
}
$result = $shopfactory->downloadByIIds($iids,$shop_id,$errormsg);
if (empty($result)) {
return array();
}
$items = array();
foreach ($result as $r){
if($r['skus']){
foreach ($r['skus']['sku'] as $sku){
$items[] = array(
'iid' => strval($r['iid']),
'sku_id' => $sku['sku_id'],
'num' => $sku['quantity'],
'id' => md5($shop_id.$r['iid'].$sku['sku_id']),
);
}
}else{
$items[] = array(
'iid' => strval($r['iid']),
'num' => $r['num'],
'id' => md5($shop_id.$r['iid']),
);
}
}
return $items;
}
//参考控制器getReleaseStock方法 库存更新规则、店铺可售库存、发布库存获取
private function get_export_release_stock($ids,$shop_id){
$salesMaterialObj = app::get('material')->model('sales_material');
$salesMLib = kernel::single('material_sales_material');
if(empty($ids) || !$shop_id) {
return array();
}
$adjustmentModel = $this->app->model('shop_adjustment');
$skus = $adjustmentModel->getList('shop_product_bn,bind,shop_id,shop_bn,id,mapping',array('id'=>$ids));
$pbns = array_filter(array_column($skus, 'shop_product_bn'));
if (empty($pbns)) {
return array();
}
// [普通]销售物料
$products = $salesMaterialObj->getList('sm_id,sales_material_name,sales_material_bn, sales_material_type,shop_id,class_id',array('sales_material_bn'=>$pbns));
if (empty($products)) {
return array();
}
$products = array_column($products, null, 'sales_material_bn');
kernel::single('inventorydepth_calculation_basicmaterial')->init($products);
kernel::single('inventorydepth_calculation_salesmaterial')->init($products);
$data = array();
foreach ($skus as $sku) {
$stock = kernel::single('inventorydepth_logic_stock')->getStock($products[$sku['shop_product_bn']],$sku['shop_id'],$sku['shop_bn']);
$quantity = $stock['quantity'];
$actual_stock = $stock['actual_stock'];
$asRs = $stock['regulation']['detail']['可售库存']['info'];
if($actual_stock === false) continue;
if ($quantity !== false) {
$adjustmentModel->update(array('release_stock'=>$quantity),array('id'=>$sku['id']));
}
// 详情
$actual_product_stock = array();
foreach ($asRs['basic'] as $bn => $bcRs) {
$actual_product_stock[] = array(
'bn' => $bn,
'stock' => $bcRs['quantity'],
);
}
if ($sku['mapping'] =='1') {
$rule_heading= $stock['regulation']['规则名称'];
}else{
$rule_heading= '-';
}
$data[] = array(
'id' => $sku['id'],
'quantity' => $quantity,
'actual_stock' => $sku['mapping']=='1' ? $actual_stock : '-',
'actual_product_stock'=>($sku['bind']=='1' || $sku['bind']=='2') ? $actual_product_stock :'',
'rule_heading' => $rule_heading,
);
}
return $data;
}
public function getExportDataByCustom($fields, $filter, $has_detail, $curr_sheet, $start, $end){
$title_row = $this->get_export_title_by_fields($fields,$arr_fields);
//根据选择的字段定义导出的第一行标题
if($curr_sheet == 1){
$data['content']['main'][] = $title_row;
}
// 过滤掉NULL与空数据
$filter = array_filter($filter, function($var){
return !is_null($var) && $var !== '';
});
if(!$list = $this->getList('*',$filter,$start,$end)){
return false;
}
//统一获取接口数据
$ids = array();
$iids = array();
foreach($list as $var_list){
$ids[] = $var_list["id"];
$iids[] = $var_list["shop_iid"];
}
$arr_shop_stock = $this->get_export_shop_stock($iids,$filter["shop_id"]);
$arr_release_stock = $this->get_export_release_stock($ids,$filter["shop_id"]);
foreach($list as $line => $row ){
$row_data_arr = array();
foreach($arr_fields as $k => $v ){
$current_value = $this->get_export_row_value_by_field($v,$row,$arr_shop_stock,$arr_release_stock);
$row_data_arr[$k] = $current_value;
}
ksort($row_data_arr);
$data['content']['main'][] = implode(',',$row_data_arr);
}
return $data;
}
/*
* 导出结束
*/
public function exportTemplate($filter){
foreach ($this->io_title($filter) as $v){
$title[] = kernel::single('base_charset')->utf2local($v);
}
return $title;
}
/**
* 导入前的单纯数据验证
*
* @return void
* @author
**/
public function prepared_import_csv_row($row,$title,&$goodsTmpl,&$mark,&$newObjFlag,&$msg)
{
if(empty($row)) return false;
$shop_bn = $row[$title['*:店铺编码']];
$shop_product_bn = $row[$title['*:货品编号']];
$release_stock = $row[$title['*:发布库存']];
//$barcode = $row[$title['*:条形码']];
if( substr($row[0],0,1) == '*' ){
$titleRs = array_flip($row);
$mark = 'title';
return $titleRs;
}
if(isset($this->nums)){
$this->nums++;
if($this->nums > 5000){
$msg['error'] = "导入的商品数据量过大请减少到5000单以下";
return false;
}
}else{
$this->nums = 0;
}
$mark = 'contents';
if (empty($shop_bn)) {
$msg['warning'][] = '存在店铺编码为空的记录!';
return false;
}
if (empty($shop_product_bn)) {
$msg['warning'][] = '存在货品编码为空的记录!';
return false;
}
if ((int)$release_stock<1) {
$msg['warning'][] = '存在发布库存为零的记录!';
return false;
}
return $row;
}
/**
* 导入前的数据库数据验证
*
* @return void
* @author
**/
public function prepared_import_csv_obj($data,$mark,$goodsTmpl,&$msg = '')
{
$title = $data['title'];
$contents = &$data['contents'];
$shopModel = $this->app->model('shop');
foreach($contents as $content){
$shop_bn = $content[$title['*:店铺编码']];
$shop_product_bn = $content[$title['*:货品编号']];
$release_stock = $content[$title['*:发布库存']];
$filter['shop_bn'] = $shop_bn;
$filter['shop_product_bn'] = $shop_product_bn;
$sku = $this->getList('id,shop_product_bn,shop_id,shop_type',$filter,0,1);
if (!$sku) {
$msg['error'] = "店铺【{$shop_bn}】不存在货品【{$shop_product_bn}】!";
return false;
}
$shop = $shopModel->getList('shop_id,shop_bn,name,shop_type',array('shop_bn'=>$shop_bn),0,1);
if (!$shop) {
$msg['error'] = "店铺【编号是{$shop_bn}】不存在!";
return false;
}
$sdf[] = array('release_stock'=>$release_stock,'id'=>$sku[0]['id'],'shop_id'=>$sku[0]['shop_id'],'shop_product_bn'=>$sku[0]['shop_product_bn'],'shop_type'=>$sku[0]['shop_type']);
// 记录操作日志
$optLogModel = app::get('inventorydepth')->model('operation_log');
$optLogModel->write_log('sku',$sku[0]['id'],'stockup','导入发布库存:'.$release_stock);
}
base_kvstore::instance('inventorydepth_shop_goods')->store('shop-goods-'.$this->ioObj->cacheTime,serialize($sdf));
return null;
}
public function prepared_import_csv(){
$this->ioObj->cacheTime = time();
}
public function finish_import_csv(){
base_kvstore::instance('inventorydepth_shop_goods')->fetch('shop-goods-'.$this->ioObj->cacheTime,$data);
base_kvstore::instance('inventorydepth_shop_goods')->store('shop-goods-'.$this->ioObj->cacheTime,'');
$data = unserialize($data);
$title = '导入店铺发布库存';
kernel::single('inventorydepth_queue')->insert_shop_skus_queue($title,$data);
return null;
}
/**
*
*
* @return void
* @author
**/
public function update_shop_stock($ids)
{
$sql = 'UPDATE '.$this->table_name(true).' SET shop_stock=release_stock WHERE id in('.implode(',', $ids).')';
return $this->db->exec($sql);
}
/**
* undocumented function
*
* @return void
* @author
**/
public function _filter($filter,$tableAlias=null,$baseWhere=null)
{
$where = array(1);
if (isset($filter['shop_product_bn'])) {
if (is_string($filter['shop_product_bn']) && strpos($filter['shop_product_bn'], "\n") !== false) {
$shop_product_bn = array_unique(array_map('trim', array_filter(explode("\n", $filter['shop_product_bn']))));
$filter['shop_product_bn|in'] = $shop_product_bn;
unset($filter['shop_product_bn']);
}
if ($filter['shop_product_bn'] == 'repeat') {
unset($filter['shop_product_bn']);
$pbn = $this->get_repeat_product_bn($filter);
if ($pbn) {
$filter['shop_product_bn'] = $pbn;
} else {
# 没有重复的,则结果为空
$filter['shop_product_bn'][] = 'norepeat';
}
}
if ($filter['shop_product_bn'] == 'exceptrepeat') {
unset($filter['shop_product_bn']);
$pbn = $this->get_repeat_product_bn($filter);
if ($pbn) {
$filter['shop_product_bn|notin'] = $pbn;
}
}
}
if (isset($filter['shop_iid'])) {
if (is_string($filter['shop_iid']) && strpos($filter['shop_iid'], "\n") !== false) {
$shop_iid = array_unique(array_map('trim', array_filter(explode("\n", $filter['shop_iid']))));
if ($shop_iid) $filter['shop_iid|in'] = $shop_iid;
unset($filter['shop_iid']);
}
}
if (isset($filter['shop_sku_id'])) {
if (is_string($filter['shop_sku_id']) && strpos($filter['shop_sku_id'], "\n") !== false) {
$shop_sku_id = array_unique(array_map('trim', array_filter(explode("\n", $filter['shop_sku_id']))));
if ($shop_sku_id) $filter['shop_sku_id|in'] = $shop_sku_id;
unset($filter['shop_sku_id']);
}
}
return parent::_filter($filter,$tableAlias,$baseWhere).' AND '.implode(' AND ', $where);
}
/**
* @description 获取重复货号
*/
public function get_repeat_product_bn($filter)
{
$sql = 'SELECT id,shop_product_bn,shop_id FROM '.$this->table_name(true).' WHERE shop_id="'.$filter['shop_id'].'" AND shop_product_bn!="" AND shop_product_bn is not null GROUP BY shop_product_bn,shop_id Having count(1)>1 ';
$list = $this->db->select($sql);
$pbn = array();
if ($list) {
foreach ($list as $key=>$value) {
$pbn[] = $value['shop_product_bn'];
}
}
return $pbn;
}
/**
* @description
* @access public
* @param void
* @return void
*/
public function modifier_mapping($row)
{
if ($row == '1') {
$row = '<div style="color:green;">SKU已匹配</div>';
} else {
$row = '<div style="color:red;">SKU未匹配</div>';
}
return $row;
}
public function getFinderList($cols='*', $filter=array(), $offset=0, $limit=-1, $orderType=null)
{
$this->appendCols = 'shop_iid,shop_sku_id';
$list = parent::getList($cols, $filter, $offset, $limit, $orderType);
return $list;
}
}