Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(condo): Doma-10747 store information in billing receipt about last balance update date #5541

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/condo/domains/billing/gql.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ const BILLING_RECEIPT_SERVICE_TO_PAY_DETAILS_FIELDS = `toPayDetails { ${BILLING_
const BILLING_RECEIPT_SERVICE_FIELDS = `services { id name toPay ${BILLING_RECEIPT_SERVICE_TO_PAY_DETAILS_FIELDS} }`
const BILLING_RECEIPT_RECIPIENT_FIELDS = 'recipient { name tin iec bic bankAccount }'
const BILLING_RECEIPT_COMMON_FIELDS = `context ${BILLING_INTEGRATION_ORGANIZATION_CONTEXT_FIELDS} importId property { id address addressKey } account { id number unitType unitName fullName property { address } ownerType globalId isClosed } period toPay printableNumber toPayDetails { ${BILLING_RECEIPT_TO_PAY_DETAILS_FIELDS} } ${BILLING_RECEIPT_SERVICE_FIELDS} charge formula balance recalculation privilege penalty paid receiver { id tin iec bic bankAccount isApproved } ${BILLING_RECEIPT_RECIPIENT_FIELDS} ${COMMON_FIELDS} category ${BILLING_CATEGORY_FIELDS} invalidServicesError`
const BILLING_RECEIPT_FIELDS = `{ ${BILLING_RECEIPT_COMMON_FIELDS} file { id file { id filename originalFilename publicUrl mimetype } controlSum } acquiringIntegrationId acquiringHostUrl canGroupReceipts currencyCode }`
const BILLING_RECEIPT_FIELDS = `{ ${BILLING_RECEIPT_COMMON_FIELDS} file { id file { id filename originalFilename publicUrl mimetype } controlSum } acquiringIntegrationId acquiringHostUrl canGroupReceipts currencyCode balanceUpdatedAt }`
const BILLING_RECEIPT_ADMIN_FIELDS = `{ ${BILLING_RECEIPT_COMMON_FIELDS} file { id sensitiveDataFile { id filename originalFilename publicUrl mimetype } publicDataFile { id filename originalFilename publicUrl mimetype } controlSum } isPayable }`

const BillingReceipt = generateGqlQueries('BillingReceipt', BILLING_RECEIPT_FIELDS)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,6 @@ describe('AllResidentBillingReceiptsService', () => {
serviceConsumer: { resident: { id: resident.id } },
})
const receiptAfterPayment = receiptsAfterPayment.find(({ id }) => id === receiptId )
console.error(receiptAfterPayment)
expect(Big(receiptAfterPayment.paid).toFixed(2)).toEqual(remainPay)
expect(Big(receiptAfterPayment.toPayDetails.paid).toFixed(2)).toEqual(partialPay)
})
Expand Down Expand Up @@ -411,8 +410,7 @@ describe('AllResidentBillingReceiptsService', () => {
expect(receiptAfterPayment.isPayable).toBeTruthy()
})

// TODO(dkovyazin): Add additional field on balance change to calculate new payments and display on mobile app
test.skip('paid field calculated when organization bank info changed', async () => {
test('paid field calculated when organization bank info changed', async () => {
const accountNumber = faker.random.alphaNumeric(12)
const total = '5000.00'
const jsonReceipt = utils.createJSONReceipt({ accountNumber, toPay: total })
Expand Down
6 changes: 6 additions & 0 deletions apps/condo/domains/billing/schema/BillingReceipt.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,12 @@ const BillingReceipt = new GQLListSchema('BillingReceipt', {
access: readOnlyFieldAccess,
},

balanceUpdatedAt: {
schemaDoc: 'Last date time when the balance was updated',
type: 'DateTimeUtc',
isRequired: false,
},

paid: {
...MONEY_AMOUNT_FIELD,
schemaDoc: 'Amount of money that recipient already paid by current receipt. Example: "50.00", "-50.00"',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,6 @@ const RegisterBillingReceiptsService = new GQLCustomSchema('RegisterBillingRecei
schema: 'registerBillingReceipts(data: RegisterBillingReceiptsInput!): [BillingReceipt]',
resolver: async (parent, args, context = {}) => {
const { data: { context: billingContextInput, receipts: receiptsInput, dv, sender } } = args
// The flow description:
// 1. Normalize addresses
// 2. Collect data for BillingProblems
// 3. Create BillingRecipients
// 4. Auto-detect BillingCategory

// Input guard validations
if (receiptsInput.length > RECEIPTS_LIMIT) {
throw new GQLError(ERRORS.RECEIPTS_LIMIT_HIT, context)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,11 @@ class ReceiptResolver extends Resolver {
['category', 'account', 'property', 'receiver']
)
if (!isEmpty(updateInput)) {
if (updateInput.hasOwnProperty('toPay') || updateInput.hasOwnProperty('toPayDetails')) {
updateInput['balanceUpdatedAt'] = new Date().toISOString()
}
try {
receiptIndex[index] = await BillingReceipt.update(this.context, receiptToUpdate.id, { ...updateInput, raw: receipt })
receiptIndex[index] = await BillingReceipt.update(this.context, receiptToUpdate.id, { ...updateInput, raw: receipt }, 'id')
} catch (error) {
this.error(ERRORS.RECEIPT_SAVE_FAILED, index, error)
}
Expand All @@ -65,7 +68,7 @@ class ReceiptResolver extends Resolver {
try {
receiptIndex[index] = await BillingReceipt.create(this.context, this.buildCreateInput({
...pick(receipt, RECEIPT_UPDATE_FIELDS), context: this.billingContext.id, raw: receipt,
}, ['category', 'account', 'property', 'receiver', 'context']))
}, ['category', 'account', 'property', 'receiver', 'context']), 'id')
} catch (error) {
this.error(ERRORS.RECEIPT_SAVE_FAILED, index, error)
}
Expand Down
22 changes: 14 additions & 8 deletions apps/condo/domains/billing/utils/serverSchema/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,20 @@ const getPaymentsSum = async (receiptId) => {
*/
const getNewPaymentsSum = async (receiptId) => {
const receipt = await getById('BillingReceipt', receiptId)
const payments = await find('Payment', {
AND: [
{ status_in: [PAYMENT_DONE_STATUS, PAYMENT_WITHDRAWN_STATUS] },
{ deletedAt: null },
{ receipt: { id: receiptId } },
{ OR: [ { transferDate_gte: new Date(receipt.updatedAt).toISOString() }, { transferDate: null } ] },
],
})
const conditions = [
{ status_in: [PAYMENT_DONE_STATUS, PAYMENT_WITHDRAWN_STATUS] },
{ deletedAt: null },
{ receipt: { id: receiptId } },
]
if (receipt.balanceUpdatedAt) {
conditions.push({
OR: [
{ transferDate: null },
{ transferDate_gte: new Date(receipt.balanceUpdatedAt).toISOString() },
],
})
}
const payments = await find('Payment', { AND: conditions })
return payments.reduce((total, current) => (Big(total).plus(current.amount)), 0).toFixed(8).toString()
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// auto generated by kmigrator
// KMIGRATOR:0440_billingreceipt_balanceupdatedat_and_more:IyBHZW5lcmF0ZWQgYnkgRGphbmdvIDUuMC4zIG9uIDIwMjQtMTEtMjcgMDU6MjMKCmZyb20gZGphbmdvLmRiIGltcG9ydCBtaWdyYXRpb25zLCBtb2RlbHMKCgpjbGFzcyBNaWdyYXRpb24obWlncmF0aW9ucy5NaWdyYXRpb24pOgoKICAgIGRlcGVuZGVuY2llcyA9IFsKICAgICAgICAoJ19kamFuZ29fc2NoZW1hJywgJzA0MzlfYXV0b18yMDI0MTEyNV8wNzAyJyksCiAgICBdCgogICAgb3BlcmF0aW9ucyA9IFsKICAgICAgICBtaWdyYXRpb25zLkFkZEZpZWxkKAogICAgICAgICAgICBtb2RlbF9uYW1lPSdiaWxsaW5ncmVjZWlwdCcsCiAgICAgICAgICAgIG5hbWU9J2JhbGFuY2VVcGRhdGVkQXQnLAogICAgICAgICAgICBmaWVsZD1tb2RlbHMuRGF0ZVRpbWVGaWVsZChibGFuaz1UcnVlLCBudWxsPVRydWUpLAogICAgICAgICksCiAgICAgICAgbWlncmF0aW9ucy5BZGRGaWVsZCgKICAgICAgICAgICAgbW9kZWxfbmFtZT0nYmlsbGluZ3JlY2VpcHRoaXN0b3J5cmVjb3JkJywKICAgICAgICAgICAgbmFtZT0nYmFsYW5jZVVwZGF0ZWRBdCcsCiAgICAgICAgICAgIGZpZWxkPW1vZGVscy5EYXRlVGltZUZpZWxkKGJsYW5rPVRydWUsIG51bGw9VHJ1ZSksCiAgICAgICAgKSwKICAgIF0K

exports.up = async (knex) => {
await knex.raw(`
BEGIN;
SET statement_timeout = '1500s';
--
-- Add field balanceUpdatedAt to billingreceipt
--
ALTER TABLE "BillingReceipt" ADD COLUMN "balanceUpdatedAt" timestamp with time zone NULL;
--
-- Add field balanceUpdatedAt to billingreceipthistoryrecord
--
ALTER TABLE "BillingReceiptHistoryRecord" ADD COLUMN "balanceUpdatedAt" timestamp with time zone NULL;
SET statement_timeout = '10s';
COMMIT;

