Jump to content

Probleme création de pack produits (1.5.3)


Recommended Posts

Salut à tous et toutes…

j'ai besoin de vos lumières SVP/MERCI :)

 

j'ai un souci avec la réalisation des packs produits :

dans le contenu du pack > mon avant dernier produit est doublé

et vient remplacé le dernier produit ???

Cela quel que soit la quantité d'article dans mon pack …

Avez-vous une idée d'où vient l'erreur ?

Merci de votre aide…

 

exemple (en construction) : http://www.shop-in.fr/chronoafrica/petite-famille/13-lot1.html

Link to comment
Share on other sites

  • 3 weeks later...

Bonjour,

 

Je constate en allant sur le lien proposé dans votre post que le problème semble résolu ... ?

En tout cas je ne constate pas de doublon dans le contenu du pack.

Pourriez-vous m'éclairer sur la solution car je constate le même dysfonctionnement.

 

Merci d'avance.

Link to comment
Share on other sites

Bonjour,

le code ci dessous est à insérer dans le fichier classes/Pack.php

 

{

if (!Pack::isFeatureActive())

return array();

$sql = 'SELECT p.*, product_shop.*, pl.*, image_shop.`id_image`, il.`legend`, cl.`name` AS category_default, a.quantity AS pack_quantity, product_shop.`id_category_default`, a.id_product_pack

FROM `'._DB_PREFIX_.'pack` a

LEFT JOIN `'._DB_PREFIX_.'product` p ON p.id_product = a.id_product_item

LEFT JOIN `'._DB_PREFIX_.'product_lang` pl

ON p.id_product = pl.id_product

AND pl.`id_lang` = '.(int)$id_lang.Shop::addSqlRestrictionOnLang('pl').'

LEFT JOIN `'._DB_PREFIX_.'image` i ON (i.`id_product` = p.`id_product`)'.

Shop::addSqlAssociation('image', 'i', false, 'image_shop.cover=1').'

LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = '.(int)$id_lang.')

'.Shop::addSqlAssociation('product', 'p').'

LEFT JOIN `'._DB_PREFIX_.'category_lang` cl

ON product_shop.`id_category_default` = cl.`id_category`

AND cl.`id_lang` = '.(int)$id_lang.Shop::addSqlRestrictionOnLang('cl').'

WHERE product_shop.`id_shop` = '.(int)Context::getContext()->shop->id.'

AND ((image_shop.id_image IS NOT NULL OR i.id_image IS NULL) OR (image_shop.id_image IS NULL AND i.cover=1))

AND a.`id_product_pack` = '.(int)$id_product;

$result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql);

foreach ($result as &$row)

$row = Product::getTaxesInformations($row);

 

if (!$full)

return $result;

 

unset($row); //Instruction à ajouter.

 

$array_result = array();

foreach ($result as $row)

if (!Pack::isPack($row['id_product']))

$array_result[] = Product::getProductProperties($id_lang, $row);

return $array_result;

}

  • Like 2
Link to comment
Share on other sites

  • 2 weeks later...

Topic [Résolu]

 

Si, après avoir posté dans un topic, vous trouvez une solution à votre problème, merci de venir le signaler et de décrire cette solution.

Il n'y a rien de plus frustrant pour les utilisateurs qui tomberont plus tard sur votre post que de lire "C'est bon, j'ai trouvé, merci…".

 

De plus, si vous êtes l'auteur du topic pour lequel une solution a été apportée, éditer le premier post et ajouter la mention [Résolu] au début du titre.

 

Pour marquer un topic comme [Résolu] :

- Editer le premier post du topic en cliquant sur le bouton "Editer",

- Cliquer sur le bouton "Utiliser l'éditeur complet",

- Ajouter la mention "[Résolu] " au début du titre de votre topic et cliquez sur le bouton "Envoyer le message modifié".

Link to comment
Share on other sites

Merci pour la solution

 

J'avais le même problème sur mes packs. Le prix tenait compte des articles listés dans le pack mais les descriptifs ne correspondaient pas, la dernière référence étant présentée 2 fois et une des référence était manquante.

