Ситуация такова, что когда менеджеры ведут по нескольку сделок сразу, то следить за поступление денежных средств очень не удобно. Особенно, если факт оплаты счетов заносит кто-то другой. Просматривать все счета на предмет изменения статуса муторно и долго.
В нашей компании менеджер контролирует все, что относится к его сделкам: пришли или не пришли деньги от клиента, поставили оборудование в заказ или нет, оплатили или нет поставщику, выставили или нет бумаги, отвезли груз или не отвезли и т.д.

Поэтому было принято решение о рассылке уведомлений при поступлении оплаты по счету. Собственно, механизм следующий: если у счета меняется статус оплаты на "Оплачен" или "Оплачен частично", то отсылается уведомление. Уведомление отсылается либо ответственному по сделку, если счет прицеплен к сделке, либо ответственному по счету. Отсылка сделана по образу и подобию уведомлений, которые отсылаются при создании Задачи.

В скрипт wnd_InvoiceEditScript в функцию wnd_InvoiceEditOnPrepare в самый конец добавил строчку одну строку. Теперь эта функция выглядит вот так:

function wnd_InvoiceEditOnPrepare(Window) {

        Initialize(Window);
        wnd_BaseDBEditOnPrepare(Window);
/* MODULE WORKFLOW */
        var RequestFromWorkflow = false;
/* ENDMODULE WORKFLOW */
        InvoiceEdit.IsCompleting = false;
/* MODULE WORKFLOW */
        var DefaultValues = GetAttribute(Window, 'DefaultValues');
        var Dataset = BaseDBEdit.Dataset;
        if (Assigned(DefaultValues)) {
                // Post WorkflowItemID anyway because for this Invoice new
                // workflow item was created
                var NewWorkflowItemID = DefaultValues('WorkflowItemID');
                var RequestFromWorkflow = (!IsEmptyValue(NewWorkflowItemID));
                if ((RequestFromWorkflow) &&
                        (Dataset.Values('WorkflowItemID') != NewWorkflowItemID)) {
                        Dataset.Values('WorkflowItemID') = NewWorkflowItemID;
                        if (Dataset.State == dstEdit) {
                                Dataset.Post();
                                Dataset.Edit();
                        }
                }
        }
        if (RequestFromWorkflow && (Dataset.State == dstInsert)) {
                InvoiceEdit.CanCancel = false;
                dlData.Dataset.Values('BillStatusID') = null;
        } else {
                InvoiceEdit.CanCancel = true;
        }
        btnCancel.IsEnabled = InvoiceEdit.CanCancel;
/* ENDMODULE WORKFLOW */
        EnableNumberEdit();
    InvoiceEdit.BillStatusID = Dataset('BillStatusID');
}

Также были внесены изменения в функцию btnOKOnClick:

function btnOKOnClick(Control) {
        var Dataset = dlData.Dataset;
        var DefaultValues = GetAttribute(Self, 'DefaultValues');
/* MODULE WORKFLOW */
        var WorkflowItemID = Dataset.ValAsStr('WorkflowItemID');
/* ENDMODULE WORKFLOW */
        InvoiceEdit.IsCompleting = true;
        if (CheckItemNumberDuplicate('Invoice', Dataset, 'InvoiceNumber')){
                scr_BaseDBEdit.btnOKOnClick(Control);
        }
        Dataset.Open();
        var BillStatusID = Dataset('BillStatusID');
        if (!(InvoiceEdit.BillStatusID == BillStatusID)){
                if ((BillStatusID == GetInvoicePaidStatus())||
                        (BillStatusID == GetInvoicePartialPaidStatus())) {
                        var OpportunityID = Dataset('OpportunityID');
                        if (!IsEmptyGUID(OpportunityID)){
                                var ContactID = GetDatasetFieldValueByID('ds_Opportunity',OpportunityID,'OwnerID');
                        }else{
                            var ContactID = Dataset('OwnerID');
                        }
                        ProcessSendInvoiceEmailByContactID(Dataset, ContactID);
                }
        }
/* MODULE WORKFLOW */
        if (Self.IsVisible) {
                return;
        }
        ProcessWorkflowItem(WorkflowItemID);
/* ENDMODULE WORKFLOW */
}

Затем в скрипт scr_InvoiceUtils после строки
var InvoiceUtils = new Object();

была добавлена вот эта строка:
InvoiceUtils.PartialPaidStatusCode = 'PartialPaid';

А также был добавлен ряд функций:
function GetInvoicePartialPaidStatus() {
        if (IsEmptyGUID(InvoiceUtils.PaidStatusID)) {
                GetInvoiceStatusIDs();
        }
        return InvoiceUtils.PartialPaidStatusID;
}

