Page 1 of 3

Extend Order and add a new Field to JQadm

Posted: 15 Dec 2017, 13:46
by mantik
Hello
MY Client sync the orders with a other system and he like to add the orderID from the external System to aimeos.
So he can synch teh both systems manually (later automatic).

How can i add a new Field the the order and save it with jqadm in the backend.

Re: Extend Order and add a new Field to JQadm

Posted: 16 Dec 2017, 14:36
by aimeos
The simplest way is to store the foreign order ID as service attribute. Then, you have to do nothing because the order panel in the JQAdmin inteface makes this possible. Just let you customer enter a code/value pair (e.g. "myeprid": 123)

Re: Extend Order and add a new Field to JQadm

Posted: 18 Dec 2017, 08:07
by mantik
is there no userfriendly way with a own field?
i drather like to extend the mshop_order_base-table that the user can sort and search it in the order module

Re: Extend Order and add a new Field to JQadm

Posted: 18 Dec 2017, 21:41
by aimeos
This requires some more work:
- Extend the schema for the mshop_order table in your own extension (https://aimeos.org/docs/Developers/Libr ... ing_tables)
- Create your own order item and manager (extend from the existing ones) that can handle the new property (https://aimeos.org/docs/Developers/Libr ... gers_items)
- Extend the JQAdm order client to save the new property (https://github.com/aimeos/ai-admin-jqad ... er/Invoice) and replace the order list and item template (https://github.com/aimeos/ai-admin-jqad ... ates/order)

Re: Extend Order and add a new Field to JQadm

Posted: 21 Dec 2017, 11:14
by mantik
i dont get the second point (extend item and manager)

My Item

Code: Select all

<?php
namespace Aimeos\MShop\Order\Item\Base;

class Myorder extends Standard{

	private $values;
	private $modified = false;

	public function __construct(){
		parent::__construct();
	}

	public function getCrmid(){
		if( isset( $this->values['order.base.crmid'] ) ) {
			return (string) $this->values['order.base.crmid'];
		}

		return '';
	}

	public function setCrmid( $crmid ){
		if( (string) $crmid !== $this->getCrmid() ){
			$this->values['order.base.crmid'] = (string) $crmid;
			$this->modified = true;
		}

		return $this;
	}

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

		foreach( $list as $key => $value )
		{
			switch( $key )
			{
				case 'order.base.id': $this->setId( $value ); break;
				case 'order.base.comment': $this->setComment( $value ); break;
				case 'order.base.customerid': $this->setCustomerId( $value ); break;
				case 'order.base.status': $this->setStatus( $value ); break;
				case 'order.base.languageid': $this->locale->setLanguageId( $value ); break;
				case 'order.base.crmid': $this->locale->setCrmid( $value ); break;
				default: $unknown[$key] = $value;
			}
		}

		unset( $list['order.base.siteid'] );
		unset( $list['order.base.ctime'] );
		unset( $list['order.base.mtime'] );
		unset( $list['order.base.editor'] );

		return $unknown;
	}

	public function toArray( $private = false )
	{
		$price = $this->getPrice();
		$locale = $this->getLocale();

		$list = array(
			'order.base.customerid' => $this->getCustomerId(),
			'order.base.sitecode' => $this->getSiteCode(),
			'order.base.languageid' => $locale->getLanguageId(),
			'order.base.currencyid' => $price->getCurrencyId(),
			'order.base.price' => $price->getValue(),
			'order.base.costs' => $price->getCosts(),
			'order.base.rebate' => $price->getRebate(),
			'order.base.taxvalue' => $price->getTaxValue(),
			'order.base.taxflag' => $price->getTaxFlag(),
			'order.base.status' => $this->getStatus(),
			'order.base.comment' => $this->getComment(),
			'order.base.crmid' => $this->getCrmid(),
		);

		if( $private === true )
		{
			$list['order.base.id'] = $this->getId();
			$list['order.base.siteid'] = $this->getSiteId();
			$list['order.base.mtime'] = $this->getTimeModified();
			$list['order.base.ctime'] = $this->getTimeCreated();
			$list['order.base.editor'] = $this->getEditor();
		}

		return $list;
	}

}
MAnager

Code: Select all

<?php
namespace Aimeos\MShop\Order\Manager\Base;

class Myorder extends Standard {
	private $searchConfig = array(
		'order.base.crmid' => array(
			'code' => 'order.base.crmid',
			'internalcode' => 'mordba."crmid"',
			'label' => 'crm ID',
			'type' => 'string',
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
		)
	);

	/**
	 * @param \Aimeos\MShop\Common\Item\Iface $item
	 * @param bool $fetch
	 *
	 * @return \Aimeos\MShop\Common\Item\Iface
	 * @throws \Aimeos\MShop\Common\Exception
	 * @throws \Aimeos\MShop\Order\Exception
	 * @throws \Exception
	 */
	public function saveItem( \Aimeos\MShop\Common\Item\Iface $item, $fetch = true )
	{
		$iface = '\\Aimeos\\MShop\\Order\\Item\\Base\\Iface';
		if( !( $item instanceof $iface ) ) {
			throw new \Aimeos\MShop\Order\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 )
			{
				/** mshop/order/manager/base/standard/insert/mysql
				 * Inserts a new order record into the database table
				 *
				 * @see mshop/order/manager/base/standard/insert/ansi
				 */

				/** mshop/order/manager/base/standard/insert/ansi
				 * Inserts a new order record into the database table
				 *
				 * Items with no ID yet (i.e. the ID is NULL) will be created in
				 * the database and the newly created ID retrieved afterwards
				 * using the "newid" SQL statement.
				 *
				 * The SQL statement must be a string suitable for being used as
				 * prepared statement. It must include question marks for binding
				 * the values from the order item to the statement before they are
				 * sent to the database server. The number of question marks must
				 * be the same as the number of columns listed in the INSERT
				 * statement. The order of the columns must correspond to the
				 * order in the saveItems() method, so the correct values are
				 * bound to the columns.
				 *
				 * The SQL statement should conform to the ANSI standard to be
				 * compatible with most relational database systems. This also
				 * includes using double quotes for table and column names.
				 *
				 * @param string SQL statement for inserting records
				 * @since 2014.03
				 * @category Developer
				 * @see mshop/order/manager/base/standard/update/ansi
				 * @see mshop/order/manager/base/standard/newid/ansi
				 * @see mshop/order/manager/base/standard/delete/ansi
				 * @see mshop/order/manager/base/standard/search/ansi
				 * @see mshop/order/manager/base/standard/count/ansi
				 */
				$path = 'mshop/order/manager/base/standard/insert';
			}
			else
			{
				/** mshop/order/manager/base/standard/update/mysql
				 * Updates an existing order record in the database
				 *
				 * @see mshop/order/manager/base/standard/update/ansi
				 */

				/** mshop/order/manager/base/standard/update/ansi
				 * Updates an existing order record in the database
				 *
				 * Items which already have an ID (i.e. the ID is not NULL) will
				 * be updated in the database.
				 *
				 * The SQL statement must be a string suitable for being used as
				 * prepared statement. It must include question marks for binding
				 * the values from the order item to the statement before they are
				 * sent to the database server. The order of the columns must
				 * correspond to the order in the saveItems() method, so the
				 * correct values are bound to the columns.
				 *
				 * The SQL statement should conform to the ANSI standard to be
				 * compatible with most relational database systems. This also
				 * includes using double quotes for table and column names.
				 *
				 * @param string SQL statement for updating records
				 * @since 2014.03
				 * @category Developer
				 * @see mshop/order/manager/base/standard/insert/ansi
				 * @see mshop/order/manager/base/standard/newid/ansi
				 * @see mshop/order/manager/base/standard/delete/ansi
				 * @see mshop/order/manager/base/standard/search/ansi
				 * @see mshop/order/manager/base/standard/count/ansi
				 */
				$path = 'mshop/order/manager/base/standard/update';
			}

			$priceItem = $item->getPrice();
			$localeItem = $context->getLocale();

			$stmt = $this->getCachedStatement( $conn, $path );

			$stmt->bind( 1, $item->getCustomerId() );
			$stmt->bind( 2, $localeItem->getSite()->getCode() );
			$stmt->bind( 3, $item->getLocale()->getLanguageId() );
			$stmt->bind( 4, $priceItem->getCurrencyId() );
			$stmt->bind( 5, $priceItem->getValue() );
			$stmt->bind( 6, $priceItem->getCosts() );
			$stmt->bind( 7, $priceItem->getRebate() );
			$stmt->bind( 8, $priceItem->getTaxValue() );
			$stmt->bind( 9, $priceItem->getTaxFlag(), \Aimeos\MW\DB\Statement\Base::PARAM_INT );
			$stmt->bind( 10, $item->getComment() );
			$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, $localeItem->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->bind( 16, $item->getCrmid() );

			$stmt->execute()->finish();

			if( $id === null && $fetch === true )
			{
				/** mshop/order/manager/base/standard/newid/mysql
				 * Retrieves the ID generated by the database when inserting a new record
				 *
				 * @see mshop/order/manager/base/standard/newid/ansi
				 */

				/** mshop/order/manager/base/standard/newid/ansi
				 * Retrieves the ID generated by the database when inserting a new record
				 *
				 * As soon as a new record is inserted into the database table,
				 * the database server generates a new and unique identifier for
				 * that record. This ID can be used for retrieving, updating and
				 * deleting that specific record from the table again.
				 *
				 * For MySQL:
				 *  SELECT LAST_INSERT_ID()
				 * For PostgreSQL:
				 *  SELECT currval('seq_mord_id')
				 * For SQL Server:
				 *  SELECT SCOPE_IDENTITY()
				 * For Oracle:
				 *  SELECT "seq_mord_id".CURRVAL FROM DUAL
				 *
				 * There's no way to retrive the new ID by a SQL statements that
				 * fits for most database servers as they implement their own
				 * specific way.
				 *
				 * @param string SQL statement for retrieving the last inserted record ID
				 * @since 2014.03
				 * @category Developer
				 * @see mshop/order/manager/base/standard/insert/ansi
				 * @see mshop/order/manager/base/standard/update/ansi
				 * @see mshop/order/manager/base/standard/delete/ansi
				 * @see mshop/order/manager/base/standard/search/ansi
				 * @see mshop/order/manager/base/standard/count/ansi
				 */
				$path = 'mshop/order/manager/base/standard/newid';
				$item->setId( $this->newId( $conn, $path ) );
			}

			$dbm->release( $conn, $dbname );
		}
		catch( \Exception $e )
		{
			$dbm->release( $conn, $dbname );
			throw $e;
		}

		return $item;
	}


}
?>
my config

Code: Select all

<?php

/**
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
 * @copyright Aimeos (aimeos.org), 2015-2017
 */


return array(
	'order'=>array(
	'manager' => array(
		'base' => array(
			'name'=>'Myorder',
			'address' => array(
				'standard' => array(
					'aggregate' => array(
						'ansi' => '
							SELECT "key", COUNT("val") AS "count"
							FROM (
								SELECT :key AS "key", :val AS "val"
								FROM "mshop_order_base_address" AS mordbaad
								:joins
								WHERE :cond
								/*-orderby*/ ORDER BY :order /*orderby-*/
								LIMIT :size OFFSET :start
							) AS list
							GROUP BY "key"
						'
					),
					'delete' => array(
						'ansi' => '
							DELETE FROM "mshop_order_base_address"
							WHERE :cond AND siteid = ?
						'
					),
					'insert' => array(
						'ansi' => '
							INSERT INTO "mshop_order_base_address" (
								"baseid", "addrid", "type", "company", "vatid", "salutation",
								"title", "firstname", "lastname", "address1", "address2",
								"address3", "postal", "city", "state", "countryid", "langid",
								"telephone", "email", "telefax", "website", "longitude", "latitude",
								"flag", "mtime", "editor", "siteid", "ctime"
							) VALUES (
								?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?
							)
						'
					),
					'update' => array(
						'ansi' => '
							UPDATE "mshop_order_base_address"
							SET "baseid" = ?, "addrid" = ?, "type" = ?, "company" = ?, "vatid" = ?,
								"salutation" = ?, "title" = ?, "firstname" = ?, "lastname" = ?,
								"address1" = ?, "address2" = ?, "address3" = ?, "postal" = ?,
								"city" = ?, "state" = ?, "countryid" = ?, "langid" = ?,
								"telephone" = ?, "email" = ?, "telefax" = ?, "website" = ?,
								"longitude" = ?, "latitude" = ?, "flag" = ?, "mtime" = ?, "editor" = ?
							WHERE "siteid" = ? AND "id" = ?
						'
					),
					'search' => array(
						'ansi' => '
							SELECT mordbaad."id" AS "order.base.address.id", mordbaad."baseid" AS "order.base.address.baseid",
								mordbaad."siteid" AS "order.base.address.siteid", mordbaad."addrid" AS "order.base.address.addressid",
								mordbaad."type" AS "order.base.address.type", mordbaad."flag" AS "order.base.address.flag",
								mordbaad."company" AS "order.base.address.company", mordbaad."vatid" AS "order.base.address.vatid",
								mordbaad."salutation" AS "order.base.address.salutation", mordbaad."title" AS "order.base.address.title",
								mordbaad."firstname" AS "order.base.address.firstname", mordbaad."lastname" AS "order.base.address.lastname",
								mordbaad."address1" AS "order.base.address.address1", mordbaad."address2" AS "order.base.address.address2",
								mordbaad."address3" AS "order.base.address.address3", mordbaad."postal" AS "order.base.address.postal",
								mordbaad."city" AS "order.base.address.city", mordbaad."state" AS "order.base.address.state",
								mordbaad."countryid" AS "order.base.address.countryid", mordbaad."langid" AS "order.base.address.languageid",
								mordbaad."telephone" AS "order.base.address.telephone", mordbaad."email" AS "order.base.address.email",
								mordbaad."telefax" AS "order.base.address.telefax", mordbaad."website" AS "order.base.address.website",
								mordbaad."longitude" AS "order.base.address.longitude", mordbaad."latitude" AS "order.base.address.latitude",
								mordbaad."mtime" AS "order.base.address.mtime", mordbaad."editor" AS "order.base.address.editor",
								mordbaad."ctime" AS "order.base.address.ctime"
							FROM "mshop_order_base_address" AS mordbaad
							:joins
							WHERE :cond
							GROUP BY mordbaad."id", mordbaad."baseid", mordbaad."siteid", mordbaad."addrid",
								mordbaad."type", mordbaad."flag", mordbaad."company", mordbaad."vatid",
								mordbaad."salutation", mordbaad."title", mordbaad."firstname", mordbaad."lastname",
								mordbaad."address1", mordbaad."address2", mordbaad."address3", mordbaad."postal",
								mordbaad."city", mordbaad."state", mordbaad."countryid", mordbaad."langid",
								mordbaad."telephone", mordbaad."email", mordbaad."telefax", mordbaad."website",
								mordbaad."longitude", mordbaad."latitude", mordbaad."mtime", mordbaad."editor",
								mordbaad."ctime" /*-columns*/ , :columns /*columns-*/
							/*-orderby*/ ORDER BY :order /*orderby-*/
							LIMIT :size OFFSET :start
						'
					),
					'count' => array(
						'ansi' => '
							SELECT COUNT( DISTINCT mordbaad."id" ) AS "count"
							FROM "mshop_order_base_address" AS mordbaad
							:joins
							WHERE :cond
						'
					),
					'newid' => array(
						'db2' => 'SELECT IDENTITY_VAL_LOCAL()',
						'mysql' => 'SELECT LAST_INSERT_ID()',
						'oracle' => 'SELECT mshop_order_base_address_seq.CURRVAL FROM DUAL',
						'pgsql' => 'SELECT lastval()',
						'sqlite' => 'SELECT last_insert_rowid()',
						'sqlsrv' => 'SELECT SCOPE_IDENTITY()',
						'sqlanywhere' => 'SELECT @@IDENTITY',
					),
				),
			),
			'coupon' => array(
				'standard' => array(
					'aggregate' => array(
						'ansi' => '
							SELECT "key", COUNT("val") AS "count"
							FROM (
								SELECT :key AS "key", :val AS "val"
								FROM "mshop_order_base_coupon" AS mordbaco
								:joins
								WHERE :cond
								/*-orderby*/ ORDER BY :order /*orderby-*/
								LIMIT :size OFFSET :start
							) AS list
							GROUP BY "key"
						'
					),
					'delete' => array(
						'ansi' => '
							DELETE FROM "mshop_order_base_coupon"
							WHERE :cond AND siteid = ?
							'
					),
					'insert' => array(
						'ansi' => '
							INSERT INTO "mshop_order_base_coupon" (
								"baseid", "ordprodid", "code",
								"mtime", "editor", "siteid", "ctime"
							) VALUES (
								?, ?, ?, ?, ?, ?, ?
							)
						'
					),
					'update' => array(
						'ansi' => '
							UPDATE "mshop_order_base_coupon"
							SET "baseid" = ?, "ordprodid" = ?, "code" = ?,
								"mtime" = ?, "editor" = ?
							WHERE "siteid" = ? AND "id" = ?
						'
					),
					'search' => array(
						'ansi' => '
							SELECT mordbaco."id" AS "order.base.coupon.id", mordbaco."baseid" AS "order.base.coupon.baseid",
								mordbaco."siteid" AS "order.base.coupon.siteid", mordbaco."ordprodid" AS "order.base.coupon.ordprodid",
								mordbaco."code" AS "order.base.coupon.code", mordbaco."mtime" AS "order.base.coupon.mtime",
								mordbaco."editor" AS "order.base.coupon.editor", mordbaco."ctime" AS "order.base.coupon.ctime"
							FROM "mshop_order_base_coupon" AS mordbaco
							:joins
							WHERE :cond
							GROUP BY mordbaco."id", mordbaco."baseid", mordbaco."siteid", mordbaco."ordprodid",
								mordbaco."code", mordbaco."mtime", mordbaco."editor", mordbaco."ctime"
								/*-columns*/ , :columns /*columns-*/
							/*-orderby*/ ORDER BY :order /*orderby-*/
							LIMIT :size OFFSET :start
						'
					),
					'count' => array(
						'ansi' => '
							SELECT COUNT( DISTINCT mordbaco."id" ) AS "count"
							FROM "mshop_order_base_coupon" AS mordbaco
							:joins
							WHERE :cond
						'
					),
					'newid' => array(
						'db2' => 'SELECT IDENTITY_VAL_LOCAL()',
						'mysql' => 'SELECT LAST_INSERT_ID()',
						'oracle' => 'SELECT mshop_order_base_coupon_seq.CURRVAL FROM DUAL',
						'pgsql' => 'SELECT lastval()',
						'sqlite' => 'SELECT last_insert_rowid()',
						'sqlsrv' => 'SELECT SCOPE_IDENTITY()',
						'sqlanywhere' => 'SELECT @@IDENTITY',
					),
				),
			),
			'product' => array(
				'attribute' => array(
					'standard' => array(
						'aggregate' => array(
							'ansi' => '
								SELECT "key", COUNT("val") AS "count"
								FROM (
									SELECT :key AS "key", :val AS "val"
									FROM "mshop_order_base_product_attr" AS mordbaprat
									:joins
									WHERE :cond
									/*-orderby*/ ORDER BY :order /*orderby-*/
									LIMIT :size OFFSET :start
								) AS list
								GROUP BY "key"
							'
						),
						'delete' => array(
							'ansi' => '
								DELETE FROM "mshop_order_base_product_attr"
								WHERE :cond AND siteid = ?
							'
						),
						'insert' => array(
							'ansi' => '
								INSERT INTO "mshop_order_base_product_attr" (
									"attrid", "ordprodid", "type", "code", "value",
									"name", "mtime", "editor", "siteid", "ctime"
								) VALUES (
									?, ?, ?, ?, ?, ?, ?, ?, ?, ?
								)
							'
						),
						'update' => array(
							'ansi' => '
								UPDATE "mshop_order_base_product_attr"
								SET "attrid" = ?, "ordprodid" = ?, "type" = ?, "code" = ?,
									"value" = ?, "name" = ?, "mtime" = ?, "editor" = ?
								WHERE "siteid" = ? AND "id" = ?
							'
						),
						'search' => array(
							'ansi' => '
								SELECT mordbaprat."id" AS "order.base.product.attribute.id", mordbaprat."siteid" AS "order.base.product.attribute.siteid",
									mordbaprat."attrid" AS "order.base.product.attribute.attributeid", mordbaprat."ordprodid" AS "order.base.product.attribute.parentid",
									mordbaprat."type" AS "order.base.product.attribute.type", mordbaprat."code" AS "order.base.product.attribute.code",
									mordbaprat."value" AS "order.base.product.attribute.value", mordbaprat."name" AS "order.base.product.attribute.name",
									mordbaprat."mtime" AS "order.base.product.attribute.mtime", mordbaprat."editor" AS "order.base.product.attribute.editor",
									mordbaprat."ctime" AS "order.base.product.attribute.ctime"
								FROM "mshop_order_base_product_attr" AS mordbaprat
								:joins
								WHERE :cond
								GROUP BY mordbaprat."id", mordbaprat."siteid", mordbaprat."attrid", mordbaprat."ordprodid",
									mordbaprat."type", mordbaprat."code", mordbaprat."value", mordbaprat."name",
									mordbaprat."mtime", mordbaprat."editor", mordbaprat."ctime" /*-columns*/ , :columns /*columns-*/
								/*-orderby*/ ORDER BY :order /*orderby-*/
								LIMIT :size OFFSET :start
							'
						),
						'count' => array(
							'ansi' => '
								SELECT COUNT( DISTINCT mordbaprat."id" ) AS "count"
								FROM "mshop_order_base_product_attr" AS mordbaprat
								:joins
								WHERE :cond
							'
						),
						'newid' => array(
							'db2' => 'SELECT IDENTITY_VAL_LOCAL()',
							'mysql' => 'SELECT LAST_INSERT_ID()',
							'oracle' => 'SELECT mshop_order_base_product_attr_seq.CURRVAL FROM DUAL',
							'pgsql' => 'SELECT lastval()',
							'sqlite' => 'SELECT last_insert_rowid()',
							'sqlsrv' => 'SELECT SCOPE_IDENTITY()',
							'sqlanywhere' => 'SELECT @@IDENTITY',
						),
					),
				),
				'standard' => array(
					'aggregate' => array(
						'ansi' => '
							SELECT "key", COUNT("val") AS "count"
							FROM (
								SELECT :key AS "key", :val AS "val"
								FROM "mshop_order_base_product" AS mordbapr
								:joins
								WHERE :cond
								/*-orderby*/ ORDER BY :order /*orderby-*/
								LIMIT :size OFFSET :start
							) AS list
							GROUP BY "key"
						'
					),
					'aggregateavg' => array(
						'ansi' => '
							SELECT "key", AVG("val") AS "count"
							FROM (
								SELECT :key AS "key", :val AS "val"
								FROM "mshop_order_base_product" AS mordbapr
								:joins
								WHERE :cond
								/*-orderby*/ ORDER BY :order /*orderby-*/
								LIMIT :size OFFSET :start
							) AS list
							GROUP BY "key"
						'
					),
					'aggregatesum' => array(
						'ansi' => '
							SELECT "key", SUM("val") AS "count"
							FROM (
								SELECT :key AS "key", :val AS "val"
								FROM "mshop_order_base_product" AS mordbapr
								:joins
								WHERE :cond
								/*-orderby*/ ORDER BY :order /*orderby-*/
								LIMIT :size OFFSET :start
							) AS list
							GROUP BY "key"
						'
					),
					'delete' => array(
						'ansi' => '
							DELETE FROM "mshop_order_base_product"
							WHERE :cond AND siteid = ?
						'
					),
					'insert' => array(
						'ansi' => '
							INSERT INTO "mshop_order_base_product" (
								"baseid", "ordprodid", "type", "prodid", "prodcode",
								"suppliercode", "stocktype", "name", "mediaurl", "quantity",
								"price", "costs", "rebate", "tax", "taxrate", "taxflag", "flags",
								"status", "pos", "mtime", "editor", "target", "siteid", "ctime"
							) VALUES (
								?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
							)
						'
					),
					'update' => array(
						'ansi' => '
							UPDATE "mshop_order_base_product"
							SET "baseid" = ?, "ordprodid" = ?, "type" = ?,
								"prodid" = ?, "prodcode" = ?, "suppliercode" = ?,
								"stocktype" = ?, "name" = ?, "mediaurl" = ?,
								"quantity" = ?, "price" = ?, "costs" = ?, "rebate" = ?,
								"tax" = ?, "taxrate" = ?, "taxflag" = ?, "flags" = ?,
								"status" = ?, "pos" = ?, "mtime" = ?, "editor" = ?, "target" = ?
							WHERE "siteid" = ? AND "id" = ?
						'
					),
					'search' => array(
						'ansi' => '
							SELECT mordbapr."id" AS "order.base.product.id", mordbapr."baseid" AS "order.base.product.baseid",
								mordbapr."siteid" AS "order.base.product.siteid", mordbapr."ordprodid" AS "order.base.product.ordprodid",
								mordbapr."prodid" AS "order.base.product.productid", mordbapr."prodcode" AS "order.base.product.prodcode",
								mordbapr."suppliercode" AS "order.base.product.suppliercode", mordbapr."stocktype" AS "order.base.product.stocktype",
								mordbapr."type" AS "order.base.product.type", mordbapr."name" AS "order.base.product.name",
								mordbapr."mediaurl" AS "order.base.product.mediaurl", mordbapr."quantity" AS "order.base.product.quantity",
								mordbapr."price" AS "order.base.product.price", mordbapr."costs" AS "order.base.product.costs",
								mordbapr."rebate" AS "order.base.product.rebate", mordbapr."tax" AS "order.base.product.taxvalue",
								mordbapr."taxrate" AS "order.base.product.taxrate", mordbapr."taxflag" AS "order.base.product.taxflag",
								mordbapr."flags" AS "order.base.product.flags", mordbapr."status" AS "order.base.product.status",
								mordbapr."pos" AS "order.base.product.position", mordbapr."mtime" AS "order.base.product.mtime",
								mordbapr."editor" AS "order.base.product.editor", mordbapr."ctime" AS "order.base.product.ctime",
								mordbapr."target" AS "order.base.product.target"
							FROM "mshop_order_base_product" AS mordbapr
							:joins
							WHERE :cond
							GROUP BY mordbapr."id", mordbapr."baseid", mordbapr."siteid", mordbapr."ordprodid",
								mordbapr."prodid", mordbapr."prodcode", mordbapr."suppliercode", mordbapr."stocktype",
								mordbapr."type", mordbapr."name", mordbapr."mediaurl", mordbapr."quantity",
								mordbapr."price", mordbapr."costs", mordbapr."rebate", mordbapr."tax", mordbapr."taxrate",
								mordbapr."taxflag", mordbapr."flags", mordbapr."status", mordbapr."pos", mordbapr."mtime",
								mordbapr."editor", mordbapr."target", mordbapr."ctime" /*-columns*/ , :columns /*columns-*/
							/*-orderby*/ ORDER BY :order /*orderby-*/
							LIMIT :size OFFSET :start
						'
					),
					'count' => array(
						'ansi' => '
							SELECT COUNT( DISTINCT mordbapr."id" ) AS "count"
							FROM "mshop_order_base_product" AS mordbapr
							:joins
							WHERE :cond
						'
					),
					'newid' => array(
						'db2' => 'SELECT IDENTITY_VAL_LOCAL()',
						'mysql' => 'SELECT LAST_INSERT_ID()',
						'oracle' => 'SELECT mshop_order_base_product_seq.CURRVAL FROM DUAL',
						'pgsql' => 'SELECT lastval()',
						'sqlite' => 'SELECT last_insert_rowid()',
						'sqlsrv' => 'SELECT SCOPE_IDENTITY()',
						'sqlanywhere' => 'SELECT @@IDENTITY',
					),
				),
			),
			'service' => array(
				'attribute' => array(
					'standard' => array(
						'aggregate' => array(
							'ansi' => '
								SELECT "key", COUNT("val") AS "count"
								FROM (
									SELECT :key AS "key", :val AS "val"
									FROM "mshop_order_base_service_attr" AS mordbaseat
									:joins
									WHERE :cond
									/*-orderby*/ ORDER BY :order /*orderby-*/
									LIMIT :size OFFSET :start
								) AS list
								GROUP BY "key"
							'
						),
						'delete' => array(
							'ansi' => '
								DELETE FROM "mshop_order_base_service_attr"
								WHERE :cond AND siteid = ?
							'
						),
						'insert' => array(
							'ansi' => '
								INSERT INTO "mshop_order_base_service_attr" (
									"attrid", "ordservid", "type", "code", "value",
									"name", "mtime", "editor", "siteid", "ctime"
								) VALUES (
									?, ?, ?, ?, ?, ?, ?, ?, ?, ?
								)
							'
						),
						'update' => array(
							'ansi' => '
								UPDATE "mshop_order_base_service_attr"
								SET "attrid" = ?, "ordservid" = ?, "type" = ?, "code" = ?,
									"value" = ?, "name" = ?, "mtime" = ?, "editor" = ?
								WHERE "siteid" = ? AND "id" = ?
							'
						),
						'search' => array(
							'ansi' => '
								SELECT mordbaseat."id" AS "order.base.service.attribute.id", mordbaseat."siteid" AS "order.base.service.attribute.siteid",
									mordbaseat."attrid" AS "order.base.service.attribute.attributeid", mordbaseat."ordservid" AS "order.base.service.attribute.parentid",
									mordbaseat."type" AS "order.base.service.attribute.type", mordbaseat."code" AS "order.base.service.attribute.code",
									mordbaseat."value" AS "order.base.service.attribute.value", mordbaseat."name" AS "order.base.service.attribute.name",
									mordbaseat."mtime" AS "order.base.service.attribute.mtime", mordbaseat."ctime" AS "order.base.service.attribute.ctime",
									mordbaseat."editor" AS "order.base.service.attribute.editor"
								FROM "mshop_order_base_service_attr" AS mordbaseat
								:joins
								WHERE :cond
								GROUP BY mordbaseat."id", mordbaseat."siteid", mordbaseat."attrid", mordbaseat."ordservid",
									mordbaseat."type", mordbaseat."code", mordbaseat."value", mordbaseat."name",
									mordbaseat."mtime", mordbaseat."ctime", mordbaseat."editor" /*-columns*/ , :columns /*columns-*/
								/*-orderby*/ ORDER BY :order /*orderby-*/
								LIMIT :size OFFSET :start
							'
						),
						'count' => array(
							'ansi' => '
								SELECT COUNT( DISTINCT mordbaseat."id" ) AS "count"
								FROM "mshop_order_base_service_attr" AS mordbaseat
								:joins
								WHERE :cond
							'
						),
						'newid' => array(
							'db2' => 'SELECT IDENTITY_VAL_LOCAL()',
							'mysql' => 'SELECT LAST_INSERT_ID()',
							'oracle' => 'SELECT mshop_order_base_service_attr_seq.CURRVAL FROM DUAL',
							'pgsql' => 'SELECT lastval()',
							'sqlite' => 'SELECT last_insert_rowid()',
							'sqlsrv' => 'SELECT SCOPE_IDENTITY()',
							'sqlanywhere' => 'SELECT @@IDENTITY',
						),
					),
				),
				'standard' => array(
					'aggregate' => array(
						'ansi' => '
							SELECT "key", COUNT("val") AS "count"
							FROM (
								SELECT :key AS "key", :val AS "val"
								FROM "mshop_order_base_service" AS mordbase
								:joins
								WHERE :cond
								/*-orderby*/ ORDER BY :order /*orderby-*/
								LIMIT :size OFFSET :start
							) AS list
							GROUP BY "key"
						'
					),
					'aggregateavg' => array(
						'ansi' => '
							SELECT "key", AVG("val") AS "count"
							FROM (
								SELECT :key AS "key", :val AS "val"
								FROM "mshop_order_base_service" AS mordbase
								:joins
								WHERE :cond
								/*-orderby*/ ORDER BY :order /*orderby-*/
								LIMIT :size OFFSET :start
							) AS list
							GROUP BY "key"
						'
					),
					'aggregatesum' => array(
						'ansi' => '
							SELECT "key", SUM("val") AS "count"
							FROM (
								SELECT :key AS "key", :val AS "val"
								FROM "mshop_order_base_service" AS mordbase
								:joins
								WHERE :cond
								/*-orderby*/ ORDER BY :order /*orderby-*/
								LIMIT :size OFFSET :start
							) AS list
							GROUP BY "key"
						'
					),
					'delete' => array(
						'ansi' => '
							DELETE FROM "mshop_order_base_service"
							WHERE :cond AND siteid = ?
						'
					),
					'insert' => array(
						'ansi' => '
							INSERT INTO "mshop_order_base_service" (
								"baseid", "servid", "type", "code", "name",
								"mediaurl", "price", "costs", "rebate", "tax", "taxrate",
								"taxflag", "mtime", "editor", "siteid", "ctime"
							) VALUES (
								?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
							)
						'
					),
					'update' => array(
						'ansi' => '
							UPDATE "mshop_order_base_service"
							SET "baseid" = ?, "servid" = ?, "type" = ?,
								"code" = ?, "name" = ?, "mediaurl" = ?, "price" = ?,
								"costs" = ?, "rebate" = ?, "tax" = ?, "taxrate" = ?,
								"taxflag" = ?, "mtime" = ?, "editor" = ?
							WHERE "siteid" = ? AND "id" = ?
						'
					),
					'search' => array(
						'ansi' => '
							SELECT mordbase."id" AS "order.base.service.id", mordbase."baseid" AS "order.base.service.baseid",
								mordbase."siteid" AS "order.base.service.siteid", mordbase."servid" AS "order.base.service.serviceid",
								mordbase."type" AS "order.base.service.type", mordbase."code" AS "order.base.service.code",
								mordbase."name" AS "order.base.service.name", mordbase."mediaurl" AS "order.base.service.mediaurl",
								mordbase."price" AS "order.base.service.price", mordbase."costs" AS "order.base.service.costs",
								mordbase."rebate" AS "order.base.service.rebate", mordbase."tax" AS "order.base.service.taxvalue",
								mordbase."taxrate" AS "order.base.service.taxrate", mordbase."taxflag" AS "order.base.service.taxflag",
								mordbase."mtime" AS "order.base.service.mtime", mordbase."editor" AS "order.base.service.editor",
								mordbase."ctime" AS "order.base.service.ctime"
							FROM "mshop_order_base_service" AS mordbase
							:joins
							WHERE :cond
							GROUP BY mordbase."id", mordbase."baseid", mordbase."siteid", mordbase."servid",
								mordbase."type", mordbase."code", mordbase."name", mordbase."mediaurl",
								mordbase."price", mordbase."costs", mordbase."rebate", mordbase."tax",
								mordbase."taxrate", mordbase."taxflag", mordbase."mtime", mordbase."editor",
								mordbase."ctime" /*-columns*/ , :columns /*columns-*/
							/*-orderby*/ ORDER BY :order /*orderby-*/
							LIMIT :size OFFSET :start
						'
					),
					'count' => array(
						'ansi' => '
							SELECT COUNT( DISTINCT mordbase."id" ) AS "count"
							FROM "mshop_order_base_service" AS mordbase
							:joins
							WHERE :cond
						'
					),
					'newid' => array(
						'db2' => 'SELECT IDENTITY_VAL_LOCAL()',
						'mysql' => 'SELECT LAST_INSERT_ID()',
						'oracle' => 'SELECT mshop_order_base_service_seq.CURRVAL FROM DUAL',
						'pgsql' => 'SELECT lastval()',
						'sqlite' => 'SELECT last_insert_rowid()',
						'sqlsrv' => 'SELECT SCOPE_IDENTITY()',
						'sqlanywhere' => 'SELECT @@IDENTITY',
					),
				),
			),
			'standard' => array(
				'aggregate' => array(
					'ansi' => '
						SELECT "key", COUNT("val") AS "count"
						FROM (
							SELECT :key AS "key", :val AS "val"
							FROM "mshop_order_base" AS mordba
							:joins
							WHERE :cond
							/*-orderby*/ ORDER BY :order /*orderby-*/
							LIMIT :size OFFSET :start
						) AS list
						GROUP BY "key"
					'
				),
				'aggregateavg' => array(
					'ansi' => '
						SELECT "key", AVG("val") AS "count"
						FROM (
							SELECT :key AS "key", :val AS "val"
							FROM "mshop_order_base" AS mordba
							:joins
							WHERE :cond
							/*-orderby*/ ORDER BY :order /*orderby-*/
							LIMIT :size OFFSET :start
						) AS list
						GROUP BY "key"
					'
				),
				'aggregatesum' => array(
					'ansi' => '
						SELECT "key", SUM("val") AS "count"
						FROM (
							SELECT :key AS "key", :val AS "val"
							FROM "mshop_order_base" AS mordba
							:joins
							WHERE :cond
							/*-orderby*/ ORDER BY :order /*orderby-*/
							LIMIT :size OFFSET :start
						) AS list
						GROUP BY "key"
					'
				),
				'delete' => array(
					'ansi' => '
						DELETE FROM "mshop_order_base"
						WHERE :cond AND siteid = ?
					'
				),
				'insert' => array(
					'ansi' => '
						INSERT INTO "mshop_order_base" (
							"customerid", "sitecode", "langid", "currencyid",
							"price", "costs", "rebate", "tax", "taxflag", "comment",
							"status", "mtime", "editor", "siteid", "ctime", "crmid"
						) VALUES (
							?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
						)
					'
				),
				'update' => array(
					'ansi' => '
						UPDATE "mshop_order_base"
						SET "customerid" = ?, "sitecode" = ?, "langid" = ?, "currencyid" = ?,
							"price" = ?, "costs" = ?, "rebate" = ?, "tax" = ?, "taxflag" = ?,
							"comment" = ?, "status" = ?, "mtime" = ?, "editor" = ?, "crmid" = ?
						WHERE "siteid" = ? AND "id" = ?
					'
				),
				'search' => array(
					'ansi' => '
						SELECT mordba."id" AS "order.base.id", mordba."siteid" AS "order.base.siteid",
							mordba."sitecode" AS "order.base.sitecode", mordba."customerid" AS "order.base.customerid",
							mordba."langid" AS "order.base.languageid", mordba."currencyid" AS "order.base.currencyid",
							mordba."price" AS "order.base.price", mordba."costs" AS "order.base.costs",
							mordba."rebate" AS "order.base.rebate", mordba."tax" AS "order.base.taxvalue",
							mordba."taxflag" AS "order.base.taxflag", mordba."comment" AS "order.base.comment",
							mordba."status" AS "order.base.status", mordba."mtime" AS "order.base.mtime",
							mordba."editor" AS "order.base.editor", mordba."ctime" AS "order.base.ctime",
							mordba."crmid" AS "order.base.crmid"
						FROM "mshop_order_base" AS mordba
						:joins
						WHERE :cond
						GROUP BY mordba."id", mordba."siteid", mordba."sitecode", mordba."customerid",
							mordba."langid", mordba."currencyid", mordba."price", mordba."costs",
							mordba."rebate", mordba."tax", mordba."taxflag", mordba."comment", mordba."status",
							mordba."mtime", mordba."editor", mordba."ctime", mordba."crmid" /*-columns*/ , :columns /*columns-*/
						/*-orderby*/ ORDER BY :order /*orderby-*/
						LIMIT :size OFFSET :start
					'
				),
				'count' => array(
					'ansi' => '
						SELECT COUNT( DISTINCT mordba."id" ) AS "count"
						FROM "mshop_order_base" AS mordba
						:joins
						WHERE :cond
					'
				),
				'newid' => array(
					'db2' => 'SELECT IDENTITY_VAL_LOCAL()',
					'mysql' => 'SELECT LAST_INSERT_ID()',
					'oracle' => 'SELECT mshop_order_base_seq.CURRVAL FROM DUAL',
					'pgsql' => 'SELECT lastval()',
					'sqlite' => 'SELECT last_insert_rowid()',
					'sqlsrv' => 'SELECT SCOPE_IDENTITY()',
					'sqlanywhere' => 'SELECT @@IDENTITY',
				),
			),
		),
	),
),
);

But when i go to the backend module the message appears:
Call to undefined method Aimeos\MShop\Order\Item\Base\Standard::getCrmid()

Re: Extend Order and add a new Field to JQadm

Posted: 21 Dec 2017, 21:39
by aimeos
There are several problems in your code. For the item they are:
- You need to pass the required arguments to the parent constructor
- fromArray() and toArray() must only care about it's own properties

To create items of your new class, you need to overwrite the createItemBase() method of the manager you are extending from can instantiate your class.

Re: Extend Order and add a new Field to JQadm

Posted: 22 Dec 2017, 07:19
by mantik
is there a working example?
in the documentaion there are just what you must do but not how.

for exmaple the constructor of my parents object looks like this:

Code: Select all

	/**
	 * Initializes the shopping cart.
	 *
	 * @param \Aimeos\MShop\Price\Item\Iface $price Default price of the basket (usually 0.00)
	 * @param \Aimeos\MShop\Locale\Item\Iface $locale Locale item containing the site, language and currency
	 * @param array $values Associative list of key/value pairs containing, e.g. the order or user ID
	 * @param array $products List of ordered products implementing \Aimeos\MShop\Order\Item\Base\Product\Iface
	 * @param array $addresses List of order addresses implementing \Aimeos\MShop\Order\Item\Base\Address\Iface
	 * @param array $services List of order services implementing \Aimeos\MShop\Order\Item\Base\Service\Iface
	 * @param array $coupons Associative list of coupon codes as keys and ordered products implementing \Aimeos\MShop\Order\Item\Base\Product\Iface as values
	 */
	public function __construct( \Aimeos\MShop\Price\Item\Iface $price, \Aimeos\MShop\Locale\Item\Iface $locale,
		array $values = [], array $products = [], array $addresses = [],
		array $services = [], array $coupons = [] )
	{
		parent::__construct( $price, $locale, $values, $products, $addresses, $services, $coupons );

		$this->price = $price;
		$this->locale = $locale;
		$this->values = $values;
	}

so how must my constructor looks like? also formArray and toArray too...
also if i take your example of getSearchAttributes i've here a message: Argument 1 passed to Aimeos\MW\Criteria\Attribute\Standard::__construct() must be of the type array, object given,...

createItemBase i dont have use before because i think i just need it later (on Update of Order - not on Creating the order) but thats works other then i think so i add it again.
but also here is just an empty array as parameter... what must i here do?

Re: Extend Order and add a new Field to JQadm

Posted: 25 Dec 2017, 14:08
by aimeos
The TYPO3 customer manager implementation does the same: Extend from the Standard class and uses its own item implmentation. It works the same for the order domain.
https://github.com/aimeos/ai-typo3/tree ... p/Customer

To see how your item should be implemented, you can have a look into the TYPO3 item class:
https://github.com/aimeos/ai-typo3/blob ... /Typo3.php

These are the parameters expected by the standard order item implementation:
https://github.com/aimeos/aimeos-core/b ... rd.php#L40

Re: Extend Order and add a new Field to JQadm

Posted: 01 Jan 2018, 15:48
by mantik
...It dosent works... whatever i do.
Call to undefined method Aimeos\MShop\Order\Item\Base\Standard::getCrmid()

Re: Extend Order and add a new Field to JQadm

Posted: 02 Jan 2018, 00:08
by aimeos
Did you overwrite the createItemBase() method in your manager and configured the name of your implemented manager so the factory creates this one instead of the standard one?