mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-19 22:30:31 +00:00
feat: mail receipt preview
This commit is contained in:
@@ -176,6 +176,7 @@ export default class CreditNote extends mixin(TenantModel, [
|
|||||||
const Branch = require('models/Branch');
|
const Branch = require('models/Branch');
|
||||||
const Document = require('models/Document');
|
const Document = require('models/Document');
|
||||||
const Warehouse = require('models/Warehouse');
|
const Warehouse = require('models/Warehouse');
|
||||||
|
const { PdfTemplate } = require('models/PdfTemplate');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
/**
|
/**
|
||||||
@@ -266,6 +267,18 @@ export default class CreditNote extends mixin(TenantModel, [
|
|||||||
query.where('model_ref', 'CreditNote');
|
query.where('model_ref', 'CreditNote');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Credit note may belongs to pdf branding template.
|
||||||
|
*/
|
||||||
|
pdfTemplate: {
|
||||||
|
relation: Model.BelongsToOneRelation,
|
||||||
|
modelClass: PdfTemplate,
|
||||||
|
join: {
|
||||||
|
from: 'credit_notes.pdfTemplateId',
|
||||||
|
to: 'pdf_templates.id',
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ export default class PaymentReceive extends mixin(TenantModel, [
|
|||||||
const Account = require('models/Account');
|
const Account = require('models/Account');
|
||||||
const Branch = require('models/Branch');
|
const Branch = require('models/Branch');
|
||||||
const Document = require('models/Document');
|
const Document = require('models/Document');
|
||||||
|
const { PdfTemplate } = require('models/PdfTemplate');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
customer: {
|
customer: {
|
||||||
@@ -135,6 +136,18 @@ export default class PaymentReceive extends mixin(TenantModel, [
|
|||||||
query.where('model_ref', 'PaymentReceive');
|
query.where('model_ref', 'PaymentReceive');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Payment received may belongs to pdf branding template.
|
||||||
|
*/
|
||||||
|
pdfTemplate: {
|
||||||
|
relation: Model.BelongsToOneRelation,
|
||||||
|
modelClass: PdfTemplate,
|
||||||
|
join: {
|
||||||
|
from: 'payment_receives.pdfTemplateId',
|
||||||
|
to: 'pdf_templates.id',
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { Inject } from 'typedi';
|
import { Inject, Service } from 'typedi';
|
||||||
import { SendSaleEstimateMail } from './SendSaleEstimateMail';
|
import { SendSaleEstimateMail } from './SendSaleEstimateMail';
|
||||||
import HasTenancyService from '@/services/Tenancy/TenancyService';
|
import HasTenancyService from '@/services/Tenancy/TenancyService';
|
||||||
import { GetSaleEstimateMailStateTransformer } from './GetSaleEstimateMailStateTransformer';
|
import { GetSaleEstimateMailStateTransformer } from './GetSaleEstimateMailStateTransformer';
|
||||||
import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable';
|
import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable';
|
||||||
|
|
||||||
|
@Service()
|
||||||
export class GetSaleEstimateMailState {
|
export class GetSaleEstimateMailState {
|
||||||
@Inject()
|
@Inject()
|
||||||
private estimateMail: SendSaleEstimateMail;
|
private estimateMail: SendSaleEstimateMail;
|
||||||
|
|||||||
@@ -9,7 +9,10 @@ export class GetSaleEstimateMailStateTransformer extends SaleEstimateTransfromer
|
|||||||
public includeAttributes = (): string[] => {
|
public includeAttributes = (): string[] => {
|
||||||
return [
|
return [
|
||||||
'estimateDate',
|
'estimateDate',
|
||||||
'formattedEstimateDate',
|
'estimateDateFormatted',
|
||||||
|
|
||||||
|
'expirationDate',
|
||||||
|
'expirationDateFormatted',
|
||||||
|
|
||||||
'total',
|
'total',
|
||||||
'totalFormatted',
|
'totalFormatted',
|
||||||
@@ -17,8 +20,7 @@ export class GetSaleEstimateMailStateTransformer extends SaleEstimateTransfromer
|
|||||||
'subtotal',
|
'subtotal',
|
||||||
'subtotalFormatted',
|
'subtotalFormatted',
|
||||||
|
|
||||||
'estimateNo',
|
'estimateNumber',
|
||||||
|
|
||||||
'entries',
|
'entries',
|
||||||
|
|
||||||
'companyName',
|
'companyName',
|
||||||
@@ -62,10 +64,65 @@ export class GetSaleEstimateMailStateTransformer extends SaleEstimateTransfromer
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Retrieves the estimate number.
|
||||||
* @param invoice
|
*/
|
||||||
|
protected estimateDateFormatted = (estimate) => {
|
||||||
|
return this.formattedEstimateDate(estimate);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the expiration date of the estimate.
|
||||||
|
* @param estimate
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
protected expirationDateFormatted = (estimate) => {
|
||||||
|
return this.formattedExpirationDate(estimate);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the total amount of the estimate.
|
||||||
|
* @param estimate
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
|
protected total(estimate) {
|
||||||
|
return estimate.amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the subtotal amount of the estimate.
|
||||||
|
* @param estimate
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
protected subtotal(estimate) {
|
||||||
|
return estimate.amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the formatted total of the estimate.
|
||||||
|
* @param estimate
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
protected totalFormatted(estimate) {
|
||||||
|
return this.formatMoney(estimate.amount, {
|
||||||
|
currencyCode: estimate.currencyCode,
|
||||||
|
money: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the formatted subtotal of the estimate.
|
||||||
|
* @param estimate
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
protected subtotalFormatted = (estimate) => {
|
||||||
|
return this.formatNumber(estimate.amount, { money: false });
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the estimate entries.
|
||||||
|
* @param invoice
|
||||||
|
* @returns {Array}
|
||||||
|
*/
|
||||||
protected entries = (invoice) => {
|
protected entries = (invoice) => {
|
||||||
return this.item(
|
return this.item(
|
||||||
invoice.entries,
|
invoice.entries,
|
||||||
@@ -92,9 +149,18 @@ class GetSaleEstimateMailStateEntryTransformer extends ItemEntryTransformer {
|
|||||||
return ['*'];
|
return ['*'];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Item name.
|
||||||
|
* @param entry
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
public name = (entry) => {
|
||||||
|
return entry.item.name;
|
||||||
|
};
|
||||||
|
|
||||||
public includeAttributes = (): string[] => {
|
public includeAttributes = (): string[] => {
|
||||||
return [
|
return [
|
||||||
'description',
|
'name',
|
||||||
'quantity',
|
'quantity',
|
||||||
'unitPrice',
|
'unitPrice',
|
||||||
'unitPriceFormatted',
|
'unitPriceFormatted',
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ export class GetPaymentReceivedMailState {
|
|||||||
.findById(paymentId)
|
.findById(paymentId)
|
||||||
.withGraphFetched('customer')
|
.withGraphFetched('customer')
|
||||||
.withGraphFetched('entries.invoice')
|
.withGraphFetched('entries.invoice')
|
||||||
|
.withGraphFetched('pdfTemplate')
|
||||||
.throwIfNotFound();
|
.throwIfNotFound();
|
||||||
|
|
||||||
const mailOptions =
|
const mailOptions =
|
||||||
|
|||||||
@@ -26,7 +26,10 @@ export class GetPaymentReceivedMailStateTransformer extends PaymentReceiveTransf
|
|||||||
'total',
|
'total',
|
||||||
'totalFormatted',
|
'totalFormatted',
|
||||||
|
|
||||||
'paymentNo',
|
'subtotal',
|
||||||
|
'subtotalFormatted',
|
||||||
|
|
||||||
|
'paymentNumber',
|
||||||
|
|
||||||
'entries',
|
'entries',
|
||||||
|
|
||||||
@@ -87,6 +90,17 @@ export class GetPaymentReceivedMailStateTransformer extends PaymentReceiveTransf
|
|||||||
return this.formatMoney(payment.paymentAmount);
|
return this.formatMoney(payment.paymentAmount);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the payment amount.
|
||||||
|
* @param payment
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
protected total = (payment) => {
|
||||||
|
return this.formatNumber(payment.amount, {
|
||||||
|
money: false,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the formatted payment amount.
|
* Retrieves the formatted payment amount.
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
@@ -95,6 +109,34 @@ export class GetPaymentReceivedMailStateTransformer extends PaymentReceiveTransf
|
|||||||
return this.formatMoney(payment.total);
|
return this.formatMoney(payment.total);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the payment amount.
|
||||||
|
* @param payment
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
protected subtotal = (payment) => {
|
||||||
|
return this.formatNumber(payment.amount, {
|
||||||
|
money: false,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the formatted payment amount.
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
protected subtotalFormatted = (payment) => {
|
||||||
|
return this.formatMoney(payment.total);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the payment number.
|
||||||
|
* @param payment
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
protected paymentNumber = (payment) => {
|
||||||
|
return payment.paymentReceiveNo;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the payment entries.
|
* Retrieves the payment entries.
|
||||||
* @param {IPaymentReceived} payment
|
* @param {IPaymentReceived} payment
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import {
|
|||||||
SendMailReceiptProps,
|
SendMailReceiptProps,
|
||||||
} from '../SendMailViewDrawer/SendMailViewReceiptPreview';
|
} from '../SendMailViewDrawer/SendMailViewReceiptPreview';
|
||||||
|
|
||||||
interface EstimateSendMailReceiptProps extends SendMailReceiptProps {
|
export interface EstimateSendMailReceiptProps extends SendMailReceiptProps {
|
||||||
// # Company name.
|
// # Company name.
|
||||||
companyLogoUri?: string;
|
companyLogoUri?: string;
|
||||||
companyName: string;
|
companyName: string;
|
||||||
|
|||||||
@@ -1,39 +1,20 @@
|
|||||||
import { css } from '@emotion/css';
|
import { css } from '@emotion/css';
|
||||||
import { EstimateSendMailReceipt } from './EstimateSendMailReceipt';
|
import { ComponentType, useMemo } from 'react';
|
||||||
|
import { EstimateSendMailReceipt, EstimateSendMailReceiptProps } from './EstimateSendMailReceipt';
|
||||||
import { EstimateSendMailPreviewHeader } from './EstimateSendMailPreviewHeader';
|
import { EstimateSendMailPreviewHeader } from './EstimateSendMailPreviewHeader';
|
||||||
import { Stack } from '@/components';
|
import { Stack } from '@/components';
|
||||||
|
import { useEstimateSendMailBoot } from './EstimateSendMailBoot';
|
||||||
|
import { useSendEstimateMailMessage } from './hooks';
|
||||||
|
import { defaultEstimateMailReceiptProps } from './_constants';
|
||||||
|
|
||||||
const defaultEstimateMailReceiptProps = {
|
|
||||||
companyName: 'Bigcapital Technology, Inc.',
|
|
||||||
companyLogoUri: ' ',
|
|
||||||
|
|
||||||
total: '$1,000.00',
|
|
||||||
subtotal: '$1,000.00',
|
|
||||||
estimateNumber: 'INV-0001',
|
|
||||||
expirationDate: '2 Oct 2024',
|
|
||||||
dueAmount: '$1,000.00',
|
|
||||||
items: [{ label: 'Web development', total: '$1000.00', quantity: 1 }],
|
|
||||||
message: `Hi Ahmed Bouhuolia,
|
|
||||||
|
|
||||||
Here's invoice # INV-00002 for $738.30
|
|
||||||
|
|
||||||
The amount outstanding of $737.30 is due on 01 Feb 2023.
|
|
||||||
|
|
||||||
From your online payment page you can print a PDF or view your outstanding bills.
|
|
||||||
|
|
||||||
If you have any questions, please let us know.
|
|
||||||
|
|
||||||
Thanks,
|
|
||||||
Bigcapital`,
|
|
||||||
};
|
|
||||||
export const EstimateSendMailReceiptPreview = () => {
|
export const EstimateSendMailReceiptPreview = () => {
|
||||||
return (
|
return (
|
||||||
<Stack>
|
<Stack>
|
||||||
<EstimateSendMailPreviewHeader />
|
<EstimateSendMailPreviewHeader />
|
||||||
|
|
||||||
<Stack px={4} py={6}>
|
<Stack px={4} py={6}>
|
||||||
<EstimateSendMailReceipt
|
<EstimateSendMailReceiptConnected
|
||||||
{...defaultEstimateMailReceiptProps}
|
|
||||||
className={css`
|
className={css`
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
border-radius: 5px !important;
|
border-radius: 5px !important;
|
||||||
@@ -46,3 +27,44 @@ export const EstimateSendMailReceiptPreview = () => {
|
|||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injects props from estimate mail state into the `EstimateSendMailReceipt` component.
|
||||||
|
*/
|
||||||
|
const withEstimateMailReceiptPreviewProps = <
|
||||||
|
P extends EstimateSendMailReceiptProps,
|
||||||
|
>(
|
||||||
|
WrappedComponent: ComponentType<P & EstimateSendMailReceiptProps>,
|
||||||
|
) => {
|
||||||
|
return function WithInvoiceMailReceiptPreviewProps(props: P) {
|
||||||
|
const { estimateMailState } = useEstimateSendMailBoot();
|
||||||
|
const message = useSendEstimateMailMessage();
|
||||||
|
|
||||||
|
const items = useMemo(
|
||||||
|
() =>
|
||||||
|
estimateMailState?.entries?.map((entry: any) => ({
|
||||||
|
quantity: entry.quantity,
|
||||||
|
total: entry.totalFormatted,
|
||||||
|
label: entry.name,
|
||||||
|
})),
|
||||||
|
[estimateMailState?.entries],
|
||||||
|
);
|
||||||
|
|
||||||
|
const mailReceiptPreviewProps = {
|
||||||
|
...defaultEstimateMailReceiptProps,
|
||||||
|
companyName: estimateMailState?.companyName,
|
||||||
|
companyLogoUri: estimateMailState?.companyLogoUri,
|
||||||
|
primaryColor: estimateMailState?.primaryColor,
|
||||||
|
total: estimateMailState?.totalFormatted,
|
||||||
|
expirationDate: estimateMailState?.expirationDateFormatted,
|
||||||
|
estimateNumber: estimateMailState?.estimateNumber,
|
||||||
|
estimateDate: estimateMailState?.estimateDateFormatted,
|
||||||
|
items,
|
||||||
|
message
|
||||||
|
};
|
||||||
|
return <WrappedComponent {...mailReceiptPreviewProps} {...props} />;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
const EstimateSendMailReceiptConnected = withEstimateMailReceiptPreviewProps(
|
||||||
|
EstimateSendMailReceipt
|
||||||
|
);
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
export const defaultEstimateMailReceiptProps = {
|
||||||
|
companyName: 'Bigcapital Technology, Inc.',
|
||||||
|
companyLogoUri: ' ',
|
||||||
|
|
||||||
|
total: '$1,000.00',
|
||||||
|
subtotal: '$1,000.00',
|
||||||
|
estimateNumber: 'INV-0001',
|
||||||
|
expirationDate: '2 Oct 2024',
|
||||||
|
dueAmount: '$1,000.00',
|
||||||
|
items: [{ label: 'Web development', total: '$1000.00', quantity: 1 }],
|
||||||
|
message: `Hi Ahmed Bouhuolia,
|
||||||
|
|
||||||
|
Here's invoice # INV-00002 for $738.30
|
||||||
|
|
||||||
|
The amount outstanding of $737.30 is due on 01 Feb 2023.
|
||||||
|
|
||||||
|
From your online payment page you can print a PDF or view your outstanding bills.
|
||||||
|
|
||||||
|
If you have any questions, please let us know.
|
||||||
|
|
||||||
|
Thanks,
|
||||||
|
Bigcapital`,
|
||||||
|
};
|
||||||
@@ -1,23 +1,14 @@
|
|||||||
import { css } from '@emotion/css';
|
import { css } from '@emotion/css';
|
||||||
import { PaymentReceivedMailReceipt } from './PaymentReceivedMailReceipt';
|
import { ComponentType, useMemo } from 'react';
|
||||||
|
import {
|
||||||
|
PaymentReceivedMailReceipt,
|
||||||
|
PaymentReceivedMailReceiptProps,
|
||||||
|
} from './PaymentReceivedMailReceipt';
|
||||||
import { PaymentReceivedMailPreviewHeader } from './PaymentReceivedMailPreviewHeader';
|
import { PaymentReceivedMailPreviewHeader } from './PaymentReceivedMailPreviewHeader';
|
||||||
import { Stack } from '@/components';
|
import { Stack } from '@/components';
|
||||||
|
import { useSendPaymentReceivedtMailMessage } from './_hooks';
|
||||||
const defaultPaymentReceiptMailProps = {
|
import { usePaymentReceivedSendMailBoot } from './PaymentReceivedMailBoot';
|
||||||
companyName: 'Company Name',
|
import { defaultPaymentReceiptMailProps } from './_constants';
|
||||||
companyLogoUri: 'https://via.placeholder.com/150',
|
|
||||||
primaryColor: 'rgb(0, 82, 204)',
|
|
||||||
paymentDate: '2021-01-01',
|
|
||||||
paymentDateLabel: 'Payment Date',
|
|
||||||
total: '100.00',
|
|
||||||
totalLabel: 'Total',
|
|
||||||
paymentNumber: '123456',
|
|
||||||
paymentNumberLabel: 'Payment #',
|
|
||||||
message: 'Thank you for your payment!',
|
|
||||||
subtotal: '100.00',
|
|
||||||
subtotalLabel: 'Subtotal',
|
|
||||||
items: [{ label: 'Invoice 1', total: '100.00' }],
|
|
||||||
};
|
|
||||||
|
|
||||||
export function PaymentReceivedMailPreviewReceipt() {
|
export function PaymentReceivedMailPreviewReceipt() {
|
||||||
return (
|
return (
|
||||||
@@ -25,8 +16,7 @@ export function PaymentReceivedMailPreviewReceipt() {
|
|||||||
<PaymentReceivedMailPreviewHeader />
|
<PaymentReceivedMailPreviewHeader />
|
||||||
|
|
||||||
<Stack px={4} py={6}>
|
<Stack px={4} py={6}>
|
||||||
<PaymentReceivedMailReceipt
|
<PaymentReceivedMailReceiptPreviewConnected
|
||||||
{...defaultPaymentReceiptMailProps}
|
|
||||||
className={css`
|
className={css`
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
border-radius: 5px !important;
|
border-radius: 5px !important;
|
||||||
@@ -39,3 +29,43 @@ export function PaymentReceivedMailPreviewReceipt() {
|
|||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injects props from invoice mail state into the InvoiceMailReceiptPreview component.
|
||||||
|
*/
|
||||||
|
const withPaymentReceivedMailReceiptPreviewProps = <
|
||||||
|
P extends PaymentReceivedMailReceiptProps,
|
||||||
|
>(
|
||||||
|
WrappedComponent: ComponentType<P & PaymentReceivedMailReceiptProps>,
|
||||||
|
) => {
|
||||||
|
return function WithInvoiceMailReceiptPreviewProps(props: P) {
|
||||||
|
const message = useSendPaymentReceivedtMailMessage();
|
||||||
|
const { paymentReceivedMailState } = usePaymentReceivedSendMailBoot();
|
||||||
|
|
||||||
|
const items = useMemo(
|
||||||
|
() =>
|
||||||
|
paymentReceivedMailState?.entries?.map((entry: any) => ({
|
||||||
|
quantity: entry.quantity,
|
||||||
|
total: entry.totalFormatted,
|
||||||
|
label: entry.name,
|
||||||
|
})),
|
||||||
|
[paymentReceivedMailState?.entries],
|
||||||
|
);
|
||||||
|
|
||||||
|
const mailPaymentReceivedPreviewProps = {
|
||||||
|
...defaultPaymentReceiptMailProps,
|
||||||
|
companyName: paymentReceivedMailState?.companyName,
|
||||||
|
companyLogoUri: paymentReceivedMailState?.companyLogoUri,
|
||||||
|
primaryColor: paymentReceivedMailState?.primaryColor,
|
||||||
|
total: paymentReceivedMailState?.totalFormatted,
|
||||||
|
subtotal: paymentReceivedMailState?.subtotalFormatted,
|
||||||
|
paymentNumber: paymentReceivedMailState?.paymentNumber,
|
||||||
|
items,
|
||||||
|
message,
|
||||||
|
};
|
||||||
|
return <WrappedComponent {...mailPaymentReceivedPreviewProps} {...props} />;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const PaymentReceivedMailReceiptPreviewConnected =
|
||||||
|
withPaymentReceivedMailReceiptPreviewProps(PaymentReceivedMailReceipt);
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
export const defaultPaymentReceiptMailProps = {
|
||||||
|
companyName: 'Company Name',
|
||||||
|
companyLogoUri: 'https://via.placeholder.com/150',
|
||||||
|
primaryColor: 'rgb(0, 82, 204)',
|
||||||
|
paymentDate: '2021-01-01',
|
||||||
|
paymentDateLabel: 'Payment Date',
|
||||||
|
total: '100.00',
|
||||||
|
totalLabel: 'Total',
|
||||||
|
paymentNumber: '123456',
|
||||||
|
paymentNumberLabel: 'Payment #',
|
||||||
|
message: 'Thank you for your payment!',
|
||||||
|
subtotal: '100.00',
|
||||||
|
subtotalLabel: 'Subtotal',
|
||||||
|
items: [{ label: 'Invoice 1', total: '100.00' }],
|
||||||
|
};
|
||||||
@@ -1,22 +1,14 @@
|
|||||||
|
import { ComponentType } from 'react';
|
||||||
|
import { css } from '@emotion/css';
|
||||||
import { Stack } from '@/components';
|
import { Stack } from '@/components';
|
||||||
import { ReceiptSendMailPreviewHeader } from './ReceiptSendMailPreviewHeader';
|
import { ReceiptSendMailPreviewHeader } from './ReceiptSendMailPreviewHeader';
|
||||||
import { ReceiptSendMailReceipt } from './ReceiptSendMailReceipt';
|
import {
|
||||||
import { css } from '@emotion/css';
|
ReceiptSendMailReceipt,
|
||||||
|
ReceiptSendMailReceiptProps,
|
||||||
const defaultReceiptMailProps = {
|
} from './ReceiptSendMailReceipt';
|
||||||
companyLogoUri: 'https://via.placeholder.com/150',
|
import { defaultReceiptMailProps } from './_constants';
|
||||||
companyName: 'Company Name',
|
import { useReceiptSendMailBoot } from './ReceiptSendMailBoot';
|
||||||
receiptNumber: '1234',
|
import { useSendReceiptMailMessage } from './_hooks';
|
||||||
total: '1000',
|
|
||||||
message: 'Thank you for your business!',
|
|
||||||
items: [
|
|
||||||
{ label: 'Item 1', quantity: 1, total: '500' },
|
|
||||||
{ label: 'Item 2', quantity: 2, total: '500' },
|
|
||||||
],
|
|
||||||
subtotal: '1000',
|
|
||||||
showViewReceiptButton: true,
|
|
||||||
viewReceiptButtonLabel: 'View Receipt',
|
|
||||||
};
|
|
||||||
|
|
||||||
export function ReceiptSendMailPreview() {
|
export function ReceiptSendMailPreview() {
|
||||||
return (
|
return (
|
||||||
@@ -24,8 +16,7 @@ export function ReceiptSendMailPreview() {
|
|||||||
<ReceiptSendMailPreviewHeader />
|
<ReceiptSendMailPreviewHeader />
|
||||||
|
|
||||||
<Stack px={4} py={6}>
|
<Stack px={4} py={6}>
|
||||||
<ReceiptSendMailReceipt
|
<ReceiptMailPreviewConnected
|
||||||
{...defaultReceiptMailProps}
|
|
||||||
className={css`
|
className={css`
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
border-radius: 5px !important;
|
border-radius: 5px !important;
|
||||||
@@ -38,3 +29,45 @@ export function ReceiptSendMailPreview() {
|
|||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injects props from receipt mail state into the `ReceiptMailPreviewConnected` component.
|
||||||
|
*/
|
||||||
|
const withReceiptMailReceiptPreviewProps = <
|
||||||
|
P extends ReceiptSendMailReceiptProps,
|
||||||
|
>(
|
||||||
|
WrappedComponent: ComponentType<P & ReceiptSendMailReceiptProps>,
|
||||||
|
) => {
|
||||||
|
return function WithInvoiceMailReceiptPreviewProps(props: P) {
|
||||||
|
const message = useSendReceiptMailMessage();
|
||||||
|
const { receiptMailState } = useReceiptSendMailBoot();
|
||||||
|
|
||||||
|
// const items = useMemo(
|
||||||
|
// () =>
|
||||||
|
// invoiceMailState?.entries?.map((entry: any) => ({
|
||||||
|
// quantity: entry.quantity,
|
||||||
|
// total: entry.totalFormatted,
|
||||||
|
// label: entry.name,
|
||||||
|
// })),
|
||||||
|
// [invoiceMailState?.entries],
|
||||||
|
// );
|
||||||
|
|
||||||
|
const mailReceiptPreviewProps = {
|
||||||
|
...defaultReceiptMailProps,
|
||||||
|
// companyName: receiptMailState?.companyName,
|
||||||
|
// companyLogoUri: receiptMailState?.companyLogoUri,
|
||||||
|
// primaryColor: receiptMailState?.primaryColor,
|
||||||
|
// total: receiptMailState?.totalFormatted,
|
||||||
|
// dueDate: receiptMailState?.dueDateFormatted,
|
||||||
|
// dueAmount: invoiceMailState?.dueAmountFormatted,
|
||||||
|
// invoiceNumber: invoiceMailState?.invoiceNo,
|
||||||
|
// items,
|
||||||
|
message,
|
||||||
|
};
|
||||||
|
return <WrappedComponent {...mailReceiptPreviewProps} {...props} />;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ReceiptMailPreviewConnected = withReceiptMailReceiptPreviewProps(
|
||||||
|
ReceiptSendMailReceipt,
|
||||||
|
);
|
||||||
|
|||||||
@@ -1,8 +1,17 @@
|
|||||||
import { Suspense } from 'react';
|
import { lazy, Suspense } from 'react';
|
||||||
import { Tab } from '@blueprintjs/core';
|
import { Tab } from '@blueprintjs/core';
|
||||||
import { SendMailViewPreviewTabs } from '../../Estimates/SendMailViewDrawer/SendMailViewPreviewTabs';
|
import { SendMailViewPreviewTabs } from '../../Estimates/SendMailViewDrawer/SendMailViewPreviewTabs';
|
||||||
import { ReceiptSendMailPreview } from './ReceiptSendMailPreview';
|
|
||||||
import { ReceiptSendMailPdfPreview } from './ReceiptSendMailPdfPreview';
|
const ReceiptSendMailPreview = lazy(() =>
|
||||||
|
import('./ReceiptSendMailPreview').then((module) => ({
|
||||||
|
default: module.ReceiptSendMailPreview,
|
||||||
|
})),
|
||||||
|
);
|
||||||
|
const ReceiptSendMailPdfPreview = lazy(() =>
|
||||||
|
import('./ReceiptSendMailPdfPreview').then((module) => ({
|
||||||
|
default: module.ReceiptSendMailPdfPreview,
|
||||||
|
})),
|
||||||
|
);
|
||||||
|
|
||||||
export function ReceiptSendMailPreviewTabs() {
|
export function ReceiptSendMailPreviewTabs() {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import {
|
|||||||
SendMailReceiptProps,
|
SendMailReceiptProps,
|
||||||
} from '../../Estimates/SendMailViewDrawer/SendMailViewReceiptPreview';
|
} from '../../Estimates/SendMailViewDrawer/SendMailViewReceiptPreview';
|
||||||
|
|
||||||
interface ReceiptSendMailReceiptProps extends SendMailReceiptProps {
|
export interface ReceiptSendMailReceiptProps extends SendMailReceiptProps {
|
||||||
// # Company name.
|
// # Company name.
|
||||||
companyLogoUri?: string;
|
companyLogoUri?: string;
|
||||||
companyName: string;
|
companyName: string;
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
export const defaultReceiptMailProps = {
|
||||||
|
companyLogoUri: 'https://via.placeholder.com/150',
|
||||||
|
companyName: 'Company Name',
|
||||||
|
receiptNumber: '1234',
|
||||||
|
total: '1000',
|
||||||
|
message: 'Thank you for your business!',
|
||||||
|
items: [
|
||||||
|
{ label: 'Item 1', quantity: 1, total: '500' },
|
||||||
|
{ label: 'Item 2', quantity: 2, total: '500' },
|
||||||
|
],
|
||||||
|
subtotal: '1000',
|
||||||
|
showViewReceiptButton: true,
|
||||||
|
viewReceiptButtonLabel: 'View Receipt',
|
||||||
|
};
|
||||||
@@ -269,12 +269,27 @@ export interface SaleEstimateMailStateResponse {
|
|||||||
companyName: string;
|
companyName: string;
|
||||||
customerName: string;
|
customerName: string;
|
||||||
entries: Array<any>;
|
entries: Array<any>;
|
||||||
|
|
||||||
estimateDate: string;
|
estimateDate: string;
|
||||||
|
estimateDateFormatted: string;
|
||||||
|
|
||||||
|
expirationDate: string;
|
||||||
|
expirationDateFormatted: string;
|
||||||
|
|
||||||
|
primaryColor: string;
|
||||||
|
|
||||||
|
total: number;
|
||||||
|
totalFormatted: string;
|
||||||
|
|
||||||
|
subtotal: number;
|
||||||
|
subtotalFormatted: string;
|
||||||
|
|
||||||
|
estimateNumber: string;
|
||||||
|
|
||||||
formatArgs: {
|
formatArgs: {
|
||||||
customerName: string;
|
customerName: string;
|
||||||
estimateAmount: string;
|
estimateAmount: string;
|
||||||
};
|
};
|
||||||
formattedEstimateDate: string;
|
|
||||||
from: Array<string>;
|
from: Array<string>;
|
||||||
fromOptions: Array<any>;
|
fromOptions: Array<any>;
|
||||||
message: string;
|
message: string;
|
||||||
|
|||||||
@@ -264,15 +264,29 @@ export function useSendPaymentReceiveMail(props) {
|
|||||||
export interface GetPaymentReceivedMailStateResponse {
|
export interface GetPaymentReceivedMailStateResponse {
|
||||||
companyName: string;
|
companyName: string;
|
||||||
customerName: string;
|
customerName: string;
|
||||||
|
|
||||||
entries: Array<{ paymentAmountFormatted: string }>;
|
entries: Array<{ paymentAmountFormatted: string }>;
|
||||||
|
|
||||||
from: Array<string>;
|
from: Array<string>;
|
||||||
fromOptions: Array<{ mail: string; label: string; primary: boolean }>;
|
fromOptions: Array<{ mail: string; label: string; primary: boolean }>;
|
||||||
|
|
||||||
paymentAmountFormatted: string;
|
paymentAmountFormatted: string;
|
||||||
|
|
||||||
paymentDate: string;
|
paymentDate: string;
|
||||||
paymentDateFormatted: string;
|
paymentDateFormatted: string;
|
||||||
|
|
||||||
to: Array<string>;
|
to: Array<string>;
|
||||||
toOptions: Array<{ mail: string; label: string; primary: boolean }>;
|
toOptions: Array<{ mail: string; label: string; primary: boolean }>;
|
||||||
|
|
||||||
|
total: number;
|
||||||
totalFormatted: string;
|
totalFormatted: string;
|
||||||
|
|
||||||
|
subtotal: number;
|
||||||
|
subtotalFormatted: string;
|
||||||
|
|
||||||
|
paymentNumber: string;
|
||||||
|
companyLogoUri?: string;
|
||||||
|
primaryColor?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function usePaymentReceivedMailState(
|
export function usePaymentReceivedMailState(
|
||||||
|
|||||||
Reference in New Issue
Block a user