Skip to content

Commit

Permalink
feat: cards-stage print document with many cards (#4827)
Browse files Browse the repository at this point in the history
  • Loading branch information
munkhsaikhan committed Dec 4, 2023
1 parent dc18da7 commit f1b511e
Show file tree
Hide file tree
Showing 8 changed files with 387 additions and 35 deletions.
116 changes: 106 additions & 10 deletions packages/plugin-cards-api/src/documents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ export default {
types: [
{
label: 'Cards',
type: 'cards'
type: 'cards',
subTypes: ['deal', 'task', 'ticket', 'purchase', 'stageDeal']
}
],

Expand All @@ -74,14 +75,16 @@ export default {
return [...commonFields, ...uniqueFields];
},

replaceContent: async ({ subdomain, data: { stageId, itemId, content } }) => {
replaceContent: async ({
subdomain,
data: { stageId, itemId, content, contentype, itemIds }
}) => {
const models = await generateModels(subdomain);
const stage = await models.Stages.findOne({ _id: stageId });

if (!stage) {
return '';
}

let collection;

if (stage.type == 'deal') {
Expand All @@ -101,15 +104,31 @@ export default {
if (stage.type == 'growthHack') {
collection = models.GrowthHacks;
}

if (!collection) {
return '';
}
let item;
if (contentype == 'cards:stage') {
const items = await collection.find({
stageId: stageId,
_id: { $in: itemIds.split(',') }
});

const item = await collection.findOne({ _id: itemId });
if (!items) {
return '';
}

if (!item) {
return '';
item = await cardsStage(items);

if (!item) {
return '';
}
} else {
item = await collection.findOne({ _id: itemId });

if (!item) {
return '';
}
}

const simpleFields = ['name', 'description'];
Expand Down Expand Up @@ -256,6 +275,10 @@ export default {
continue;
}

if (!pd.tickUsed) {
continue;
}

const product = await sendProductsMessage({
subdomain,
action: 'findOne',
Expand Down Expand Up @@ -294,9 +317,9 @@ export default {
<thead>
<tr>
<th>№</th>
<th>${
type === 'product' ? 'Product name' : 'Service name'
}</th>
<th>
${type === 'product' ? 'Product name' : 'Service name'}
</th>
<th>Quantity</th>
<th>Unit price</th>
<th>Total amount</th>
Expand Down Expand Up @@ -406,3 +429,76 @@ export default {
return [replacedContent];
}
};

const cardsStage = async (items: any[]) => {
try {
const itemsArray = items;
const aggregatedData: Record<string, any> = {
amount: {
AED: 0
},
productsData: []
};
itemsArray.forEach(item => {
const combinedNames = itemsArray.map(item => item.name).join(',');
aggregatedData.isComplete = item.isComplete;
aggregatedData.assignedUserIds = item.assignedUserIds;
aggregatedData.watchedUserIds = item.watchedUserIds;
aggregatedData.labelIds = item.labelIds;
aggregatedData.tagIds = item.tagIds;
aggregatedData.branchIds = item.branchIds;
aggregatedData.departmentIds = item.departmentIds;
aggregatedData.modifiedAt = item.modifiedAt;
aggregatedData.createdAt = item.createdAt;
aggregatedData.stageChangedDate = item.stageChangedDate;
aggregatedData.sourceConversationIds = item.sourceConversationIds;
aggregatedData.status = item.status;
aggregatedData.name = combinedNames;
aggregatedData.stageId = item.stageId;
aggregatedData.customFieldsData = item.customFieldsData;
aggregatedData.initialStageId = item.initialStageId;
aggregatedData.modifiedBy = item.modifiedBy;
aggregatedData.userId = item.userId;
aggregatedData.searchText = combinedNames;

if (item.productsData) {
item.productsData.forEach(product => {
const existingProduct = aggregatedData.productsData.find(
p =>
p.productId === product.productId &&
p.branchId === product.branchId &&
p.departmentId === product.departmentId
);

if (existingProduct) {
existingProduct.quantity += product.quantity;
existingProduct.amount += product.amount;
} else {
aggregatedData.productsData.push({
tax: product.tax,
taxPercent: product.taxPercent,
discount: product.discount,
vatPercent: product.vatPercent,
discountPercent: product.discountPercent,
amount: product.amount,
currency: product.currency,
tickUsed: product.tickUsed,
maxQuantity: product.maxQuantity,
quantity: product.quantity,
productId: product.productId,
unitPrice: product.unitPrice,
globalUnitPrice: product.globalUnitPrice,
unitPricePercent: product.unitPricePercent
});
}

// Update the total amount for this stage
aggregatedData.amount.AED += product.amount * product.quantity;
});
}
});
return aggregatedData;
} catch (error) {
return { error: error.message };
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ const documentQueries = {
}

if (subType) {
selector.subType = subType;
selector.$or = [
{ subType },
{ subType: { $exists: false } },
{ subType: { $in: ['', null, undefined] } }
];
}

if (limit) {
Expand Down
5 changes: 2 additions & 3 deletions packages/plugin-documents-ui/src/graphql/queries.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
const documents = `
query documents($page: Int, $perPage: Int, $contentType: String) {
documents(page: $page, perPage: $perPage, contentType: $contentType) {
query documents($page: Int, $perPage: Int, $contentType: String, $subType: String) {
documents(page: $page, perPage: $perPage, contentType: $contentType, subType: $subType) {
_id
contentType
subType
name
createdAt
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,12 +156,11 @@ class BulkDocuments extends React.Component<Props, State> {
this.setState({ showPopup: true, selectedDocumentId });
};

onChange = (name, e) => {
this.setState({ [name]: e.currentTarget.value } as any, () => {
localStorage.setItem(
`erxes_products_documents_${name}`,
e.currentTarget.value
);
onChange = e => {
const name = e.target.name;
const value = e.target.value;
this.setState({ [name]: value } as any, () => {
localStorage.setItem(`erxes_products_documents_${name}`, value);
});
};

Expand Down Expand Up @@ -226,7 +225,7 @@ class BulkDocuments extends React.Component<Props, State> {
{...formProps}
name="copies"
value={copies}
onChange={this.onChange.bind(this, 'copies')}
onChange={this.onChange}
/>
</FormGroup>
<FormGroup>
Expand All @@ -235,7 +234,7 @@ class BulkDocuments extends React.Component<Props, State> {
{...formProps}
name="width"
value={width}
onChange={this.onChange.bind(this, 'width')}
onChange={this.onChange}
/>
</FormGroup>
<FormGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,13 @@ export default class PrintActionButton extends React.Component<Props, State> {
}

loadDocuments = () => {
const { item } = this.props;
this.setState({ loading: true });

client
.mutate({
mutation: gql(queries.documents),
variables: { contentType: 'cards' }
variables: { contentType: 'cards', subType: item.stage?.type }
})
.then(({ data }) => {
this.setState({ documents: data.documents });
Expand Down
47 changes: 37 additions & 10 deletions packages/ui-cards/src/boards/components/stage/Stage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,16 @@ import ItemList from '../stage/ItemList';
import ItemProductProbabilities from '../../../deals/components/ItemProductProbabilities';
import ModalTrigger from '@erxes/ui/src/components/ModalTrigger';
import React from 'react';
import { __ } from '@erxes/ui/src/utils/core';
import { __, isEnabled } from '@erxes/ui/src/utils/core';
import StageModal from './StageModal';

type Props = {
loadingItems: () => boolean;
removeStage: (stageId: string) => void;
index: number;
stage: IStage;
length: number;
items: IItem[];
items: any[];
onAddItem: (stageId: string, item: IItem) => void;
onRemoveItem: (itemId: string, stageId: string) => void;
loadMore: () => void;
Expand All @@ -43,6 +44,8 @@ type Props = {

type State = {
showSortOptions: boolean;
renderModal: boolean;
items: any[];
};

export default class Stage extends React.Component<Props, State> {
Expand All @@ -51,14 +54,16 @@ export default class Stage extends React.Component<Props, State> {

constructor(props: Props) {
super(props);

this.bodyRef = React.createRef();

this.state = { showSortOptions: false };
this.state = {
showSortOptions: false,
renderModal: false,
items: []
};
}

componentDidMount() {
// Load items until scroll created
const handle = setInterval(() => {
if (this.props.loadingItems()) {
return;
Expand Down Expand Up @@ -98,10 +103,11 @@ export default class Stage extends React.Component<Props, State> {

shouldComponentUpdate(nextProps: Props, nextState: State) {
const { stage, index, length, items, loadingItems } = this.props;
const { showSortOptions } = this.state;
const { showSortOptions, renderModal } = this.state;

if (
showSortOptions !== nextState.showSortOptions ||
renderModal !== nextState.renderModal ||
index !== nextProps.index ||
loadingItems() !== nextProps.loadingItems() ||
length !== nextProps.length ||
Expand All @@ -124,10 +130,16 @@ export default class Stage extends React.Component<Props, State> {
this.setState({ showSortOptions: !showSortOptions });
};

toggleModal = () => {
this.setState(prevState => ({
renderModal: !prevState.renderModal
}));
this.onClosePopover();
};

renderPopover() {
const { stage } = this.props;
const { stage, options } = this.props;
const { showSortOptions } = this.state;

const archiveList = () => {
this.props.archiveList();
this.onClosePopover();
Expand Down Expand Up @@ -159,10 +171,13 @@ export default class Stage extends React.Component<Props, State> {
<li onClick={removeStage} key="remove-stage">
{__('Remove stage')}
</li>

<Dropdown.Divider />

<li onClick={this.toggleSortOptions}>{__('Sort By')}</li>
{isEnabled('documents') && options.type === 'deal' && (
<li>
<a onClick={this.toggleModal}>{__('Print document')}</a>
</li>
)}
</>
)}
</ActionList>
Expand Down Expand Up @@ -343,6 +358,16 @@ export default class Stage extends React.Component<Props, State> {
);
}

renderTriggerModal() {
return this.state.renderModal ? (
<StageModal
item={this.props.items}
toggleModal={this.toggleModal}
stage={this.props.stage}
/>
) : null;
}

render() {
const { index, stage } = this.props;

Expand Down Expand Up @@ -378,10 +403,12 @@ export default class Stage extends React.Component<Props, State> {
{this.renderCtrl()}
</StageTitle>
{renderDetail()}

<Indicator>{this.renderIndicator()}</Indicator>
</Header>
<Body innerRef={this.bodyRef} onScroll={this.onScroll}>
{this.renderItemList()}
{this.renderTriggerModal()},
</Body>
{this.renderAddItemTrigger()}
</StageRoot>
Expand Down
Loading

0 comments on commit f1b511e

Please sign in to comment.