`)
}

exports.down = async (knex) => {
await knex.raw(`
BEGIN;
--
-- Add field balanceUpdatedAt to billingreceipthistoryrecord
--
ALTER TABLE "BillingReceiptHistoryRecord" DROP COLUMN "balanceUpdatedAt" CASCADE;
--
-- Add field balanceUpdatedAt to billingreceipt
--
ALTER TABLE "BillingReceipt" DROP COLUMN "balanceUpdatedAt" CASCADE;
COMMIT;

`)
}
28 changes: 28 additions & 0 deletions apps/condo/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -12526,6 +12526,7 @@ type BillingReceiptHistoryRecord {
recalculation: String
privilege: String
penalty: String
balanceUpdatedAt: String
paid: String
toPayDetails: JSON
services: JSON
Expand Down Expand Up @@ -12680,6 +12681,14 @@ input BillingReceiptHistoryRecordWhereInput {
penalty_gte: String
penalty_in: [String]
penalty_not_in: [String]
balanceUpdatedAt: String
balanceUpdatedAt_not: String
balanceUpdatedAt_lt: String
balanceUpdatedAt_lte: String
balanceUpdatedAt_gt: String
balanceUpdatedAt_gte: String
balanceUpdatedAt_in: [String]
balanceUpdatedAt_not_in: [String]
paid: String
paid_not: String
paid_lt: String
Expand Down Expand Up @@ -12811,6 +12820,8 @@ enum SortBillingReceiptHistoryRecordsBy {
privilege_DESC
penalty_ASC
penalty_DESC
balanceUpdatedAt_ASC
balanceUpdatedAt_DESC
paid_ASC
paid_DESC
id_ASC
Expand Down Expand Up @@ -12847,6 +12858,7 @@ input BillingReceiptHistoryRecordUpdateInput {
recalculation: String
privilege: String
penalty: String
balanceUpdatedAt: String
paid: String
toPayDetails: JSON
services: JSON
Expand Down Expand Up @@ -12888,6 +12900,7 @@ input BillingReceiptHistoryRecordCreateInput {
recalculation: String
privilege: String
penalty: String
balanceUpdatedAt: String
paid: String
toPayDetails: JSON
services: JSON
Expand Down Expand Up @@ -13086,6 +13099,9 @@ type BillingReceipt {
"""
penalty: String

""" Last date time when the balance was updated """
balanceUpdatedAt: String

""" Amount of money that recipient already paid by current receipt. Example: "50.00", "-50.00"
"""
paid: String
Expand Down Expand Up @@ -13277,6 +13293,14 @@ input BillingReceiptWhereInput {
penalty_gte: String
penalty_in: [String]
penalty_not_in: [String]
balanceUpdatedAt: String
balanceUpdatedAt_not: String
balanceUpdatedAt_lt: String
balanceUpdatedAt_lte: String
balanceUpdatedAt_gt: String
balanceUpdatedAt_gte: String
balanceUpdatedAt_in: [String]
balanceUpdatedAt_not_in: [String]
paid: String
paid_not: String
paid_lt: String
Expand Down Expand Up @@ -13392,6 +13416,8 @@ enum SortBillingReceiptsBy {
privilege_DESC
penalty_ASC
penalty_DESC
balanceUpdatedAt_ASC
balanceUpdatedAt_DESC
paid_ASC
paid_DESC
receiver_ASC
Expand Down Expand Up @@ -13432,6 +13458,7 @@ input BillingReceiptUpdateInput {
recalculation: String
privilege: String
penalty: String
balanceUpdatedAt: String
paid: String
toPayDetails: BillingReceiptToPayDetailsFieldInput
services: [BillingReceiptServiceFieldInput!]
Expand Down Expand Up @@ -13470,6 +13497,7 @@ input BillingReceiptCreateInput {
recalculation: String
privilege: String
penalty: String
balanceUpdatedAt: String
paid: String
toPayDetails: BillingReceiptToPayDetailsFieldInput
services: [BillingReceiptServiceFieldInput!]
Expand Down
27 changes: 27 additions & 0 deletions apps/condo/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18290,6 +18290,8 @@ export type BillingReceipt = {
acquiringIntegrationId?: Maybe<Scalars['ID']['output']>
/** Recipient balance on the receipt creation moment. Example: "50.00", "-50.00" */
balance?: Maybe<Scalars['String']['output']>
/** Last date time when the balance was updated */
balanceUpdatedAt?: Maybe<Scalars['String']['output']>
/** Can multiple receipts be united through this acquiring */
canGroupReceipts?: Maybe<Scalars['Boolean']['output']>
/** A category to print on display on the payment document. */
Expand Down Expand Up @@ -18355,6 +18357,7 @@ export type BillingReceipt = {
export type BillingReceiptCreateInput = {
account?: InputMaybe<BillingAccountRelateToOneInput>
balance?: InputMaybe<Scalars['String']['input']>
balanceUpdatedAt?: InputMaybe<Scalars['String']['input']>
category?: InputMaybe<BillingCategoryRelateToOneInput>
charge?: InputMaybe<Scalars['String']['input']>
context?: InputMaybe<BillingIntegrationOrganizationContextRelateToOneInput>
Expand Down Expand Up @@ -18830,6 +18833,7 @@ export type BillingReceiptHistoryRecord = {
_label_?: Maybe<Scalars['String']['output']>
account?: Maybe<Scalars['String']['output']>
balance?: Maybe<Scalars['String']['output']>
balanceUpdatedAt?: Maybe<Scalars['String']['output']>
category?: Maybe<Scalars['String']['output']>
charge?: Maybe<Scalars['String']['output']>
context?: Maybe<Scalars['String']['output']>
Expand Down Expand Up @@ -18867,6 +18871,7 @@ export type BillingReceiptHistoryRecord = {
export type BillingReceiptHistoryRecordCreateInput = {
account?: InputMaybe<Scalars['String']['input']>
balance?: InputMaybe<Scalars['String']['input']>
balanceUpdatedAt?: InputMaybe<Scalars['String']['input']>
category?: InputMaybe<Scalars['String']['input']>
charge?: InputMaybe<Scalars['String']['input']>
context?: InputMaybe<Scalars['String']['input']>
Expand Down Expand Up @@ -18909,6 +18914,7 @@ export enum BillingReceiptHistoryRecordHistoryActionType {
export type BillingReceiptHistoryRecordUpdateInput = {
account?: InputMaybe<Scalars['String']['input']>
balance?: InputMaybe<Scalars['String']['input']>
balanceUpdatedAt?: InputMaybe<Scalars['String']['input']>
category?: InputMaybe<Scalars['String']['input']>
charge?: InputMaybe<Scalars['String']['input']>
context?: InputMaybe<Scalars['String']['input']>
Expand Down Expand Up @@ -18950,6 +18956,14 @@ export type BillingReceiptHistoryRecordWhereInput = {
account_not?: InputMaybe<Scalars['String']['input']>
account_not_in?: InputMaybe<Array<InputMaybe<Scalars['String']['input']>>>
balance?: InputMaybe<Scalars['String']['input']>
balanceUpdatedAt?: InputMaybe<Scalars['String']['input']>
balanceUpdatedAt_gt?: InputMaybe<Scalars['String']['input']>
balanceUpdatedAt_gte?: InputMaybe<Scalars['String']['input']>
balanceUpdatedAt_in?: InputMaybe<Array<InputMaybe<Scalars['String']['input']>>>
balanceUpdatedAt_lt?: InputMaybe<Scalars['String']['input']>
balanceUpdatedAt_lte?: InputMaybe<Scalars['String']['input']>
balanceUpdatedAt_not?: InputMaybe<Scalars['String']['input']>
balanceUpdatedAt_not_in?: InputMaybe<Array<InputMaybe<Scalars['String']['input']>>>
balance_gt?: InputMaybe<Scalars['String']['input']>
balance_gte?: InputMaybe<Scalars['String']['input']>
balance_in?: InputMaybe<Array<InputMaybe<Scalars['String']['input']>>>
Expand Down Expand Up @@ -19267,6 +19281,7 @@ export type BillingReceiptToPayDetailsFieldInput = {
export type BillingReceiptUpdateInput = {
account?: InputMaybe<BillingAccountRelateToOneInput>
balance?: InputMaybe<Scalars['String']['input']>
balanceUpdatedAt?: InputMaybe<Scalars['String']['input']>
category?: InputMaybe<BillingCategoryRelateToOneInput>
charge?: InputMaybe<Scalars['String']['input']>
context?: InputMaybe<BillingIntegrationOrganizationContextRelateToOneInput>
Expand Down Expand Up @@ -19303,6 +19318,14 @@ export type BillingReceiptWhereInput = {
account?: InputMaybe<BillingAccountWhereInput>
account_is_null?: InputMaybe<Scalars['Boolean']['input']>
balance?: InputMaybe<Scalars['String']['input']>
balanceUpdatedAt?: InputMaybe<Scalars['String']['input']>
balanceUpdatedAt_gt?: InputMaybe<Scalars['String']['input']>
balanceUpdatedAt_gte?: InputMaybe<Scalars['String']['input']>
balanceUpdatedAt_in?: InputMaybe<Array<InputMaybe<Scalars['String']['input']>>>
balanceUpdatedAt_lt?: InputMaybe<Scalars['String']['input']>
balanceUpdatedAt_lte?: InputMaybe<Scalars['String']['input']>
balanceUpdatedAt_not?: InputMaybe<Scalars['String']['input']>
balanceUpdatedAt_not_in?: InputMaybe<Array<InputMaybe<Scalars['String']['input']>>>
balance_gt?: InputMaybe<Scalars['String']['input']>
balance_gte?: InputMaybe<Scalars['String']['input']>
balance_in?: InputMaybe<Array<InputMaybe<Scalars['String']['input']>>>
Expand Down Expand Up @@ -78927,6 +78950,8 @@ export enum SortBillingReceiptFilesBy {
}

export enum SortBillingReceiptHistoryRecordsBy {
BalanceUpdatedAtAsc = 'balanceUpdatedAt_ASC',
BalanceUpdatedAtDesc = 'balanceUpdatedAt_DESC',
BalanceAsc = 'balance_ASC',
BalanceDesc = 'balance_DESC',
ChargeAsc = 'charge_ASC',
Expand Down Expand Up @@ -78970,6 +78995,8 @@ export enum SortBillingReceiptHistoryRecordsBy {
export enum SortBillingReceiptsBy {
AccountAsc = 'account_ASC',
AccountDesc = 'account_DESC',
BalanceUpdatedAtAsc = 'balanceUpdatedAt_ASC',
BalanceUpdatedAtDesc = 'balanceUpdatedAt_DESC',
BalanceAsc = 'balance_ASC',
BalanceDesc = 'balance_DESC',
CategoryAsc = 'category_ASC',
Expand Down
Loading