Page 3 of 7

Re: How to add additional fields to a customer

Posted: 09 Apr 2018, 08:08
by aimeos
Also looks OK. Now you have to debug the files mentioned, especially the Factory.php. Tried to reconfigure the price manager myself and it worked like expected.

Re: How to add additional fields to a customer

Posted: 09 Apr 2018, 09:56
by mohal_04
aimeos wrote:Also looks OK. Now you have to debug the files mentioned, especially the Factory.php. Tried to reconfigure the price manager myself and it worked like expected.
Hi,

Thanks for the tips! Debugging inside Factory.php and PHPArray.php, I am able to see that my Manager is being loaded, which is a good thing. At least, it has been recognized.

But the Million Dollar question still there. If manager is being loaded then why is it not working. :'(

Any more places I can debug?

Thanks!

Re: How to add additional fields to a customer

Posted: 09 Apr 2018, 12:43
by mohal_04
aimeos wrote:Also looks OK. Now you have to debug the files mentioned, especially the Factory.php. Tried to reconfigure the price manager myself and it worked like expected.
Laravel: 5.6
Aimeos: 2017.10


Hello,

Thanks for being available and replying to my questions.

The so far progress is this that value of new custom field is retrieving from DB but it is not saving in the DB. Can you look at my code once again and see what am I doing wrong. I think there is something wrong in insert and update queries...

./ext/myextension/lib/custom/src/MShop/Price/Item/Custompricefields.php

Code: Select all

namespace Aimeos\MShop\Price\Item;
 
class Custompricefields extends Standard
{
    private $myvalues;
 
    public function __construct(array $values, array $listItems, array $refItems)
    {
        parent::__construct($values, $listItems, $refItems);
        $this->myvalues = $values;
    }
 
    public function getMinimumAdvertisedPrice()
    {
        if (isset($this->myvalues['price.minimumadvertisedprice'])) {
            return (string) $this->myvalues['price.minimumadvertisedprice'];
        }
        return '';
    }
 
    public function setMinimumAdvertisedPrice($minimumadvertisedprice)
    {
        if ((string) $minimumadvertisedprice !== $this->getMinimumAdvertisedPrice()) {
            $this->myvalues['price.minimumadvertisedprice'] = (string) $minimumadvertisedprice;
            $this->setModified();
        }
        return $this;
    }
 
    public function fromArray(array $list)
    {
        $unknown = [];
        $list = parent::fromArray($list);

        foreach ($list as $key => $value) {
            switch ($key) {
                case 'price.minimumadvertisedprice':
                    $this->setMinimumAdvertisedPrice($value);
                    break;
                default:
                    $unknown[$key] = $value;
            }
        }
        return $unknown;
    }
 
    public function toArray($private = false)
    {
        $list = parent::toArray($private);
        if ($private === true) {
            $list['price.minimumadvertisedprice'] = $this->getMinimumAdvertisedPrice();
        }
        return $list;
    }
}
./ext/myextension/lib/custom/src/MShop/Price/Manager/Custompricefields.php

Code: Select all

namespace Aimeos\MShop\Price\Manager;
 
class Custompricefields extends Standard
{
    private $searchConfig = array(
        'price.minimumadvertisedprice' => array(
            'code' => 'price.minimumadvertisedprice',
            'internalcode' => 'mpri."minimumadvertisedprice"',
            'label' => 'Minimum Advertised Price',
            'type' => 'float', // integer, string, etc.
            'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_FLOAT, // _INT, _STR, etc.
        )
    );
 
