<?php

/**
 * @am_plugin_api 6.0
 */
class Am_Plugin_GiftCard extends Am_Plugin
{
    const PLUGIN_STATUS = self::STATUS_BETA;
    const PLUGIN_REVISION = '6.3.43';
    const PERM = 'gift-card';

    protected $_configPrefix = 'misc.';

    static function getDbXml()
    {
        return <<<CUT
<schema version="4.0.0">
    <table name="gift_card">
        <field name="gift_card_id" type="int" notnull="1" extra="auto_increment"/>

        <field name="dattm" type="datetime" notnull="1" />
        <field name="invoice_id" type="int" notnull="0"/>
        <field name="purchase_user_id" type="int"  notnull="0"/>
        <field name="redeem_user_id" type="int" notnull="0"/>
        <field name="amount" type="decimal" len="12,2" notnull="1"/>
        <field name="balance" type="decimal" len="12,2" notnull="1"/>
        <field name="currency" type="char" len="3" notnull="1" />

        <field name="code" type="varchar" len="10"/>
        <field name="status" type="enum" len="'pending','sent','partially_used', 'used', 'expired'"/>

        <field name="email" type="varchar" len="255"/>
        <field name="name" type="varchar" len="255"/>
        <field name="comment" type="varchar" len="255"/>

        <field name="ondate" type="date"/>
        <field name="expire" type="date"/>

        <index name="PRIMARY" unique="1">
            <field name="gift_card_id" />
        </index>
        <index name="code" unique="1">
            <field name="code" />
        </index>
    </table>
    <table name="invoice">
        <field name="gift_card_id" type="int"/>
    </table>
</schema>
CUT;
    }

    static function getEtXml()
    {
        return <<<CUT
<table_data name="email_template">
    <row type="email_template">
        <field name="name">misc.gift-card.email_redeem</field>
        <field name="lang">en</field>
        <field name="format">text</field>
        <field name="subject">%site_title%: Gift Card (%card.amount%%card.currency%) from %user.name_f% %user.name_l%</field>
        <field name="txt"><![CDATA[
Hello %card.name%,

%user.name% sent you a gift card for %card.amount%%card.currency% at site:
%root_url%/signup

Card Code: %card.code%
Expire: %card.expire|date%

You can share balance of this card among multiple purchase.
Enter card code to field 'Gift Code' on signup form
to apply it to your order.

Message from %user.name_f% %user.name_l%
%card.comment%

--
Best Regards,
%site_title%
%root_url%
        ]]></field>
    </row>
        <row type="email_template">
        <field name="name">misc.gift-card.admin_email_redeem</field>
        <field name="lang">en</field>
        <field name="format">text</field>
        <field name="subject">%site_title%: Gift Card (%card.amount%%card.currency%)</field>
        <field name="txt"><![CDATA[
Hello %card.name%,

Gift card for %card.amount%%card.currency% at site:
%root_url%/signup

Card Code: %card.code%
Expire: %card.expire|date%

You can share balance of this card among multiple purchase.
Enter card code to field 'Gift Code' on signup form
to apply it to your order.

%card.comment%

--
Best Regards,
%site_title%
%root_url%
        ]]></field>
    </row>
    <row type="email_template">
        <field name="name">misc.gift-card.email_purchase</field>
        <field name="email_template_layout_id">1</field>
        <field name="lang">en</field>
        <field name="format">text</field>
        <field name="subject">%site_title%: Gift Card Information</field>
        <field name="txt">

** You sent a gift card to %card.email% **

You ordered a gift card for %card.amount%%card.currency%.
It will be sent to %card.name% on %card.ondate|date%.

Card Code: %card.code%

        </field>
    </row>
</table_data>
CUT;
    }

