mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-19 06:10:31 +00:00
Merge pull request #332 from bigcapitalhq/big-105-convert-invoice-status-after-sending-mail-notification
feat: convert invoice status after sending mail notification
This commit is contained in:
@@ -173,3 +173,9 @@ export type IPaymentReceiveGLCommonEntry = Pick<
|
|||||||
export interface PaymentReceiveMailOpts extends CommonMailOptions {}
|
export interface PaymentReceiveMailOpts extends CommonMailOptions {}
|
||||||
|
|
||||||
export interface PaymentReceiveMailOptsDTO extends CommonMailOptionsDTO {}
|
export interface PaymentReceiveMailOptsDTO extends CommonMailOptionsDTO {}
|
||||||
|
|
||||||
|
export interface PaymentReceiveMailPresendEvent {
|
||||||
|
tenantId: number;
|
||||||
|
paymentReceiveId: number;
|
||||||
|
messageOptions: PaymentReceiveMailOptsDTO;
|
||||||
|
}
|
||||||
|
|||||||
@@ -132,4 +132,10 @@ export interface SaleEstimateMailOptions extends CommonMailOptions {
|
|||||||
|
|
||||||
export interface SaleEstimateMailOptionsDTO extends CommonMailOptionsDTO {
|
export interface SaleEstimateMailOptionsDTO extends CommonMailOptionsDTO {
|
||||||
attachEstimate?: boolean;
|
attachEstimate?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ISaleEstimateMailPresendEvent {
|
||||||
|
tenantId: number;
|
||||||
|
saleEstimateId: number;
|
||||||
|
messageOptions: SaleEstimateMailOptionsDTO;
|
||||||
|
}
|
||||||
|
|||||||
@@ -201,3 +201,15 @@ export interface ISaleInvoiceNotifyPayload {
|
|||||||
saleInvoiceId: number;
|
saleInvoiceId: number;
|
||||||
messageDTO: SendInvoiceMailDTO;
|
messageDTO: SendInvoiceMailDTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ISaleInvoiceMailSend {
|
||||||
|
tenantId: number;
|
||||||
|
saleInvoiceId: number;
|
||||||
|
messageOptions: SendInvoiceMailDTO;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ISaleInvoiceMailSent {
|
||||||
|
tenantId: number;
|
||||||
|
saleInvoiceId: number;
|
||||||
|
messageOptions: SendInvoiceMailDTO;
|
||||||
|
}
|
||||||
|
|||||||
@@ -143,3 +143,9 @@ export interface SaleReceiptMailOpts extends CommonMailOptions {
|
|||||||
export interface SaleReceiptMailOptsDTO extends CommonMailOptionsDTO {
|
export interface SaleReceiptMailOptsDTO extends CommonMailOptionsDTO {
|
||||||
attachReceipt?: boolean;
|
attachReceipt?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ISaleReceiptMailPresend {
|
||||||
|
tenantId: number;
|
||||||
|
saleReceiptId: number;
|
||||||
|
messageOptions: SaleReceiptMailOptsDTO;
|
||||||
|
}
|
||||||
|
|||||||
@@ -84,6 +84,9 @@ import { WriteInvoiceTaxTransactionsSubscriber } from '@/services/TaxRates/subsc
|
|||||||
import { BillTaxRateValidateSubscriber } from '@/services/TaxRates/subscribers/BillTaxRateValidateSubscriber';
|
import { BillTaxRateValidateSubscriber } from '@/services/TaxRates/subscribers/BillTaxRateValidateSubscriber';
|
||||||
import { WriteBillTaxTransactionsSubscriber } from '@/services/TaxRates/subscribers/WriteBillTaxTransactionsSubscriber';
|
import { WriteBillTaxTransactionsSubscriber } from '@/services/TaxRates/subscribers/WriteBillTaxTransactionsSubscriber';
|
||||||
import { SyncItemTaxRateOnEditTaxSubscriber } from '@/services/TaxRates/SyncItemTaxRateOnEditTaxSubscriber';
|
import { SyncItemTaxRateOnEditTaxSubscriber } from '@/services/TaxRates/SyncItemTaxRateOnEditTaxSubscriber';
|
||||||
|
import { InvoiceChangeStatusOnMailSentSubscriber } from '@/services/Sales/Invoices/subscribers/InvoiceChangeStatusOnMailSentSubscriber';
|
||||||
|
import { SaleReceiptMarkClosedOnMailSentSubcriber } from '@/services/Sales/Receipts/subscribers/SaleReceiptMarkClosedOnMailSentSubcriber';
|
||||||
|
import { SaleEstimateMarkApprovedOnMailSent } from '@/services/Sales/Estimates/subscribers/SaleEstimateMarkApprovedOnMailSent';
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
return new EventPublisher();
|
return new EventPublisher();
|
||||||
@@ -104,8 +107,12 @@ export const susbcribers = () => {
|
|||||||
InventorySubscriber,
|
InventorySubscriber,
|
||||||
CustomerWriteGLOpeningBalanceSubscriber,
|
CustomerWriteGLOpeningBalanceSubscriber,
|
||||||
VendorsWriteGLOpeningSubscriber,
|
VendorsWriteGLOpeningSubscriber,
|
||||||
|
|
||||||
|
// # Estimate
|
||||||
SaleEstimateAutoSerialSubscriber,
|
SaleEstimateAutoSerialSubscriber,
|
||||||
SaleEstimateSmsNotificationSubscriber,
|
SaleEstimateSmsNotificationSubscriber,
|
||||||
|
SaleEstimateMarkApprovedOnMailSent,
|
||||||
|
|
||||||
ExpensesWriteGLSubscriber,
|
ExpensesWriteGLSubscriber,
|
||||||
SaleReceiptAutoSerialSubscriber,
|
SaleReceiptAutoSerialSubscriber,
|
||||||
SaleInvoiceAutoIncrementSubscriber,
|
SaleInvoiceAutoIncrementSubscriber,
|
||||||
@@ -152,11 +159,13 @@ export const susbcribers = () => {
|
|||||||
// #Invoices
|
// #Invoices
|
||||||
InvoicePaymentGLRewriteSubscriber,
|
InvoicePaymentGLRewriteSubscriber,
|
||||||
InvoiceCostGLEntriesSubscriber,
|
InvoiceCostGLEntriesSubscriber,
|
||||||
|
InvoiceChangeStatusOnMailSentSubscriber,
|
||||||
|
|
||||||
BillPaymentsGLEntriesRewriteSubscriber,
|
BillPaymentsGLEntriesRewriteSubscriber,
|
||||||
|
|
||||||
// # Receipts
|
// # Receipts
|
||||||
SaleReceiptCostGLEntriesSubscriber,
|
SaleReceiptCostGLEntriesSubscriber,
|
||||||
|
SaleReceiptMarkClosedOnMailSentSubcriber,
|
||||||
|
|
||||||
// Transaction locking.
|
// Transaction locking.
|
||||||
SalesTransactionLockingGuardSubscriber,
|
SalesTransactionLockingGuardSubscriber,
|
||||||
@@ -199,6 +208,6 @@ export const susbcribers = () => {
|
|||||||
BillTaxRateValidateSubscriber,
|
BillTaxRateValidateSubscriber,
|
||||||
WriteBillTaxTransactionsSubscriber,
|
WriteBillTaxTransactionsSubscriber,
|
||||||
|
|
||||||
SyncItemTaxRateOnEditTaxSubscriber
|
SyncItemTaxRateOnEditTaxSubscriber,
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { IAccountTransaction } from '@/interfaces';
|
import { IAccountTransaction } from '@/interfaces';
|
||||||
import { Transformer } from '@/lib/Transformer/Transformer';
|
import { Transformer } from '@/lib/Transformer/Transformer';
|
||||||
import { transaction } from 'objection';
|
|
||||||
|
|
||||||
export default class AccountTransactionTransformer extends Transformer {
|
export default class AccountTransactionTransformer extends Transformer {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ export class AccountTransformer extends Transformer {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve formatted account amount.
|
* Retrieve formatted account amount.
|
||||||
* @param {IAccount} invoice
|
* @param {IAccount} invoice
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
protected formattedAmount = (account: IAccount): string => {
|
protected formattedAmount = (account: IAccount): string => {
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import { IAccountEventActivatedPayload } from '@/interfaces';
|
|||||||
import events from '@/subscribers/events';
|
import events from '@/subscribers/events';
|
||||||
import UnitOfWork from '@/services/UnitOfWork';
|
import UnitOfWork from '@/services/UnitOfWork';
|
||||||
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
||||||
import { CommandAccountValidators } from './CommandAccountValidators';
|
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class ActivateAccount {
|
export class ActivateAccount {
|
||||||
@@ -18,9 +17,6 @@ export class ActivateAccount {
|
|||||||
@Inject()
|
@Inject()
|
||||||
private uow: UnitOfWork;
|
private uow: UnitOfWork;
|
||||||
|
|
||||||
@Inject()
|
|
||||||
private validator: CommandAccountValidators;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Activates/Inactivates the given account.
|
* Activates/Inactivates the given account.
|
||||||
* @param {number} tenantId
|
* @param {number} tenantId
|
||||||
|
|||||||
@@ -8,11 +8,14 @@ import {
|
|||||||
import { SaleEstimatesPdf } from './SaleEstimatesPdf';
|
import { SaleEstimatesPdf } from './SaleEstimatesPdf';
|
||||||
import { GetSaleEstimate } from './GetSaleEstimate';
|
import { GetSaleEstimate } from './GetSaleEstimate';
|
||||||
import {
|
import {
|
||||||
|
ISaleEstimateMailPresendEvent,
|
||||||
SaleEstimateMailOptions,
|
SaleEstimateMailOptions,
|
||||||
SaleEstimateMailOptionsDTO,
|
SaleEstimateMailOptionsDTO,
|
||||||
} from '@/interfaces';
|
} from '@/interfaces';
|
||||||
import { ContactMailNotification } from '@/services/MailNotification/ContactMailNotification';
|
import { ContactMailNotification } from '@/services/MailNotification/ContactMailNotification';
|
||||||
import { parseAndValidateMailOptions } from '@/services/MailNotification/utils';
|
import { parseAndValidateMailOptions } from '@/services/MailNotification/utils';
|
||||||
|
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
||||||
|
import events from '@/subscribers/events';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class SendSaleEstimateMail {
|
export class SendSaleEstimateMail {
|
||||||
@@ -31,6 +34,9 @@ export class SendSaleEstimateMail {
|
|||||||
@Inject('agenda')
|
@Inject('agenda')
|
||||||
private agenda: any;
|
private agenda: any;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private eventPublisher: EventPublisher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggers the reminder mail of the given sale estimate.
|
* Triggers the reminder mail of the given sale estimate.
|
||||||
* @param {number} tenantId -
|
* @param {number} tenantId -
|
||||||
@@ -49,6 +55,13 @@ export class SendSaleEstimateMail {
|
|||||||
messageOptions,
|
messageOptions,
|
||||||
};
|
};
|
||||||
await this.agenda.now('sale-estimate-mail-send', payload);
|
await this.agenda.now('sale-estimate-mail-send', payload);
|
||||||
|
|
||||||
|
// Triggers `onSaleEstimatePreMailSend` event.
|
||||||
|
await this.eventPublisher.emitAsync(events.saleEstimate.onPreMailSend, {
|
||||||
|
tenantId,
|
||||||
|
saleEstimateId,
|
||||||
|
messageOptions,
|
||||||
|
} as ISaleEstimateMailPresendEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -99,7 +112,7 @@ export class SendSaleEstimateMail {
|
|||||||
return {
|
return {
|
||||||
...mailOptions,
|
...mailOptions,
|
||||||
data: formatterData,
|
data: formatterData,
|
||||||
attachEstimate: true
|
attachEstimate: true,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
import { Inject, Service } from 'typedi';
|
||||||
|
import events from '@/subscribers/events';
|
||||||
|
import { ISaleEstimateMailPresendEvent } from '@/interfaces';
|
||||||
|
import { DeliverSaleEstimate } from '../DeliverSaleEstimate';
|
||||||
|
import { ServiceError } from '@/exceptions';
|
||||||
|
import { ERRORS } from '../constants';
|
||||||
|
|
||||||
|
@Service()
|
||||||
|
export class SaleEstimateMarkApprovedOnMailSent {
|
||||||
|
@Inject()
|
||||||
|
private deliverEstimateService: DeliverSaleEstimate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attaches events.
|
||||||
|
*/
|
||||||
|
public attach(bus) {
|
||||||
|
bus.subscribe(events.saleEstimate.onPreMailSend, this.markEstimateApproved);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marks the given estimate approved on submitting mail.
|
||||||
|
* @param {ISaleEstimateMailPresendEvent}
|
||||||
|
*/
|
||||||
|
private markEstimateApproved = async ({
|
||||||
|
tenantId,
|
||||||
|
saleEstimateId,
|
||||||
|
}: ISaleEstimateMailPresendEvent) => {
|
||||||
|
try {
|
||||||
|
await this.deliverEstimateService.deliverSaleEstimate(
|
||||||
|
tenantId,
|
||||||
|
saleEstimateId
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
if (
|
||||||
|
error instanceof ServiceError &&
|
||||||
|
error.errorType === ERRORS.SALE_ESTIMATE_ALREADY_DELIVERED
|
||||||
|
) {
|
||||||
|
} else {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -4,7 +4,6 @@ import { ServiceError } from '@/exceptions';
|
|||||||
import {
|
import {
|
||||||
ISaleInvoiceDeliveringPayload,
|
ISaleInvoiceDeliveringPayload,
|
||||||
ISaleInvoiceEventDeliveredPayload,
|
ISaleInvoiceEventDeliveredPayload,
|
||||||
ISystemUser,
|
|
||||||
} from '@/interfaces';
|
} from '@/interfaces';
|
||||||
import { ERRORS } from './constants';
|
import { ERRORS } from './constants';
|
||||||
import { Inject, Service } from 'typedi';
|
import { Inject, Service } from 'typedi';
|
||||||
@@ -36,8 +35,7 @@ export class DeliverSaleInvoice {
|
|||||||
*/
|
*/
|
||||||
public async deliverSaleInvoice(
|
public async deliverSaleInvoice(
|
||||||
tenantId: number,
|
tenantId: number,
|
||||||
saleInvoiceId: number,
|
saleInvoiceId: number
|
||||||
authorizedUser: ISystemUser
|
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const { SaleInvoice } = this.tenancy.models(tenantId);
|
const { SaleInvoice } = this.tenancy.models(tenantId);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Inject, Service } from 'typedi';
|
import { Inject, Service } from 'typedi';
|
||||||
import Mail from '@/lib/Mail';
|
import Mail from '@/lib/Mail';
|
||||||
import { SendInvoiceMailDTO } from '@/interfaces';
|
import { ISaleInvoiceMailSend, SendInvoiceMailDTO } from '@/interfaces';
|
||||||
import { SaleInvoicePdf } from './SaleInvoicePdf';
|
import { SaleInvoicePdf } from './SaleInvoicePdf';
|
||||||
import { SendSaleInvoiceMailCommon } from './SendInvoiceInvoiceMailCommon';
|
import { SendSaleInvoiceMailCommon } from './SendInvoiceInvoiceMailCommon';
|
||||||
import {
|
import {
|
||||||
@@ -8,6 +8,8 @@ import {
|
|||||||
DEFAULT_INVOICE_MAIL_SUBJECT,
|
DEFAULT_INVOICE_MAIL_SUBJECT,
|
||||||
} from './constants';
|
} from './constants';
|
||||||
import { parseAndValidateMailOptions } from '@/services/MailNotification/utils';
|
import { parseAndValidateMailOptions } from '@/services/MailNotification/utils';
|
||||||
|
import events from '@/subscribers/events';
|
||||||
|
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class SendSaleInvoiceMail {
|
export class SendSaleInvoiceMail {
|
||||||
@@ -20,6 +22,9 @@ export class SendSaleInvoiceMail {
|
|||||||
@Inject('agenda')
|
@Inject('agenda')
|
||||||
private agenda: any;
|
private agenda: any;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private eventPublisher: EventPublisher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends the invoice mail of the given sale invoice.
|
* Sends the invoice mail of the given sale invoice.
|
||||||
* @param {number} tenantId
|
* @param {number} tenantId
|
||||||
@@ -29,14 +34,21 @@ export class SendSaleInvoiceMail {
|
|||||||
public async triggerMail(
|
public async triggerMail(
|
||||||
tenantId: number,
|
tenantId: number,
|
||||||
saleInvoiceId: number,
|
saleInvoiceId: number,
|
||||||
messageDTO: SendInvoiceMailDTO
|
messageOptions: SendInvoiceMailDTO
|
||||||
) {
|
) {
|
||||||
const payload = {
|
const payload = {
|
||||||
tenantId,
|
tenantId,
|
||||||
saleInvoiceId,
|
saleInvoiceId,
|
||||||
messageDTO,
|
messageOptions,
|
||||||
};
|
};
|
||||||
await this.agenda.now('sale-invoice-mail-send', payload);
|
await this.agenda.now('sale-invoice-mail-send', payload);
|
||||||
|
|
||||||
|
// Triggers the event `onSaleInvoicePreMailSend`.
|
||||||
|
await this.eventPublisher.emitAsync(events.saleInvoice.onPreMailSend, {
|
||||||
|
tenantId,
|
||||||
|
saleInvoiceId,
|
||||||
|
messageOptions,
|
||||||
|
} as ISaleInvoiceMailSend);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -64,7 +76,7 @@ export class SendSaleInvoiceMail {
|
|||||||
public async sendMail(
|
public async sendMail(
|
||||||
tenantId: number,
|
tenantId: number,
|
||||||
saleInvoiceId: number,
|
saleInvoiceId: number,
|
||||||
messageDTO: SendInvoiceMailDTO
|
messageOptions: SendInvoiceMailDTO
|
||||||
) {
|
) {
|
||||||
const defaultMessageOpts = await this.getMailOption(
|
const defaultMessageOpts = await this.getMailOption(
|
||||||
tenantId,
|
tenantId,
|
||||||
@@ -73,7 +85,7 @@ export class SendSaleInvoiceMail {
|
|||||||
// Merge message opts with default options and validate the incoming options.
|
// Merge message opts with default options and validate the incoming options.
|
||||||
const messageOpts = parseAndValidateMailOptions(
|
const messageOpts = parseAndValidateMailOptions(
|
||||||
defaultMessageOpts,
|
defaultMessageOpts,
|
||||||
messageDTO
|
messageOptions
|
||||||
);
|
);
|
||||||
const mail = new Mail()
|
const mail = new Mail()
|
||||||
.setSubject(messageOpts.subject)
|
.setSubject(messageOpts.subject)
|
||||||
@@ -90,6 +102,20 @@ export class SendSaleInvoiceMail {
|
|||||||
{ filename: 'invoice.pdf', content: invoicePdfBuffer },
|
{ filename: 'invoice.pdf', content: invoicePdfBuffer },
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
// Triggers the event `onSaleInvoiceSend`.
|
||||||
|
await this.eventPublisher.emitAsync(events.saleInvoice.onMailSend, {
|
||||||
|
tenantId,
|
||||||
|
saleInvoiceId,
|
||||||
|
messageOptions,
|
||||||
|
} as ISaleInvoiceMailSend);
|
||||||
|
|
||||||
await mail.send();
|
await mail.send();
|
||||||
|
|
||||||
|
// Triggers the event `onSaleInvoiceSend`.
|
||||||
|
await this.eventPublisher.emitAsync(events.saleInvoice.onMailSent, {
|
||||||
|
tenantId,
|
||||||
|
saleInvoiceId,
|
||||||
|
messageOptions,
|
||||||
|
} as ISaleInvoiceMailSend);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,11 +19,11 @@ export class SendSaleInvoiceMailJob {
|
|||||||
* Triggers sending invoice mail.
|
* Triggers sending invoice mail.
|
||||||
*/
|
*/
|
||||||
private handler = async (job, done: Function) => {
|
private handler = async (job, done: Function) => {
|
||||||
const { tenantId, saleInvoiceId, messageDTO } = job.attrs.data;
|
const { tenantId, saleInvoiceId, messageOptions } = job.attrs.data;
|
||||||
const sendInvoiceMail = Container.get(SendSaleInvoiceMail);
|
const sendInvoiceMail = Container.get(SendSaleInvoiceMail);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await sendInvoiceMail.sendMail(tenantId, saleInvoiceId, messageDTO);
|
await sendInvoiceMail.sendMail(tenantId, saleInvoiceId, messageOptions);
|
||||||
done();
|
done();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
import { Inject, Service } from 'typedi';
|
import { Inject, Service } from 'typedi';
|
||||||
import { SendInvoiceMailDTO } from '@/interfaces';
|
import {
|
||||||
|
ISaleInvoiceMailSend,
|
||||||
|
ISaleInvoiceMailSent,
|
||||||
|
SendInvoiceMailDTO,
|
||||||
|
} from '@/interfaces';
|
||||||
import Mail from '@/lib/Mail';
|
import Mail from '@/lib/Mail';
|
||||||
import { SaleInvoicePdf } from './SaleInvoicePdf';
|
import { SaleInvoicePdf } from './SaleInvoicePdf';
|
||||||
import { SendSaleInvoiceMailCommon } from './SendInvoiceInvoiceMailCommon';
|
import { SendSaleInvoiceMailCommon } from './SendInvoiceInvoiceMailCommon';
|
||||||
@@ -8,6 +12,8 @@ import {
|
|||||||
DEFAULT_INVOICE_REMINDER_MAIL_SUBJECT,
|
DEFAULT_INVOICE_REMINDER_MAIL_SUBJECT,
|
||||||
} from './constants';
|
} from './constants';
|
||||||
import { parseAndValidateMailOptions } from '@/services/MailNotification/utils';
|
import { parseAndValidateMailOptions } from '@/services/MailNotification/utils';
|
||||||
|
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
||||||
|
import events from '@/subscribers/events';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class SendInvoiceMailReminder {
|
export class SendInvoiceMailReminder {
|
||||||
@@ -20,6 +26,9 @@ export class SendInvoiceMailReminder {
|
|||||||
@Inject()
|
@Inject()
|
||||||
private invoiceCommonMail: SendSaleInvoiceMailCommon;
|
private invoiceCommonMail: SendSaleInvoiceMailCommon;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private eventPublisher: EventPublisher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggers the reminder mail of the given sale invoice.
|
* Triggers the reminder mail of the given sale invoice.
|
||||||
* @param {number} tenantId
|
* @param {number} tenantId
|
||||||
@@ -86,6 +95,18 @@ export class SendInvoiceMailReminder {
|
|||||||
{ filename: 'invoice.pdf', content: invoicePdfBuffer },
|
{ filename: 'invoice.pdf', content: invoicePdfBuffer },
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
// Triggers the event `onSaleInvoiceSend`.
|
||||||
|
await this.eventPublisher.emitAsync(events.saleInvoice.onMailReminderSend, {
|
||||||
|
saleInvoiceId,
|
||||||
|
messageOptions,
|
||||||
|
} as ISaleInvoiceMailSend);
|
||||||
|
|
||||||
await mail.send();
|
await mail.send();
|
||||||
|
|
||||||
|
// Triggers the event `onSaleInvoiceSent`.
|
||||||
|
await this.eventPublisher.emitAsync(events.saleInvoice.onMailReminderSent, {
|
||||||
|
saleInvoiceId,
|
||||||
|
messageOptions,
|
||||||
|
} as ISaleInvoiceMailSent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
import { Inject, Service } from 'typedi';
|
||||||
|
import events from '@/subscribers/events';
|
||||||
|
import { ISaleInvoiceMailSent } from '@/interfaces';
|
||||||
|
import { DeliverSaleInvoice } from '../DeliverSaleInvoice';
|
||||||
|
import { ServiceError } from '@/exceptions';
|
||||||
|
import { ERRORS } from '../constants';
|
||||||
|
|
||||||
|
@Service()
|
||||||
|
export class InvoiceChangeStatusOnMailSentSubscriber {
|
||||||
|
@Inject()
|
||||||
|
private markInvoiceDelivedService: DeliverSaleInvoice;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attaches events.
|
||||||
|
*/
|
||||||
|
public attach(bus) {
|
||||||
|
bus.subscribe(events.saleInvoice.onPreMailSend, this.markInvoiceDelivered);
|
||||||
|
bus.subscribe(
|
||||||
|
events.saleInvoice.onMailReminderSent,
|
||||||
|
this.markInvoiceDelivered
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marks the invoice delivered once the invoice mail sent.
|
||||||
|
* @param {ISaleInvoiceMailSent}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private markInvoiceDelivered = async ({
|
||||||
|
tenantId,
|
||||||
|
saleInvoiceId,
|
||||||
|
messageOptions,
|
||||||
|
}: ISaleInvoiceMailSent) => {
|
||||||
|
try {
|
||||||
|
await this.markInvoiceDelivedService.deliverSaleInvoice(
|
||||||
|
tenantId,
|
||||||
|
saleInvoiceId
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
if (
|
||||||
|
error instanceof ServiceError &&
|
||||||
|
error.errorType === ERRORS.SALE_INVOICE_ALREADY_DELIVERED
|
||||||
|
) {
|
||||||
|
} else {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ import { Inject, Service } from 'typedi';
|
|||||||
import {
|
import {
|
||||||
PaymentReceiveMailOpts,
|
PaymentReceiveMailOpts,
|
||||||
PaymentReceiveMailOptsDTO,
|
PaymentReceiveMailOptsDTO,
|
||||||
|
PaymentReceiveMailPresendEvent,
|
||||||
SendInvoiceMailDTO,
|
SendInvoiceMailDTO,
|
||||||
} from '@/interfaces';
|
} from '@/interfaces';
|
||||||
import Mail from '@/lib/Mail';
|
import Mail from '@/lib/Mail';
|
||||||
@@ -13,6 +14,8 @@ import {
|
|||||||
import { GetPaymentReceive } from './GetPaymentReceive';
|
import { GetPaymentReceive } from './GetPaymentReceive';
|
||||||
import { ContactMailNotification } from '@/services/MailNotification/ContactMailNotification';
|
import { ContactMailNotification } from '@/services/MailNotification/ContactMailNotification';
|
||||||
import { parseAndValidateMailOptions } from '@/services/MailNotification/utils';
|
import { parseAndValidateMailOptions } from '@/services/MailNotification/utils';
|
||||||
|
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
||||||
|
import events from '@/subscribers/events';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class SendPaymentReceiveMailNotification {
|
export class SendPaymentReceiveMailNotification {
|
||||||
@@ -28,6 +31,9 @@ export class SendPaymentReceiveMailNotification {
|
|||||||
@Inject('agenda')
|
@Inject('agenda')
|
||||||
private agenda: any;
|
private agenda: any;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private eventPublisher: EventPublisher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends the mail of the given payment receive.
|
* Sends the mail of the given payment receive.
|
||||||
* @param {number} tenantId
|
* @param {number} tenantId
|
||||||
@@ -46,6 +52,13 @@ export class SendPaymentReceiveMailNotification {
|
|||||||
messageDTO,
|
messageDTO,
|
||||||
};
|
};
|
||||||
await this.agenda.now('payment-receive-mail-send', payload);
|
await this.agenda.now('payment-receive-mail-send', payload);
|
||||||
|
|
||||||
|
// Triggers `onPaymentReceivePreMailSend` event.
|
||||||
|
await this.eventPublisher.emitAsync(events.paymentReceive.onPreMailSend, {
|
||||||
|
tenantId,
|
||||||
|
paymentReceiveId,
|
||||||
|
messageOptions: messageDTO,
|
||||||
|
} as PaymentReceiveMailPresendEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -7,9 +7,15 @@ import {
|
|||||||
DEFAULT_RECEIPT_MAIL_CONTENT,
|
DEFAULT_RECEIPT_MAIL_CONTENT,
|
||||||
DEFAULT_RECEIPT_MAIL_SUBJECT,
|
DEFAULT_RECEIPT_MAIL_SUBJECT,
|
||||||
} from './constants';
|
} from './constants';
|
||||||
import { SaleReceiptMailOpts, SaleReceiptMailOptsDTO } from '@/interfaces';
|
import {
|
||||||
|
ISaleReceiptMailPresend,
|
||||||
|
SaleReceiptMailOpts,
|
||||||
|
SaleReceiptMailOptsDTO,
|
||||||
|
} from '@/interfaces';
|
||||||
import { ContactMailNotification } from '@/services/MailNotification/ContactMailNotification';
|
import { ContactMailNotification } from '@/services/MailNotification/ContactMailNotification';
|
||||||
import { parseAndValidateMailOptions } from '@/services/MailNotification/utils';
|
import { parseAndValidateMailOptions } from '@/services/MailNotification/utils';
|
||||||
|
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
||||||
|
import events from '@/subscribers/events';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class SaleReceiptMailNotification {
|
export class SaleReceiptMailNotification {
|
||||||
@@ -25,6 +31,9 @@ export class SaleReceiptMailNotification {
|
|||||||
@Inject()
|
@Inject()
|
||||||
private contactMailNotification: ContactMailNotification;
|
private contactMailNotification: ContactMailNotification;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private eventPublisher: EventPublisher;
|
||||||
|
|
||||||
@Inject('agenda')
|
@Inject('agenda')
|
||||||
private agenda: any;
|
private agenda: any;
|
||||||
|
|
||||||
@@ -37,14 +46,21 @@ export class SaleReceiptMailNotification {
|
|||||||
public async triggerMail(
|
public async triggerMail(
|
||||||
tenantId: number,
|
tenantId: number,
|
||||||
saleReceiptId: number,
|
saleReceiptId: number,
|
||||||
messageOpts: SaleReceiptMailOptsDTO
|
messageOptions: SaleReceiptMailOptsDTO
|
||||||
) {
|
) {
|
||||||
const payload = {
|
const payload = {
|
||||||
tenantId,
|
tenantId,
|
||||||
saleReceiptId,
|
saleReceiptId,
|
||||||
messageOpts,
|
messageOpts: messageOptions,
|
||||||
};
|
};
|
||||||
await this.agenda.now('sale-receipt-mail-send', payload);
|
await this.agenda.now('sale-receipt-mail-send', payload);
|
||||||
|
|
||||||
|
// Triggers the event `onSaleReceiptPreMailSend`.
|
||||||
|
await this.eventPublisher.emitAsync(events.saleReceipt.onPreMailSend, {
|
||||||
|
tenantId,
|
||||||
|
saleReceiptId,
|
||||||
|
messageOptions,
|
||||||
|
} as ISaleReceiptMailPresend);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { SaleReceiptCostGLEntries } from '../SaleReceiptCostGLEntries';
|
|||||||
@Service()
|
@Service()
|
||||||
export class SaleReceiptCostGLEntriesSubscriber {
|
export class SaleReceiptCostGLEntriesSubscriber {
|
||||||
@Inject()
|
@Inject()
|
||||||
saleReceiptCostEntries: SaleReceiptCostGLEntries;
|
private saleReceiptCostEntries: SaleReceiptCostGLEntries;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attaches events.
|
* Attaches events.
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
import { ISaleReceiptMailPresend } from '@/interfaces';
|
||||||
|
import events from '@/subscribers/events';
|
||||||
|
import { CloseSaleReceipt } from '../CloseSaleReceipt';
|
||||||
|
import { Inject, Service } from 'typedi';
|
||||||
|
import { ServiceError } from '@/exceptions';
|
||||||
|
import { ERRORS } from '../constants';
|
||||||
|
|
||||||
|
@Service()
|
||||||
|
export class SaleReceiptMarkClosedOnMailSentSubcriber {
|
||||||
|
@Inject()
|
||||||
|
private closeReceiptService: CloseSaleReceipt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attaches events.
|
||||||
|
*/
|
||||||
|
public attach(bus) {
|
||||||
|
bus.subscribe(events.saleReceipt.onPreMailSend, this.markReceiptClosed);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marks the sale receipt closed on submitting mail.
|
||||||
|
* @param {ISaleReceiptMailPresend}
|
||||||
|
*/
|
||||||
|
private markReceiptClosed = async ({
|
||||||
|
tenantId,
|
||||||
|
saleReceiptId,
|
||||||
|
messageOptions,
|
||||||
|
}: ISaleReceiptMailPresend) => {
|
||||||
|
try {
|
||||||
|
await this.closeReceiptService.closeSaleReceipt(tenantId, saleReceiptId);
|
||||||
|
} catch (error) {
|
||||||
|
if (
|
||||||
|
error instanceof ServiceError &&
|
||||||
|
error.errorType === ERRORS.SALE_RECEIPT_IS_ALREADY_CLOSED
|
||||||
|
) {
|
||||||
|
} else {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -131,7 +131,14 @@ export default {
|
|||||||
onNotifiedSms: 'onSaleInvoiceNotifiedSms',
|
onNotifiedSms: 'onSaleInvoiceNotifiedSms',
|
||||||
|
|
||||||
onNotifyMail: 'onSaleInvoiceNotifyMail',
|
onNotifyMail: 'onSaleInvoiceNotifyMail',
|
||||||
onNotifyReminderMail: 'onSaleInvoiceNotifyReminderMail'
|
onNotifyReminderMail: 'onSaleInvoiceNotifyReminderMail',
|
||||||
|
|
||||||
|
onPreMailSend: 'onSaleInvoicePreMailSend',
|
||||||
|
onMailSend: 'onSaleInvoiceMailSend',
|
||||||
|
onMailSent: 'onSaleInvoiceMailSent',
|
||||||
|
|
||||||
|
onMailReminderSend: 'onSaleInvoiceMailReminderSend',
|
||||||
|
onMailReminderSent: 'onSaleInvoiceMailReminderSent',
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -164,7 +171,11 @@ export default {
|
|||||||
onRejecting: 'onSaleEstimateRejecting',
|
onRejecting: 'onSaleEstimateRejecting',
|
||||||
onRejected: 'onSaleEstimateRejected',
|
onRejected: 'onSaleEstimateRejected',
|
||||||
|
|
||||||
onNotifyMail: 'onSaleEstimateNotifyMail'
|
onNotifyMail: 'onSaleEstimateNotifyMail',
|
||||||
|
|
||||||
|
onPreMailSend: 'onSaleEstimatePreMailSend',
|
||||||
|
onMailSend: 'onSaleEstimateMailSend',
|
||||||
|
onMailSent: 'onSaleEstimateMailSend',
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -188,6 +199,10 @@ export default {
|
|||||||
|
|
||||||
onNotifySms: 'onSaleReceiptNotifySms',
|
onNotifySms: 'onSaleReceiptNotifySms',
|
||||||
onNotifiedSms: 'onSaleReceiptNotifiedSms',
|
onNotifiedSms: 'onSaleReceiptNotifiedSms',
|
||||||
|
|
||||||
|
onPreMailSend: 'onSaleReceiptPreMailSend',
|
||||||
|
onMailSend: 'onSaleReceiptMailSend',
|
||||||
|
onMailSent: 'onSaleReceiptMailSent',
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -208,6 +223,10 @@ export default {
|
|||||||
|
|
||||||
onNotifySms: 'onPaymentReceiveNotifySms',
|
onNotifySms: 'onPaymentReceiveNotifySms',
|
||||||
onNotifiedSms: 'onPaymentReceiveNotifiedSms',
|
onNotifiedSms: 'onPaymentReceiveNotifiedSms',
|
||||||
|
|
||||||
|
onPreMailSend: 'onPaymentReceivePreMailSend',
|
||||||
|
onMailSend: 'onPaymentReceiveMailSend',
|
||||||
|
onMailSent: 'onPaymentReceiveMailSent',
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -580,6 +599,6 @@ export default {
|
|||||||
onActivated: 'onTaxRateActivated',
|
onActivated: 'onTaxRateActivated',
|
||||||
|
|
||||||
onInactivating: 'onTaxRateInactivating',
|
onInactivating: 'onTaxRateInactivating',
|
||||||
onInactivated: 'onTaxRateInactivated'
|
onInactivated: 'onTaxRateInactivated',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -53,6 +53,9 @@ export enum DialogsName {
|
|||||||
EstimateMail = 'estimate-mail',
|
EstimateMail = 'estimate-mail',
|
||||||
ReceiptMail = 'receipt-mail',
|
ReceiptMail = 'receipt-mail',
|
||||||
PaymentMail = 'payment-mail',
|
PaymentMail = 'payment-mail',
|
||||||
|
InvoiceFormMailDeliver = 'InvoiceFormMailDeliver',
|
||||||
|
EstimateFormMailDeliver = 'EstimateFormMailDeliver',
|
||||||
|
ReceiptFormMailDeliver = 'ReceiptFormMailDeliver',
|
||||||
BalanceSheetPdfPreview = 'BalanceSheetPdfPreview',
|
BalanceSheetPdfPreview = 'BalanceSheetPdfPreview',
|
||||||
TrialBalanceSheetPdfPreview = 'TrialBalanceSheetPdfPreview',
|
TrialBalanceSheetPdfPreview = 'TrialBalanceSheetPdfPreview',
|
||||||
CashflowSheetPdfPreview = 'CashflowSheetPdfPreview',
|
CashflowSheetPdfPreview = 'CashflowSheetPdfPreview',
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import React from 'react';
|
||||||
|
import { Dialog, DialogSuspense } from '@/components';
|
||||||
|
import withDialogRedux from '@/components/DialogReduxConnect';
|
||||||
|
import { compose } from '@/utils';
|
||||||
|
|
||||||
|
const EstimateFormMailDeliverDialogContent = React.lazy(
|
||||||
|
() => import('./EstimateFormMailDeliverDialogContent'),
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Estimate mail dialog.
|
||||||
|
*/
|
||||||
|
function EstimateFormMailDeliverDialog({
|
||||||
|
dialogName,
|
||||||
|
payload: { estimateId = null },
|
||||||
|
isOpen,
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
name={dialogName}
|
||||||
|
title={'Estimate Mail'}
|
||||||
|
isOpen={isOpen}
|
||||||
|
canEscapeJeyClose={false}
|
||||||
|
isCloseButtonShown={false}
|
||||||
|
autoFocus={true}
|
||||||
|
style={{ width: 600 }}
|
||||||
|
>
|
||||||
|
<DialogSuspense>
|
||||||
|
<EstimateFormMailDeliverDialogContent
|
||||||
|
dialogName={dialogName}
|
||||||
|
estimateId={estimateId}
|
||||||
|
/>
|
||||||
|
</DialogSuspense>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default compose(withDialogRedux())(EstimateFormMailDeliverDialog);
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import * as R from 'ramda';
|
||||||
|
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||||
|
import { useHistory } from 'react-router-dom';
|
||||||
|
import EstimateMailDialogContent from '../../EstimateMailDialog/EstimateMailDialogContent';
|
||||||
|
import { DialogsName } from '@/constants/dialogs';
|
||||||
|
|
||||||
|
interface EstimateFormDeliverDialogContent {
|
||||||
|
estimateId: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
function EstimateFormDeliverDialogContentRoot({
|
||||||
|
estimateId,
|
||||||
|
|
||||||
|
// #withDialogActions
|
||||||
|
closeDialog,
|
||||||
|
}: EstimateFormDeliverDialogContent) {
|
||||||
|
const history = useHistory();
|
||||||
|
|
||||||
|
const handleSubmit = () => {
|
||||||
|
closeDialog(DialogsName.EstimateFormMailDeliver);
|
||||||
|
history.push('/estimates');
|
||||||
|
};
|
||||||
|
const handleCancel = () => {
|
||||||
|
closeDialog(DialogsName.EstimateFormMailDeliver);
|
||||||
|
history.push('/estimates');
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<EstimateMailDialogContent
|
||||||
|
estimateId={estimateId}
|
||||||
|
onFormSubmit={handleSubmit}
|
||||||
|
onCancelClick={handleCancel}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default R.compose(withDialogActions)(
|
||||||
|
EstimateFormDeliverDialogContentRoot,
|
||||||
|
);
|
||||||
@@ -2,6 +2,8 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useFormikContext } from 'formik';
|
import { useFormikContext } from 'formik';
|
||||||
import EstimateNumberDialog from '@/containers/Dialogs/EstimateNumberDialog';
|
import EstimateNumberDialog from '@/containers/Dialogs/EstimateNumberDialog';
|
||||||
|
import EstimateFormMailDeliverDialog from './Dialogs/EstimateFormMailDeliverDialog';
|
||||||
|
import { DialogsName } from '@/constants/dialogs';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Estimate form dialogs.
|
* Estimate form dialogs.
|
||||||
@@ -25,6 +27,9 @@ export default function EstimateFormDialogs() {
|
|||||||
dialogName={'estimate-number-form'}
|
dialogName={'estimate-number-form'}
|
||||||
onConfirm={handleEstimateNumberFormConfirm}
|
onConfirm={handleEstimateNumberFormConfirm}
|
||||||
/>
|
/>
|
||||||
|
<EstimateFormMailDeliverDialog
|
||||||
|
dialogName={DialogsName.EstimateFormMailDeliver}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ import { Dialog, DialogSuspense } from '@/components';
|
|||||||
import withDialogRedux from '@/components/DialogReduxConnect';
|
import withDialogRedux from '@/components/DialogReduxConnect';
|
||||||
import { compose } from '@/utils';
|
import { compose } from '@/utils';
|
||||||
|
|
||||||
const EstimateMailDialogContent = React.lazy(
|
const EstimateMailDialogBody = React.lazy(
|
||||||
() => import('./EstimateMailDialogContent'),
|
() => import('./EstimateMailDialogBody'),
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoice mail dialog.
|
* Estimate mail dialog.
|
||||||
*/
|
*/
|
||||||
function EstimateMailDialog({
|
function EstimateMailDialog({
|
||||||
dialogName,
|
dialogName,
|
||||||
@@ -26,10 +26,7 @@ function EstimateMailDialog({
|
|||||||
style={{ width: 600 }}
|
style={{ width: 600 }}
|
||||||
>
|
>
|
||||||
<DialogSuspense>
|
<DialogSuspense>
|
||||||
<EstimateMailDialogContent
|
<EstimateMailDialogBody estimateId={estimateId} />
|
||||||
dialogName={dialogName}
|
|
||||||
estimateId={estimateId}
|
|
||||||
/>
|
|
||||||
</DialogSuspense>
|
</DialogSuspense>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import * as R from 'ramda';
|
||||||
|
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||||
|
import EstimateMailDialogContent from './EstimateMailDialogContent';
|
||||||
|
import { DialogsName } from '@/constants/dialogs';
|
||||||
|
|
||||||
|
interface EstimateMailDialogBodyProps {
|
||||||
|
estimateId: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
function EstimateMailDialogBodyRoot({
|
||||||
|
estimateId,
|
||||||
|
|
||||||
|
// #withDialogActions
|
||||||
|
closeDialog,
|
||||||
|
}: EstimateMailDialogBodyProps) {
|
||||||
|
const handleSubmit = () => {
|
||||||
|
closeDialog(DialogsName.EstimateMail);
|
||||||
|
};
|
||||||
|
const handleCancelClick = () => {
|
||||||
|
closeDialog(DialogsName.EstimateMail);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<EstimateMailDialogContent
|
||||||
|
estimateId={estimateId}
|
||||||
|
onFormSubmit={handleSubmit}
|
||||||
|
onCancelClick={handleCancelClick}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default R.compose(withDialogActions)(EstimateMailDialogBodyRoot);
|
||||||
@@ -6,12 +6,14 @@ import { DialogContent } from '@/components';
|
|||||||
interface EstimateMailDialogBootValues {
|
interface EstimateMailDialogBootValues {
|
||||||
estimateId: number;
|
estimateId: number;
|
||||||
mailOptions: any;
|
mailOptions: any;
|
||||||
|
redirectToEstimatesList: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const EstimateMailDialagBoot = createContext<EstimateMailDialogBootValues>();
|
const EstimateMailDialagBoot = createContext<EstimateMailDialogBootValues>();
|
||||||
|
|
||||||
interface EstimateMailDialogBootProps {
|
interface EstimateMailDialogBootProps {
|
||||||
estimateId: number;
|
estimateId: number;
|
||||||
|
redirectToEstimatesList?: boolean;
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,6 +22,7 @@ interface EstimateMailDialogBootProps {
|
|||||||
*/
|
*/
|
||||||
function EstimateMailDialogBoot({
|
function EstimateMailDialogBoot({
|
||||||
estimateId,
|
estimateId,
|
||||||
|
redirectToEstimatesList,
|
||||||
...props
|
...props
|
||||||
}: EstimateMailDialogBootProps) {
|
}: EstimateMailDialogBootProps) {
|
||||||
const { data: mailOptions, isLoading: isMailOptionsLoading } =
|
const { data: mailOptions, isLoading: isMailOptionsLoading } =
|
||||||
@@ -29,6 +32,7 @@ function EstimateMailDialogBoot({
|
|||||||
saleEstimateId: estimateId,
|
saleEstimateId: estimateId,
|
||||||
mailOptions,
|
mailOptions,
|
||||||
isMailOptionsLoading,
|
isMailOptionsLoading,
|
||||||
|
redirectToEstimatesList,
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -2,16 +2,21 @@ import { EstimateMailDialogBoot } from './EstimateMailDialogBoot';
|
|||||||
import { EstimateMailDialogForm } from './EstimateMailDialogForm';
|
import { EstimateMailDialogForm } from './EstimateMailDialogForm';
|
||||||
|
|
||||||
interface EstimateMailDialogContentProps {
|
interface EstimateMailDialogContentProps {
|
||||||
dialogName: string;
|
|
||||||
estimateId: number;
|
estimateId: number;
|
||||||
|
onFormSubmit?: () => void;
|
||||||
|
onCancelClick?: () => void;
|
||||||
}
|
}
|
||||||
export default function EstimateMailDialogContent({
|
export default function EstimateMailDialogContent({
|
||||||
dialogName,
|
|
||||||
estimateId,
|
estimateId,
|
||||||
|
onFormSubmit,
|
||||||
|
onCancelClick,
|
||||||
}: EstimateMailDialogContentProps) {
|
}: EstimateMailDialogContentProps) {
|
||||||
return (
|
return (
|
||||||
<EstimateMailDialogBoot estimateId={estimateId}>
|
<EstimateMailDialogBoot estimateId={estimateId}>
|
||||||
<EstimateMailDialogForm />
|
<EstimateMailDialogForm
|
||||||
|
onFormSubmit={onFormSubmit}
|
||||||
|
onCancelClick={onCancelClick}
|
||||||
|
/>
|
||||||
</EstimateMailDialogBoot>
|
</EstimateMailDialogBoot>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import { Formik } from 'formik';
|
import { Formik } from 'formik';
|
||||||
import * as R from 'ramda';
|
import * as R from 'ramda';
|
||||||
|
import { Intent } from '@blueprintjs/core';
|
||||||
import { useEstimateMailDialogBoot } from './EstimateMailDialogBoot';
|
import { useEstimateMailDialogBoot } from './EstimateMailDialogBoot';
|
||||||
import { DialogsName } from '@/constants/dialogs';
|
import { DialogsName } from '@/constants/dialogs';
|
||||||
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||||
@@ -12,7 +13,6 @@ import {
|
|||||||
transformMailFormToInitialValues,
|
transformMailFormToInitialValues,
|
||||||
transformMailFormToRequest,
|
transformMailFormToRequest,
|
||||||
} from '@/containers/SendMailNotification/utils';
|
} from '@/containers/SendMailNotification/utils';
|
||||||
import { Intent } from '@blueprintjs/core';
|
|
||||||
import { AppToaster } from '@/components';
|
import { AppToaster } from '@/components';
|
||||||
|
|
||||||
const initialFormValues = {
|
const initialFormValues = {
|
||||||
@@ -25,11 +25,15 @@ interface EstimateMailFormValues extends MailNotificationFormValues {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function EstimateMailDialogFormRoot({
|
function EstimateMailDialogFormRoot({
|
||||||
|
onFormSubmit,
|
||||||
|
onCancelClick,
|
||||||
|
|
||||||
// #withDialogClose
|
// #withDialogClose
|
||||||
closeDialog,
|
closeDialog,
|
||||||
}) {
|
}) {
|
||||||
const { mutateAsync: sendEstimateMail } = useSendSaleEstimateMail();
|
const { mutateAsync: sendEstimateMail } = useSendSaleEstimateMail();
|
||||||
const { mailOptions, saleEstimateId } = useEstimateMailDialogBoot();
|
const { mailOptions, saleEstimateId, redirectToEstimatesList } =
|
||||||
|
useEstimateMailDialogBoot();
|
||||||
|
|
||||||
const initialValues = transformMailFormToInitialValues(
|
const initialValues = transformMailFormToInitialValues(
|
||||||
mailOptions,
|
mailOptions,
|
||||||
@@ -48,14 +52,16 @@ function EstimateMailDialogFormRoot({
|
|||||||
});
|
});
|
||||||
closeDialog(DialogsName.EstimateMail);
|
closeDialog(DialogsName.EstimateMail);
|
||||||
setSubmitting(false);
|
setSubmitting(false);
|
||||||
|
onFormSubmit && onFormSubmit();
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch(() => {
|
||||||
setSubmitting(false);
|
setSubmitting(false);
|
||||||
closeDialog(DialogsName.EstimateMail);
|
closeDialog(DialogsName.EstimateMail);
|
||||||
AppToaster.show({
|
AppToaster.show({
|
||||||
message: 'Something went wrong.',
|
message: 'Something went wrong.',
|
||||||
intent: Intent.DANGER,
|
intent: Intent.DANGER,
|
||||||
});
|
});
|
||||||
|
onCancelClick && onCancelClick();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import React from 'react';
|
||||||
|
import { Dialog, DialogSuspense } from '@/components';
|
||||||
|
import withDialogRedux from '@/components/DialogReduxConnect';
|
||||||
|
import { compose } from '@/utils';
|
||||||
|
|
||||||
|
const InvoiceFormMailDeliverDialogContent = React.lazy(
|
||||||
|
() => import('./InvoiceFormMailDeliverDialogContent'),
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invoice mail dialog.
|
||||||
|
*/
|
||||||
|
function InvoiceFormMailDeliverDialog({
|
||||||
|
dialogName,
|
||||||
|
payload: { invoiceId = null },
|
||||||
|
isOpen,
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
name={dialogName}
|
||||||
|
title={'Invoice Mail'}
|
||||||
|
isOpen={isOpen}
|
||||||
|
canEscapeJeyClose={false}
|
||||||
|
isCloseButtonShown={false}
|
||||||
|
autoFocus={true}
|
||||||
|
style={{ width: 600 }}
|
||||||
|
>
|
||||||
|
<DialogSuspense>
|
||||||
|
<InvoiceFormMailDeliverDialogContent
|
||||||
|
dialogName={dialogName}
|
||||||
|
invoiceId={invoiceId}
|
||||||
|
/>
|
||||||
|
</DialogSuspense>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default compose(withDialogRedux())(InvoiceFormMailDeliverDialog);
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import * as R from 'ramda';
|
||||||
|
import { useHistory } from 'react-router-dom';
|
||||||
|
import InvoiceMailDialogContent from '../../../InvoiceMailDialog/InvoiceMailDialogContent';
|
||||||
|
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||||
|
import { DialogsName } from '@/constants/dialogs';
|
||||||
|
|
||||||
|
interface InvoiceFormDeliverDialogContent {
|
||||||
|
invoiceId: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
function InvoiceFormDeliverDialogContentRoot({
|
||||||
|
invoiceId,
|
||||||
|
|
||||||
|
// #withDialogActions
|
||||||
|
closeDialog,
|
||||||
|
}: InvoiceFormDeliverDialogContent) {
|
||||||
|
const history = useHistory();
|
||||||
|
|
||||||
|
const handleSubmit = () => {
|
||||||
|
history.push('/invoices');
|
||||||
|
closeDialog(DialogsName.InvoiceFormMailDeliver);
|
||||||
|
};
|
||||||
|
const handleCancel = () => {
|
||||||
|
history.push('/invoices');
|
||||||
|
closeDialog(DialogsName.InvoiceFormMailDeliver);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<InvoiceMailDialogContent
|
||||||
|
invoiceId={invoiceId}
|
||||||
|
onFormSubmit={handleSubmit}
|
||||||
|
onCancelClick={handleCancel}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default R.compose(withDialogActions)(
|
||||||
|
InvoiceFormDeliverDialogContentRoot,
|
||||||
|
);
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import React from 'react';
|
|
||||||
import { useFormikContext } from 'formik';
|
import { useFormikContext } from 'formik';
|
||||||
import InvoiceNumberDialog from '@/containers/Dialogs/InvoiceNumberDialog';
|
import InvoiceNumberDialog from '@/containers/Dialogs/InvoiceNumberDialog';
|
||||||
import { DialogsName } from '@/constants/dialogs';
|
import { DialogsName } from '@/constants/dialogs';
|
||||||
|
import InvoiceFormMailDeliverDialog from './Dialogs/InvoiceFormMailDeliverDialog/InvoiceFormMailDeliverDialog';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoice form dialogs.
|
* Invoice form dialogs.
|
||||||
@@ -23,9 +23,14 @@ export default function InvoiceFormDialogs() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<InvoiceNumberDialog
|
<>
|
||||||
dialogName={DialogsName.InvoiceNumberSettings}
|
<InvoiceNumberDialog
|
||||||
onConfirm={handleInvoiceNumberFormConfirm}
|
dialogName={DialogsName.InvoiceNumberSettings}
|
||||||
/>
|
onConfirm={handleInvoiceNumberFormConfirm}
|
||||||
|
/>
|
||||||
|
<InvoiceFormMailDeliverDialog
|
||||||
|
dialogName={DialogsName.InvoiceFormMailDeliver}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import { Dialog, DialogSuspense } from '@/components';
|
|||||||
import withDialogRedux from '@/components/DialogReduxConnect';
|
import withDialogRedux from '@/components/DialogReduxConnect';
|
||||||
import { compose } from '@/utils';
|
import { compose } from '@/utils';
|
||||||
|
|
||||||
const InvoiceMailDialogContent = React.lazy(
|
const InvoiceMailDialogBody = React.lazy(
|
||||||
() => import('./InvoiceMailDialogContent'),
|
() => import('./InvoiceMailDialogBody'),
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -21,15 +21,13 @@ function InvoiceMailDialog({
|
|||||||
name={dialogName}
|
name={dialogName}
|
||||||
title={'Invoice Mail'}
|
title={'Invoice Mail'}
|
||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
canEscapeJeyClose={true}
|
canEscapeJeyClose={false}
|
||||||
|
isCloseButtonShown={false}
|
||||||
autoFocus={true}
|
autoFocus={true}
|
||||||
style={{ width: 600 }}
|
style={{ width: 600 }}
|
||||||
>
|
>
|
||||||
<DialogSuspense>
|
<DialogSuspense>
|
||||||
<InvoiceMailDialogContent
|
<InvoiceMailDialogBody invoiceId={invoiceId} />
|
||||||
dialogName={dialogName}
|
|
||||||
invoiceId={invoiceId}
|
|
||||||
/>
|
|
||||||
</DialogSuspense>
|
</DialogSuspense>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import * as R from 'ramda';
|
||||||
|
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||||
|
import InvoiceMailDialogContent, {
|
||||||
|
InvoiceMailDialogContentProps,
|
||||||
|
} from './InvoiceMailDialogContent';
|
||||||
|
import { DialogsName } from '@/constants/dialogs';
|
||||||
|
|
||||||
|
export interface InvoiceMailDialogBodyProps
|
||||||
|
extends InvoiceMailDialogContentProps {}
|
||||||
|
|
||||||
|
function InvoiceMailDialogBodyRoot({
|
||||||
|
invoiceId,
|
||||||
|
onCancelClick,
|
||||||
|
onFormSubmit,
|
||||||
|
|
||||||
|
// #withDialogActions
|
||||||
|
closeDialog,
|
||||||
|
}: InvoiceMailDialogBodyProps) {
|
||||||
|
const handleCancelClick = () => {
|
||||||
|
closeDialog(DialogsName.InvoiceMail);
|
||||||
|
};
|
||||||
|
const handleSubmitClick = () => {
|
||||||
|
closeDialog(DialogsName.InvoiceMail);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<InvoiceMailDialogContent
|
||||||
|
invoiceId={invoiceId}
|
||||||
|
onCancelClick={handleCancelClick}
|
||||||
|
onFormSubmit={handleSubmitClick}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default R.compose(withDialogActions)(InvoiceMailDialogBodyRoot);
|
||||||
@@ -6,12 +6,14 @@ import { DialogContent } from '@/components';
|
|||||||
interface InvoiceMailDialogBootValues {
|
interface InvoiceMailDialogBootValues {
|
||||||
invoiceId: number;
|
invoiceId: number;
|
||||||
mailOptions: any;
|
mailOptions: any;
|
||||||
|
redirectToInvoicesList: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const InvoiceMailDialagBoot = createContext<InvoiceMailDialogBootValues>();
|
const InvoiceMailDialagBoot = createContext<InvoiceMailDialogBootValues>();
|
||||||
|
|
||||||
interface InvoiceMailDialogBootProps {
|
interface InvoiceMailDialogBootProps {
|
||||||
invoiceId: number;
|
invoiceId: number;
|
||||||
|
redirectToInvoicesList?: boolean;
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,6 +22,7 @@ interface InvoiceMailDialogBootProps {
|
|||||||
*/
|
*/
|
||||||
function InvoiceMailDialogBoot({
|
function InvoiceMailDialogBoot({
|
||||||
invoiceId,
|
invoiceId,
|
||||||
|
redirectToInvoicesList,
|
||||||
...props
|
...props
|
||||||
}: InvoiceMailDialogBootProps) {
|
}: InvoiceMailDialogBootProps) {
|
||||||
const { data: mailOptions, isLoading: isMailOptionsLoading } =
|
const { data: mailOptions, isLoading: isMailOptionsLoading } =
|
||||||
@@ -29,6 +32,7 @@ function InvoiceMailDialogBoot({
|
|||||||
saleInvoiceId: invoiceId,
|
saleInvoiceId: invoiceId,
|
||||||
mailOptions,
|
mailOptions,
|
||||||
isMailOptionsLoading,
|
isMailOptionsLoading,
|
||||||
|
redirectToInvoicesList,
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,17 +1,22 @@
|
|||||||
import { InvoiceMailDialogBoot } from './InvoiceMailDialogBoot';
|
import { InvoiceMailDialogBoot } from './InvoiceMailDialogBoot';
|
||||||
import { InvoiceMailDialogForm } from './InvoiceMailDialogForm';
|
import { InvoiceMailDialogForm } from './InvoiceMailDialogForm';
|
||||||
|
|
||||||
interface InvoiceMailDialogContentProps {
|
export interface InvoiceMailDialogContentProps {
|
||||||
dialogName: string;
|
|
||||||
invoiceId: number;
|
invoiceId: number;
|
||||||
|
onFormSubmit?: () => void;
|
||||||
|
onCancelClick?: () => void;
|
||||||
}
|
}
|
||||||
export default function InvoiceMailDialogContent({
|
export default function InvoiceMailDialogContent({
|
||||||
dialogName,
|
|
||||||
invoiceId,
|
invoiceId,
|
||||||
|
onFormSubmit,
|
||||||
|
onCancelClick,
|
||||||
}: InvoiceMailDialogContentProps) {
|
}: InvoiceMailDialogContentProps) {
|
||||||
return (
|
return (
|
||||||
<InvoiceMailDialogBoot invoiceId={invoiceId}>
|
<InvoiceMailDialogBoot invoiceId={invoiceId}>
|
||||||
<InvoiceMailDialogForm />
|
<InvoiceMailDialogForm
|
||||||
|
onFormSubmit={onFormSubmit}
|
||||||
|
onCancelClick={onCancelClick}
|
||||||
|
/>
|
||||||
</InvoiceMailDialogBoot>
|
</InvoiceMailDialogBoot>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import { Formik } from 'formik';
|
import { Formik } from 'formik';
|
||||||
import * as R from 'ramda';
|
|
||||||
import { Intent } from '@blueprintjs/core';
|
import { Intent } from '@blueprintjs/core';
|
||||||
import { useInvoiceMailDialogBoot } from './InvoiceMailDialogBoot';
|
import { useInvoiceMailDialogBoot } from './InvoiceMailDialogBoot';
|
||||||
import { DialogsName } from '@/constants/dialogs';
|
|
||||||
import { AppToaster } from '@/components';
|
import { AppToaster } from '@/components';
|
||||||
import { useSendSaleInvoiceMail } from '@/hooks/query';
|
import { useSendSaleInvoiceMail } from '@/hooks/query';
|
||||||
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
|
||||||
import { InvoiceMailDialogFormContent } from './InvoiceMailDialogFormContent';
|
import { InvoiceMailDialogFormContent } from './InvoiceMailDialogFormContent';
|
||||||
import { InvoiceMailFormSchema } from './InvoiceMailDialogForm.schema';
|
import { InvoiceMailFormSchema } from './InvoiceMailDialogForm.schema';
|
||||||
import {
|
import {
|
||||||
@@ -25,10 +22,7 @@ interface InvoiceMailFormValues extends MailNotificationFormValues {
|
|||||||
attachInvoice: boolean;
|
attachInvoice: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
function InvoiceMailDialogFormRoot({
|
export function InvoiceMailDialogForm({ onFormSubmit, onCancelClick }) {
|
||||||
// #withDialogActions
|
|
||||||
closeDialog,
|
|
||||||
}) {
|
|
||||||
const { mailOptions, saleInvoiceId } = useInvoiceMailDialogBoot();
|
const { mailOptions, saleInvoiceId } = useInvoiceMailDialogBoot();
|
||||||
const { mutateAsync: sendInvoiceMail } = useSendSaleInvoiceMail();
|
const { mutateAsync: sendInvoiceMail } = useSendSaleInvoiceMail();
|
||||||
|
|
||||||
@@ -47,8 +41,8 @@ function InvoiceMailDialogFormRoot({
|
|||||||
message: 'The mail notification has been sent successfully.',
|
message: 'The mail notification has been sent successfully.',
|
||||||
intent: Intent.SUCCESS,
|
intent: Intent.SUCCESS,
|
||||||
});
|
});
|
||||||
closeDialog(DialogsName.InvoiceMail);
|
|
||||||
setSubmitting(false);
|
setSubmitting(false);
|
||||||
|
onFormSubmit && onFormSubmit(values);
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
AppToaster.show({
|
AppToaster.show({
|
||||||
@@ -60,7 +54,7 @@ function InvoiceMailDialogFormRoot({
|
|||||||
};
|
};
|
||||||
// Handle the close button click.
|
// Handle the close button click.
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
closeDialog(DialogsName.InvoiceMail);
|
onCancelClick && onCancelClick();
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -73,7 +67,3 @@ function InvoiceMailDialogFormRoot({
|
|||||||
</Formik>
|
</Formik>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const InvoiceMailDialogForm = R.compose(withDialogActions)(
|
|
||||||
InvoiceMailDialogFormRoot,
|
|
||||||
);
|
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
export * from './InvoiceMailDialog';
|
export * from './InvoiceMailDialog';
|
||||||
|
export * from './InvoiceMailDialogContent';
|
||||||
@@ -13,7 +13,12 @@ const PaymentMailDialogContent = React.lazy(
|
|||||||
*/
|
*/
|
||||||
function PaymentMailDialog({
|
function PaymentMailDialog({
|
||||||
dialogName,
|
dialogName,
|
||||||
payload: { paymentReceiveId = null },
|
payload: {
|
||||||
|
paymentReceiveId = null,
|
||||||
|
|
||||||
|
// Redirects to the payments list on mail submitting.
|
||||||
|
redirectToPaymentsList = false,
|
||||||
|
},
|
||||||
isOpen,
|
isOpen,
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
@@ -29,6 +34,7 @@ function PaymentMailDialog({
|
|||||||
<PaymentMailDialogContent
|
<PaymentMailDialogContent
|
||||||
dialogName={dialogName}
|
dialogName={dialogName}
|
||||||
paymentReceiveId={paymentReceiveId}
|
paymentReceiveId={paymentReceiveId}
|
||||||
|
redirectToPaymentsList={redirectToPaymentsList}
|
||||||
/>
|
/>
|
||||||
</DialogSuspense>
|
</DialogSuspense>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ const PaymentMailDialogBootContext =
|
|||||||
|
|
||||||
interface PaymentMailDialogBootProps {
|
interface PaymentMailDialogBootProps {
|
||||||
paymentReceiveId: number;
|
paymentReceiveId: number;
|
||||||
|
redirectToPaymentsList: boolean;
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,7 +30,8 @@ function PaymentMailDialogBoot({
|
|||||||
const provider = {
|
const provider = {
|
||||||
mailOptions,
|
mailOptions,
|
||||||
isMailOptionsLoading,
|
isMailOptionsLoading,
|
||||||
paymentReceiveId
|
paymentReceiveId,
|
||||||
|
redirectToPaymentsList
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -4,13 +4,18 @@ import { PaymentMailDialogForm } from './PaymentMailDialogForm';
|
|||||||
interface PaymentMailDialogContentProps {
|
interface PaymentMailDialogContentProps {
|
||||||
dialogName: string;
|
dialogName: string;
|
||||||
paymentReceiveId: number;
|
paymentReceiveId: number;
|
||||||
|
redirectToPaymentsList: boolean;
|
||||||
}
|
}
|
||||||
export default function PaymentMailDialogContent({
|
export default function PaymentMailDialogContent({
|
||||||
dialogName,
|
dialogName,
|
||||||
paymentReceiveId,
|
paymentReceiveId,
|
||||||
|
redirectToPaymentsList,
|
||||||
}: PaymentMailDialogContentProps) {
|
}: PaymentMailDialogContentProps) {
|
||||||
return (
|
return (
|
||||||
<PaymentMailDialogBoot paymentReceiveId={paymentReceiveId}>
|
<PaymentMailDialogBoot
|
||||||
|
paymentReceiveId={paymentReceiveId}
|
||||||
|
redirectToPaymentsList={redirectToPaymentsList}
|
||||||
|
>
|
||||||
<PaymentMailDialogForm />
|
<PaymentMailDialogForm />
|
||||||
</PaymentMailDialogBoot>
|
</PaymentMailDialogBoot>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import { Formik, FormikBag } from 'formik';
|
|||||||
import * as R from 'ramda';
|
import * as R from 'ramda';
|
||||||
import { Intent } from '@blueprintjs/core';
|
import { Intent } from '@blueprintjs/core';
|
||||||
import { usePaymentMailDialogBoot } from './PaymentMailDialogBoot';
|
import { usePaymentMailDialogBoot } from './PaymentMailDialogBoot';
|
||||||
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
|
||||||
import { DialogsName } from '@/constants/dialogs';
|
import { DialogsName } from '@/constants/dialogs';
|
||||||
import { useSendPaymentReceiveMail } from '@/hooks/query';
|
import { useSendPaymentReceiveMail } from '@/hooks/query';
|
||||||
import { PaymentMailDialogFormContent } from './PaymentMailDialogFormContent';
|
import { PaymentMailDialogFormContent } from './PaymentMailDialogFormContent';
|
||||||
@@ -14,6 +13,8 @@ import {
|
|||||||
transformMailFormToInitialValues,
|
transformMailFormToInitialValues,
|
||||||
} from '@/containers/SendMailNotification/utils';
|
} from '@/containers/SendMailNotification/utils';
|
||||||
import { AppToaster } from '@/components';
|
import { AppToaster } from '@/components';
|
||||||
|
import { useHistory } from 'react-router-dom';
|
||||||
|
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||||
|
|
||||||
const initialFormValues = {
|
const initialFormValues = {
|
||||||
...initialMailNotificationValues,
|
...initialMailNotificationValues,
|
||||||
@@ -28,9 +29,12 @@ export function PaymentMailDialogFormRoot({
|
|||||||
// #withDialogActions
|
// #withDialogActions
|
||||||
closeDialog,
|
closeDialog,
|
||||||
}) {
|
}) {
|
||||||
const { mailOptions, paymentReceiveId } = usePaymentMailDialogBoot();
|
const { mailOptions, paymentReceiveId, redirectToPaymentsList } =
|
||||||
|
usePaymentMailDialogBoot();
|
||||||
const { mutateAsync: sendPaymentMail } = useSendPaymentReceiveMail();
|
const { mutateAsync: sendPaymentMail } = useSendPaymentReceiveMail();
|
||||||
|
|
||||||
|
const history = useHistory();
|
||||||
|
|
||||||
const initialValues = transformMailFormToInitialValues(
|
const initialValues = transformMailFormToInitialValues(
|
||||||
mailOptions,
|
mailOptions,
|
||||||
initialFormValues,
|
initialFormValues,
|
||||||
@@ -51,6 +55,11 @@ export function PaymentMailDialogFormRoot({
|
|||||||
});
|
});
|
||||||
setSubmitting(false);
|
setSubmitting(false);
|
||||||
closeDialog(DialogsName.PaymentMail);
|
closeDialog(DialogsName.PaymentMail);
|
||||||
|
|
||||||
|
// Redirects to payments list if the option is enabled.
|
||||||
|
if (redirectToPaymentsList) {
|
||||||
|
history.push('/payment-receives');
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
AppToaster.show({
|
AppToaster.show({
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import React from 'react';
|
||||||
|
import { Dialog, DialogSuspense } from '@/components';
|
||||||
|
import withDialogRedux from '@/components/DialogReduxConnect';
|
||||||
|
import { compose } from '@/utils';
|
||||||
|
|
||||||
|
const ReceiptFormMailDeliverDialogContent = React.lazy(
|
||||||
|
() => import('./ReceiptFormMailDeliverDialogContent'),
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Receipt mail dialog.
|
||||||
|
*/
|
||||||
|
function ReceiptFormMailDeliverDialog({
|
||||||
|
dialogName,
|
||||||
|
payload: { receiptId = null },
|
||||||
|
isOpen,
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
name={dialogName}
|
||||||
|
title={'Receipt Mail'}
|
||||||
|
isOpen={isOpen}
|
||||||
|
canEscapeJeyClose={false}
|
||||||
|
isCloseButtonShown={false}
|
||||||
|
autoFocus={true}
|
||||||
|
style={{ width: 600 }}
|
||||||
|
>
|
||||||
|
<DialogSuspense>
|
||||||
|
<ReceiptFormMailDeliverDialogContent
|
||||||
|
dialogName={dialogName}
|
||||||
|
receiptId={receiptId}
|
||||||
|
/>
|
||||||
|
</DialogSuspense>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default compose(withDialogRedux())(ReceiptFormMailDeliverDialog);
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import * as R from 'ramda';
|
||||||
|
import { useHistory } from 'react-router-dom';
|
||||||
|
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||||
|
import ReceiptMailDialogContent from '../../ReceiptMailDialog/ReceiptMailDialogContent';
|
||||||
|
import { DialogsName } from '@/constants/dialogs';
|
||||||
|
|
||||||
|
interface ReceiptFormDeliverDialogContent {
|
||||||
|
receiptId: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
function ReceiptFormDeliverDialogContentRoot({
|
||||||
|
receiptId,
|
||||||
|
|
||||||
|
// #withDialogActions
|
||||||
|
closeDialog,
|
||||||
|
}: ReceiptFormDeliverDialogContent) {
|
||||||
|
const history = useHistory();
|
||||||
|
|
||||||
|
const handleSubmit = () => {
|
||||||
|
history.push('/receipts');
|
||||||
|
closeDialog(DialogsName.ReceiptFormMailDeliver);
|
||||||
|
};
|
||||||
|
const handleCancel = () => {
|
||||||
|
history.push('/receipts');
|
||||||
|
closeDialog(DialogsName.ReceiptFormMailDeliver);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ReceiptMailDialogContent
|
||||||
|
receiptId={receiptId}
|
||||||
|
onFormSubmit={handleSubmit}
|
||||||
|
onCancelClick={handleCancel}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default R.compose(withDialogActions)(
|
||||||
|
ReceiptFormDeliverDialogContentRoot,
|
||||||
|
);
|
||||||
@@ -2,6 +2,8 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useFormikContext } from 'formik';
|
import { useFormikContext } from 'formik';
|
||||||
import ReceiptNumberDialog from '@/containers/Dialogs/ReceiptNumberDialog';
|
import ReceiptNumberDialog from '@/containers/Dialogs/ReceiptNumberDialog';
|
||||||
|
import ReceiptFormMailDeliverDialog from './Dialogs/ReceiptFormMailDeliverDialog';
|
||||||
|
import { DialogsName } from '@/constants/dialogs';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Receipt form dialogs.
|
* Receipt form dialogs.
|
||||||
@@ -27,6 +29,9 @@ export default function ReceiptFormDialogs() {
|
|||||||
dialogName={'receipt-number-form'}
|
dialogName={'receipt-number-form'}
|
||||||
onConfirm={handleReceiptNumberFormConfirm}
|
onConfirm={handleReceiptNumberFormConfirm}
|
||||||
/>
|
/>
|
||||||
|
<ReceiptFormMailDeliverDialog
|
||||||
|
dialogName={DialogsName.ReceiptFormMailDeliver}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ import { Dialog, DialogSuspense } from '@/components';
|
|||||||
import withDialogRedux from '@/components/DialogReduxConnect';
|
import withDialogRedux from '@/components/DialogReduxConnect';
|
||||||
import { compose } from '@/utils';
|
import { compose } from '@/utils';
|
||||||
|
|
||||||
const ReceiptMailDialogContent = React.lazy(
|
const ReceiptMailDialogBody = React.lazy(
|
||||||
() => import('./ReceiptMailDialogContent'),
|
() => import('./ReceiptMailDialogBody'),
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoice mail dialog.
|
* Receipt mail dialog.
|
||||||
*/
|
*/
|
||||||
function ReceiptMailDialog({
|
function ReceiptMailDialog({
|
||||||
dialogName,
|
dialogName,
|
||||||
@@ -26,10 +26,7 @@ function ReceiptMailDialog({
|
|||||||
style={{ width: 600 }}
|
style={{ width: 600 }}
|
||||||
>
|
>
|
||||||
<DialogSuspense>
|
<DialogSuspense>
|
||||||
<ReceiptMailDialogContent
|
<ReceiptMailDialogBody receiptId={receiptId} />
|
||||||
dialogName={dialogName}
|
|
||||||
receiptId={receiptId}
|
|
||||||
/>
|
|
||||||
</DialogSuspense>
|
</DialogSuspense>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import * as R from 'ramda';
|
||||||
|
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||||
|
import ReceiptMailDialogContent, {
|
||||||
|
ReceiptMailDialogContentProps,
|
||||||
|
} from './ReceiptMailDialogContent';
|
||||||
|
import { DialogsName } from '@/constants/dialogs';
|
||||||
|
|
||||||
|
interface ReceiptMailDialogBodyProps extends ReceiptMailDialogContentProps {}
|
||||||
|
|
||||||
|
function ReceiptMailDialogBodyRoot({
|
||||||
|
receiptId,
|
||||||
|
|
||||||
|
// #withDialogActions
|
||||||
|
closeDialog,
|
||||||
|
}: ReceiptMailDialogBodyProps) {
|
||||||
|
const handleCancelClick = () => {
|
||||||
|
closeDialog(DialogsName.ReceiptMail);
|
||||||
|
};
|
||||||
|
const handleSubmitClick = () => {
|
||||||
|
closeDialog(DialogsName.ReceiptMail);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ReceiptMailDialogContent
|
||||||
|
receiptId={receiptId}
|
||||||
|
onFormSubmit={handleSubmitClick}
|
||||||
|
onCancelClick={handleCancelClick}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default R.compose(withDialogActions)(ReceiptMailDialogBodyRoot);
|
||||||
@@ -6,6 +6,7 @@ import { DialogContent } from '@/components';
|
|||||||
interface ReceiptMailDialogBootValues {
|
interface ReceiptMailDialogBootValues {
|
||||||
receiptId: number;
|
receiptId: number;
|
||||||
mailOptions: any;
|
mailOptions: any;
|
||||||
|
redirectToReceiptsList: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ReceiptMailDialogBootContext =
|
const ReceiptMailDialogBootContext =
|
||||||
@@ -14,6 +15,7 @@ const ReceiptMailDialogBootContext =
|
|||||||
interface ReceiptMailDialogBootProps {
|
interface ReceiptMailDialogBootProps {
|
||||||
receiptId: number;
|
receiptId: number;
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
|
redirectToReceiptsList?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -21,6 +23,7 @@ interface ReceiptMailDialogBootProps {
|
|||||||
*/
|
*/
|
||||||
function ReceiptMailDialogBoot({
|
function ReceiptMailDialogBoot({
|
||||||
receiptId,
|
receiptId,
|
||||||
|
redirectToReceiptsList = false,
|
||||||
...props
|
...props
|
||||||
}: ReceiptMailDialogBootProps) {
|
}: ReceiptMailDialogBootProps) {
|
||||||
const { data: mailOptions, isLoading: isMailOptionsLoading } =
|
const { data: mailOptions, isLoading: isMailOptionsLoading } =
|
||||||
@@ -30,6 +33,7 @@ function ReceiptMailDialogBoot({
|
|||||||
saleReceiptId: receiptId,
|
saleReceiptId: receiptId,
|
||||||
mailOptions,
|
mailOptions,
|
||||||
isMailOptionsLoading,
|
isMailOptionsLoading,
|
||||||
|
redirectToReceiptsList,
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -2,17 +2,22 @@ import React from 'react';
|
|||||||
import { ReceiptMailDialogBoot } from './ReceiptMailDialogBoot';
|
import { ReceiptMailDialogBoot } from './ReceiptMailDialogBoot';
|
||||||
import { ReceiptMailDialogForm } from './ReceiptMailDialogForm';
|
import { ReceiptMailDialogForm } from './ReceiptMailDialogForm';
|
||||||
|
|
||||||
interface ReceiptMailDialogContentProps {
|
export interface ReceiptMailDialogContentProps {
|
||||||
dialogName: string
|
|
||||||
receiptId: number;
|
receiptId: number;
|
||||||
|
onFormSubmit?: () => void;
|
||||||
|
onCancelClick?: () => void;
|
||||||
}
|
}
|
||||||
export default function ReceiptMailDialogContent({
|
export default function ReceiptMailDialogContent({
|
||||||
dialogName,
|
|
||||||
receiptId,
|
receiptId,
|
||||||
|
onFormSubmit,
|
||||||
|
onCancelClick
|
||||||
}: ReceiptMailDialogContentProps) {
|
}: ReceiptMailDialogContentProps) {
|
||||||
return (
|
return (
|
||||||
<ReceiptMailDialogBoot receiptId={receiptId}>
|
<ReceiptMailDialogBoot receiptId={receiptId}>
|
||||||
<ReceiptMailDialogForm />
|
<ReceiptMailDialogForm
|
||||||
|
onFormSubmit={onFormSubmit}
|
||||||
|
onCancelClick={onCancelClick}
|
||||||
|
/>
|
||||||
</ReceiptMailDialogBoot>
|
</ReceiptMailDialogBoot>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,16 @@ interface ReceiptMailFormValues extends MailNotificationFormValues {
|
|||||||
attachReceipt: boolean;
|
attachReceipt: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
function ReceiptMailDialogFormRoot({ closeDialog }) {
|
interface ReceiptMailDialogFormProps {
|
||||||
|
onFormSubmit?: () => void;
|
||||||
|
onCancelClick?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ReceiptMailDialogForm({
|
||||||
|
// #props
|
||||||
|
onFormSubmit,
|
||||||
|
onCancelClick,
|
||||||
|
}: ReceiptMailDialogFormProps) {
|
||||||
const { mailOptions, saleReceiptId } = useReceiptMailDialogBoot();
|
const { mailOptions, saleReceiptId } = useReceiptMailDialogBoot();
|
||||||
const { mutateAsync: sendReceiptMail } = useSendSaleReceiptMail();
|
const { mutateAsync: sendReceiptMail } = useSendSaleReceiptMail();
|
||||||
|
|
||||||
@@ -46,8 +55,8 @@ function ReceiptMailDialogFormRoot({ closeDialog }) {
|
|||||||
message: 'The mail notification has been sent successfully.',
|
message: 'The mail notification has been sent successfully.',
|
||||||
intent: Intent.SUCCESS,
|
intent: Intent.SUCCESS,
|
||||||
});
|
});
|
||||||
closeDialog(DialogsName.ReceiptMail);
|
|
||||||
setSubmitting(false);
|
setSubmitting(false);
|
||||||
|
onFormSubmit && onFormSubmit(values);
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
AppToaster.show({
|
AppToaster.show({
|
||||||
@@ -59,7 +68,7 @@ function ReceiptMailDialogFormRoot({ closeDialog }) {
|
|||||||
};
|
};
|
||||||
// Handle the close button click.
|
// Handle the close button click.
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
closeDialog(DialogsName.ReceiptMail);
|
onCancelClick && onCancelClick();
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -68,7 +77,3 @@ function ReceiptMailDialogFormRoot({ closeDialog }) {
|
|||||||
</Formik>
|
</Formik>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ReceiptMailDialogForm = R.compose(withDialogActions)(
|
|
||||||
ReceiptMailDialogFormRoot,
|
|
||||||
);
|
|
||||||
|
|||||||
Reference in New Issue
Block a user