(Prestashop 1.5.3)

Link to comment
Share on other sites

Salut à tous,

 

Je viens à peine de me retrouver face à ce bug en voulant créer un pack,

 

Etant débutant, j'aimerai que l'on m'explique ou placer exactement dans le fichier pack.php le code que nous donne Apparence,

 

Merci de bien vouloir m'aider

 

 

Edit : c'est bon j'ai reussi, il suffit de repérer les mêmes lignes sur le fichier.

 

 

Merci encore pour la solution

Edited by Fehmi135 (see edit history)
Link to comment
Share on other sites

Bonjour Fehmi135,

je ne suis pas un expert Prestashop mais je pense qu'en attendant un correctif officiel, une surcharge de la classe "Pack" dans le dossier "override" serait plus propre.

Je ne sais pas ce qu'en penseront nos compères plus aguerris ?

Bon courage à toi.

Link to comment
Share on other sites

Salut Cocorodeo,

 

Je ne sais pas du tout comment corriger autrement ce bug, la solution plus propre dont tu parles, fonctionne t-elle ?

 

bravo @ViCLiC !

 

Mais une question se pose à present, est-ce que un pack acheter, va diminuer automatiquement le stock des produits unitaires constituant ce pack ?

 

Merci

Link to comment
Share on other sites

  • 4 weeks later...

Je vous déconseille d'appliquer le 'fix' qui consiste à supprimer la variable $row. (unset($row))

 

J'ai tenté de comprendre la méthode appliquée, le problème principal vient du fait que la variable $row est utilisée de manière récurrente (dans 2 boucles) et le script s'emmêle les pinceaux, mais il ne faut pas pour autant supprimer cette variable.

 

Après des tentatives infructueuses je me suis reporté au modifications apportées dans la 1.5.4 et présentent sur le Github.

https://github.com/P...s/Pack.php#L145

 

J'ai solutionner le problème en appliquant la méthode de la 1.5.4 qui utilise des nom de variables différent pour chaque boucle. Mais vous pouvez également migrer vers la 1.5.4 si c'est envisageable pour vous.

 

Solution prestashop 1.5.3.1

 

Fichier: /classes/Pack.php

Lignes: 146 -> 156

Opération: remplacer

Code:

 


	foreach ($result as &$line)
		$line = Product::getTaxesInformations($line);

	if (!$full)
		return $result;

	$array_result = array();
	foreach ($result as $prow)
		if (!Pack::isPack($prow['id_product']))
			$array_result[] = Product::getProductProperties($id_lang, $prow);
	return $array_result;

 

Je vous conseille d'appliquer la méthode d'override pour toute modification sur le core de Prestashop.

 

J'ai également identifié plusieurs autres modifications dans la version 1.5.4, il est donc possible que d'autres problèmes apparaissent.

Edited by Sire-Sam (see edit history)
Link to comment
Share on other sites

Bonjour Sire-Sam,

 

Merci pour cette réponse très précise. Je viens de migrer toute juste en 1.5.4 et je n'ai pas encore eu le temps de vérifier les packs produits.

J'essaierai (si j'arrive a trouver du temps ^^) de faire une petite réponse sur cette version 1.5.4.

 

Fehmi135 :

Mais une question se pose à present, est-ce que un pack acheter, va diminuer automatiquement le stock des produits unitaires constituant ce pack ?

 

Normalement oui, si je ne me trompe pas le fonctionnement d'un pack est celui-ci.

 

Bon courage à tous...

Link to comment
Share on other sites

  • 3 months later...

Bonjour,

 

Après avoir ajouté unset($row); je n'ai plus accès aux "traductions des noms des champs"... quelqu'un a t-il rencontré ce problème?

Selon vous, est-ce que ça peut être lié?

 

Je suis Prestashop 1.5.3.1

 

Bonne soirée

et merci pour vos idées

Link to comment
Share on other sites

Bonjour mandine35,

 