    public function saveItem(\Aimeos\MShop\Common\Item\Iface $item, $fetch = true)
    {
        $iface = '\\Aimeos\\MShop\\Price\\Item\\Iface';
        if( !( $item instanceof $iface ) ) {
            throw new \Aimeos\MShop\Price\Exception( sprintf( 'Object is not of required type "%1$s"', $iface ) );
        }
		
        if (! $item->isModified()) {
            return $item;
        }
        $context = $this->getContext();
        $dbm = $context->getDatabaseManager();
        $dbname = $this->getResourceName();
        $conn = $dbm->acquire( $dbname );

        try {
            $id = $item->getId();
            $date = date( 'Y-m-d H:i:s' );

            if ($id === null) {
                $path = 'mshop/price/manager/standard/insert';
            } else {
                $path = 'mshop/price/manager/standard/update';
            }
            $stmt = $this->getCachedStatement($conn, $path);

            $stmt->bind(1, $item->getMinimumAdvertisedPrice());
            $stmt->bind(2, $item->getTypeId(), \Aimeos\MW\DB\Statement\Base::PARAM_INT);
            $stmt->bind(3, $item->getCurrencyId());
            $stmt->bind(4, $item->getDomain());
            $stmt->bind(5, $item->getLabel());
            $stmt->bind(6, $item->getQuantity(), \Aimeos\MW\DB\Statement\Base::PARAM_INT);
            $stmt->bind(7, $item->getValue());
            $stmt->bind(8, $item->getCosts());
            $stmt->bind(9, $item->getRebate());
            $stmt->bind(10, $item->getTaxRate());
            $stmt->bind(11, $item->getStatus(), \Aimeos\MW\DB\Statement\Base::PARAM_INT);
            $stmt->bind(12, $date); //mtime
            $stmt->bind(13, $context->getEditor());
            $stmt->bind(14, $context->getLocale()->getSiteId(), \Aimeos\MW\DB\Statement\Base::PARAM_INT);
            if ($id !== null) {
                $stmt->bind(15, $id, \Aimeos\MW\DB\Statement\Base::PARAM_INT);
                $item->setId($id);
            } else {
                $stmt->bind(15, $date); //ctime
            }
			$stmt->execute()->finish();
            if ($id === null && $fetch === true) {
                $path = 'mshop/price/manager/standard/newid';
                $item->setId($this->newId($conn, $path));
            }
            $dbm->release($conn, $dbname);
        } catch(\Exception $e) {
            $dbm->release($conn, $dbname);
            throw $e;
        }
        return $item;
    }
 
    public function getSearchAttributes($withsub = true)
    {
        $list = parent::getSearchAttributes($withsub);
        foreach ($this->searchConfig as $key => $fields) {
            $list[$key] = new \Aimeos\MW\Criteria\Attribute\Standard($fields);
        }
        return $list;
    }
 
    protected function createItemBase(array $values = [], array $listitems = [], array $refItems = [])
    {
        return new \Aimeos\MShop\Price\Item\Custompricefields($values, $listitems, $refItems);
    }
}

./ext/myextension/lib/custom/config/mshop.php

Code: Select all