    function onSetupEmailTemplateTypes(Am_Event $e)
    {
        $e->addReturn([
            'id' => 'misc.gift-card.email_redeem',
            'title' => 'Gift Card to Recipient',
            'mailPeriodic' => Am_Mail::USER_REQUESTED,
            'vars' => [
                'user',
                'card.email' => 'Gift Recipient E-Mail',
                'card.name' => 'Gift Recipient Name',
                'card.comment' => 'Gift Messages',
                'card.code' => 'Gift Card Code',
                'card.amount' => 'Gift Card Amount',
                'card.currency' => 'Gift Card Currency',
            ],
        ], 'misc.gift-card.email_redeem');

        $e->addReturn([
            'id' => 'misc.gift-card.admin_email_redeem',
            'title' => 'Gift Card to Recipient',
            'mailPeriodic' => Am_Mail::USER_REQUESTED,
            'vars' => [
                'card.email' => 'Gift Recipient E-Mail',
                'card.name' => 'Gift Recipient Name',
                'card.comment' => 'Gift Messages',
                'card.code' => 'Gift Card Code',
                'card.amount' => 'Gift Card Amount',
                'card.currency' => 'Gift Card Currency',
            ],
        ], 'misc.gift-card.admin_email_redeem');

        $e->addReturn([
            'id' => 'misc.gift-card.email_purchase',
            'title' => 'Gift Card to Purchaser',
            'mailPeriodic' => Am_Mail::USER_REQUESTED,
            'vars' => [
                'user',
                'card.email' => 'Gift Recipient E-Mail',
                'card.name' => 'Gift Recipient Name',
                'card.comment' => 'Gift Messages',
                'card.code' => 'Gift Card Code',
                'card.amount' => 'Gift Card Amount',
                'card.currency' => 'Gift Card Currency',
            ],
        ], 'misc.gift-card.email_purchase');
    }

    public function _initSetupForm(Am_Form_Setup $form)
    {
        $form->setTitle('Gift Card');

        $form->addPeriod('expire')
            ->setLabel(___("Gift Card Period\n".
                "gift card should be used within this period after purchase"));

        $form->addElement('email_link', 'email_redeem')
            ->setLabel(___('Send Gift Card to Recipient (User Purchased)'));
        $form->addElement('email_link', 'admin_email_redeem')
            ->setLabel(___('Send Gift Card to Recipient (Admin Added)'));

        $form->addElement('email_checkbox', 'email_purchase')
            ->setLabel(___('Send Gift Card to Purchaser'));

        $form->setDefault('expire', '1y');
        $form->addScript()
            ->setScript(<<<CUT
jQuery(function(){
    jQuery('select[name*=expire]').change(function () {
        var count = $(this).closest('div').find('input[type=text]');
        var val = $(this).val();
        val == "lifetime" ? count.hide().val('2037-12-31') : count.show();
        if (val != 'lifetime') // if reverting from lifetime, reset "count"
        {
            if (count.val() == '2037-12-31')
                count.val('');
        }
    }).change()
})
CUT
        );

        $form->addSelect('block_target')
            ->setLabel('Widget Position')
            ->loadOptions([
                'member/main/right' => 'Dashboard (Right Column)',
                'member/main/left' => 'Dashboard (Left Column)',
            ]);
    }

    public function onAdminMenu(Am_Event $e)
    {
        $e->getMenu()->addPage([
            'id' => 'gift-card',
            'module' => 'default',
            'controller' => 'admin-gift-card',
            'action' => 'index',
            'label' => ___('Gift Card'),
            'resource' => self::PERM
        ]);
    }

    function onGetPermissionsList(Am_Event $e)
    {
        $e->addReturn(___('Gift Card'), self::PERM);
    }

    function onInvoiceStarted(Am_Event $e)
    {
        $invoice = $e->getInvoice();

        if ($invoice->data()->get('_gift_card_amount')) {
            $card = $this->issueCard($invoice);
            if ($card->ondate <= sqlDate('now')) {
                $this->sendCard($card);
            }

            $user = $invoice->getUser();
            if ($this->getConfig('email_purchase') && ($et = Am_Mail_Template::load('misc.gift-card.email_purchase', $user->lang))) {

                $et->setUser($user);
                $et->setCard($card);
                $et->send($user);
            }
        }

        $credit_used = $invoice->data()->get("_gift_card_balance_used");
        if ($credit_used){
            $card = $this->getDi()->giftCardTable->findFirstByCode($invoice->data()->get('_gift_card'));

            $card->balance -= $credit_used;
            $card->status = $card->balance > 0 ? GiftCard::S_PARTIALLY_USED : GiftCard::S_USED;
            $card->redeem_user_id = $invoice->user_id;
            $card->save();

            $invoice->updateQuick('gift_card_id', $card->pk());
        }
    }

