WIP: Allocate landed cost.

This commit is contained in:
a.bouhuolia
2021-07-22 18:11:17 +02:00
parent 1eacc254d8
commit 76c6cb3699
33 changed files with 1577 additions and 163 deletions

View File

@@ -103,6 +103,7 @@ export default class Bill extends TenantModel {
'remainingDays',
'overdueDays',
'isOverdue',
'unallocatedCostAmount'
];
}
@@ -178,6 +179,14 @@ export default class Bill extends TenantModel {
return this.overdueDays > 0;
}
/**
* Retrieve the unallocated cost amount.
* @return {number}
*/
get unallocatedCostAmount() {
return Math.max(this.landedCostAmount - this.allocatedCostAmount, 0);
}
getOverdueDays(asDate = moment().format('YYYY-MM-DD')) {
// Can't continue in case due date not defined.
if (!this.dueDate) {
@@ -195,6 +204,7 @@ export default class Bill extends TenantModel {
static get relationMappings() {
const Contact = require('models/Contact');
const ItemEntry = require('models/ItemEntry');
const BillLandedCost = require('models/BillLandedCost');
return {
vendor: {
@@ -220,6 +230,15 @@ export default class Bill extends TenantModel {
builder.where('reference_type', 'Bill');
},
},
locatedLandedCosts: {
relation: Model.HasManyRelation,
modelClass: BillLandedCost.default,
join: {
from: 'bills.id',
to: 'bill_located_costs.billId',
},
},
};
}

View File

@@ -0,0 +1,36 @@
import { Model } from 'objection';
import TenantModel from 'models/TenantModel';
export default class BillLandedCost extends TenantModel {
/**
* Table name
*/
static get tableName() {
return 'bill_located_costs';
}
/**
* Model timestamps.
*/
get timestamps() {
return ['createdAt', 'updatedAt'];
}
/**
* Relationship mapping.
*/
static get relationMappings() {
const BillLandedCostEntry = require('models/BillLandedCostEntry');
return {
allocateEntries: {
relation: Model.HasManyRelation,
modelClass: BillLandedCostEntry.default,
join: {
from: 'bill_located_costs.id',
to: 'bill_located_cost_entries.billLocatedCostId',
},
},
};
}
}

View File

@@ -0,0 +1,10 @@
import TenantModel from 'models/TenantModel';
export default class BillLandedCostEntry extends TenantModel {
/**
* Table name
*/
static get tableName() {
return 'bill_located_cost_entries';
}
}

View File

@@ -1,27 +1,27 @@
import { Model } from "objection";
import TenantModel from "models/TenantModel";
import { viewRolesBuilder } from "lib/ViewRolesBuilder";
import { Model } from 'objection';
import TenantModel from 'models/TenantModel';
import { viewRolesBuilder } from 'lib/ViewRolesBuilder';
export default class Expense extends TenantModel {
/**
* Table name
*/
static get tableName() {
return "expenses_transactions";
return 'expenses_transactions';
}
/**
* Account transaction reference type.
*/
static get referenceType() {
return "Expense";
return 'Expense';
}
/**
* Model timestamps.
*/
get timestamps() {
return ["createdAt", "updatedAt"];
return ['createdAt', 'updatedAt'];
}
/**
@@ -37,14 +37,19 @@ export default class Expense extends TenantModel {
static get media() {
return true;
}
static get virtualAttributes() {
return ["isPublished"];
return ['isPublished', 'unallocatedLandedCost'];
}
isPublished() {
return Boolean(this.publishedAt);
}
unallocatedLandedCost() {
return Math.max(this.amount - this.allocatedCostAmount, 0);
}
/**
* Model modifiers.
*/
@@ -52,28 +57,28 @@ export default class Expense extends TenantModel {
return {
filterByDateRange(query, startDate, endDate) {
if (startDate) {
query.where("date", ">=", startDate);
query.where('date', '>=', startDate);
}
if (endDate) {
query.where("date", "<=", endDate);
query.where('date', '<=', endDate);
}
},
filterByAmountRange(query, from, to) {
if (from) {
query.where("amount", ">=", from);
query.where('amount', '>=', from);
}
if (to) {
query.where("amount", "<=", to);
query.where('amount', '<=', to);
}
},
filterByExpenseAccount(query, accountId) {
if (accountId) {
query.where("expense_account_id", accountId);
query.where('expense_account_id', accountId);
}
},
filterByPaymentAccount(query, accountId) {
if (accountId) {
query.where("payment_account_id", accountId);
query.where('payment_account_id', accountId);
}
},
viewRolesBuilder(query, conditionals, expression) {
@@ -94,40 +99,40 @@ export default class Expense extends TenantModel {
* Relationship mapping.
*/
static get relationMappings() {
const Account = require("models/Account");
const ExpenseCategory = require("models/ExpenseCategory");
const Media = require("models/Media");
const Account = require('models/Account');
const ExpenseCategory = require('models/ExpenseCategory');
const Media = require('models/Media');
return {
paymentAccount: {
relation: Model.BelongsToOneRelation,
modelClass: Account.default,
join: {
from: "expenses_transactions.paymentAccountId",
to: "accounts.id",
from: 'expenses_transactions.paymentAccountId',
to: 'accounts.id',
},
},
categories: {
relation: Model.HasManyRelation,
modelClass: ExpenseCategory.default,
join: {
from: "expenses_transactions.id",
to: "expense_transaction_categories.expenseId",
from: 'expenses_transactions.id',
to: 'expense_transaction_categories.expenseId',
},
},
media: {
relation: Model.ManyToManyRelation,
modelClass: Media.default,
join: {
from: "expenses_transactions.id",
from: 'expenses_transactions.id',
through: {
from: "media_links.model_id",
to: "media_links.media_id",
from: 'media_links.model_id',
to: 'media_links.media_id',
},
to: "media.id",
to: 'media.id',
},
filter(query) {
query.where("model_name", "Expense");
query.where('model_name', 'Expense');
},
},
};
@@ -139,39 +144,39 @@ export default class Expense extends TenantModel {
static get fields() {
return {
payment_date: {
label: "Payment date",
column: "payment_date",
columnType: "date",
label: 'Payment date',
column: 'payment_date',
columnType: 'date',
},
payment_account: {
label: "Payment account",
column: "payment_account_id",
relation: "accounts.id",
optionsResource: "account",
label: 'Payment account',
column: 'payment_account_id',
relation: 'accounts.id',
optionsResource: 'account',
},
amount: {
label: "Amount",
column: "total_amount",
columnType: "number",
label: 'Amount',
column: 'total_amount',
columnType: 'number',
},
currency_code: {
label: "Currency",
column: "currency_code",
optionsResource: "currency",
label: 'Currency',
column: 'currency_code',
optionsResource: 'currency',
},
reference_no: {
label: "Reference No.",
column: "reference_no",
columnType: "string",
label: 'Reference No.',
column: 'reference_no',
columnType: 'string',
},
description: {
label: "Description",
column: "description",
columnType: "string",
label: 'Description',
column: 'description',
columnType: 'string',
},
published: {
label: "Published",
column: "published_at",
label: 'Published',
column: 'published_at',
},
status: {
label: 'Status',
@@ -194,9 +199,9 @@ export default class Expense extends TenantModel {
},
},
created_at: {
label: "Created at",
column: "created_at",
columnType: "date",
label: 'Created at',
column: 'created_at',
columnType: 'date',
},
};
}

View File

@@ -9,6 +9,21 @@ export default class ExpenseCategory extends TenantModel {
return 'expense_transaction_categories';
}
/**
* Virtual attributes.
*/
static get virtualAttributes() {
return ['unallocatedLandedCost'];
}
/**
* Remain unallocated landed cost.
* @return {number}
*/
get unallocatedLandedCost() {
return Math.max(this.amount - this.allocatedCostAmount, 0);
}
/**
* Relationship mapping.
*/