return [
    'product' => [
        'manager' => [
            'name' => 'Abc',
            'standard' => [
				'insert' => array(
					'ansi' => '
						INSERT INTO "mshop_product" (
							"countryoforigin", "oldcode", "typeid", "code", "label", "status", "start", "end",
							"config", "mtime", "editor", "target", "siteid", "ctime"
						) VALUES (
							?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
						)
					'
				),
				'update' => array(
					'ansi' => '
						UPDATE "mshop_product"
						SET "countryoforigin" = ?, "oldcode" = ?, "typeid" = ?, "code" = ?, "label" = ?, "status" = ?,
							"start" = ?, "end" = ?, "config" = ?, "mtime" = ?, "editor" = ?, "target" = ?
						WHERE "siteid" = ? AND "id" = ?
					'
				),
				'search' => array(
					'ansi' => '
						SELECT mpro."id" AS "product.id", mpro."siteid" AS "product.siteid",
							mpro."typeid" AS "product.typeid", mpro."code" AS "product.code",
							mpro."label" AS "product.label", mpro."config" AS "product.config",
							mpro."start" AS "product.datestart", mpro."end" AS "product.dateend",
							mpro."status" AS "product.status", mpro."ctime" AS "product.ctime",
							mpro."mtime" AS "product.mtime", mpro."editor" AS "product.editor",
							mpro."target" AS "product.target",
							mpro."oldcode" AS "product.oldcode",
							mpro."countryoforigin" AS "product.countryoforigin"
						FROM "mshop_product" AS mpro
						:joins
						WHERE :cond
						GROUP BY mpro."id", mpro."siteid", mpro."typeid", mpro."code",
							mpro."label", mpro."config", mpro."start", mpro."end",
							mpro."status", mpro."ctime", mpro."mtime", mpro."editor",
							mpro."target", mpro."oldcode", mpro."countryoforigin"
							/*-columns*/ , :columns /*columns-*/
						/*-orderby*/ ORDER BY :order /*orderby-*/
						LIMIT :size OFFSET :start
					'
				),
				'count' => array(
					'ansi' => '
						SELECT COUNT(*) AS "count"
						FROM (
							SELECT DISTINCT mpro."id"
							FROM "mshop_product" AS mpro
							:joins
							WHERE :cond
							LIMIT 10000 OFFSET 0
						) AS list
					'
				),
				'newid' => array(
					'db2' => 'SELECT IDENTITY_VAL_LOCAL()',
					'mysql' => 'SELECT LAST_INSERT_ID()',
					'oracle' => 'SELECT mshop_product_seq.CURRVAL FROM DUAL',
					'pgsql' => 'SELECT lastval()',
					'sqlite' => 'SELECT last_insert_rowid()',
					'sqlsrv' => 'SELECT SCOPE_IDENTITY()',
					'sqlanywhere' => 'SELECT @@IDENTITY',
				),
            ],
        ],
    ],
    'price' => [
        'manager' => [
            'name' => 'Custompricefields',
            'standard' => [
				'delete' => array(
					'ansi' => '
						DELETE FROM "mshop_price"
						WHERE :cond AND siteid = ?
					'
				),
				'insert' => array(
					'ansi' => '
						INSERT INTO "mshop_price" (
							"minimumadvertisedprice", "typeid", "currencyid", "domain", "label",
							"quantity", "value", "costs", "rebate", "taxrate",
							"status", "mtime", "editor", "siteid", "ctime"
						) VALUES (
							?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
						)
					'
				),
				'update' => array(
					'ansi' => '
						UPDATE "mshop_price"
						SET "minimumadvertisedprice" = ?, "typeid" = ?, "currencyid" = ?, "domain" = ?, "label" = ?,
							"quantity" = ?, "value" = ?, "costs" = ?, "rebate" = ?,
							"taxrate" = ?, "status" = ?, "mtime" = ?, "editor" = ?
						WHERE "siteid" = ? AND "id" = ?
					'
				),
				'search' => array(
					'ansi' => '
						SELECT mpri."id" AS "price.id", mpri."siteid" AS "price.siteid",
							mpri."typeid" AS "price.typeid", mpri."currencyid" AS "price.currencyid",
							mpri."domain" AS "price.domain", mpri."label" AS "price.label",
							mpri."quantity" AS "price.quantity", mpri."value" AS "price.value",
							mpri."costs" AS "price.costs", mpri."rebate" AS "price.rebate",
							mpri."taxrate" AS "price.taxrate", mpri."status" AS "price.status",
							mpri."mtime" AS "price.mtime", mpri."editor" AS "price.editor",
							mpri."ctime" AS "price.ctime",
							mpri."minimumadvertisedprice" AS "price.minimumadvertisedprice"
						FROM "mshop_price" AS mpri
						:joins
						WHERE :cond
						GROUP BY mpri."id", mpri."siteid", mpri."typeid", mpri."currencyid",
							mpri."domain", mpri."label", mpri."quantity", mpri."value",
							mpri."costs", mpri."rebate", mpri."taxrate", mpri."status",
							mpri."mtime", mpri."editor", mpri."ctime", mpri."minimumadvertisedprice"
							/*-columns*/ , :columns /*columns-*/
						/*-orderby*/ ORDER BY :order /*orderby-*/
						LIMIT :size OFFSET :start
					'
				),
				'count' => array(
					'ansi' => '
						SELECT COUNT(*) AS "count"
						FROM (
							SELECT DISTINCT mpri."id"
							FROM "mshop_price" AS mpri
							:joins
							WHERE :cond
							LIMIT 10000 OFFSET 0
						) AS list
					'
				),
				'newid' => array(
					'db2' => 'SELECT IDENTITY_VAL_LOCAL()',
					'mysql' => 'SELECT LAST_INSERT_ID()',
					'oracle' => 'SELECT mshop_price_seq.CURRVAL FROM DUAL',
					'pgsql' => 'SELECT lastval()',
					'sqlite' => 'SELECT last_insert_rowid()',
					'sqlsrv' => 'SELECT SCOPE_IDENTITY()',
					'sqlanywhere' => 'SELECT @@IDENTITY',
				),
            ],
        ],
    ],
];
Can you please again check out what is wrong in my code? SELECT query is workin' fine but INSERT and UPDATE queries are not working. I had the same issue when I was working on extending Product Manager but at that time it was Item class's __construct() method's parameter issue but this time I have rechecked and __construct() parameter are same as parent class.