    function onInvoiceCalculate(Am_Event $e)
    {
        //avoid endless recursion
        if (@$GLOBALS[$this->getId()]) return;
        $GLOBALS[$this->getId()] = true;

        /* @var $invoice Invoice */
        $invoice = $e->getInvoice();
        if ($code = $invoice->data()->get('_gift_card')) {
            $card = $this->getDi()->giftCardTable->findFirstByCode($code);

            $balance = $card->balance;
            if ($balance) {
                $invoice->setDiscount(0,0);
                $invoice->calculate();
                $invoice->setDiscount(
                    $card_balance_used = ($balance > $invoice->first_total ? $invoice->first_total : $balance));
                $invoice->data()->set('_gift_card_balance_used', $card_balance_used);
                $invoice->calculate();
            }
        }

        $GLOBALS[$this->getId()] = false;
    }

    public function onDaily(Am_Event $e)
    {
        $cards = $this->getDi()->giftCardTable->findBy([
                ['ondate', '<=', $e->getDate()],
                'status' => GiftCard::S_PENDING
        ]);

        foreach ($cards as $card) {
            $this->sendCard($card);
        }

        $cards = $this->getDi()->giftCardTable->findBy([
                ['status', '<>', GiftCard::S_EXPIRED],
                ['balance', '>', 0],
                ['expire', '<', $e->getDate()]
        ]);

        foreach ($cards as $card) {
            $card->updateQuick('status', GiftCard::S_EXPIRED);
        }
    }

    function onInitFinished(Am_Event $e)
    {
        if (($u = $e->getDi()->auth->getUser()) &&
            $cards = $e->getDi()->giftCardTable->findBy([
                'redeem_user_id' => $u->pk(),
                'status' => [
                    GiftCard::S_SENT,
                    GiftCard::S_PARTIALLY_USED
                ]
            ])) {

            $e->getDi()->blocks->add(
                $this->getConfig('block_target', 'member/main/right'),
                new Am_Block_Base(___('Gift Card Balance'), $this->getId(), null,
                function (Am_View $v) use ($cards) {
                    $out = [];
                    foreach ($cards as $c) {
                        $out[] = sprintf('<li><strong>%s</strong> &ndash; %s%s</li>',
                            Am_Html::escape($c->code),
                            Am_Html::escape(Am_Currency::render($c->balance, $c->currency)),
                            $c->expire == Am_Period::MAX_SQL_DATE ?
                                '' :
                                '<br /><small>' . ___('valid until %s', amDate($c->expire)) . '</small>'
                            );
                    }
                    return sprintf("<ul class=\"am-widget-list am-list-gift-cards\">\n%s\n</ul>",
                        implode("\n", $out));
                }));
        }
    }

    function isValid($code)
    {
        if (empty($code)) return true;

        $card = $this->getDi()->giftCardTable->findFirstByCode($code);
        $user_id = $this->getDi()->auth->getUserId();
        return $card &&
            $card->expire > sqlDate('now') &&
            $card->balance > 0 &&
            (is_null($card->redeem_user_id) || $card->redeem_user_id == $user_id);
    }

    function sendCard($card)
    {
        if ($card->purchase_user_id) {
            $user = $this->getDi()->userTable->load($card->purchase_user_id);
            $et = Am_Mail_Template::load('misc.gift-card.email_redeem', $user->lang);

            $et->setUser($user);
            $et->setCard($card);
            $et->send($card->email);
        } else {
            $et = Am_Mail_Template::load('misc.gift-card.admin_email_redeem');

            $et->setCard($card);
            $et->send($card->email);
        }

        $card->updateQuick('status', GiftCard::S_SENT);
    }

    function issueCard(Invoice $invoice)
    {
        $card = $this->getDi()->giftCardRecord;

        $card->dattm = sqlTime('now');

        $card->invoice_id = $invoice->pk();
        $card->purchase_user_id = $invoice->user_id;
        $card->status = GiftCard::S_PENDING;

        $card->balance =
        $card->amount = $invoice->data()->get('_gift_card_amount');
        $card->currency = $invoice->currency;

        $card->name = $invoice->data()->get('_gift_card_name');
        $card->email = $invoice->data()->get('_gift_card_email');
        $card->comment = $invoice->data()->get('_gift_card_comment');

        $card->ondate = $invoice->data()->get('_gift_card_later') ?
            $invoice->data()->get('_gift_card_ondate') :
            sqlDate('now');

        $period = new Am_Period($this->getConfig('expire', '1y'));

        $card->expire = $period->addTo(sqlDate('now'));

        do {
            $card->code = strtoupper($this->getDi()->security->randomString(10));
        } while ($this->getDi()->giftCardTable->findFirstByCode($card->code));

        $card->save();

        return $card;
    }
}

