Avail Until mod

This mod will add “Avail until” field to the Admin/Catalog/Products/Update screen. Currently, only “Avail since” appears there - which lets you “soft launch” products. “Avail until” will let you “expire” products without using the “Status = Disabled” option. As others have mentioned, using “Status = Disabled” results in a 404 error for customers and spiders visiting defunct items - which is less than ideal.



Note: the following involves changes to existing files in 2.0.12 and does not use hooks. This means that the next time you upgrade CS-Cart, there will be conflicts which you will need to resolve manually.



First, we add the new field and language to the database. In phpmyadmin, enter the following SQL statment:```php ALTER TABLE cscart_products ADD avail_until INT( 11 ) UNSIGNED NOT NULL DEFAULT ‘0’ AFTER avail_since;

INSERT INTO cscart_language_values (lang_code, name, value) VALUES (‘EN’, ‘available_until’, ‘Avail until’);

INSERT INTO cscart_language_values (lang_code, name, value) VALUES (‘EN’, ‘product_gone’, ‘This item is no longer available.’); ```



Now, open /skins/basic/admin/views/products/update.tpl, and find this: ```php



{$lang.available_since}:

{include file=“common_templates/calendar.tpl” date_id=“date_avail_holder” date_name=“product_data[avail_since]” date_val=$product_data.avail_since|default:“” start_year=$settings.Company.company_start_year}

``` and paste this just below:```php {* Avail Until mod *}

{$lang.available_until}:
{include file="common_templates/calendar.tpl" date_id="date_avail_until_holder" date_name="product_data[avail_until]" date_val=$product_data.avail_until|default:"" start_year=$settings.Company.company_start_year}
```


Now, open /skins/basic/admin/views/products/m_update.tpl, and find this: ```php {elseif $field == "avail_since"}
{include file="common_templates/calendar.tpl" date_id="field_`$field`__date" date_name="override_$name[$field]" date_val=$smarty.const.TIME start_year=$settings.Company.company_start_year extra=" disabled=\"disabled\"" date_meta="input-text-disabled"}
```and paste this just below:```php {* Avail Until mod *}
{elseif $field == "avail_until"}
{include file="common_templates/calendar.tpl" date_id="field_`$field`__date" date_name="override_$name[$field]" date_val=$smarty.const.TIME start_year=$settings.Company.company_start_year extra=" disabled=\"disabled\"" date_meta="input-text-disabled"}
```Now, find this:```php {elseif $field == "avail_since"}
{include file="common_templates/calendar.tpl" date_id="date_avail_holder_`$product.product_id`" date_name="$name[`$product.product_id`][$field]" date_val=$product.$field start_year=$settings.Company.company_start_year}
```and paste this just below:```php {* Avail Until mod *}
{elseif $field == "avail_until"}
{include file="common_templates/calendar.tpl" date_id="date_avail_until_holder_`$product.product_id`" date_name="$name[`$product.product_id`][$field]" date_val=$product.$field start_year=$settings.Company.company_start_year}
```