Please, reply ASAP!

Thanks!

Re: How to add additional fields to a customer

Posted: 10 Apr 2018, 07:06
by aimeos
If saving doensn't work, please check:
- Is the new valule available in saveItem() of the manager
- Is the new value set in fromArray() of the item
- Is the new value available in fromArray() of the admin client
- Is the new value passed correctly in the template

Re: How to add additional fields to a customer

Posted: 10 Apr 2018, 09:14
by mohal_04
aimeos wrote:If saving doensn't work, please check:
- Is the new valule available in saveItem() of the manager
- Is the new value set in fromArray() of the item
- Is the new value available in fromArray() of the admin client
- Is the new value passed correctly in the template
Hi,
aimeos wrote:- Is the new valule available in saveItem() of the manager

Yes, new value "price.minimumadvertisedprice" is available in saveItem() method of "Custompricefields" manager. See below.
./ext/myextension/lib/custom/src/MShop/Price/Manager/Custompricefields.php

Code: Select all

public function saveItem(\Aimeos\MShop\Common\Item\Iface $item, $fetch = true)
    {
        $iface = '\\Aimeos\\MShop\\Price\\Item\\Iface';
        if( !( $item instanceof $iface ) ) {
            throw new \Aimeos\MShop\Price\Exception( sprintf( 'Object is not of required type "%1$s"', $iface ) );
        }
		
        if (! $item->isModified()) {
            return $item;
        }
        $context = $this->getContext();
        $dbm = $context->getDatabaseManager();
        $dbname = $this->getResourceName();
        $conn = $dbm->acquire( $dbname );

        try {
            $id = $item->getId();
            $date = date( 'Y-m-d H:i:s' );

            if ($id === null) {
                $path = 'mshop/price/manager/standard/insert';
            } else {
                $path = 'mshop/price/manager/standard/update';
            }
            $stmt = $this->getCachedStatement($conn, $path);

            $stmt->bind(1, $item->getMinimumAdvertisedPrice());
            $stmt->bind(2, $item->getTypeId(), \Aimeos\MW\DB\Statement\Base::PARAM_INT);
            $stmt->bind(3, $item->getCurrencyId());
            $stmt->bind(4, $item->getDomain());
            $stmt->bind(5, $item->getLabel());
            $stmt->bind(6, $item->getQuantity(), \Aimeos\MW\DB\Statement\Base::PARAM_INT);
            $stmt->bind(7, $item->getValue());
            $stmt->bind(8, $item->getCosts());
            $stmt->bind(9, $item->getRebate());
            $stmt->bind(10, $item->getTaxRate());
            $stmt->bind(11, $item->getStatus(), \Aimeos\MW\DB\Statement\Base::PARAM_INT);
            $stmt->bind(12, $date); //mtime
            $stmt->bind(13, $context->getEditor());
            $stmt->bind(14, $context->getLocale()->getSiteId(), \Aimeos\MW\DB\Statement\Base::PARAM_INT);
            if ($id !== null) {
                $stmt->bind(15, $id, \Aimeos\MW\DB\Statement\Base::PARAM_INT);
                $item->setId($id);
            } else {
                $stmt->bind(15, $date); //ctime
            }
			$stmt->execute()->finish();
            if ($id === null && $fetch === true) {
                $path = 'mshop/price/manager/standard/newid';
                $item->setId($this->newId($conn, $path));
            }
            $dbm->release($conn, $dbname);
        } catch(\Exception $e) {
            $dbm->release($conn, $dbname);
            throw $e;
        }
        return $item;
    }
aimeos wrote:- Is the new value set in fromArray() of the item

Yes, new value "price.minimumadvertisedprice" is set in fromArray() method of "Custompricefields" Item. See below:
./ext/myextension/lib/custom/src/MShop/Price/Item/Custompricefields.php

Code: Select all