/**
 * @extends Am_Table<GiftCard>
 * @method GiftCard|null findFirstByCode($value)
 */
class GiftCardTable extends Am_Table
{
    protected $_table = '?_gift_card';
    protected $_recordClass = 'GiftCard';
    protected $_key = 'gift_card_id';
}

class GiftCard extends Am_Record
{
    const S_PENDING = 'pending';
    const S_SENT = 'sent';
    const S_PARTIALLY_USED = 'partially_used';
    const S_USED = 'used';
    const S_EXPIRED = 'expired';
}

class AdminGiftCardController extends Am_Mvc_Controller_Grid
{
    public function checkAdminPermissions(Admin $admin)
    {
        return $admin->hasPermission(Am_Plugin_GiftCard::PERM);
    }

    public function createGrid()
    {
        $ds = new Am_Query($this->getDi()->giftCardTable, 't');
        $ds->leftJoin('?_invoice', 'i', 't.invoice_id = i.invoice_id')
            ->leftJoin('?_user', 'up', 't.purchase_user_id=up.user_id')
            ->leftJoin('?_user', 'ur', 't.redeem_user_id=ur.user_id')
            ->addField('i.public_id')
            ->addField('up.name_f', 'p_name_f')
            ->addField('up.name_l', 'p_name_l')
            ->addField('up.login', 'p_login')
            ->addField('ur.name_f', 'r_name_f')
            ->addField('ur.name_l', 'r_name_l')
            ->addField('ur.login', 'r_login')
            ->setOrder('dattm', 'DESC');

        $grid = new Am_Grid_Editable('_gc', ___("Gift Card"), $ds, $this->_request, $this->view);
        $grid->setPermissionId(Am_Plugin_GiftCard::PERM);
        $grid->actionsClear();
        $grid->actionAdd(new Am_Grid_Action_Insert());

        $grid->addField(new Am_Grid_Field_Date('dattm', ___('Date/Time')));
        $grid->addField('amount', ___('Amount'))
            ->setGetFunction(function($r, $g, $fn, $fo) {
                return Am_Currency::render($r->$fn, $r->currency);
            });
        $grid->addField('balance', ___('Balance'))
            ->setGetFunction(function($r, $g, $fn, $fo) {
                return Am_Currency::render($r->$fn, $r->currency);
            });
        $grid->addField('_purchase', ___('Purchase'), false)
            ->setRenderFunction([$this, 'renderPurchase']);
        $grid->addField('invoice_id', ___("Invoice"), false)
            ->setRenderFunction([$this, 'renderInvoice']);
        $grid->addField('_redeem', ___('Recipient'), false)
            ->setRenderFunction([$this, 'renderRecipient']);
        $grid->addField('code', ___('Code'));
        $grid->addField(new Am_Grid_Field_Enum('status', ___('Status')))
            ->setTranslations([
                GiftCard::S_PENDING => ___('Pending'),
                GiftCard::S_SENT => ___('Sent'),
                GiftCard::S_PARTIALLY_USED => ___('Partially Used'),
                GiftCard::S_USED => ___('Used'),
                GiftCard::S_EXPIRED => ___('Expired')
            ]);
        $grid->addField(new Am_Grid_Field_Date('ondate', ___('Sending')))->setFormatDate();
        $grid->addField(new Am_Grid_Field_Date('expire', ___('Expire')))->setFormatDate();
        $grid->addField(new Am_Grid_Field_Expandable('comment', ___('Comment'), false))
            ->setPlaceholder(Am_Grid_Field_Expandable::PLACEHOLDER_SELF_TRUNCATE_END);

        $grid->setForm([$this, 'createForm']);
        $grid->addCallback(Am_Grid_Editable::CB_AFTER_INSERT, function(& $v, $card, $grid){
            $card->dattm = sqlTime('now');
            $card->status = GiftCard::S_PENDING;
            $card->balance = $card->amount;
            $card->currency = Am_Currency::getDefault();
            $card->ondate = $v['_later'] ? $card->ondate : sqlDate('now');

            $period = new Am_Period($this->getPlugin()->getConfig('expire', '1y'));

            $card->expire = $period->addTo(sqlDate('now'));

            do {
                $card->code = strtoupper($this->getDi()->security->randomString(10));
            } while ($this->getDi()->giftCardTable->findFirstByCode($card->code));

            $card->save();

            if ($card->ondate <= sqlDate('now')) {
                $this->getPlugin()->sendCard($card);
            }

        });

        $grid->setFilter(new Am_Grid_Filter_Text(___('Search by Card Code'), ['code' => 'LIKE']));

        return $grid;
    }