Now, open /controllers/admin/products.php (we have a few edits here) and find:```php $product_data = !empty($_REQUEST['override_products_data']) ? $_REQUEST['override_products_data'] : array();
if (isset($product_data['avail_since'])) {
$product_data['avail_since'] = fn_parse_date($product_data['avail_since']);
} ```and paste this just below:```php // Avail Until mod
if (isset($product_data['avail_until'])) {
$product_data['avail_until'] = fn_parse_date($product_data['avail_until']);
} ```Now, find this:```php array(
'name' => '[data][avail_since]',
'text' => fn_get_lang_var('available_since')
), ```and paste this just below:```php // Avail Until mod
array(
'name' => '[data][avail_until]',
'text' => fn_get_lang_var('avail_until')
), ```Now, find this:```php 'avail_since' => 'products_data',
```and paste this just below:```php // Avail Until mod
'avail_until' => 'products_data', ```Now, find this:```php } elseif ($field == 'avail_since') {
$desc = 'available_since'; ```and paste this just below:```php // Avail Until mod
} elseif ($field == 'avail_until') {
$desc = 'available_until'; ```Now, find this:```php if (!empty($product_data['avail_since'])) {
$_data['avail_since'] = fn_parse_date($product_data['avail_since']);
} ```and paste this just below:```php // Avail Until mod
if (!empty($product_data['avail_until'])) {
$_data['avail_until'] = fn_parse_date($product_data['avail_until']);
} ```Now, open /core/fn.catalog.php and find this:```php 'avail_since',
```and paste this just below:```php //Avail Until mod
'avail_until', ```Finally, open /skins/yourskin/customer/common_templates/product_data.tpl and find this:```php {if $product.avail_since <= $smarty.const.TIME || ($product.avail_since > $smarty.const.TIME && $product.buy_in_advance == "Y")}
{if $product.has_options && !$show_product_options && !$details_page}
{include file="buttons/button.tpl" but_id="button_cart_`$obj_id`" but_text=$lang.select_options but_href="$index_script?dispatch=products.view&product_id=`$product.product_id`" but_role="text" but_name=""}
{else}
{if $extra_button}{$extra_button} {/if}
{include file="buttons/add_to_cart.tpl" but_id="button_cart_`$obj_id`" but_name="dispatch[checkout.add..`$obj_id`]" but_role=$but_role}
{assign var="cart_button_exists" value=true}
{/if}
{/if}
{if $product.avail_since > $smarty.const.TIME}
{include file="common_templates/coming_soon_notice.tpl" avail_date=$product.avail_since add_to_cart=$product.buy_in_advance}
{/if}
```and replace with this:```php {*Avail Until mod *}
{if ($product.avail_until + 86400) > $smarty.const.TIME || $product.avail_until == 0}
{if $product.avail_since <= $smarty.const.TIME || ($product.avail_since > $smarty.const.TIME && $product.buy_in_advance == "Y")}
{if $product.has_options && !$show_product_options && !$details_page}
{include file="buttons/button.tpl" but_id="button_cart_`$obj_id`" but_text=$lang.select_options but_href="$index_script?dispatch=products.view&product_id=`$product.product_id`" but_role="text" but_name=""}
{else}
{if $extra_button}{$extra_button} {/if}
{include file="buttons/add_to_cart.tpl" but_id="button_cart_`$obj_id`" but_name="dispatch[checkout.add..`$obj_id`]" but_role=$but_role}
{assign var="cart_button_exists" value=true}
{/if}
{/if}
{/if}


{if (($product.avail_until + 86400) < $smarty.const.TIME) && ($product.avail_until > 0) }
{$lang.product_gone}
{else}
{if $product.avail_since > $smarty.const.TIME}
{include file="common_templates/coming_soon_notice.tpl" avail_date=$product.avail_since add_to_cart=$product.buy_in_advance}
{/if}
{/if}

```(One note about this change: I add 86400 seconds to the avail_until here date because I would expect the item to be available on the day of expiration, and gone the next.)

There are quite a few edits involved in this mod, so please double-check your work if it doesn't perform as expected. Also, be sure to clear your cache with "&cc" in the URL when testing.

cheers,
Glen

admin.png

Thank you for your hard work and for sharing this with the community. It’s what the forums are all about.

Nice! I just got a quote from cs-cart to do something similar, but maybe your mod is even better. It says it does not set products to disabled, so does this just leave the product status alone?



I have a store that is not live yet so I will test it out soon and report back.

Ogio:

Yes, the Status is untouched. This mod will leave expired products in the catalog but disable their “Add to cart” button - in the same way that they would appear if they had “Avail since” set and that date hadn’t been reached yet.



The biggest benefit for me is that product links never get broken when I discontinue/expire an item - leaving me with the opportunity for an upsell through “Other Customers Bought”.



cheers,

Glen

:cool: I like that! I will have a use for this in my existing store as well. I have ‘expired’ products that I had to disable and then had to manually set up a 301 redirect. This would eliminate that problem.



Unfortunately, I ran into an issue when executing the SQL. I’m not sure what is wrong with it, but I added those variables manually at Content > Languages instead. :slight_smile:


