Skip to content

Commit 136c1f7

Browse files
committed
OXDEV-5088 Cover more temporary active product cases
1 parent ac5d0f3 commit 136c1f7

File tree

8 files changed

+223
-56
lines changed

8 files changed

+223
-56
lines changed

CHANGELOG-8.0.md

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
- Admin directory is not removed from the url in `ViewConfig::getModuleUrl` anymore [PR-817](https://github.com/OXID-eSales/oxideshop_ce/pull/817)
77
- Reset created product "sold" counter during Copying of the product [PR-913](https://github.com/OXID-eSales/oxideshop_ce/pull/913)
88
- `ModuleConfigurationValidatorInterface` is not optional anymore in the module activation service.
9+
- The visibility of time-activated products has changed, products with an undefined end date appear in the shop for an unlimited period of time
910

1011
### Removed
1112
- Remove console classes from the Internal namespace: `Executor`, `ExecutorInterface`, `CommandsProvider`, `CommandsProviderInterface`

source/Application/Controller/Admin/ArticleList.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ public function render()
8585

8686
return "article_list";
8787
}
88+
8889
/**
8990
* Returns array of fields which may be used for product data search
9091
*
@@ -305,7 +306,7 @@ private function setIsActiveFieldForProductsInList(ListModel $productList): void
305306

306307
if ($useTimeCheck) {
307308
$product->hasActiveTimeRange = $product->hasProductValidTimeRange();
308-
$product->isActiveNow = $product->isProductActive($now);
309+
$product->isActiveNow = $product->isProductTemporaryActive($now);
309310
}
310311
$productList[$key] = $product;
311312
}

source/Application/Model/Article.php

+42-22
Original file line numberDiff line numberDiff line change
@@ -557,19 +557,17 @@ public function setId($sId = null)
557557
*/
558558
public function getActiveCheckQuery($blForceCoreTable = null)
559559
{
560-
$sTable = $this->getViewName($blForceCoreTable);
560+
$viewName = $this->getViewName($blForceCoreTable);
561561

562-
// check if article is still active
563-
$sQ = " $sTable.oxactive = 1 ";
562+
$query = " $viewName.oxactive = 1 ";
564563

565-
$sQ .= " and $sTable.oxhidden = 0 ";
564+
$query .= " and $viewName.oxhidden = 0 ";
566565

567-
// enabled time range check ?
568566
if (Registry::getConfig()->getConfigParam('blUseTimeCheck')) {
569-
$sQ = $this->addSqlActiveRangeSnippet($sQ, $sTable);
567+
$query = $this->addSqlActiveRangeSnippet($query, $viewName);
570568
}
571569

572-
return $sQ;
570+
return $query;
573571
}
574572

575573
/**
@@ -1029,6 +1027,21 @@ public function setRangePrice($blIsRangePrice = true)
10291027
return $this->_blIsRangePrice = $blIsRangePrice;
10301028
}
10311029

1030+
public function isProductTemporaryActive(): bool
1031+
{
1032+
$activeFrom = $this->oxarticles__oxactivefrom->value;
1033+
$activeTo = $this->oxarticles__oxactiveto->value;
1034+
$now = Registry::getUtilsDate()->getTime();
1035+
1036+
if (!$this->hasProductValidTimeRange()) {
1037+
return false;
1038+
}
1039+
1040+
return (Registry::getUtilsDate()->isEmptyDate($activeTo) || strtotime($activeTo) >= $now)
1041+
&& (Registry::getUtilsDate()->isEmptyDate($activeFrom) || strtotime($activeFrom) <= $now);
1042+
}
1043+
1044+
10321045
/**
10331046
* Checks if article has visible status. Returns TRUE if its visible
10341047
*
@@ -1038,19 +1051,16 @@ public function isVisible()
10381051
{
10391052
// admin preview mode
10401053
if (($blCanPreview = Registry::getUtils()->canPreview()) !== null) {
1054+
10411055
return $blCanPreview;
10421056
}
10431057

1044-
// active ?
1045-
$sNow = date('Y-m-d H:i:s');
1058+
$blUseTimeCheck = Registry::getConfig()->getConfigParam('blUseTimeCheck');
10461059
if (
1047-
!$this->oxarticles__oxactive->value &&
1048-
(
1049-
!Registry::getConfig()->getConfigParam('blUseTimeCheck') ||
1050-
$this->oxarticles__oxactivefrom->value > $sNow ||
1051-
$this->oxarticles__oxactiveto->value < $sNow
1052-
)
1060+
!$this->oxarticles__oxactive->value
1061+
&& (($blUseTimeCheck && !$this->isProductTemporaryActive()) || !$blUseTimeCheck)
10531062
) {
1063+
10541064
return false;
10551065
}
10561066

@@ -1062,6 +1072,7 @@ public function isVisible()
10621072
$iOnStock += $session->getBasketReservations()->getReservedAmount($this->getId());
10631073
}
10641074
if ($iOnStock <= 0) {
1075+
10651076
return false;
10661077
}
10671078
}
@@ -4042,13 +4053,6 @@ public function isProductAlwaysActive(): bool
40424053
return !empty($this->oxarticles__oxactive->value);
40434054
}
40444055

4045-
public function isProductActive(string $date): bool
4046-
{
4047-
return $this->hasProductValidTimeRange()
4048-
&& $this->oxarticles__oxactivefrom->value <= $date
4049-
&& $this->oxarticles__oxactiveto->value >= $date;
4050-
}
4051-
40524056
/**
40534057
* Applies VAT to article
40544058
*
@@ -5270,4 +5274,20 @@ protected function updateManufacturerBeforeLoading($oManufacturer)
52705274
{
52715275
$oManufacturer->setReadOnly(true);
52725276
}
5277+
5278+
protected function addSqlActiveRangeSnippet($query, $tableName): string
5279+
{
5280+
$dateUtils = Registry::getUtilsDate();
5281+
$secondsToRoundForQueryCache = $this->getSecondsToRoundForQueryCache();
5282+
$dateNow = $dateUtils->getRoundedRequestDateDBFormatted($secondsToRoundForQueryCache);
5283+
$defaultDBDate = $dateUtils->formatDBDate('-');
5284+
5285+
$activeToCondition = "$tableName.oxactivefrom <= '$dateNow' AND " .
5286+
"$tableName.oxactivefrom != '$defaultDBDate' AND $tableName.oxactiveto = '$defaultDBDate'";
5287+
$activeFromToCondition = "$tableName.oxactivefrom <= '$dateNow' AND $tableName.oxactiveto >= '$dateNow'";
5288+
5289+
$query = $query ? " $query or " : '';
5290+
5291+
return " ( $query (($activeToCondition) OR ($activeFromToCondition)) )";
5292+
}
52735293
}

tests/Codeception/Acceptance/Admin/ProductListStatusTestCest.php

+28-4
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@
1010
namespace Acceptance\Admin;
1111

1212
use Codeception\Attribute\Group;
13+
use DateTime;
1314
use OxidEsales\EshopCommunity\Tests\Codeception\Support\AcceptanceTester;
1415

1516
#[Group('admin', 'product')]
1617
final class ProductListStatusTestCest
1718
{
18-
private string $temporaryActiveProductID = '1003';
19-
private string $temporaryInactiveProductID = '1004';
19+
private string $productID = '1000';
2020

2121
public function _before(AcceptanceTester $I): void
2222
{
@@ -32,7 +32,19 @@ public function checkProductsStatuses(AcceptanceTester $I): void
3232

3333
$I->expect('the given product is active in the list');
3434

35-
$productList->filterByProductNumber($this->temporaryActiveProductID);
35+
$I->updateInDatabase(
36+
'oxarticles',
37+
[
38+
'OXACTIVE' => false,
39+
'OXACTIVEFROM' => (new DateTime())->modify('-1 day')->format('Y-m-d 00:00:00'),
40+
'OXACTIVETO' => (new DateTime())->modify('+1 day')->format('Y-m-d 00:00:00')
41+
],
42+
[
43+
'OXID' => $this->productID
44+
]
45+
);
46+
47+
$productList->filterByProductNumber($this->productID);
3648

3749
$I->assertStringContainsString(
3850
'temp-active',
@@ -41,7 +53,19 @@ public function checkProductsStatuses(AcceptanceTester $I): void
4153

4254
$I->expect('the given product is not active in the list');
4355

44-
$productList->filterByProductNumber($this->temporaryInactiveProductID);
56+
$I->updateInDatabase(
57+
'oxarticles',
58+
[
59+
'OXACTIVE' => false,
60+
'OXACTIVEFROM' => (new DateTime())->modify('+1 day')->format('Y-m-d 00:00:00'),
61+
'OXACTIVETO' => (new DateTime())->modify('+2 day')->format('Y-m-d 00:00:00')
62+
],
63+
[
64+
'OXID' => $this->productID
65+
]
66+
);
67+
68+
$productList->filterByProductNumber($this->productID);
4569

4670
$I->assertStringContainsString(
4771
'temp-inactive',
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
<?php
2+
3+
/**
4+
* Copyright © OXID eSales AG. All rights reserved.
5+
* See LICENSE file for license details.
6+
*/
7+
8+
declare(strict_types=1);
9+
10+
namespace Acceptance;
11+
12+
use Codeception\Attribute\Group;
13+
use Codeception\Util\Fixtures;
14+
use DateTime;
15+
use OxidEsales\EshopCommunity\Tests\Codeception\Support\AcceptanceTester;
16+
17+
#[Group('product')]
18+
final class ProductStatusTestCest
19+
{
20+
private string $productID = '1000';
21+
private array $productData;
22+
23+
public function _before(AcceptanceTester $I): void
24+
{
25+
$I->updateConfigInDatabase('blUseTimeCheck', true, 'bool');
26+
$product = $this->getProductData($this->productID);
27+
$this->productData = [
28+
'title' => $product['OXTITLE_1'],
29+
'description' => $product['OXSHORTDESC_1'],
30+
'price' => $product['OXPRICE']
31+
];
32+
}
33+
34+
public function checkProductsTemporaryActiveStatus(AcceptanceTester $I): void
35+
{
36+
$I->wantToTest('Product active in list');
37+
38+
$homePage = $I->openShop();
39+
40+
$I->amGoingTo('Test product temporary active in the list with empty activeto');
41+
42+
$I->updateInDatabase(
43+
'oxarticles',
44+
[
45+
'OXACTIVE' => false,
46+
'OXACTIVEFROM' => (new DateTime())->modify('-1 day')->format('Y-m-d 00:00:00'),
47+
'OXACTIVETO' => '0000-00-00 00:00:00'
48+
],
49+
[
50+
'OXID' => $this->productID
51+
]
52+
);
53+
54+
$I->expect('Product is shown');
55+
$productList = $homePage->searchFor($this->productID);
56+
$productList->seeProductData($this->productData);
57+
58+
59+
$I->amGoingTo('Test product temporary active in the list with empty activefrom');
60+
61+
$I->updateInDatabase(
62+
'oxarticles',
63+
[
64+
'OXACTIVE' => false,
65+
'OXACTIVEFROM' => '0000-00-00 00:00:00',
66+
'OXACTIVETO' => (new DateTime())->modify('+1 day')->format('Y-m-d 00:00:00')
67+
],
68+
[
69+
'OXID' => $this->productID
70+
]
71+
);
72+
73+
$I->expect('Product is shown');
74+
$productList = $homePage->searchFor($this->productID);
75+
$productList->seeProductData($this->productData);
76+
}
77+
78+
public function checkProductsTemporaryNotActiveStatus(AcceptanceTester $I): void
79+
{
80+
$I->wantToTest('Product not active in list');
81+
82+
$homePage = $I->openShop();
83+
84+
$I->amGoingTo('Test product temporary inactive in the list with empty activeto');
85+
86+
$I->updateInDatabase(
87+
'oxarticles',
88+
[
89+
'OXACTIVE' => false,
90+
'OXACTIVEFROM' => (new DateTime())->modify('+1 day')->format('Y-m-d 00:00:00'),
91+
'OXACTIVETO' => '0000-00-00 00:00:00'
92+
],
93+
[
94+
'OXID' => $this->productID
95+
]
96+
);
97+
98+
$I->expect('Product is not shown in case 1');
99+
$productList = $homePage->searchFor($this->productID);
100+
$productList->dontSeeProductData($this->productData);
101+
102+
103+
$I->amGoingTo('Test product temporary inactive in the list with empty activefrom');
104+
105+
$I->updateInDatabase(
106+
'oxarticles',
107+
[
108+
'OXACTIVE' => false,
109+
'OXACTIVEFROM' => '0000-00-00 00:00:00',
110+
'OXACTIVETO' => (new DateTime())->modify('-1 day')->format('Y-m-d 00:00:00')
111+
],
112+
[
113+
'OXID' => $this->productID
114+
]
115+
);
116+
117+
$I->expect('Product is not shown in case 2');
118+
$productList = $homePage->searchFor($this->productID);
119+
$productList->dontSeeProductData($this->productData);
120+
}
121+
122+
private function getProductData(string $productID): array
123+
{
124+
return Fixtures::get(sprintf('product-%s', $productID));
125+
}
126+
}

tests/Codeception/Support/Data/dump.sql

-5
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,6 @@ REPLACE INTO `oxarticles` (`OXID`, `OXSHOPID`, `OXPARENTID`, `OXACTIVE`, `OX
99
( '1001', 1, '', 1, '1001', '[DE 1] Test product 1 šÄßüл', 'Test product 1 short desc [DE]', 100, 0, 0, 0, 150, '', 0, 10, 0, 0, 1, '', '', '2030-01-01', '2008-02-04', '2008-02-04 17:35:49', 0, 0, 0, 'search1001', 1, '', 0, 0, '', 100, 0, '', '', 'Test product 1 [EN] šÄßüл', 'Test product 1 short desc [EN] šÄßüл', 'šÄßüл1001', '', '', '', 0, 'testdistributor', 'testmanufacturer', 0, 1, 'WEEK'),
1010
('10014', 1, '', 1, '10014', '13 DE product šÄßüл', '14 DE description', 1.6, 0, 0, 0, 0, '', 0, NULL, 0, 0, 1, '', '', '0000-00-00', '2008-04-03', '2008-04-03 12:50:20', 0, 0, 0, '', 1, 'size[DE] | color | type', 0, 12, '', 15, 25, 'size[EN] | color | type', '', '14 EN product šÄßüл', '13 EN description šÄßüл', '', '', '', '', 0, '', '', 0, 0, '');
1111

12-
REPLACE INTO `oxarticles` (`OXID`, `OXSHOPID`, `OXPARENTID`, `OXACTIVE`, `OXARTNUM`, `OXTITLE`, `OXSHORTDESC`, `OXPRICE`, `OXPRICEA`, `OXPRICEB`, `OXPRICEC`, `OXTPRICE`, `OXUNITNAME`, `OXUNITQUANTITY`, `OXVAT`, `OXWEIGHT`, `OXSTOCK`, `OXSTOCKFLAG`, `OXSTOCKTEXT`, `OXNOSTOCKTEXT`, `OXDELIVERY`, `OXINSERT`, `OXTIMESTAMP`, `OXLENGTH`, `OXWIDTH`, `OXHEIGHT`, `OXSEARCHKEYS`, `OXISSEARCH`, `OXVARNAME`, `OXVARSTOCK`, `OXVARCOUNT`, `OXVARSELECT`, `OXVARMINPRICE`, `OXVARMAXPRICE`, `OXVARNAME_1`, `OXVARSELECT_1`, `OXTITLE_1`, `OXSHORTDESC_1`, `OXSEARCHKEYS_1`, `OXBUNDLEID`, `OXSTOCKTEXT_1`, `OXNOSTOCKTEXT_1`, `OXSORT`, `OXVENDORID`, `OXMANUFACTURERID`, `OXMINDELTIME`, `OXMAXDELTIME`, `OXDELTIMEUNIT`,`OXACTIVEFROM`, `OXACTIVETO`) VALUES
13-
('1003', 1, '', 0, '1003', '[DE 4] Test product 3 šÄßüл', 'Test product 3 short desc [DE]', 50, 35, 45, 55, 0, 'kg', 2, NULL, 2, 15, 1, 'In stock [DE]', 'Out of stock [DE]', '0000-00-00', '2008-02-04', '2008-02-04 17:07:29', 1, 2, 2, 'search1003', 1, '', 0, 0, '', 50, 0, '', '', 'Test product 3 [EN] šÄßüл', 'Test product 3 short desc [EN] šÄßüл', '', 'oxarticle', 'In stock [EN] šÄßüл', 'Out of stock [EN] šÄßüл', 0, 'testdistributor', 'testmanufacturer', 1, 1, 'DAY',now() - interval 1 day,now() + interval 1 day),
14-
('1004', 1, '', 0, '1004', '[DE 1] Test product 4 šÄßüл', 'Test product 4 short desc [DE]', 100, 0, 0, 0, 150, '', 0, 10, 0, 0, 1, '', '', '2030-01-01', '2008-02-04', '2008-02-04 17:35:43', 0, 0, 0, 'search1004', 1, '', 0, 0, '', 100, 0, '', '', 'Test product 4 [EN] šÄßüл', 'Test product 4 short desc [EN] šÄßüл', '', 'oxarticle', '', '', 0, 'testdistributor', 'testmanufacturer', 0, 1, 'WEEK',now() + interval 1 day,now() + interval 2 day),
15-
('1005', 1, '', 0, '1005', '[DE 2] Test product 5 šÄßüл', 'Test product 5 short desc [DE]', 55, 0, 0, 0, 0, '', 0, NULL, 0, 0, 1, 'In stock [DE]', 'Out of stock [DE]', '0000-00-00', '2008-02-04', '2008-02-04 17:27:47', 0, 0, 0, 'search1005', 1, 'variants [DE]', 10, 2, '', 55, 67, 'variants [EN] šÄßüл', '', 'Test product 5 [EN] šÄßüл', 'Test product 5 short desc [EN] šÄßüл', '', 'oxarticle', 'In stock [EN] šÄßüл', 'Out of stock [EN] šÄßüл', 0, 'testdistributor', 'testmanufacturer', 1, 1, 'MONTH','0000-00-00 00:00:00' ,'0000-00-00 00:00:00');
16-
1712
#demodata for multidimensional variants
1813
REPLACE INTO `oxarticles` (`OXID`, `OXSHOPID`, `OXPARENTID`, `OXACTIVE`, `OXARTNUM`, `OXPRICE`, `OXSTOCK`, `OXSTOCKFLAG`, `OXINSERT`, `OXTIMESTAMP`, `OXVARSELECT`, `OXVARSELECT_1`, `OXSUBCLASS`, `OXSORT`) VALUES
1914
('1001432', 1, '10014', 1, '10014-3-2', 15, 3, 1, '2008-04-03', '2008-04-03 12:50:20', 'M | black | material [DE]', 'L | black | material', 'oxarticle', 3002),

0 commit comments

Comments
 (0)