    function createForm()
    {
        $form = new Am_Form_Admin();

        $form->addText('amount')
            ->setLabel(___('Card Amount'))
            ->addRule('required');
        $form->addText('name')
            ->setLabel(___('Recipient Name'))
            ->addRule('required');
        $form->addText('email')
            ->setLabel(___('Recipient Email'))
            ->addRule('required');

        $form->addTextarea('comment', ['class' => 'am-el-wide'])
            ->setLabel(___("Your Message to Recipient\nincluded to email with Gift Card"));

        $form->addAdvCheckbox('_later', null, ['content' => ___("Send Email with Gift Code at later date")]);
        $form->addDate('ondate')
            ->setLabel(___('Send Date'));

        $form->addScript()->setScript(<<<CUT
jQuery(document).ready(function($){
    $('input[type=checkbox][name=_later]').change(function(){
        $('input[name=ondate]').closest('.am-row').toggle(this.checked);
    }).change();
});
CUT
        );

        return $form;
    }

    function _getAmount(Am_Record $p)
    {
        return Am_Currency::render($p->amount, $p->currency);
    }

    function renderInvoice(Am_Record $rec)
    {
        if ($rec->invoice_id) {
            return $this->renderTd(sprintf(
                '<a href="%s" class="link" target="_top">%s</a>',
                $this->getDi()->url("admin-user-payments/index/user_id/{$rec->purchase_user_id}#invoice-{$rec->invoice_id}"),
                "$rec->invoice_id/$rec->public_id"
            ), false);
        } else {
            return $this->renderTd('&mdash;', false);
        }
    }

    function _getInvoiceNum(Am_Record $invoice)
    {
        return $invoice->invoice_id ? "$invoice->invoice_id/$invoice->public_id" : '&mdash;';
    }

    function renderPurchase($record)
    {
        if ($record->purchase_user_id) {
            $s = sprintf('<a href="%s" target="_top">%s %s (%s)</a>',
                $this->view->escape($this->view->userUrl($record->purchase_user_id)),
                $this->view->escape($record->p_name_f),
                $this->view->escape($record->p_name_l),
                $this->view->escape($record->p_login));
        } else {
            $s = '&mdash;';
        }

        return $this->renderTd($s, false);
    }

    function renderRecipient($record)
    {
        $s = $record->redeem_user_id ?
            sprintf('<a href="%s" target="_top">%s %s (%s)</a>',
                $this->view->escape($this->view->userUrl($record->redeem_user_id)),
                $this->view->escape($record->r_name_f),
                $this->view->escape($record->r_name_l),
                $this->view->escape($record->r_login)) :
            sprintf('%s &lt;<a href="mailto:%s">%s</a>&gt;',
                $this->view->escape($record->name),
                $this->view->escape($record->email),
                $this->view->escape($record->email));

        return $this->renderTd($s, false);
    }

    function getPlugin()
    {
        return $this->getDi()->plugins_misc->loadGet('gift-card');
    }
}

