import { Model } from 'objection'; import TenantModel from 'models/TenantModel'; import PaginationQueryBuilder from './Pagination'; import QueryParser from 'lib/LogicEvaluation/QueryParser'; class CustomerQueryBuilder extends PaginationQueryBuilder { constructor(...args) { super(...args); this.onBuild((builder) => { if (builder.isFind() || builder.isDelete() || builder.isUpdate()) { builder.where('contact_service', 'customer'); } }); } } export default class Customer extends TenantModel { /** * Query builder. */ static get QueryBuilder() { return CustomerQueryBuilder; } /** * Table name */ static get tableName() { return 'contacts'; } /** * Model timestamps. */ get timestamps() { return ['createdAt', 'updatedAt']; } /** * Defined virtual attributes. */ static get virtualAttributes() { return ['closingBalance', 'contactNormal']; } /** * Closing balance attribute. */ get closingBalance() { return this.balance; } /** * Retrieve the contact noraml; */ get contactNormal() { return 'debit'; } /** * Model modifiers. */ static get modifiers() { return { /** * Filters the active customers. */ active(query) { query.where('active', 1); }, /** * Filters the inactive customers. */ inactive(query) { query.where('active', 0); }, /** * Filters the customers that have overdue invoices. */ overdue(query) { query.select( '*', Customer .relatedQuery('overDueInvoices', query.knex()) .count() .as('countOverdue'), ); query.having('countOverdue', '>', 0); }, /** * Filters the unpaid customers. */ unpaid(query) { query.whereRaw('`BALANCE` + `OPENING_BALANCE` <> 0'); } }; } /** * Relationship mapping. */ static get relationMappings() { const SaleInvoice = require('models/SaleInvoice'); return { salesInvoices: { relation: Model.HasManyRelation, modelClass: SaleInvoice.default, join: { from: 'contacts.id', to: 'sales_invoices.customerId', }, }, overDueInvoices: { relation: Model.HasManyRelation, modelClass: SaleInvoice.default, join: { from: 'contacts.id', to: 'sales_invoices.customerId', }, filter: (query) => { query.modify('overdue'); } } }; } static get fields() { return { contact_service: { column: 'contact_service', }, display_name: { column: 'display_name', }, email: { column: 'email', }, work_phone: { column: 'work_phone', }, personal_phone: { column: 'personal_phone', }, company_name: { column: 'company_name', }, website: { column: 'website' }, created_at: { column: 'created_at', }, balance: { column: 'balance', }, opening_balance: { column: 'opening_balance', }, opening_balance_at: { column: 'opening_balance_at', }, currency_code: { column: 'currency_code', }, status: { label: 'Status', options: [ { key: 'active', label: 'Active' }, { key: 'inactive', label: 'Inactive' }, { key: 'overdue', label: 'Overdue' }, { key: 'unpaid', label: 'Unpaid' }, ], query: (query, role) => { switch(role.value) { case 'active': query.modify('active'); break; case 'inactive': query.modify('inactive'); break; case 'overdue': query.modify('overdue'); break; case 'unpaid': query.modify('unpaid'); break; } }, }, created_at: { column: 'created_at', } }; } }