You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INSERT INTO `cscart_language_values` (`lang_code`, `name`, `value`) VALUES ('EN'' at line 1

Nice mod! I may just use this one because I tend to have products that I eliminate from my offerings but want to keep and point the customer to a replacement product.



Thanks!!

[quote name=‘ogia’]

Unfortunately, I ran into an issue when executing the SQL. I’m not sure what is wrong with it, but I added those variables manually at Content > Languages instead. [/QUOTE]



That must have been a copy/paste issue. I just tried the SQL again myself and don’t get the error. Glad you were able to get those language variables added manually.



Glen

I have this all installed now. It’s so close to what I need, but I need my products to be hidden before they are available. I think maybe I can write a cron job to accomplish this.



THANKS so much for taking the time to post this! Post your PayPal address so I can send you a donation.

Thank you sixnin9, You are a Genius this is a great mod. I appreciate you time and effort for sharing this with the community. Great Work.



Joe

Thanks for giving to the community! It’s appreciated.

WTF YOU DID IT, YOU GREAT MAN!

thanks for all the works, i dont need custom development anymore

sixnin9, yesterday you said that avail_since need to have the option of hidden right, so it will be perfect if we can set avail_since option to hidden the product or not

and [HIDDEN ()] will be placed next to avail_since in product settings



if hidden is checked then the product will be hidden until the date of avail since

if hidden is not checked then the product will appears all the time.

by default its not checked.



if you make this, then i assume we dont need deal of the day addons anymore, cause everything is in there, we just go make a block, using product feature you made, and set product avail since avail until, then we can set for a week of deal of the day product, only do it one time for a week/month/year, we dont need to do it twice, and its automatic.



i hope you can make the last option ‘HIDDEN’ next to avail since,

thank you for your work sixnin9.

-------------------------------------------------



i wonder if the product we set reach the avail until date, after avail until date the product will be hidden by it self? or it will be stay like that without option add to cart?

it will be good if there is option [hidden] next to avail_until

to make dotd addons work, only 1 thing left, it is hidden the product before set date, and hidden the product after set date.

Adding the option to toggle Hidden/Active status completely changes this. This mod works great as-is depending on your needs. I am going to be able to use this for one of my stores to expire products without having to worry about 404 pages. For that store, I wouldn’t need or want to change the product status.



For my new store, I do need that additional functionality. I had inquired with CS-Cart about something similar and the way they were going to accomplish this was “We will create a cron script that will check products for which the “availability” check box is selected, and if the current time goes beyond the period defined for a product, the product status will be set to hidden.” It sounds pretty simple? If I come up with a solution I’ll post it.

Please update if you had any solutions with hidden product before date and after date, if anyone can make this, ill be sure the deal of the day block will be done.

[quote name=‘vidan’]Please update if you had any solutions with hidden product before date and after date, if anyone can make this, ill be sure the deal of the day block will be done.[/QUOTE]

All I need is the right syntax to determine if the product is in the available date range. If anyone is good at writing mysql commands, please help:

[url]http://forum.cs-cart.com/showthread.php?t=16044[/url]



(By the way, it depends on what you want from a DOTD mod. I think it may just be you and I that are interested in hiding products.)

Vidan:

I’m currently stuck on another mod that adds “Publish start” / “Publish end” fields to Products. This was supposed to completely hide an item until the scheduled dates. Unfortunately, I don’t think it’s workable because there are so many queries that check a product’s status and every one of those would need to be edited to include these new fields. Others have described using a cron job to flip Product Status, but I have no experience with cron.

Glen

i dont coding and everybody knows im not

but from my point of view its like:

use if hidden is checked then assign var hidden product

if hidden not checked then show product

is it something simple like that?

[quote name=‘vidan’]i dont coding and everybody knows im not

but from my point of view its like:

use if hidden is checked then assign var hidden product

if hidden not checked then show product

is it something simple like that?[/QUOTE]

Rather than adding a different type of status my solution uses the built-in hidden/active status so it should be pretty simple.

I just found an issue with the Avail Until mod when doing a bulk update. If I attempt to change the Avail until date, it remains unchanged and the Avail since date is changed instead. I double checked my edits and they appear to be correct. Does anyone else have the same problem?