Am_Di::getInstance()->hook->add(Am_Event::LOAD_BRICKS, function(Am_Event $e) {

    class Am_Form_Brick_GiftCardPurchase extends Am_Form_Brick
    {
        protected $hideIfLoggedInPossible = self::HIDE_DONT;
        protected $labels = [
            'Card Amount',
            'Recipient Name',
            'Recipient Email',
            "Your Message to Recipient\nincluded to email with Gift Card",
            'Gift Card',
            "Send Email with Gift Code at later date",
            'Send Date',
            'The minimum amount is %s',
            'The maximum amount is %s'
        ];

        public function __construct($id = null, $config = null)
        {
            $this->name = ___('Gift Card (Purchase)');
            parent::__construct($id, $config);
        }

        public function init()
        {
            Am_Di::getInstance()->hook->add(Am_Event::SIGNUP_INVOICE_ITEMS, [$this, 'handleGiftCard']);
        }

        function handleGiftCard(Am_Event $e)
        {
            /* @var $invoice Invoice */
            $invoice = $e->getInvoice();
            $vars = $e->getVars();
            $invoice->add(new Charge($vars['_gift_card_amount'], $invoice->currency, ___('Gift Card')));
            foreach ([
                    '_gift_card_amount',
                    '_gift_card_name',
                    '_gift_card_email',
                    '_gift_card_comment',
                    '_gift_card_later',
                    '_gift_card_ondate'
                     ] as $token) {

                $invoice->data()->set($token, $vars[$token]);
            }
        }

        public function initConfigForm(Am_Form $form)
        {
            $g = $form->addGroup();
            $g->setLabel(___('Possible Gift Card Amount Range'));
            $g->setSeparator(' ');

            $g->addText('min', ['size'=>5, 'placeholder' => ___('Min')]);
            $g->addHtml()->setHtml('&ndash;');
            $g->addText('max', ['size'=>5, 'placeholder' => ___('Max')]);
        }

        public function isAcceptableForForm(Am_Form_Bricked $form)
        {
            return $form instanceof Am_Form_Signup;
        }

        public function insertBrick(HTML_QuickForm2_Container $form)
        {
            $fs = $form->addFieldset()
                ->setLabel($this->___('Gift Card'));

            $amount = $fs->addText('_gift_card_amount', ['size'=>5])
                ->setLabel($this->___('Card Amount'));
            $amount->addRule('required');
            if ($min = $this->getConfig('min')) {
                $amount->addRule('gte', $this->___('The minimum amount is %s', $min), $min);
            }
            if ($max = $this->getConfig('max')) {
                $amount->addRule('lte', $this->___('The maximum amount is %s', $max), $max);
            }

            $fs->addText('_gift_card_name')
                ->setLabel($this->___('Recipient Name'))
                ->addRule('required');

            $fs->addText('_gift_card_email')
                ->setLabel($this->___('Recipient Email'))
                ->addRule('required');

            $fs->addTextarea('_gift_card_comment', ['class' => 'am-el-wide'])
                ->setLabel($this->___("Your Message to Recipient\nincluded to email with Gift Card"));

            $fs->addAdvCheckbox('_gift_card_later', null, ['content' => $this->___("Send Email with Gift Code at later date")]);
            $fs->addDate('_gift_card_ondate')
                ->setLabel($this->___('Send Date'));

            $form->addScript()->setScript(<<<CUT
jQuery(document).ready(function($){
    $('input[type=checkbox][name=_gift_card_later]').change(function(){
        $('input[name=_gift_card_ondate]').closest('.am-row').toggle(this.checked);
    }).change();
});
CUT
            );
        }
    }

    class Am_Form_Brick_GiftCardRedeem extends Am_Form_Brick
    {
        protected $hideIfLoggedInPossible = self::HIDE_DONT;
        protected $labels = [
            "Gift Card\nfill in gift card here if you have one",
            'Card code is either invalid or already used'
        ];

        public function __construct($id = null, $config = null)
        {
            $this->name = ___('Gift Card (Redeem)');
            parent::__construct($id, $config);
        }

        public function init()
        {
            Am_Di::getInstance()->hook->add(Am_Event::SIGNUP_INVOICE_ITEMS, [$this, 'handleGiftCard']);
        }

        function handleGiftCard(Am_Event $e)
        {
            /* @var $invoice Invoice */
            $invoice = $e->getInvoice();
            $vars = $e->getVars();
            if ($vars['_gift_card']) {
                $invoice->data()->set('_gift_card', $vars['_gift_card']);
            }
        }

        public function isAcceptableForForm(Am_Form_Bricked $form)
        {
            return $form instanceof Am_Form_Signup;
        }

        public function insertBrick(HTML_QuickForm2_Container $form)
        {
            $form->addText('_gift_card')
                ->setLabel($this->___("Gift Card\nfill in gift card here if you have one"))
                ->addRule('callback', $this->___('Card code is either invalid or already used'),
                    [Am_Di::getInstance()->plugins_misc->loadGet('gift-card'), 'isValid']);

            //force update invoice summary
            $form->addScript()
                ->setScript(<<<CUT
jQuery(function($){
    $([name=_gift_card]).change(function(){
        $(this).closest('form').find('[name^=product_id]:first').change();
    }).change();
});
CUT
                    );
        }
    }
});