mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-16 04:40:32 +00:00
Merge branch 'develop' into inconsistance-pagination-page-size
This commit is contained in:
@@ -150,6 +150,15 @@
|
||||
"contributions": [
|
||||
"bug"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Champetaman",
|
||||
"name": "Camilo Oviedo",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/64604272?v=4",
|
||||
"profile": "https://www.camilooviedo.com/",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
}
|
||||
],
|
||||
"contributorsPerLine": 7,
|
||||
|
||||
@@ -129,6 +129,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/oleynikd"><img src="https://avatars.githubusercontent.com/u/3976868?v=4?s=100" width="100px;" alt="Denis"/><br /><sub><b>Denis</b></sub></a><br /><a href="https://github.com/bigcapitalhq/bigcapital/issues?q=author%3Aoleynikd" title="Bug reports">🐛</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://myself.vercel.app/"><img src="https://avatars.githubusercontent.com/u/42431274?v=4?s=100" width="100px;" alt="Sachin Mittal"/><br /><sub><b>Sachin Mittal</b></sub></a><br /><a href="https://github.com/bigcapitalhq/bigcapital/issues?q=author%3Amittalsam98" title="Bug reports">🐛</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://www.camilooviedo.com/"><img src="https://avatars.githubusercontent.com/u/64604272?v=4?s=100" width="100px;" alt="Camilo Oviedo"/><br /><sub><b>Camilo Oviedo</b></sub></a><br /><a href="https://github.com/bigcapitalhq/bigcapital/commits?author=Champetaman" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -67,7 +67,7 @@ export interface IPaymentReceivedEntry {
|
||||
export interface IPaymentReceivedEntryDTO {
|
||||
id?: number;
|
||||
index: number;
|
||||
paymentReceiveId: number;
|
||||
paymentReceiveId?: number;
|
||||
invoiceId: number;
|
||||
paymentAmount: number;
|
||||
}
|
||||
|
||||
@@ -1,18 +1,25 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { initialize } from 'objection';
|
||||
import { Knex } from 'knex';
|
||||
import { first } from 'lodash';
|
||||
import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable';
|
||||
import { GetMatchedTransactionBillsTransformer } from './GetMatchedTransactionBillsTransformer';
|
||||
import { GetMatchedTransactionsFilter, MatchedTransactionPOJO } from './types';
|
||||
import HasTenancyService from '@/services/Tenancy/TenancyService';
|
||||
import {
|
||||
GetMatchedTransactionsFilter,
|
||||
IMatchTransactionDTO,
|
||||
MatchedTransactionPOJO,
|
||||
} from './types';
|
||||
import { GetMatchedTransactionsByType } from './GetMatchedTransactionsByType';
|
||||
import { CreateBillPayment } from '@/services/Purchases/BillPayments/CreateBillPayment';
|
||||
import { IBillPaymentDTO } from '@/interfaces';
|
||||
|
||||
@Service()
|
||||
export class GetMatchedTransactionsByBills extends GetMatchedTransactionsByType {
|
||||
@Inject()
|
||||
private tenancy: HasTenancyService;
|
||||
private transformer: TransformerInjectable;
|
||||
|
||||
@Inject()
|
||||
private transformer: TransformerInjectable;
|
||||
private createPaymentMadeService: CreateBillPayment;
|
||||
|
||||
/**
|
||||
* Retrieves the matched transactions.
|
||||
@@ -71,4 +78,62 @@ export class GetMatchedTransactionsByBills extends GetMatchedTransactionsByType
|
||||
new GetMatchedTransactionBillsTransformer()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the common matched transaction.
|
||||
* @param {number} tenantId
|
||||
* @param {Array<number>} uncategorizedTransactionIds
|
||||
* @param {IMatchTransactionDTO} matchTransactionDTO
|
||||
* @param {Knex.Transaction} trx
|
||||
*/
|
||||
public async createMatchedTransaction(
|
||||
tenantId: number,
|
||||
uncategorizedTransactionIds: Array<number>,
|
||||
matchTransactionDTO: IMatchTransactionDTO,
|
||||
trx?: Knex.Transaction
|
||||
): Promise<void> {
|
||||
await super.createMatchedTransaction(
|
||||
tenantId,
|
||||
uncategorizedTransactionIds,
|
||||
matchTransactionDTO,
|
||||
trx
|
||||
);
|
||||
const { Bill, UncategorizedCashflowTransaction, MatchedBankTransaction } =
|
||||
this.tenancy.models(tenantId);
|
||||
|
||||
const uncategorizedTransactionId = first(uncategorizedTransactionIds);
|
||||
const uncategorizedTransaction =
|
||||
await UncategorizedCashflowTransaction.query(trx)
|
||||
.findById(uncategorizedTransactionId)
|
||||
.throwIfNotFound();
|
||||
|
||||
const bill = await Bill.query(trx)
|
||||
.findById(matchTransactionDTO.referenceId)
|
||||
.throwIfNotFound();
|
||||
|
||||
const createPaymentMadeDTO: IBillPaymentDTO = {
|
||||
vendorId: bill.vendorId,
|
||||
paymentAccountId: uncategorizedTransaction.accountId,
|
||||
paymentDate: uncategorizedTransaction.date,
|
||||
exchangeRate: 1,
|
||||
entries: [
|
||||
{
|
||||
paymentAmount: bill.dueAmount,
|
||||
billId: bill.id,
|
||||
},
|
||||
],
|
||||
branchId: bill.branchId,
|
||||
};
|
||||
// Create a new bill payment associated to the matched bill.
|
||||
const billPayment = await this.createPaymentMadeService.createBillPayment(
|
||||
tenantId,
|
||||
createPaymentMadeDTO,
|
||||
trx
|
||||
);
|
||||
// Link the create bill payment with matched transaction.
|
||||
await super.createMatchedTransaction(tenantId, uncategorizedTransactionIds, {
|
||||
referenceType: 'BillPayment',
|
||||
referenceId: billPayment.id,
|
||||
}, trx);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,26 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { initialize } from 'objection';
|
||||
import { Knex } from 'knex';
|
||||
import { first } from 'lodash';
|
||||
import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable';
|
||||
import { GetMatchedTransactionInvoicesTransformer } from './GetMatchedTransactionInvoicesTransformer';
|
||||
import {
|
||||
GetMatchedTransactionsFilter,
|
||||
IMatchTransactionDTO,
|
||||
MatchedTransactionPOJO,
|
||||
MatchedTransactionsPOJO,
|
||||
} from './types';
|
||||
import HasTenancyService from '@/services/Tenancy/TenancyService';
|
||||
import { GetMatchedTransactionsByType } from './GetMatchedTransactionsByType';
|
||||
import { CreatePaymentReceived } from '@/services/Sales/PaymentReceived/CreatePaymentReceived';
|
||||
import { IPaymentReceivedCreateDTO } from '@/interfaces';
|
||||
|
||||
@Service()
|
||||
export class GetMatchedTransactionsByInvoices extends GetMatchedTransactionsByType {
|
||||
@Inject()
|
||||
protected tenancy: HasTenancyService;
|
||||
protected transformer: TransformerInjectable;
|
||||
|
||||
@Inject()
|
||||
protected transformer: TransformerInjectable;
|
||||
protected createPaymentReceivedService: CreatePaymentReceived;
|
||||
|
||||
/**
|
||||
* Retrieves the matched transactions.
|
||||
@@ -78,4 +82,64 @@ export class GetMatchedTransactionsByInvoices extends GetMatchedTransactionsByTy
|
||||
new GetMatchedTransactionInvoicesTransformer()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the common matched transaction.
|
||||
* @param {number} tenantId
|
||||
* @param {Array<number>} uncategorizedTransactionIds
|
||||
* @param {IMatchTransactionDTO} matchTransactionDTO
|
||||
* @param {Knex.Transaction} trx
|
||||
*/
|
||||
public async createMatchedTransaction(
|
||||
tenantId: number,
|
||||
uncategorizedTransactionIds: Array<number>,
|
||||
matchTransactionDTO: IMatchTransactionDTO,
|
||||
trx?: Knex.Transaction
|
||||
) {
|
||||
await super.createMatchedTransaction(
|
||||
tenantId,
|
||||
uncategorizedTransactionIds,
|
||||
matchTransactionDTO,
|
||||
trx
|
||||
);
|
||||
const { SaleInvoice, UncategorizedCashflowTransaction, MatchedBankTransaction } =
|
||||
this.tenancy.models(tenantId);
|
||||
|
||||
const uncategorizedTransactionId = first(uncategorizedTransactionIds);
|
||||
const uncategorizedTransaction =
|
||||
await UncategorizedCashflowTransaction.query(trx)
|
||||
.findById(uncategorizedTransactionId)
|
||||
.throwIfNotFound();
|
||||
|
||||
const invoice = await SaleInvoice.query(trx)
|
||||
.findById(matchTransactionDTO.referenceId)
|
||||
.throwIfNotFound();
|
||||
|
||||
const createPaymentReceivedDTO: IPaymentReceivedCreateDTO = {
|
||||
customerId: invoice.customerId,
|
||||
paymentDate: uncategorizedTransaction.date,
|
||||
amount: invoice.dueAmount,
|
||||
depositAccountId: uncategorizedTransaction.accountId,
|
||||
entries: [
|
||||
{
|
||||
index: 1,
|
||||
invoiceId: invoice.id,
|
||||
paymentAmount: invoice.dueAmount,
|
||||
},
|
||||
],
|
||||
branchId: invoice.branchId,
|
||||
};
|
||||
// Create a payment received associated to the matched invoice.
|
||||
const paymentReceived = await this.createPaymentReceivedService.createPaymentReceived(
|
||||
tenantId,
|
||||
createPaymentReceivedDTO,
|
||||
{},
|
||||
trx
|
||||
);
|
||||
// Link the create payment received with matched invoice transaction.
|
||||
await super.createMatchedTransaction(tenantId, uncategorizedTransactionIds, {
|
||||
referenceType: 'PaymentReceive',
|
||||
referenceId: paymentReceived.id,
|
||||
}, trx)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
.root {
|
||||
padding: 20px;
|
||||
border: 2px dotted #c5cbd3;
|
||||
@@ -9,4 +7,14 @@
|
||||
flex-direction: column;
|
||||
background: #fff;
|
||||
position: relative;
|
||||
transition: background-color 0.3s ease, border-color 0.3s ease;
|
||||
|
||||
&.dropzoneAccept {
|
||||
border-color: rgb(0, 82, 204);
|
||||
background: rgba(0, 82, 204, 0.05);
|
||||
}
|
||||
&.dropzoneReject {
|
||||
border-color: #AC2F33;
|
||||
background: rgba(172, 47, 51, 0.05)
|
||||
}
|
||||
}
|
||||
@@ -235,7 +235,14 @@ export const Dropzone = (_props: DropzoneProps) => {
|
||||
>
|
||||
<Box
|
||||
{...getRootProps({
|
||||
className: clsx(styles.root, classNames?.root),
|
||||
className: clsx(
|
||||
styles.root,
|
||||
{
|
||||
[styles.dropzoneAccept]: isDragAccept,
|
||||
[styles.dropzoneReject]: isDragReject
|
||||
},
|
||||
classNames?.root
|
||||
),
|
||||
})}
|
||||
// {...getStyles('root', { focusable: true })}
|
||||
{...others}
|
||||
@@ -253,7 +260,7 @@ export const Dropzone = (_props: DropzoneProps) => {
|
||||
<input {...getInputProps(inputProps)} name={name} />
|
||||
<div
|
||||
data-enable-pointer-events={enablePointerEvents || undefined}
|
||||
className={classNames?.content}
|
||||
className={clsx(styles.content, classNames?.content)}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
@@ -268,8 +275,6 @@ Dropzone.Idle = DropzoneIdle;
|
||||
Dropzone.Reject = DropzoneReject;
|
||||
|
||||
|
||||
|
||||
|
||||
type PossibleRef<T> = Ref<T> | undefined;
|
||||
|
||||
export function assignRef<T>(ref: PossibleRef<T>, value: T) {
|
||||
|
||||
@@ -120,6 +120,7 @@ export function UploadAttachmentsPopoverContent({
|
||||
uploadIcon={null}
|
||||
value={null}
|
||||
title={''}
|
||||
subtitle={'Drag and drop file here or choose file'}
|
||||
classNames={{ root: styles.dropzoneRoot }}
|
||||
onChange={handleChangeDropzone}
|
||||
dropzoneProps={{
|
||||
|
||||
@@ -13,6 +13,8 @@ export function ImportDropzone() {
|
||||
<Field id={'file'} name={'file'} type="file">
|
||||
{({ form }) => (
|
||||
<ImportDropzoneField
|
||||
title={'Drag and drop files here or click to select files'}
|
||||
subtitle={''}
|
||||
value={form.file}
|
||||
onChange={(file) => {
|
||||
hideAlerts();
|
||||
|
||||
Reference in New Issue
Block a user