Je n'ai pas rencontré ce problème mais si tu lis le dernier post de Sire-Sam (#15) explique bien la méthode d'override des classes PS. Il déconseille fortement d'utiliser le "unset($row)". Peut être que les problèmes que tu rencontre viennent de là.

Je te conseille d'appliquer ce que Sire-Sam décrit dans son post.

 

En espérant que cela résolve ton problème.

 

Bon courage.

Link to comment
Share on other sites

Mandine,

 

Chaque classe du coeur (core) PS ne devrait,dans l'absolu, jamais être modifiée.

 

C'est pourquoi il existe un mécanisme de surcharge de ces classes dans PS. Cela permet de venir les modifier, sans jamais toucher aux fichiers du coeur.

Tu remarqueras que toutes les classes dans le dossier "/classes/" de PS se nomment "xxxCore" (ex : PackCore, ProductCore ...).

 

Il existe également un dossier "/override/" dans l'arborescence PS qui te permet de venir surcharger chacune des classes "xxxCore" de PS.

De mémoire, en 1.5.3.x, tous lez fichiers de surcharge sont déjà présents dans ce dossier. Les classes sont donc déjà surchargées mais avec des fichiers vides (ce n'est plus le cas en 1.5.4.x il faut créer les fichiers soi-même).

 

Dans ce dossier, tu trouveras un fichier Pack.php qui contiendra la déclaration de la classe :

 

class Pack extends PackCore
{
}

 

Tu remarqueras qu'elle "hérite" de la classe Core de PS. Je t'invite à lire ceci si tu ne maîtrise pas la POO (Programmation Orientée Objet) en php.

 

Dans ce fichier, tu vas pouvoir ajouter tes propres méthodes, ou modifier celles de PS. Il te suffit de récupérer la fonction qui t'intéresse dans le fichier coeur de PS (en l'occurrence dans le fichier /classes/Pack.php) et de la coller dans le fichier /override.Pack.php.

 

Tu pourras appliquer le correctif de Sire-Sam "proprement".

 

Bon courage.

Edited by cocorodeo (see edit history)
Link to comment
Share on other sites

Merci!

 

Voilà qui est plus clair pour moi, suis allée voir il y a bien un dossier "override", donc me reste à modifier le fichier Pack.php qui est dedans, c'est bien ça?

 

Par contre j'ai remis mon ancien fichier classes/Pack.php comme à son origine et je n'ai tjrs pas accès aux traductions des "Noms des champs" j'ai une page blanche...ggrrr

Link to comment
Share on other sites

En fait c'est juste après avoir modifié le fichier Pack.php que j'ai remarqué le problème avec les traductions. J'ai donc pensé que c'était en lien mais on dirait bien que non.

J'ai lu que ça pouvait être un manque de mémoire...je suis chez 1and1, par contre aucun message ne s'affiche, pas d'erreur 500.

Link to comment
Share on other sites

Essaie de passer en mode debug et d'afficher les erreurs php dans le fichier config/defines.inc.php

 

/* Debug only */
define('_PS_MODE_DEV_', true);
if (_PS_MODE_DEV_)
{
@ini_set('display_errors', 'on');
define('_PS_DEBUG_SQL_', true);
/* Compatibility warning */
define('_PS_DISPLAY_COMPATIBILITY_WARNING_', true);
}

Link to comment
Share on other sites

Pour passer en mode debug, c'est bien là que ça se passe? et je dois cliquer sur "Ouvrir la console avec un paramètre dans l'URL (SMARTY_DEBUG)" ? et aller voir après dans le fichier config/defines.inc.php ce qu'il y a?

 

Ne pas ouvrir la console

Ouvrir la console avec un paramètre dans l'URL (SMARTY_DEBUG)

Toujours ouvrir la console

 

Humm, désolée mais peur de faire des bêtises ...

Link to comment
Share on other sites