function GetInvoiceNotifyMessageHTMLBody(Dataset) {
        var DataFields = Dataset.DataFields;
        var HTMLBody = '
\n'
;
        HTMLBody = HTMLBody + 'Вы получили данное уведомление об оплате счета, так как являетесь ответственным лицом.\n
'
;
        HTMLBody = HTMLBody + GetDatasetFieldHTMLView(DataFields.ItemsByName('InvoiceNumber')) + ' от ' + Dataset.ValAsStr('InvoiceDate') + '\n';
        HTMLBody = HTMLBody + '
\n'
;
        HTMLBody = HTMLBody + GetDatasetFieldHTMLView(DataFields.ItemsByName('OpportunityID')) + '\n';
        HTMLBody = HTMLBody + '
\n'
;
    HTMLBody = HTMLBody + '' + DataFields.ItemsByName('BasicAmount').Caption + ': ' + Dataset.ValAsStr('BasicAmount') + '\n';
        HTMLBody = HTMLBody + '
\n'
;
        HTMLBody = HTMLBody + GetDatasetFieldHTMLView(DataFields.ItemsByName('CustomerID')) + '\n';
        HTMLBody = HTMLBody + '
\n'
;
        HTMLBody = HTMLBody + GetDatasetFieldHTMLView(DataFields.ItemsByName('SupplierID')) + '\n';
        HTMLBody = HTMLBody + '

\n'
;
        HTMLBody = HTMLBody + GetDatasetFieldHTMLView(DataFields.ItemsByName('BillStatusID')) + '\n';
        HTMLBody = HTMLBody + '
\n'
;
    HTMLBody = HTMLBody + '' + DataFields.ItemsByName('PaymentAmount').Caption + ': ' + Dataset.ValAsStr('PaymentAmount') + '\n';
        HTMLBody = HTMLBody + '        ';
        HTMLBody = HTMLBody + GetDatasetFieldHTMLView(DataFields.ItemsByName('PaymentDate')) + '\n';
        HTMLBody = HTMLBody + '

\n'
;
        HTMLBody = HTMLBody + '\n';
        HTMLBody = HTMLBody + GetDatasetFieldHTMLView(DataFields.ItemsByName('ID')) + '\n';
        HTMLBody = HTMLBody + '

Нравится

Поделиться

10 комментариев

Хороший вариант решения.

А мы - просто автоматически добавляем напоминания (оплачен или частично оплачен - ответственному за счет; счет готов к отгрузке товара со склада - ответственному за склад и т.д.)

--
www.it-sfera.com.ua
Terrasoft Solution Partner

Тоже вариант, но у меня например, всегда висит окошко с кучкой напоминаний и не всегда видно, если что-то появляется свежее. А почтовый клиент сразу начинает моргать в трее.

Может быть создать динамическую папку, "счета, оплаченные сегодня(вчера, за последнюю неделю)"? Можно добавить соответствующее поле И (что-то типа - ознакомлен, не отработано и т.д.) С созданием соответствующих фильтров есс-но?

Динамические группы и так сделаны, правда без разбивки по времени, просто по статусу оплаты. Однако это тоже работает только когда сам заглядываешь в Террасофт. А уже создание дополнительных полей "Ознакомлен, не ознакомлен" это еще сложение. Кто будет менять значение этого поля? Лишний раз редактировать карточку.

Уведомление по почте легче и нагляднее. В идеале вообще было бы хорошо получить возможность настройки уведомления по почте на любое событие в системе... А это мысль, кстати! Надо будет подумать над возможной реализацией. :)

Коллеги,
все зависит от регламентов работы менеджеров и их заинтересованности.
1) Поддерживаю динамические группы как инструмент. Любой уважающий себя менеджер начинает работу с просмотра оплат. Таким образом он открывает раздел и знает куда ему бежать.

2) Если менеджер пергружен или его он немотивирован на оплату счетов :) ( что вряд ли), тогда в помощь ему напоминания:
а) напоминания в Terrasoft - для всех пользователей системы,
б) если надо информировать и других сотрудников, то эффективнее e-mail рассылки.

Good luck in the life!

Согласен, что все это зависит от регламентов. У нас идет отдельный учет исходящих счетов (мы выставляем клиенту) и входящих счетов (нам выставляет поставщик). Закупкой занимаются совсем другие люди. Так что в динамической группе найти счет от неизвестного поставщика, по которому ведется закупка оборудования по конкретной сделке, сложновато.
При уведомлении по почте, менеджер видит оплаты от клиента, а также факт закупки оборудования у поставщика (когда позиции заказные, а у нас таких много).

Почта - это личная напоминаловка по каждому событию.
Она пинает менеджера, что было событие, на которое надо обратить внимание.

Если же надо посмотреть ситуацию в целом, то группы помогают лучше.
Таким образом группы дополняют напоминания (любого способа).

Я бы сделал и то, и другое. Но начинал все же с динамических групп.

Good luck in the life!

"a.shekhovtsov" написал:Я бы сделал и то, и другое. Но начинал все же с динамических групп.

Совершенно согласен. У нас было сделано точно также. Просто когда просмотр состояния начинает занимать слишком много времени, стоит подключить напоминания.

У нас упор сделан на оперативность работы. За состоянием счета следят постоянно, а не как у большинства компаний - "У нас выписки снимают только два раза в день и все". В таком случае менеджер может знать, что информация об оплате может появится только в четко оговоренное время. Это как бы работа по таймеру.
А у нас ближе к событийной системе. :) Не сидеть же менеджеру и через каждые 5 минут мониторить счета. Он тогда все свое время только на это будет тратить. А так, произошло событие "деньги от клиент", сразу же после этого все пошло в работу.

Согласен. Для оперативности запуска процесса после прихода денег такой вариант наиболее удобен.

Good luck in the life!

"Барабанов Алексей Александрович" написал:А у нас ближе к событийной системе. :) Не сидеть же менеджеру и через каждые 5 минут мониторить счета.

Совершенно поддерживаю... а если менеджер в командировке и не имеет возможности запускать приложение и его средства комуникации ограничиваются телефоном и максимум нотбуком и тем же телефонным интернетом? В бою сапог надежнее(с) :-)))

Показать все комментарии