Newer
Older

Patrick Müller
committed
use QUI\ERP\Products\Field\Field as ProductField;
use QUI\ERP\Products\Handler\Categories as ProductCategories;
use QUI\ERP\Products\Handler\Fields as ProductFields;
use QUI\ERP\Products\Handler\Products as ProductsHandler;
use QUI\ERP\Products\Handler\Search as ProductSearchHandler;
use QUI\ERP\Products\Product\Product;
use QUI\Memberships\Handler as MembershipsHandler;
use QUI\Memberships\Products\MembershipField;
use QUI\Memberships\Users\Handler as MembershipUsersHandler;
use QUI\Package\Package;
/**
* Class Events
*
* Basic events for quiqqer/memberships
*/
class Events
{
/**
* quiqqer/quiqqer: onPackageSetup
*
* @param Package $Package
* @return void
*/
public static function onPackageSetup(Package $Package)
{
if ($Package->getName() !== 'quiqqer/memberships') {
return;
}
$packages = Utils::getInstalledMembershipPackages();

Patrick Müller
committed
try {
foreach ($packages as $package) {
switch ($package) {
case 'quiqqer/products':
self::createProductFields();
self::createProductCategory();

Patrick Müller
committed
case 'quiqqer/contracts':
// @todo setup routine for quiqqer/contracts

Patrick Müller
committed
}

Patrick Müller
committed
} catch (\Exception $Exception) {
QUI\System\Log::writeException($Exception);
/**
* quiqqer/products: onQuiqqerProductsProductDelete
*
* @param Product $Product
* @return void
*/
public static function onQuiqqerProductsProductDelete(Product $Product)
{

Patrick Müller
committed
$membershipFieldId = Handler::getProductMembershipField()->getId();
if (!$membershipFieldId) {
return;
}
// check if Product is assigned to a Membership

Patrick Müller
committed
$membershipId = $Product->getFieldValue($membershipFieldId);
if (empty($membershipId)) {
return;
}
// delete Product ID from MembershipUsers
try {
$Membership = MembershipsHandler::getInstance()->getChild($membershipId);
$MembershipUsers = MembershipUsersHandler::getInstance();

Patrick Müller
committed
$membershipUserIds = $Membership->searchUsers([
'productId' => $Product->getId()

Patrick Müller
committed
]);
foreach ($membershipUserIds as $membershipUserId) {
$MembershipUser = $MembershipUsers->getChild($membershipUserId);
$MembershipUser->setAttribute('productId', null);
$MembershipUser->update();
}
} catch (\Exception $Exception) {
QUI\System\Log::addError(
self::class . ' :: onQuiqqerProductsProductDelete -> '
. $Exception->getMessage()
/**
* quiqqer/quiqqer: onUserSave
*
* @param QUI\Users\User $User
* @return void
*/
public static function onUserSave(QUI\Users\User $User)
{
$DefaultMembership = MembershipsHandler::getDefaultMembership();
if ($DefaultMembership === false) {
return;
}
try {
$DefaultMembership->getMembershipUser($User->getId());
} catch (\Exception $Exception) {
if ($Exception->getCode() !== 404) {
return;
}
$DefaultMembership->addUser($User);
}
}
/**
* quiqqer/quiqqer: onUserDelete
*
* Delete user from alle memberships
*
* @param QUI\Users\User $User
* @return void
*/
public static function onUserDelete(QUI\Users\User $User): void
{
$membershipUsers = QUI\Memberships\Users\Handler::getInstance()->getMembershipUsersByUserId($User->getId());
foreach ($membershipUsers as $MembershipUser) {
$MembershipUser->delete();
}
}

Patrick Müller
committed
* Create necessary membership product fields and save their IDs to the config

Patrick Müller
committed
* @throws \QUI\Exception
protected static function createProductFields()

Patrick Müller
committed
$Conf = QUI::getPackage('quiqqer/memberships')->getConfig();

Patrick Müller
committed
// Membership field (create new one is not configured)
$MembershipField = Handler::getProductMembershipField();
if ($MembershipField === false) {
$translations = [
'de' => '',
'en' => ''
];
foreach ($translations as $l => $t) {
$L->setCurrent($l);
$translations[$l] = $L->get(
'quiqqer/memberships',
'products.field.membership'
);
}

Patrick Müller
committed
try {
$MembershipField = ProductFields::createField([
'type' => MembershipField::TYPE,
'titles' => $translations,

Patrick Müller
committed
'workingtitles' => $translations
]);
$MembershipField->setAttribute('search_type', ProductSearchHandler::SEARCHTYPE_TEXT);
$MembershipField->save();
// add field id to config
$Conf->set('products', 'membershipFieldId', $MembershipField->getId());
$Conf->save();
} catch (\Exception $Exception) {
QUI\System\Log::addError(self::class . ' :: createProductFields');

Patrick Müller
committed
QUI\System\Log::writeException($Exception);
}
} elseif (!($MembershipField instanceof MembershipField)) {
QUI\System\Log::addError(
'quiqqer/memberships :: Cannot create memership field because product field with ID ' .
$MembershipField->getId() . ' is not a membership field.'
);

Patrick Müller
committed
// Membership flag field (create new one is not configured)
$MembershipFlagField = Handler::getProductMembershipFlagField();
if ($MembershipFlagField === false) {
$translations = [
'de' => '',
'en' => ''
];
foreach ($translations as $l => $t) {
$L->setCurrent($l);
$translations[$l] = $L->get(
'quiqqer/memberships',
'products.field.membershipflag'
);
}

Patrick Müller
committed
try {
$MembershipFlagField = ProductFields::createField([
'type' => ProductFields::TYPE_BOOL,
'titles' => $translations,

Patrick Müller
committed
'workingtitles' => $translations
]);
$MembershipFlagField->setAttribute('search_type', ProductSearchHandler::SEARCHTYPE_BOOL);
$MembershipFlagField->save();
// add Flag field to backend search
$BackendSearch = ProductSearchHandler::getBackendSearch();
$searchFields = $BackendSearch->getSearchFields();

Patrick Müller
committed
$searchFields[$MembershipFlagField->getId()] = true;
$BackendSearch->setSearchFields($searchFields);
// add field id to config
$Conf->set('products', 'membershipFlagFieldId', $MembershipFlagField->getId());
$Conf->save();
} catch (\Exception $Exception) {
QUI\System\Log::addError(self::class . ' :: createProductFields');

Patrick Müller
committed
QUI\System\Log::writeException($Exception);
}
* quiqqer/order: onQuiqqerOrderSuccessful
* Add user to a membership if he ordered a product that contains one
*
* @param QUI\ERP\Order\Order|QUI\ERP\Order\OrderInProcess $Order
public static function onQuiqqerOrderSuccessful($Order)
$MembershipField = Handler::getProductMembershipField();
if ($MembershipField === false) {
QUI\System\Log::addError(
self::class . ' :: onQuiqqerOrderSuccessful -> Could not parse membership'
. ' from Order #' . $Order->getPrefixedId() . ' because no membership field'
. ' is configured. Please execute a system setup.'
);
return;
}
$membershipFieldId = $MembershipField->getId();
$Memberships = Handler::getInstance();
$Users = QUI::getUsers();
try {
$User = $Users->get($Order->getCustomer()->getId());
} catch (\Exception $Exception) {
QUI\System\Log::writeDebugException($Exception);
QUI\System\Log::addError(
self::class . ' :: onQuiqqerOrderSuccessful -> Could not load user #' . $Order->getCustomer()->getId()
. ' from Order #' . $Order->getPrefixedId() . '. Cannot add user to membership'
return;
}
// do not add guests to a membership!
// $SessionUser = QUI::getUserBySession();
//
// if (!$SessionUser->isSU()
// && !$Users->isSystemUser($SessionUser)
// && !$Users->isAuth($User)) {
// return;
// }
$SystemUser = QUI::getUsers()->getSystemUser();
/** @var QUI\ERP\Accounting\Article $Article */
foreach ($Order->getArticles()->getArticles() as $Article) {
$Product = ProductsHandler::getProduct($Article->getId());
$ProductMembershipField = $Product->getField($membershipFieldId);
$membershipId = $ProductMembershipField->getValue();
if (empty($membershipId)) {
continue;
}
$Membership = $Memberships->getChild($membershipId);
$Membership->setEditUser($SystemUser);
$MembershipUser = $Membership->addUser($User);
$MembershipUser->setEditUser($SystemUser);
$MembershipUser->addHistoryEntry(
MembershipUsersHandler::HISTORY_TYPE_MISC,
$MembershipUser->update();

Patrick Müller
committed
} catch (\QUI\ERP\Products\Product\Exception $Exception) {
// nothing, this can happen if the $Product does not have a membership field assigned
QUI\System\Log::writeDebugException($Exception);
} catch (\Exception $Exception) {
QUI\System\Log::writeException($Exception);
}
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
/**
* quiqqer/contracts: onQuiqqerContractsExtend
*
* Automatically extend all MembershipUsers associated with the contract that is extended
*
* @param Contract $Contract
* @param \DateTime $EndDate
* @param \DateTime $NewEndDate
*/
public static function onQuiqqerContractsExtend(Contract $Contract, \DateTime $EndDate, \DateTime $NewEndDate)
{
try {
$Conf = QUI::getPackage('quiqqer/memberships')->getConfig();
if (!$Conf->get('membershipusers', 'linkWithContracts')) {
return;
}
} catch (\Exception $Exception) {
QUI\System\Log::writeException($Exception);
return;
}
$MembershipUsers = MembershipUsersHandler::getInstance();
try {
$result = QUI::getDataBase()->fetch([
'select' => ['id'],
'from' => $MembershipUsers->getDataBaseTableName(),
'where' => [
'contractId' => $Contract->getCleanId()
]
]);
} catch (\Exception $Exception) {
QUI\System\Log::writeException($Exception);
return;
}
foreach ($result as $row) {
try {
/** @var QUI\Memberships\Users\MembershipUser $MembershipUser */
$MembershipUser = $MembershipUsers->getChild($row['id']);

Patrick Müller
committed
// Calculate new cylce begin date
$NextBeginDate = clone $EndDate;
$NextBeginDate->add(\date_interval_create_from_date_string('1 day'));
$NextBeginDate->setTime(0, 0, 0);
$MembershipUser->extend(true, $NextBeginDate, $NewEndDate);
} catch (\Exception $Exception) {
QUI\System\Log::writeException($Exception);
}
}
}

Patrick Müller
committed
/**
* quiqqer/contracts: onQuiqqerContractsCreateFromOrder

Patrick Müller
committed
*
* If a contract is created from an order, check if the Order also contains a Membership product

Patrick Müller
committed
*
* @param Contract $Contract
* @param QUI\ERP\Order\OrderInProcess $Order

Patrick Müller
committed
* @return void
*/
public static function onQuiqqerContractsCreateFromOrder(Contract $Contract, $Order)

Patrick Müller
committed
{
try {
$Conf = QUI::getPackage('quiqqer/memberships')->getConfig();
if (!$Conf->get('membershipusers', 'linkWithContracts')) {
return;
}
} catch (\Exception $Exception) {
QUI\System\Log::writeException($Exception);
return;
}

Patrick Müller
committed
$MembershipField = Handler::getProductMembershipField();
if ($MembershipField === false) {
QUI\System\Log::addError(
self::class . ' :: onQuiqqerContractsCreateFromOrder -> Could not parse membership'
. ' from Order #' . $Order->getPrefixedId() . ' because no membership field'
. ' is configured. Please execute a system setup.'

Patrick Müller
committed
);
return;
}
$membershipFieldId = $MembershipField->getId();
$Memberships = Handler::getInstance();
$Customer = $Order->getCustomer();

Patrick Müller
committed
// Look for the article/product that contains a membership and add
/** @var QUI\ERP\Accounting\Article $Article */
foreach ($Order->getArticles()->getArticles() as $Article) {
try {
$Product = ProductsHandler::getProduct($Article->getId());

Patrick Müller
committed
$ProductMembershipField = $Product->getField($membershipFieldId);
$Membership = $Memberships->getChild($ProductMembershipField->getValue());

Patrick Müller
committed
$MembershipUser = $Membership->getMembershipUser($Customer->getId());
$MembershipUser->setEditUser(QUI::getUsers()->getSystemUser());

Patrick Müller
committed
$MembershipUser->linkToContract($Contract->getCleanId());

Patrick Müller
committed
break;
} catch (\QUI\ERP\Products\Product\Exception $Exception) {
QUI\System\Log::writeDebugException($Exception);

Patrick Müller
committed
// nothing, this can happen if the $Product does not have a membership field assigned
} catch (\Exception $Exception) {
QUI\System\Log::writeException($Exception);
}
}
}
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
// /**
// * quiqqer/contracts: onQuiqqerContractsCancel
// *
// * Cancel a membership if a contract is cancelled
// *
// * @param Contract $Contract
// * @return void
// * @throws \QUI\Exception
// * @throws \Exception
// */
// public static function onQuiqqerContractsCancel(Contract $Contract)
// {
// $MembershipUsers = MembershipUsersHandler::getInstance();
//
// $result = QUI::getDataBase()->fetch([
// 'select' => ['id'],
// 'from' => $MembershipUsers->getDataBaseTableName(),
// 'where' => [
// 'contractId' => $Contract->getCleanId()
// ]
// ]);
//
// if (empty($result)) {
// return;
// }
//
// /** @var QUI\Memberships\Users\MembershipUser $MembershipUser */
// $MembershipUser = $MembershipUsers->getChild($result[0]['id']);
//
// $MembershipUser->setAttributes([
// 'cancelStatus' => MembershipUsersHandler::CANCEL_STATUS_CANCELLED,
// 'cancelEndDate' => $Contract->getTerminationDate()->format('Y-m-d 23:59:59')
// ]);
//
//
// $MembershipUser->sendConfirmCancelMail();
// }
* quiqqer/contracts: onQuiqqerContractsDelete
*
* Delete contract from all MembershipUsers
*
* @param Contract $Contract
* @throws QUI\Database\Exception
*/
public static function onQuiqqerContractsDelete(Contract $Contract)
{
$MembershipUsers = MembershipUsersHandler::getInstance();
$result = QUI::getDataBase()->fetch([
'select' => ['id'],
'from' => $MembershipUsers->getDataBaseTableName(),
'where' => [
'contractId' => $Contract->getCleanId()
]
]);
foreach ($result as $row) {
QUI::getDataBase()->update(
$MembershipUsers->getDataBaseTableName(),
[
'contractId' => null
],
[
'id' => $row['id']
]
);
}
}
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
/**
* quiqqer/contracts: onQuiqqerContractsCancel
*
* Cancel MembershipUser of associated contract
*
* @param Contract $Contract
* @throws QUI\Database\Exception
*/
public static function onQuiqqerContractsCancel(Contract $Contract)
{
try {
$Conf = QUI::getPackage('quiqqer/memberships')->getConfig();
if (!$Conf->get('membershipusers', 'linkWithContracts')) {
return;
}
} catch (\Exception $Exception) {
QUI\System\Log::writeException($Exception);
return;
}
$MembershipUser = MembershipUsersHandler::getInstance()->getMembershipUserByContractId($Contract->getCleanId());
if (!$MembershipUser) {
return;
}
try {
$MembershipUser->autoCancel();
} catch (\Exception $Exception) {
QUI\System\Log::writeException($Exception);
}
}
/**
* quiqqer/products: onQuiqqerProductsFieldDeleteBefore
*
* @param ProductField $Field
* @throws Exception
*/
public static function onQuiqqerProductsFieldDeleteBefore(ProductField $Field)

Patrick Müller
committed
{
$MembershipField = Handler::getProductMembershipField();
if ($MembershipField !== false && $MembershipField->getId() === $Field->getId()) {
throw new Exception([
'quiqqer/memberships',
'exception.Events.onQuiqqerProductsFieldDelete.cannot_delete_field'
]);
}
$MembershipFlagField = Handler::getProductMembershipFlagField();
if ($MembershipFlagField !== false && $MembershipFlagField->getId() === $Field->getId()) {
throw new Exception([
'quiqqer/memberships',
'exception.Events.onQuiqqerProductsFieldDelete.cannot_delete_field'
]);
}

Patrick Müller
committed
}
/**
* quiqqer/verification: onQuiqqerVerificationDeleteUnverified
*
* Send message to a membership user if he has not verified a cancellation.
*
* @param int $membershipUserId
* @return void
*/
public static function onQuiqqerVerificationDeleteUnverified($membershipUserId)
{
try {
/** @var QUI\Memberships\Users\MembershipUser $MembershipUser */
$MembershipUser = MembershipUsersHandler::getInstance()->getChild($membershipUserId);
} catch (\Exception $Exception) {
QUI\System\Log::writeDebugException($Exception);
return;
}
if (
(int)$MembershipUser->getAttribute(
'cancelStatus'
) !== MembershipUsersHandler::CANCEL_STATUS_CANCEL_CONFIRM_PENDING
) {
return;
}
$MembershipUser->addHistoryEntry(
QUI\Memberships\Users\Handler::HISTORY_TYPE_MISC,
QUI::getLocale()->get('quiqqer/memberships', 'history.misc.cancel_abort_unverified')
);
$MembershipUser->confirmAbortCancel();
}
/**
* Create a product category for memberships
*
* @return void
*/
protected static function createProductCategory()
{
$Category = MembershipsHandler::getProductCategory();
// do not create a product category if a default category has already been set
if ($Category !== false) {
return;
}
try {
$Category = ProductCategories::createCategory();
} catch (\Exception $Exception) {
QUI\System\Log::addError(self::class . ' :: createProductCategory()');
QUI\System\Log::writeException($Exception);
return;
}

Patrick Müller
committed
$titles = [

Patrick Müller
committed
];

Patrick Müller
committed
$descriptions = [

Patrick Müller
committed
];
$L = new QUI\Locale();
foreach ($titles as $l => $t) {
$L->setCurrent($l);
$t = $L->get('quiqqer/memberships', 'products.category.title');
$d = $L->get('quiqqer/memberships', 'products.category.description');
$titles[$l] = $t;
$titles[$l . '_edit'] = $t;
$descriptions[$l] = $d;
$descriptions[$l . '_edit'] = $d;
}
// change title and description
QUI\Translator::edit(
'quiqqer/products',
'quiqqer/products',
array_merge(
$titles,

Patrick Müller
committed
[

Patrick Müller
committed
]
)
);
QUI\Translator::edit(
'quiqqer/products',
'products.category.' . $catId . '.description',
'quiqqer/products',
array_merge(
$descriptions,

Patrick Müller
committed
[

Patrick Müller
committed
]

Patrick Müller
committed
// assign Membership Field to category
$MembershipField = MembershipsHandler::getProductMembershipField();
if ($MembershipField !== false) {
$Category->addField($MembershipField);
}
$MembershipFlagField = MembershipsHandler::getProductMembershipFlagField();
if ($MembershipFlagField !== false) {
$Category->addField($MembershipFlagField);
}

Patrick Müller
committed
$Category->save();
// set new category as default product category for memberships
$Conf = QUI::getPackage('quiqqer/memberships')->getConfig();
$Conf->set('products', 'categoryId', $catId);
$Conf->save();