public function fromArray(array $list)
    {
        $unknown = [];
        $list = parent::fromArray($list);

        foreach ($list as $key => $value) {
            switch ($key) {
                case 'price.minimumadvertisedprice':
                    $this->setMinimumAdvertisedPrice($value);
                    break;
                default:
                    $unknown[$key] = $value;
            }
        }
        return $unknown;
    }
But this method is not being called. I don't know why. Maybe you could help!
aimeos wrote:- Is the new value available in fromArray() of the admin client

No idea about this. Which one is this file? The documentation https://aimeos.org/docs/Developers/Libr ... gers_items says nothing about it. Kindly, guide me, which file is it?
aimeos wrote:- Is the new value passed correctly in the template
Yes, I think so. You can check template code below.
./ext/myextension/admin/jqadm/templates/product/item-price-default.php

Code: Select all

<div class="form-group row">
							<label class="col-sm-4 form-control-label help"><?= $enc->html( $this->translate( 'admin', 'Minimum Advertised Price' ) ); ?></label>
							<div class="col-sm-8">
								<input class="form-control item-value" type="number" step="0.01" tabindex="<?= $this->get( 'tabindex' ); ?>"
									name="<?= $enc->attr( $this->formparam( array( 'price', 'price.minimumadvertisedprice', '' ) ) ); ?>"
									placeholder="<?= $enc->attr( $this->translate( 'admin', 'Minimum Advertised Price' ) ); ?>"
									value="<?= $enc->attr( $this->get( 'priceData/price.minimumadvertisedprice/' . $idx, '0.00' ) ); ?>"
									<?= $this->site()->readonly( $this->get( 'priceData/product.lists.siteid/' . $idx ) ); ?> />
							</div>
							<div class="col-sm-12 form-text text-muted help-text">
								<?= $enc->html( $this->translate( 'admin', 'Minimum Advertised Price for the article' ) ); ?>
							</div>
						</div>
Can you please review all the code provided above? fromArray() method in Custompricefields Item class is not being invoked.

Thanks!

Re: How to add additional fields to a customer

Posted: 11 Apr 2018, 07:38
by aimeos
Your new value isn't set in the item there:
https://github.com/aimeos/ai-admin-jqad ... d.php#L357

Re: How to add additional fields to a customer

Posted: 11 Apr 2018, 07:56
by mohal_04
aimeos wrote:Your new value isn't set in the item there:
https://github.com/aimeos/ai-admin-jqad ... d.php#L357
Hi,

Thanks for your guidance! I thought all changes must be in my extension. Anyhow, I have moved to Aimeos 2018.04 and now I am facing a different issue. I want to add Old SKU field on the product detail page (front-end) but product detail page is not showing latest changes.

According to the documentation (https://aimeos.org/docs/Developers/Html ... _templates) I have copied the exact directory structure in <myextension>.

./ext/myextension/client/html/templates/catalog/detail/body-standard.php

BUT nothing changes on the front-end. I have cleared Laravel cache also but front-end view is not updating. May you help me with this?

Now my setup consists of:
Laravel: 5.6
Aimeos: 2018.04
Environment: Linux

Thanks!

Re: How to add additional fields to a customer

Posted: 11 Apr 2018, 08:01
by mohal_04
aimeos wrote:Your new value isn't set in the item there:
https://github.com/aimeos/ai-admin-jqad ... d.php#L357
Hi,

One more thing... Is the official documentation applicable on latest Aimeos version? Because on the documentation page it says "2016.xx version."
doc_aimeos_ver.jpg
doc_aimeos_ver.jpg (167.86 KiB) Viewed 4337 times
Thanks!

Re: How to add additional fields to a customer

Posted: 11 Apr 2018, 10:28
by tenkraD
Hi moval,

dont forget, if you update the aimeos you have to rebuild your extension with the extensionbuilder that it is working right.
because they have changed the directory structur and some other stuff, i made this mistake too.

bye

Re: How to add additional fields to a customer

Posted: 11 Apr 2018, 11:31
by mohal_04
tenkraD wrote:Hi moval,

dont forget, if you update the aimeos you have to rebuild your extension with the extensionbuilder that it is working right.
because they have changed the directory structur and some other stuff, i made this mistake too.

bye
Thanks Buddy!!! Already did that :) ...