->all();
$productsIds = ArrayHelper::getColumn($products, 'id');
- if (CityStore::find()->where(['id' => $storeId])->one()->city_id == 1342) {
- $region = 52;
- } elseif (CityStore::find()->where(['id' => $storeId])->one()->city_id == 1) {
- $region = 77;
- } else {
- $region = null;
+ $storeParams = CityStoreParams::find()
+ ->where(['store_id' => $storeId])
+ ->one();
+
+ $region = $storeParams?->address_region;
+
+ if (!$region) {
+ $cityId = CityStore::find()->select('city_id')->where(['id' => $storeId])->scalar();
+ $region = $cityId == 1
+ ? BouquetComposition::REGION_MSK
+ : BouquetComposition::REGION_NN;
}
$priceRecords = PricesDynamic::find()
->select(['product_id', 'price'])
->where(['product_id' => $productsIds])
->andWhere(['active' => 1])
- ->andWhere(['or', ['region_id' => $region], ['region_id' => null]])
+ ->andWhere(['region_id' => $region])
->indexBy('product_id')
->asArray()
->all();
$filters['month'],
$year,
$goals,
- $productSalesShare,
- $filters['category'],
- $filters['subcategory'],
- $filters['species']
+ $productSalesShare
);
*/
public function getUnmarkedProductsComponents(int $storeId, string $month, string $year, int $regionId = null, $typeFilter = null): array
{
- $date = new \DateTimeImmutable(sprintf('%04d-%02d-01', $year, $month));
-
-
- $region = CityStoreParams::find()
+ $storeParams = CityStoreParams::find()
->where(['store_id' => $storeId])
- ->one()->address_region;
+ ->one();
+
+ $region = $storeParams?->address_region;
- if (!$regionId && !$region) {
- // определяем регион по городу
+ if (!$region && !$regionId) {
$cityId = CityStore::find()->select('city_id')->where(['id' => $storeId])->scalar();
- if ($cityId == 1) {
- $region = BouquetComposition::REGION_MSK;
- } else {
- $region = BouquetComposition::REGION_NN;
- }
+ $region = $cityId == 1
+ ? BouquetComposition::REGION_MSK
+ : BouquetComposition::REGION_NN;
}
$monthStart = sprintf('%04d-%02d-01 00:00:00', $year, $month);
$priceDynamics = PricesDynamic::find()
->andWhere(['region_id' => $region])
->andWhere(['product_id' => array_values( ArrayHelper::getColumn($nomenclatures, 'id') )])
- // ->andWhere(['<=', 'date_from', $monthStart])
- // ->andWhere(['>=', 'date_to', $monthEnd])
->orderBy(['date_from' => SORT_DESC])
->all();
public function calculateProductForecastInPiecesProductsWithHistory(
int $storeId,
- string $month, string $year,
+ string $month,
+ string $year,
array $speciesGoals,
- array $productSalesShare,
- string $category = null,
- string $subcategory = null,
- string $species = null
+ array $productSalesShare
): array {
$result = [];
$goalsMap = $this->mapGoalsBySpecies($speciesGoals);
- $region = CityStoreParams::find()
+ $storeParams = CityStoreParams::find()
->where(['store_id' => $storeId])
- ->one()->address_region ?? null;
+ ->one();
+
+ $region = $storeParams?->address_region;
if (!$region) {
$cityId = CityStore::find()->select('city_id')->where(['id' => $storeId])->scalar();
- $region = ($cityId == 1)
+ $region = $cityId == 1
? BouquetComposition::REGION_MSK
: BouquetComposition::REGION_NN;
}
+ $priceRecords = PricesDynamic::find()
+ ->where([
+ 'product_id' => array_keys($productSalesShare),
+ 'region_id' => $region,
+ 'active' => 1,
+ ])
+ ->indexBy('product_id')->asArray()->all();
foreach ($productSalesShare as $productId => $data) {
$share = $data['share'] ?? 0.0;
continue;
}
- $priceRecord = PricesDynamic::find()
- ->where([
- 'product_id' => $productId,
- 'region_id' => $region,
- 'active' => 1,
- ])
- ->one();
-
- if (!$priceRecord || $priceRecord->price <= 0) {
+ if (!$priceRecords[$productId] || $priceRecords[$productId]['price'] <= 0) {
continue;
}
$cat = $data['category'];
$sub = $data['subcategory'];
$spec = $data['species'];
+ $price = $priceRecords[$productId]['price'];
if (
! isset(
$goalsMap[$storeId],
$goalsMap[$storeId][$cat][$sub][$spec]
)
) {
-
continue;
}
$forecastSum = $goal * $share;
- $forecastCount = $forecastSum / $priceRecord->price;
+ $forecastCount = $forecastSum / $price;
$result[] = [
'month' => $month,
'product_id' => $productId,
'goal' => $goal,
'goal_share' => round($forecastSum, 2),
- 'price' => $priceRecord->price,
+ 'price' => $price,
'forecast_pieces' => round($forecastCount),
'store_id' => $data['store_id'],
'category' => $data['category'],
* @param array|int $storeIds
* @param int $month
* @param int $year
- * @param int $regionId
+ * @param string $type
* @return array список строк с полями:
* sale_id, sale_date, product_id, product_name,
* component_guid, component_name, component_category,
*/
public function getProductsComponentsInCategory(int $storeId, string $month, string $year, string $type = self::TYPE_SALES): array
{
- $region = CityStoreParams::find()
+ $storeParams = CityStoreParams::find()
->where(['store_id' => $storeId])
- ->one()->address_region ?? null;
+ ->one();
+
+ $region = $storeParams?->address_region;
if (!$region) {
$cityId = CityStore::find()->select('city_id')->where(['id' => $storeId])->scalar();
$componentProducts = $writeOffsProducts;
}
- $components = [];
- $rows = [];
+ $componentGuids = [];
+ $componentDataRecords = [];
foreach ($componentProducts as $cp) {
$js = trim($cp['components']);
if ($js === '' || $js[0] !== '{') {
if ($qty <= 0) {
continue;
}
- $components[$guid] = true;
- $rows[] = [
+ $componentGuids[$guid] = true;
+ $componentDataRecords[] = [
'record_id' => $cp['id'] ?? $cp['write_off_id'],
'sale_date' => $cp['date'] ?? $cp['write_off_date'],
'product_id' => $cp['product_id'],
}
}
- if (empty($rows)) {
+ if (empty($componentDataRecords)) {
return [];
}
- $guids = array_keys($components);
+ $guids = array_keys($componentGuids);
$nomenclatures = Products1cNomenclature::find()
->andWhere(['id' => $guids])
->andWhere(['not in', 'category', ['', 'букет', 'сборка', 'сервис']])
->all();
$pricesByProduct = [];
- foreach ($priceDynamics as $pd) {
- $pricesByProduct[$pd->product_id][] = $pd;
+ foreach ($priceDynamics as $priceRecord) {
+ $pricesByProduct[$priceRecord->product_id][] = $priceRecord;
}
$result = [];
- foreach ($rows as $r) {
- $guid = $r['component_guid'];
- $n = $nomenclatures[$guid] ?? null;
- $pid = $n?->id;
+
+ foreach ($componentDataRecords as $componentDataRecord) {
+ $guid = $componentDataRecord['component_guid'];
+ $nomenclatureData = $nomenclatures[$guid] ?? null;
+ $productId = $nomenclatureData?->id;
$price = 0;
- foreach ($pricesByProduct[$pid] ?? [] as $pd) {
- if ($pd->date_from <= $r['sale_date'] && $pd->date_to >= $r['sale_date']) {
- if ($pid == '2b72702a-792f-11e8-9edd-1c6f659fb563') {
- $price = 8.66; // TODO: заглушка для цены гелия - исправить
- } else {
- $price = $pd->price;
+ $dailyPrices = [];
+ foreach ($pricesByProduct[$productId] ?? [] as $priceRecordForProduct) {
+ if ($productId == '2b72702a-792f-11e8-9edd-1c6f659fb563') {
+ $saleDay = (new \DateTime($componentDataRecord['sale_date']))->format('Y-m-d');
+ $fromDay = (new \DateTime($priceRecordForProduct->date_from))->modify('-1 day')->format('Y-m-d');
+ $toDay = (new \DateTime($priceRecordForProduct->date_to ))->modify('+1 day')->format('Y-m-d');
+
+ if ($fromDay <= $saleDay && $saleDay <= $toDay) {
+ $dailyPrices[] = (float)$priceRecordForProduct->price;
}
-
-
+ }
+ if ($priceRecordForProduct->date_from <= $componentDataRecord['sale_date'] && $priceRecordForProduct->date_to >= $componentDataRecord['sale_date']) {
+ $price = $priceRecordForProduct->price;
break;
}
}
- $cost = $r['quantity'] * $price * $r['quantity_product'];
- $costComponent = $r['quantity'] * $price;
+ if (!empty($dailyPrices)) {
+ $price = min($dailyPrices);
+ } else {
+ $price = 0.0;
+ }
+ $cost = $componentDataRecord['quantity'] * $price * $componentDataRecord['quantity_product'];
+ $costComponent = $componentDataRecord['quantity'] * $price;
$result[] = [
'store_id' => $storeId,
- 'record_id' => $r['record_id'],
- 'sale_date' => $r['sale_date'],
- 'product_id' => $r['product_id'],
- 'product_name' => $r['product_name'],
- 'quantity_product' => $r['quantity_product'],
+ 'record_id' => $componentDataRecord['record_id'],
+ 'sale_date' => $componentDataRecord['sale_date'],
+ 'product_id' => $componentDataRecord['product_id'],
+ 'product_name' => $componentDataRecord['product_name'],
+ 'quantity_product' => $componentDataRecord['quantity_product'],
'component_guid' => $guid,
- 'component_name' => $n?->name,
- 'component_category' => $n?->category,
- 'component_subcategory'=> $n?->subcategory,
- 'component_species' => $n?->species,
- 'quantity' => $r['quantity'],
+ 'component_name' => $nomenclatureData?->name,
+ 'component_category' => $nomenclatureData?->category,
+ 'component_subcategory'=> $nomenclatureData?->subcategory,
+ 'component_species' => $nomenclatureData?->species,
+ 'quantity' => $componentDataRecord['quantity'],
'price' => $price,
'cost' => $cost,
'component_cost' => $costComponent,
'type' => $type,
- 'operation' => $r['operation'],
+ 'operation' => $componentDataRecord['operation'],
];
}