Le mode "dev" et non "debug" (désolé pour l'erreur) force l'affichage des erreurs php. Il faut modifier le fichier defines.inc.php pour cela tel que je te l'ai décrit. Le mode dev n'est donc pas recommandé pour un site en production car il est possible que les erreurs php seront visibles pour les internautes.

La console (SMARTY_DEBUG) sert à afficher les variables et données SMARTY.

Edited by cocorodeo (see edit history)
Link to comment
Share on other sites

Ah ok, mon site est en production mais je peux l'arrêter le temps de tester.

Par contre où les messages d'erreur vont-ils s'afficher, à la place de mes pages blanches?

 

Je me suis aperçue qu'après avoir cliqué sur Traductions, Noms des champs, je n'avais même pas le choix entre "Default" "Prestahop" ou "Theme" pour ça je dois réactualiser la page...

par contre je suis sûre que ça a marché, est-ce que ça pourrait être un module rajouté qui ferait ça?

 

Et comme d'autres je n'ai pas accès à "Modules", "Paiements", là aussi j'ai une page blanche, et ça n'a jamais fonctionné...

 

Bonne journée!

Link to comment
Share on other sites

Les messages d'erreur vont s'afficher à la place des pages blanches mais ce sont certainement des erreurs php. Si tu n'es pas compétente en développement php, tu risque de ne pas pouvoir y faire grand chose.

De plus, si plusieurs écrans de ton admin PS dysfonctionnent, tu n'es peut-être pas au bout de tes peines. Commence par les erreurs php avec le mode "dev" mais tu risque de te retrouver face à du des bugs php ou de la config serveur LAMP à modifier. Chose que tu ne pourras pas faire étant chez 1&1 en mutualisé je suppose ...

Malheureusement je ne pourrais pas t'en dire plus. Je t'invite à afficher tes erreurs php puis poster un message spécifique à l'erreur que tu obtiendras dans le forum.

 

Bon courage

Edited by cocorodeo (see edit history)
Link to comment
Share on other sites

  • 4 months later...

Bonjour,

 

Je relance le topic parce que j'ai ce problème de synchromisation avec la gestion des stocks avancées et la création de packs.

 

Je n'ai pas bien compris l'astuce de l'override . Que doit-on mettre exactement entre les accolade. Juste la modif ou la totalité du fichier /classes/pack.php mais modifié.

 

En clair dans /classes/pack.php j'ai ce code

<?php
/*
* 2007-2012 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to [email protected] so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
*  @author PrestaShop SA <[email protected]>
*  @copyright  2007-2012 PrestaShop SA
*  @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
*  International Registered Trademark & Property of PrestaShop SA
*/

class PackCore extends Product
{
	protected static $cachePackItems = array();
	protected static $cacheIsPack = array();
	protected static $cacheIsPacked = array();

	/**
	 * Is product a pack?
	 *
	 * @static
	 * @param $id_product
	 * @return bool
	 */
	public static function isPack($id_product)
	{
		if (!Pack::isFeatureActive())
			return false;

		if (!$id_product)
			return false;

		if (!array_key_exists($id_product, self::$cacheIsPack))
		{
			$result = Db::getInstance()->getValue('SELECT COUNT(*) FROM '._DB_PREFIX_.'pack WHERE id_product_pack = '.(int)$id_product);
			self::$cacheIsPack[$id_product] = ($result > 0);
		}
		return self::$cacheIsPack[$id_product];
	}

	/**
	 * Is product in a pack?
	 *
	 * @static
	 * @param $id_product
	 * @return bool
	 */
	public static function isPacked($id_product)
	{
		if (!Pack::isFeatureActive())
			return false;

		if (!array_key_exists($id_product, self::$cacheIsPacked))
		{
			$result = Db::getInstance()->getValue('SELECT COUNT(*) FROM '._DB_PREFIX_.'pack WHERE id_product_item = '.(int)$id_product);
			self::$cacheIsPacked[$id_product] = ($result > 0);
		}
		return self::$cacheIsPacked[$id_product];
	}

	public static function noPackPrice($id_product)
	{
		$sum = 0;
		$price_display_method = !self::$_taxCalculationMethod;
		$items = Pack::getItems($id_product, Configuration::get('PS_LANG_DEFAULT'));
		foreach ($items as $item)
			$sum += $item->getPrice($price_display_method) * $item->pack_quantity;
		return $sum;
	}

	public static function getItems($id_product, $id_lang)
	{
		if (!Pack::isFeatureActive())
			return array();

		if (array_key_exists($id_product, self::$cachePackItems))
			return self::$cachePackItems[$id_product];
		$result = Db::getInstance()->executeS('SELECT id_product_item, quantity FROM '._DB_PREFIX_.'pack where id_product_pack = '.(int)$id_product);
		$array_result = array();
		foreach ($result as $row)
		{
			$p = new Product($row['id_product_item'], false, $id_lang);
			$p->loadStockData();
			$p->pack_quantity = $row['quantity'];
			$array_result[] = $p;
		}
		self::$cachePackItems[$id_product] = $array_result;
		return self::$cachePackItems[$id_product];
	}

	public static function isInStock($id_product)
	{
		if (!Pack::isFeatureActive())
			return true;

		$items = Pack::getItems((int)$id_product, Configuration::get('PS_LANG_DEFAULT'));

		foreach ($items as $item)
		{
			// Updated for 1.5.0
			if (Product::getQuantity($item->id) < $item->pack_quantity
				|| (Product::getQuantity($item->id) < $item->pack_quantity && !$item->isAvailableWhenOutOfStock((int)$item->out_of_stock)))
				return false;
		}
		return true;
	}

	public static function getItemTable($id_product, $id_lang, $full = false)
	{
		if (!Pack::isFeatureActive())
			return array();

		$sql = 'SELECT p.*, product_shop.*, pl.*, image_shop.`id_image`, il.`legend`, cl.`name` AS category_default, a.quantity AS pack_quantity, product_shop.`id_category_default`, a.id_product_pack
				FROM `'._DB_PREFIX_.'pack` a
				LEFT JOIN `'._DB_PREFIX_.'product` p ON p.id_product = a.id_product_item
				LEFT JOIN `'._DB_PREFIX_.'product_lang` pl
					ON p.id_product = pl.id_product
					AND pl.`id_lang` = '.(int)$id_lang.Shop::addSqlRestrictionOnLang('pl').'
				LEFT JOIN `'._DB_PREFIX_.'image` i ON (i.`id_product` = p.`id_product`)'.
				Shop::addSqlAssociation('image', 'i', false, 'image_shop.cover=1').'
				LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = '.(int)$id_lang.')
				'.Shop::addSqlAssociation('product', 'p').'
				LEFT JOIN `'._DB_PREFIX_.'category_lang` cl
					ON product_shop.`id_category_default` = cl.`id_category`
					AND cl.`id_lang` = '.(int)$id_lang.Shop::addSqlRestrictionOnLang('cl').'
				WHERE product_shop.`id_shop` = '.(int)Context::getContext()->shop->id.'
				AND ((image_shop.id_image IS NOT NULL OR i.id_image IS NULL) OR (image_shop.id_image IS NULL AND i.cover=1))
				AND a.`id_product_pack` = '.(int)$id_product;
		$result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql);

		foreach ($result as &$row)
			$row = Product::getTaxesInformations($row);
			
		if (!$full)
			return $result;

		$array_result = array();
		foreach ($result as $row)
			if (!Pack::isPack($row['id_product']))
				$array_result[] = Product::getProductProperties($id_lang, $row);
		return $array_result;
	}

	public static function getPacksTable($id_product, $id_lang, $full = false, $limit = null)
	{
		if (!Pack::isFeatureActive())
			return array();

		$packs = Db::getInstance()->getValue('
		SELECT GROUP_CONCAT(a.`id_product_pack`)
		FROM `'._DB_PREFIX_.'pack` a
		WHERE a.`id_product_item` = '.(int)$id_product);

		if (!(int)$packs)
			return array();

		$sql = '
		SELECT p.*, product_shop.*, pl.*, image_shop.`id_image`, il.`legend`
		FROM `'._DB_PREFIX_.'product` p
		NATURAL LEFT JOIN `'._DB_PREFIX_.'product_lang` pl
		'.Shop::addSqlAssociation('product', 'p').'
		LEFT JOIN `'._DB_PREFIX_.'image` i ON (i.`id_product` = p.`id_product`)'.
		Shop::addSqlAssociation('image', 'i', false, 'image_shop.cover=1').'
		LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = '.(int)$id_lang.')
		WHERE pl.`id_lang` = '.(int)$id_lang.'
			'.Shop::addSqlRestrictionOnLang('pl').'
			AND p.`id_product` IN ('.$packs.')
			AND ((image_shop.id_image IS NOT NULL OR i.id_image IS NULL) OR (image_shop.id_image IS NULL AND i.cover=1))';
		if ($limit)
			$sql .= ' LIMIT '.(int)$limit;
		$result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql);
		if (!$full)
			return $result;

		$array_result = array();
		foreach ($result as $row)
			if (!Pack::isPacked($row['id_product']))
				$array_result[] = Product::getProductProperties($id_lang, $row);
		return $array_result;
	}

	public static function deleteItems($id_product)
	{
		return Db::getInstance()->update('product', array('cache_is_pack' => 0), 'id_product = '.(int)$id_product) &&
			Db::getInstance()->execute('DELETE FROM `'._DB_PREFIX_.'pack` WHERE `id_product_pack` = '.(int)$id_product) &&
			Configuration::updateGlobalValue('PS_PACK_FEATURE_ACTIVE', Pack::isCurrentlyUsed());
	}

	/**
	* Add an item to the pack
	*
	* @param integer $id_product
	* @param integer $id_item
	* @param integer $qty
	* @return boolean true if everything was fine
	*/
	public static function addItem($id_product, $id_item, $qty)
	{
		return Db::getInstance()->update('product', array('cache_is_pack' => 1), 'id_product = '.(int)$id_product) &&
			Db::getInstance()->insert('pack', array('id_product_pack' => (int)$id_product, 'id_product_item' => (int)$id_item, 'quantity' => (int)$qty)) &&
			Configuration::updateGlobalValue('PS_PACK_FEATURE_ACTIVE', '1');
	}

	public static function duplicate($id_product_old, $id_product_new)
	{
		Db::getInstance()->execute('INSERT INTO '._DB_PREFIX_.'pack (id_product_pack, id_product_item, quantity)
		(SELECT '.(int)$id_product_new.', id_product_item, quantity FROM '._DB_PREFIX_.'pack WHERE id_product_pack = '.(int)$id_product_old.')');

		// If return query result, a non-pack product will return false
		return true;
	}

	/**
	 * This method is allow to know if a feature is used or active
	 * @since 1.5.0.1
	 * @return bool
	 */
	public static function isFeatureActive()
	{
		return Configuration::get('PS_PACK_FEATURE_ACTIVE');
	}

	/**
	 * This method is allow to know if a Pack entity is currently used
	 * @since 1.5.0
	 * @param $table
	 * @param $has_active_column
	 * @return bool
	 */
	public static function isCurrentlyUsed($table = null, $has_active_column = false)
	{
		// We dont't use the parent method because the identifier isn't id_pack
		return (bool)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue('
			SELECT `id_product_pack`
			FROM `'._DB_PREFIX_.'pack`
		');
	}

	/**
	 * For a given pack, tells if it has at least one product using the advanced stock management
	 *
	 * @param int $id_product id_pack
	 * @return bool
	 */
	public static function usesAdvancedStockManagement($id_product)
	{
		if (!Pack::isPack($id_product))
			return false;

		$products = Pack::getItems($id_product, Configuration::get('PS_LANG_DEFAULT'));
		foreach ($products as $product)
		{
			// if one product uses the advanced stock management
			if ($product->advanced_stock_management == 1)
				return true;
		}
		// not used
		return false;
	}
}

 et dans /override/classes/pack.php , un fichier presque vide

<?php

class Pack extends PackCore
{

}

Que dois-je mettre exactement entre les accolades ?

 

merci d'avance

 

Nicolas

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...