Updated via schema editor on 2025-06-19 01:50
This commit is contained in:
parent
6764c421bf
commit
06ef1c22e8
File diff suppressed because one or more lines are too long
@ -15,6 +15,10 @@ module.exports = class OwnersDBApi {
|
||||
{
|
||||
id: data.id || undefined,
|
||||
|
||||
lives_on_site: data.lives_on_site || false,
|
||||
|
||||
emergency_contact: data.emergency_contact || null,
|
||||
mailing_address: data.mailing_address || null,
|
||||
importHash: data.importHash || null,
|
||||
createdById: currentUser.id,
|
||||
updatedById: currentUser.id,
|
||||
@ -22,6 +26,14 @@ module.exports = class OwnersDBApi {
|
||||
{ transaction },
|
||||
);
|
||||
|
||||
await owners.setUser_account(data.user_account || null, {
|
||||
transaction,
|
||||
});
|
||||
|
||||
await owners.setUnit(data.unit || [], {
|
||||
transaction,
|
||||
});
|
||||
|
||||
return owners;
|
||||
}
|
||||
|
||||
@ -33,6 +45,10 @@ module.exports = class OwnersDBApi {
|
||||
const ownersData = data.map((item, index) => ({
|
||||
id: item.id || undefined,
|
||||
|
||||
lives_on_site: item.lives_on_site || false,
|
||||
|
||||
emergency_contact: item.emergency_contact || null,
|
||||
mailing_address: item.mailing_address || null,
|
||||
importHash: item.importHash || null,
|
||||
createdById: currentUser.id,
|
||||
updatedById: currentUser.id,
|
||||
@ -55,10 +71,31 @@ module.exports = class OwnersDBApi {
|
||||
|
||||
const updatePayload = {};
|
||||
|
||||
if (data.lives_on_site !== undefined)
|
||||
updatePayload.lives_on_site = data.lives_on_site;
|
||||
|
||||
if (data.emergency_contact !== undefined)
|
||||
updatePayload.emergency_contact = data.emergency_contact;
|
||||
|
||||
if (data.mailing_address !== undefined)
|
||||
updatePayload.mailing_address = data.mailing_address;
|
||||
|
||||
updatePayload.updatedById = currentUser.id;
|
||||
|
||||
await owners.update(updatePayload, { transaction });
|
||||
|
||||
if (data.user_account !== undefined) {
|
||||
await owners.setUser_account(
|
||||
data.user_account,
|
||||
|
||||
{ transaction },
|
||||
);
|
||||
}
|
||||
|
||||
if (data.unit !== undefined) {
|
||||
await owners.setUnit(data.unit, { transaction });
|
||||
}
|
||||
|
||||
return owners;
|
||||
}
|
||||
|
||||
@ -120,6 +157,14 @@ module.exports = class OwnersDBApi {
|
||||
|
||||
const output = owners.get({ plain: true });
|
||||
|
||||
output.user_account = await owners.getUser_account({
|
||||
transaction,
|
||||
});
|
||||
|
||||
output.unit = await owners.getUnit({
|
||||
transaction,
|
||||
});
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
@ -135,7 +180,39 @@ module.exports = class OwnersDBApi {
|
||||
|
||||
const transaction = (options && options.transaction) || undefined;
|
||||
|
||||
let include = [];
|
||||
let include = [
|
||||
{
|
||||
model: db.users,
|
||||
as: 'user_account',
|
||||
|
||||
where: filter.user_account
|
||||
? {
|
||||
[Op.or]: [
|
||||
{
|
||||
id: {
|
||||
[Op.in]: filter.user_account
|
||||
.split('|')
|
||||
.map((term) => Utils.uuid(term)),
|
||||
},
|
||||
},
|
||||
{
|
||||
firstName: {
|
||||
[Op.or]: filter.user_account
|
||||
.split('|')
|
||||
.map((term) => ({ [Op.iLike]: `%${term}%` })),
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
: {},
|
||||
},
|
||||
|
||||
{
|
||||
model: db.units,
|
||||
as: 'unit',
|
||||
required: false,
|
||||
},
|
||||
];
|
||||
|
||||
if (filter) {
|
||||
if (filter.id) {
|
||||
@ -145,6 +222,28 @@ module.exports = class OwnersDBApi {
|
||||
};
|
||||
}
|
||||
|
||||
if (filter.emergency_contact) {
|
||||
where = {
|
||||
...where,
|
||||
[Op.and]: Utils.ilike(
|
||||
'owners',
|
||||
'emergency_contact',
|
||||
filter.emergency_contact,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
if (filter.mailing_address) {
|
||||
where = {
|
||||
...where,
|
||||
[Op.and]: Utils.ilike(
|
||||
'owners',
|
||||
'mailing_address',
|
||||
filter.mailing_address,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
if (filter.active !== undefined) {
|
||||
where = {
|
||||
...where,
|
||||
@ -152,6 +251,45 @@ module.exports = class OwnersDBApi {
|
||||
};
|
||||
}
|
||||
|
||||
if (filter.lives_on_site) {
|
||||
where = {
|
||||
...where,
|
||||
lives_on_site: filter.lives_on_site,
|
||||
};
|
||||
}
|
||||
|
||||
if (filter.unit) {
|
||||
const searchTerms = filter.unit.split('|');
|
||||
|
||||
include = [
|
||||
{
|
||||
model: db.units,
|
||||
as: 'unit_filter',
|
||||
required: searchTerms.length > 0,
|
||||
where:
|
||||
searchTerms.length > 0
|
||||
? {
|
||||
[Op.or]: [
|
||||
{
|
||||
id: {
|
||||
[Op.in]: searchTerms.map((term) => Utils.uuid(term)),
|
||||
},
|
||||
},
|
||||
{
|
||||
unit_number: {
|
||||
[Op.or]: searchTerms.map((term) => ({
|
||||
[Op.iLike]: `%${term}%`,
|
||||
})),
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
: undefined,
|
||||
},
|
||||
...include,
|
||||
];
|
||||
}
|
||||
|
||||
if (filter.createdAtRange) {
|
||||
const [start, end] = filter.createdAtRange;
|
||||
|
||||
|
||||
@ -31,6 +31,10 @@ module.exports = class UnitsDBApi {
|
||||
transaction,
|
||||
});
|
||||
|
||||
await units.setOwners(data.owners || [], {
|
||||
transaction,
|
||||
});
|
||||
|
||||
return units;
|
||||
}
|
||||
|
||||
@ -94,6 +98,10 @@ module.exports = class UnitsDBApi {
|
||||
);
|
||||
}
|
||||
|
||||
if (data.owners !== undefined) {
|
||||
await units.setOwners(data.owners, { transaction });
|
||||
}
|
||||
|
||||
return units;
|
||||
}
|
||||
|
||||
@ -169,6 +177,10 @@ module.exports = class UnitsDBApi {
|
||||
transaction,
|
||||
});
|
||||
|
||||
output.owners = await units.getOwners({
|
||||
transaction,
|
||||
});
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
@ -210,6 +222,12 @@ module.exports = class UnitsDBApi {
|
||||
}
|
||||
: {},
|
||||
},
|
||||
|
||||
{
|
||||
model: db.owners,
|
||||
as: 'owners',
|
||||
required: false,
|
||||
},
|
||||
];
|
||||
|
||||
if (filter) {
|
||||
@ -330,6 +348,38 @@ module.exports = class UnitsDBApi {
|
||||
};
|
||||
}
|
||||
|
||||
if (filter.owners) {
|
||||
const searchTerms = filter.owners.split('|');
|
||||
|
||||
include = [
|
||||
{
|
||||
model: db.owners,
|
||||
as: 'owners_filter',
|
||||
required: searchTerms.length > 0,
|
||||
where:
|
||||
searchTerms.length > 0
|
||||
? {
|
||||
[Op.or]: [
|
||||
{
|
||||
id: {
|
||||
[Op.in]: searchTerms.map((term) => Utils.uuid(term)),
|
||||
},
|
||||
},
|
||||
{
|
||||
id: {
|
||||
[Op.or]: searchTerms.map((term) => ({
|
||||
[Op.iLike]: `%${term}%`,
|
||||
})),
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
: undefined,
|
||||
},
|
||||
...include,
|
||||
];
|
||||
}
|
||||
|
||||
if (filter.createdAtRange) {
|
||||
const [start, end] = filter.createdAtRange;
|
||||
|
||||
|
||||
@ -283,6 +283,10 @@ module.exports = class UsersDBApi {
|
||||
transaction,
|
||||
});
|
||||
|
||||
output.owners_user_account = await users.getOwners_user_account({
|
||||
transaction,
|
||||
});
|
||||
|
||||
output.avatar = await users.getAvatar({
|
||||
transaction,
|
||||
});
|
||||
|
||||
96
backend/src/db/migrations/1750297828377.js
Normal file
96
backend/src/db/migrations/1750297828377.js
Normal file
@ -0,0 +1,96 @@
|
||||
module.exports = {
|
||||
/**
|
||||
* @param {QueryInterface} queryInterface
|
||||
* @param {Sequelize} Sequelize
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async up(queryInterface, Sequelize) {
|
||||
/**
|
||||
* @type {Transaction}
|
||||
*/
|
||||
const transaction = await queryInterface.sequelize.transaction();
|
||||
try {
|
||||
await queryInterface.addColumn(
|
||||
'owners',
|
||||
'user_accountId',
|
||||
{
|
||||
type: Sequelize.DataTypes.UUID,
|
||||
|
||||
references: {
|
||||
model: 'users',
|
||||
key: 'id',
|
||||
},
|
||||
},
|
||||
{ transaction },
|
||||
);
|
||||
|
||||
await queryInterface.addColumn(
|
||||
'owners',
|
||||
'lives_on_site',
|
||||
{
|
||||
type: Sequelize.DataTypes.BOOLEAN,
|
||||
|
||||
defaultValue: false,
|
||||
allowNull: false,
|
||||
},
|
||||
{ transaction },
|
||||
);
|
||||
|
||||
await queryInterface.addColumn(
|
||||
'owners',
|
||||
'emergency_contact',
|
||||
{
|
||||
type: Sequelize.DataTypes.TEXT,
|
||||
},
|
||||
{ transaction },
|
||||
);
|
||||
|
||||
await queryInterface.addColumn(
|
||||
'owners',
|
||||
'mailing_address',
|
||||
{
|
||||
type: Sequelize.DataTypes.TEXT,
|
||||
},
|
||||
{ transaction },
|
||||
);
|
||||
|
||||
await transaction.commit();
|
||||
} catch (err) {
|
||||
await transaction.rollback();
|
||||
throw err;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @param {QueryInterface} queryInterface
|
||||
* @param {Sequelize} Sequelize
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async down(queryInterface, Sequelize) {
|
||||
/**
|
||||
* @type {Transaction}
|
||||
*/
|
||||
const transaction = await queryInterface.sequelize.transaction();
|
||||
try {
|
||||
await queryInterface.removeColumn('owners', 'mailing_address', {
|
||||
transaction,
|
||||
});
|
||||
|
||||
await queryInterface.removeColumn('owners', 'emergency_contact', {
|
||||
transaction,
|
||||
});
|
||||
|
||||
await queryInterface.removeColumn('owners', 'lives_on_site', {
|
||||
transaction,
|
||||
});
|
||||
|
||||
await queryInterface.removeColumn('owners', 'user_accountId', {
|
||||
transaction,
|
||||
});
|
||||
|
||||
await transaction.commit();
|
||||
} catch (err) {
|
||||
await transaction.rollback();
|
||||
throw err;
|
||||
}
|
||||
},
|
||||
};
|
||||
@ -14,6 +14,21 @@ module.exports = function (sequelize, DataTypes) {
|
||||
primaryKey: true,
|
||||
},
|
||||
|
||||
lives_on_site: {
|
||||
type: DataTypes.BOOLEAN,
|
||||
|
||||
allowNull: false,
|
||||
defaultValue: false,
|
||||
},
|
||||
|
||||
emergency_contact: {
|
||||
type: DataTypes.TEXT,
|
||||
},
|
||||
|
||||
mailing_address: {
|
||||
type: DataTypes.TEXT,
|
||||
},
|
||||
|
||||
importHash: {
|
||||
type: DataTypes.STRING(255),
|
||||
allowNull: true,
|
||||
@ -28,10 +43,36 @@ module.exports = function (sequelize, DataTypes) {
|
||||
);
|
||||
|
||||
owners.associate = (db) => {
|
||||
db.owners.belongsToMany(db.units, {
|
||||
as: 'unit',
|
||||
foreignKey: {
|
||||
name: 'owners_unitId',
|
||||
},
|
||||
constraints: false,
|
||||
through: 'ownersUnitUnits',
|
||||
});
|
||||
|
||||
db.owners.belongsToMany(db.units, {
|
||||
as: 'unit_filter',
|
||||
foreignKey: {
|
||||
name: 'owners_unitId',
|
||||
},
|
||||
constraints: false,
|
||||
through: 'ownersUnitUnits',
|
||||
});
|
||||
|
||||
/// loop through entities and it's fields, and if ref === current e[name] and create relation has many on parent entity
|
||||
|
||||
//end loop
|
||||
|
||||
db.owners.belongsTo(db.users, {
|
||||
as: 'user_account',
|
||||
foreignKey: {
|
||||
name: 'user_accountId',
|
||||
},
|
||||
constraints: false,
|
||||
});
|
||||
|
||||
db.owners.belongsTo(db.users, {
|
||||
as: 'createdBy',
|
||||
});
|
||||
|
||||
@ -48,6 +48,24 @@ module.exports = function (sequelize, DataTypes) {
|
||||
);
|
||||
|
||||
units.associate = (db) => {
|
||||
db.units.belongsToMany(db.owners, {
|
||||
as: 'owners',
|
||||
foreignKey: {
|
||||
name: 'units_ownersId',
|
||||
},
|
||||
constraints: false,
|
||||
through: 'unitsOwnersOwners',
|
||||
});
|
||||
|
||||
db.units.belongsToMany(db.owners, {
|
||||
as: 'owners_filter',
|
||||
foreignKey: {
|
||||
name: 'units_ownersId',
|
||||
},
|
||||
constraints: false,
|
||||
through: 'unitsOwnersOwners',
|
||||
});
|
||||
|
||||
/// loop through entities and it's fields, and if ref === current e[name] and create relation has many on parent entity
|
||||
|
||||
db.units.hasMany(db.users, {
|
||||
|
||||
@ -110,6 +110,14 @@ module.exports = function (sequelize, DataTypes) {
|
||||
constraints: false,
|
||||
});
|
||||
|
||||
db.users.hasMany(db.owners, {
|
||||
as: 'owners_user_account',
|
||||
foreignKey: {
|
||||
name: 'user_accountId',
|
||||
},
|
||||
constraints: false,
|
||||
});
|
||||
|
||||
//end loop
|
||||
|
||||
db.users.belongsTo(db.roles, {
|
||||
|
||||
@ -45,6 +45,14 @@ const BudgetsData = [
|
||||
|
||||
expenses: 23000,
|
||||
},
|
||||
|
||||
{
|
||||
year: 2019,
|
||||
|
||||
total_budget: 45000,
|
||||
|
||||
expenses: 24000,
|
||||
},
|
||||
];
|
||||
|
||||
const DocumentsData = [
|
||||
@ -79,6 +87,14 @@ const DocumentsData = [
|
||||
|
||||
// type code here for "relation_many" field
|
||||
},
|
||||
|
||||
{
|
||||
name: 'Maintenance Schedule',
|
||||
|
||||
// type code here for "files" field
|
||||
|
||||
// type code here for "relation_many" field
|
||||
},
|
||||
];
|
||||
|
||||
const MaintenanceRequestsData = [
|
||||
@ -87,7 +103,7 @@ const MaintenanceRequestsData = [
|
||||
|
||||
description: 'Leaking faucet in kitchen',
|
||||
|
||||
status: 'in_progress',
|
||||
status: 'pending',
|
||||
|
||||
request_date: new Date('2023-10-01T10:00:00Z'),
|
||||
},
|
||||
@ -97,7 +113,7 @@ const MaintenanceRequestsData = [
|
||||
|
||||
description: 'Broken window in living room',
|
||||
|
||||
status: 'pending',
|
||||
status: 'in_progress',
|
||||
|
||||
request_date: new Date('2023-09-25T14:30:00Z'),
|
||||
},
|
||||
@ -107,7 +123,7 @@ const MaintenanceRequestsData = [
|
||||
|
||||
description: 'Heating not working',
|
||||
|
||||
status: 'pending',
|
||||
status: 'in_progress',
|
||||
|
||||
request_date: new Date('2023-09-20T09:00:00Z'),
|
||||
},
|
||||
@ -117,10 +133,20 @@ const MaintenanceRequestsData = [
|
||||
|
||||
description: 'Elevator malfunction',
|
||||
|
||||
status: 'pending',
|
||||
status: 'in_progress',
|
||||
|
||||
request_date: new Date('2023-10-02T11:15:00Z'),
|
||||
},
|
||||
|
||||
{
|
||||
// type code here for "relation_one" field
|
||||
|
||||
description: 'Paint peeling in hallway',
|
||||
|
||||
status: 'completed',
|
||||
|
||||
request_date: new Date('2023-09-28T13:45:00Z'),
|
||||
},
|
||||
];
|
||||
|
||||
const NoticesData = [
|
||||
@ -163,6 +189,16 @@ const NoticesData = [
|
||||
|
||||
sent_date: new Date('2023-09-26T11:00:00Z'),
|
||||
},
|
||||
|
||||
{
|
||||
// type code here for "relation_many" field
|
||||
|
||||
title: 'Holiday Party',
|
||||
|
||||
content: 'Join us for the holiday party on December 20th.',
|
||||
|
||||
sent_date: new Date('2023-09-25T12:00:00Z'),
|
||||
},
|
||||
];
|
||||
|
||||
const UnitsData = [
|
||||
@ -175,9 +211,11 @@ const UnitsData = [
|
||||
|
||||
unit_factor: 1,
|
||||
|
||||
cond_fee: 52.98,
|
||||
cond_fee: 40.89,
|
||||
|
||||
parking_stall: 7,
|
||||
parking_stall: 5,
|
||||
|
||||
// type code here for "relation_many" field
|
||||
},
|
||||
|
||||
{
|
||||
@ -187,11 +225,13 @@ const UnitsData = [
|
||||
|
||||
balance: 0,
|
||||
|
||||
unit_factor: 1,
|
||||
unit_factor: 4,
|
||||
|
||||
cond_fee: 98.25,
|
||||
cond_fee: 27.38,
|
||||
|
||||
parking_stall: 9,
|
||||
parking_stall: 1,
|
||||
|
||||
// type code here for "relation_many" field
|
||||
},
|
||||
|
||||
{
|
||||
@ -201,11 +241,13 @@ const UnitsData = [
|
||||
|
||||
balance: 150,
|
||||
|
||||
unit_factor: 5,
|
||||
unit_factor: 3,
|
||||
|
||||
cond_fee: 59.63,
|
||||
cond_fee: 47.22,
|
||||
|
||||
parking_stall: 8,
|
||||
parking_stall: 9,
|
||||
|
||||
// type code here for "relation_many" field
|
||||
},
|
||||
|
||||
{
|
||||
@ -215,15 +257,93 @@ const UnitsData = [
|
||||
|
||||
balance: 0,
|
||||
|
||||
unit_factor: 7,
|
||||
unit_factor: 8,
|
||||
|
||||
cond_fee: 32.97,
|
||||
cond_fee: 53.42,
|
||||
|
||||
parking_stall: 4,
|
||||
parking_stall: 1,
|
||||
|
||||
// type code here for "relation_many" field
|
||||
},
|
||||
|
||||
{
|
||||
unit_number: '105',
|
||||
|
||||
// type code here for "relation_one" field
|
||||
|
||||
balance: 300,
|
||||
|
||||
unit_factor: 6,
|
||||
|
||||
cond_fee: 18.67,
|
||||
|
||||
parking_stall: 2,
|
||||
|
||||
// type code here for "relation_many" field
|
||||
},
|
||||
];
|
||||
|
||||
const OwnersData = [{}, {}, {}, {}];
|
||||
const OwnersData = [
|
||||
{
|
||||
// type code here for "relation_one" field
|
||||
|
||||
lives_on_site: false,
|
||||
|
||||
emergency_contact: 'Leonard Euler',
|
||||
|
||||
mailing_address: 'Jonas Salk',
|
||||
|
||||
// type code here for "relation_many" field
|
||||
},
|
||||
|
||||
{
|
||||
// type code here for "relation_one" field
|
||||
|
||||
lives_on_site: true,
|
||||
|
||||
emergency_contact: 'Enrico Fermi',
|
||||
|
||||
mailing_address: 'Paul Dirac',
|
||||
|
||||
// type code here for "relation_many" field
|
||||
},
|
||||
|
||||
{
|
||||
// type code here for "relation_one" field
|
||||
|
||||
lives_on_site: false,
|
||||
|
||||
emergency_contact: 'Claude Bernard',
|
||||
|
||||
mailing_address: 'Frederick Sanger',
|
||||
|
||||
// type code here for "relation_many" field
|
||||
},
|
||||
|
||||
{
|
||||
// type code here for "relation_one" field
|
||||
|
||||
lives_on_site: true,
|
||||
|
||||
emergency_contact: 'Edward O. Wilson',
|
||||
|
||||
mailing_address: 'J. Robert Oppenheimer',
|
||||
|
||||
// type code here for "relation_many" field
|
||||
},
|
||||
|
||||
{
|
||||
// type code here for "relation_one" field
|
||||
|
||||
lives_on_site: true,
|
||||
|
||||
emergency_contact: 'Joseph J. Thomson',
|
||||
|
||||
mailing_address: 'Michael Faraday',
|
||||
|
||||
// type code here for "relation_many" field
|
||||
},
|
||||
];
|
||||
|
||||
// Similar logic for "relation_many"
|
||||
|
||||
@ -271,6 +391,17 @@ async function associateUserWithUnit() {
|
||||
if (User3?.setUnit) {
|
||||
await User3.setUnit(relatedUnit3);
|
||||
}
|
||||
|
||||
const relatedUnit4 = await Units.findOne({
|
||||
offset: Math.floor(Math.random() * (await Units.count())),
|
||||
});
|
||||
const User4 = await Users.findOne({
|
||||
order: [['id', 'ASC']],
|
||||
offset: 4,
|
||||
});
|
||||
if (User4?.setUnit) {
|
||||
await User4.setUnit(relatedUnit4);
|
||||
}
|
||||
}
|
||||
|
||||
// Similar logic for "relation_many"
|
||||
@ -319,6 +450,17 @@ async function associateMaintenanceRequestWithUnit() {
|
||||
if (MaintenanceRequest3?.setUnit) {
|
||||
await MaintenanceRequest3.setUnit(relatedUnit3);
|
||||
}
|
||||
|
||||
const relatedUnit4 = await Units.findOne({
|
||||
offset: Math.floor(Math.random() * (await Units.count())),
|
||||
});
|
||||
const MaintenanceRequest4 = await MaintenanceRequests.findOne({
|
||||
order: [['id', 'ASC']],
|
||||
offset: 4,
|
||||
});
|
||||
if (MaintenanceRequest4?.setUnit) {
|
||||
await MaintenanceRequest4.setUnit(relatedUnit4);
|
||||
}
|
||||
}
|
||||
|
||||
// Similar logic for "relation_many"
|
||||
@ -367,8 +509,80 @@ async function associateUnitWithOwner() {
|
||||
if (Unit3?.setOwner) {
|
||||
await Unit3.setOwner(relatedOwner3);
|
||||
}
|
||||
|
||||
const relatedOwner4 = await Users.findOne({
|
||||
offset: Math.floor(Math.random() * (await Users.count())),
|
||||
});
|
||||
const Unit4 = await Units.findOne({
|
||||
order: [['id', 'ASC']],
|
||||
offset: 4,
|
||||
});
|
||||
if (Unit4?.setOwner) {
|
||||
await Unit4.setOwner(relatedOwner4);
|
||||
}
|
||||
}
|
||||
|
||||
// Similar logic for "relation_many"
|
||||
|
||||
async function associateOwnerWithUser_account() {
|
||||
const relatedUser_account0 = await Users.findOne({
|
||||
offset: Math.floor(Math.random() * (await Users.count())),
|
||||
});
|
||||
const Owner0 = await Owners.findOne({
|
||||
order: [['id', 'ASC']],
|
||||
offset: 0,
|
||||
});
|
||||
if (Owner0?.setUser_account) {
|
||||
await Owner0.setUser_account(relatedUser_account0);
|
||||
}
|
||||
|
||||
const relatedUser_account1 = await Users.findOne({
|
||||
offset: Math.floor(Math.random() * (await Users.count())),
|
||||
});
|
||||
const Owner1 = await Owners.findOne({
|
||||
order: [['id', 'ASC']],
|
||||
offset: 1,
|
||||
});
|
||||
if (Owner1?.setUser_account) {
|
||||
await Owner1.setUser_account(relatedUser_account1);
|
||||
}
|
||||
|
||||
const relatedUser_account2 = await Users.findOne({
|
||||
offset: Math.floor(Math.random() * (await Users.count())),
|
||||
});
|
||||
const Owner2 = await Owners.findOne({
|
||||
order: [['id', 'ASC']],
|
||||
offset: 2,
|
||||
});
|
||||
if (Owner2?.setUser_account) {
|
||||
await Owner2.setUser_account(relatedUser_account2);
|
||||
}
|
||||
|
||||
const relatedUser_account3 = await Users.findOne({
|
||||
offset: Math.floor(Math.random() * (await Users.count())),
|
||||
});
|
||||
const Owner3 = await Owners.findOne({
|
||||
order: [['id', 'ASC']],
|
||||
offset: 3,
|
||||
});
|
||||
if (Owner3?.setUser_account) {
|
||||
await Owner3.setUser_account(relatedUser_account3);
|
||||
}
|
||||
|
||||
const relatedUser_account4 = await Users.findOne({
|
||||
offset: Math.floor(Math.random() * (await Users.count())),
|
||||
});
|
||||
const Owner4 = await Owners.findOne({
|
||||
order: [['id', 'ASC']],
|
||||
offset: 4,
|
||||
});
|
||||
if (Owner4?.setUser_account) {
|
||||
await Owner4.setUser_account(relatedUser_account4);
|
||||
}
|
||||
}
|
||||
|
||||
// Similar logic for "relation_many"
|
||||
|
||||
module.exports = {
|
||||
up: async (queryInterface, Sequelize) => {
|
||||
await Budgets.bulkCreate(BudgetsData);
|
||||
@ -395,6 +609,12 @@ module.exports = {
|
||||
// Similar logic for "relation_many"
|
||||
|
||||
await associateUnitWithOwner(),
|
||||
|
||||
// Similar logic for "relation_many"
|
||||
|
||||
await associateOwnerWithUser_account(),
|
||||
|
||||
// Similar logic for "relation_many"
|
||||
]);
|
||||
},
|
||||
|
||||
|
||||
@ -20,6 +20,13 @@ router.use(checkCrudPermissions('owners'));
|
||||
* type: object
|
||||
* properties:
|
||||
|
||||
* emergency_contact:
|
||||
* type: string
|
||||
* default: emergency_contact
|
||||
* mailing_address:
|
||||
* type: string
|
||||
* default: mailing_address
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -295,7 +302,7 @@ router.get(
|
||||
const currentUser = req.currentUser;
|
||||
const payload = await OwnersDBApi.findAll(req.query, { currentUser });
|
||||
if (filetype && filetype === 'csv') {
|
||||
const fields = ['id'];
|
||||
const fields = ['id', 'emergency_contact', 'mailing_address'];
|
||||
const opts = { fields };
|
||||
try {
|
||||
const csv = parse(payload.rows, opts);
|
||||
|
||||
@ -50,6 +50,8 @@ module.exports = class SearchService {
|
||||
notices: ['title', 'content'],
|
||||
|
||||
units: ['unit_number'],
|
||||
|
||||
owners: ['emergency_contact', 'mailing_address'],
|
||||
};
|
||||
const columnsInt = {
|
||||
budgets: ['year', 'total_budget', 'expenses'],
|
||||
|
||||
@ -75,7 +75,62 @@ const CardOwners = ({
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<dl className='divide-y divide-stone-300 dark:divide-dark-700 px-6 py-4 text-sm leading-6 h-64 overflow-y-auto'></dl>
|
||||
<dl className='divide-y divide-stone-300 dark:divide-dark-700 px-6 py-4 text-sm leading-6 h-64 overflow-y-auto'>
|
||||
<div className='flex justify-between gap-x-4 py-3'>
|
||||
<dt className=' text-gray-500 dark:text-dark-600'>
|
||||
User Account
|
||||
</dt>
|
||||
<dd className='flex items-start gap-x-2'>
|
||||
<div className='font-medium line-clamp-4'>
|
||||
{dataFormatter.usersOneListFormatter(item.user_account)}
|
||||
</div>
|
||||
</dd>
|
||||
</div>
|
||||
|
||||
<div className='flex justify-between gap-x-4 py-3'>
|
||||
<dt className=' text-gray-500 dark:text-dark-600'>
|
||||
Lives On Site
|
||||
</dt>
|
||||
<dd className='flex items-start gap-x-2'>
|
||||
<div className='font-medium line-clamp-4'>
|
||||
{dataFormatter.booleanFormatter(item.lives_on_site)}
|
||||
</div>
|
||||
</dd>
|
||||
</div>
|
||||
|
||||
<div className='flex justify-between gap-x-4 py-3'>
|
||||
<dt className=' text-gray-500 dark:text-dark-600'>
|
||||
Emergency Contact
|
||||
</dt>
|
||||
<dd className='flex items-start gap-x-2'>
|
||||
<div className='font-medium line-clamp-4'>
|
||||
{item.emergency_contact}
|
||||
</div>
|
||||
</dd>
|
||||
</div>
|
||||
|
||||
<div className='flex justify-between gap-x-4 py-3'>
|
||||
<dt className=' text-gray-500 dark:text-dark-600'>
|
||||
Mailing Address
|
||||
</dt>
|
||||
<dd className='flex items-start gap-x-2'>
|
||||
<div className='font-medium line-clamp-4'>
|
||||
{item.mailing_address}
|
||||
</div>
|
||||
</dd>
|
||||
</div>
|
||||
|
||||
<div className='flex justify-between gap-x-4 py-3'>
|
||||
<dt className=' text-gray-500 dark:text-dark-600'>Unit</dt>
|
||||
<dd className='flex items-start gap-x-2'>
|
||||
<div className='font-medium line-clamp-4'>
|
||||
{dataFormatter
|
||||
.unitsManyListFormatter(item.unit)
|
||||
.join(', ')}
|
||||
</div>
|
||||
</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</li>
|
||||
))}
|
||||
{!loading && owners.length === 0 && (
|
||||
|
||||
@ -50,7 +50,46 @@ const ListOwners = ({
|
||||
className={
|
||||
'flex-1 px-4 py-6 h-24 flex divide-x-2 divide-stone-300 items-center overflow-hidden`}> dark:divide-dark-700 overflow-x-auto'
|
||||
}
|
||||
></Link>
|
||||
>
|
||||
<div className={'flex-1 px-3'}>
|
||||
<p className={'text-xs text-gray-500 '}>User Account</p>
|
||||
<p className={'line-clamp-2'}>
|
||||
{dataFormatter.usersOneListFormatter(item.user_account)}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className={'flex-1 px-3'}>
|
||||
<p className={'text-xs text-gray-500 '}>
|
||||
Lives On Site
|
||||
</p>
|
||||
<p className={'line-clamp-2'}>
|
||||
{dataFormatter.booleanFormatter(item.lives_on_site)}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className={'flex-1 px-3'}>
|
||||
<p className={'text-xs text-gray-500 '}>
|
||||
Emergency Contact
|
||||
</p>
|
||||
<p className={'line-clamp-2'}>{item.emergency_contact}</p>
|
||||
</div>
|
||||
|
||||
<div className={'flex-1 px-3'}>
|
||||
<p className={'text-xs text-gray-500 '}>
|
||||
Mailing Address
|
||||
</p>
|
||||
<p className={'line-clamp-2'}>{item.mailing_address}</p>
|
||||
</div>
|
||||
|
||||
<div className={'flex-1 px-3'}>
|
||||
<p className={'text-xs text-gray-500 '}>Unit</p>
|
||||
<p className={'line-clamp-2'}>
|
||||
{dataFormatter
|
||||
.unitsManyListFormatter(item.unit)
|
||||
.join(', ')}
|
||||
</p>
|
||||
</div>
|
||||
</Link>
|
||||
<ListActionsPopover
|
||||
onDelete={onDelete}
|
||||
itemId={item.id}
|
||||
|
||||
@ -20,6 +20,8 @@ import _ from 'lodash';
|
||||
import dataFormatter from '../../helpers/dataFormatter';
|
||||
import { dataGridStyles } from '../../styles';
|
||||
|
||||
import CardOwners from './CardOwners';
|
||||
|
||||
const perPage = 10;
|
||||
|
||||
const TableSampleOwners = ({
|
||||
@ -461,7 +463,18 @@ const TableSampleOwners = ({
|
||||
<p>Are you sure you want to delete this item?</p>
|
||||
</CardBoxModal>
|
||||
|
||||
{dataGrid}
|
||||
{owners && Array.isArray(owners) && !showGrid && (
|
||||
<CardOwners
|
||||
owners={owners}
|
||||
loading={loading}
|
||||
onDelete={handleDeleteModalAction}
|
||||
currentPage={currentPage}
|
||||
numPages={numPages}
|
||||
onPageChange={onPageChange}
|
||||
/>
|
||||
)}
|
||||
|
||||
{showGrid && dataGrid}
|
||||
|
||||
{selectedRows.length > 0 &&
|
||||
createPortal(
|
||||
|
||||
@ -38,6 +38,83 @@ export const loadColumns = async (
|
||||
const hasUpdatePermission = hasPermission(user, 'UPDATE_OWNERS');
|
||||
|
||||
return [
|
||||
{
|
||||
field: 'user_account',
|
||||
headerName: 'User Account',
|
||||
flex: 1,
|
||||
minWidth: 120,
|
||||
filterable: false,
|
||||
headerClassName: 'datagrid--header',
|
||||
cellClassName: 'datagrid--cell',
|
||||
|
||||
editable: hasUpdatePermission,
|
||||
|
||||
sortable: false,
|
||||
type: 'singleSelect',
|
||||
getOptionValue: (value: any) => value?.id,
|
||||
getOptionLabel: (value: any) => value?.label,
|
||||
valueOptions: await callOptionsApi('users'),
|
||||
valueGetter: (params: GridValueGetterParams) =>
|
||||
params?.value?.id ?? params?.value,
|
||||
},
|
||||
|
||||
{
|
||||
field: 'lives_on_site',
|
||||
headerName: 'Lives On Site',
|
||||
flex: 1,
|
||||
minWidth: 120,
|
||||
filterable: false,
|
||||
headerClassName: 'datagrid--header',
|
||||
cellClassName: 'datagrid--cell',
|
||||
|
||||
editable: hasUpdatePermission,
|
||||
|
||||
type: 'boolean',
|
||||
},
|
||||
|
||||
{
|
||||
field: 'emergency_contact',
|
||||
headerName: 'Emergency Contact',
|
||||
flex: 1,
|
||||
minWidth: 120,
|
||||
filterable: false,
|
||||
headerClassName: 'datagrid--header',
|
||||
cellClassName: 'datagrid--cell',
|
||||
|
||||
editable: hasUpdatePermission,
|
||||
},
|
||||
|
||||
{
|
||||
field: 'mailing_address',
|
||||
headerName: 'Mailing Address',
|
||||
flex: 1,
|
||||
minWidth: 120,
|
||||
filterable: false,
|
||||
headerClassName: 'datagrid--header',
|
||||
cellClassName: 'datagrid--cell',
|
||||
|
||||
editable: hasUpdatePermission,
|
||||
},
|
||||
|
||||
{
|
||||
field: 'unit',
|
||||
headerName: 'Unit',
|
||||
flex: 1,
|
||||
minWidth: 120,
|
||||
filterable: false,
|
||||
headerClassName: 'datagrid--header',
|
||||
cellClassName: 'datagrid--cell',
|
||||
|
||||
editable: false,
|
||||
sortable: false,
|
||||
type: 'singleSelect',
|
||||
valueFormatter: ({ value }) =>
|
||||
dataFormatter.unitsManyListFormatter(value).join(', '),
|
||||
renderEditCell: (params) => (
|
||||
<DataGridMultiSelect {...params} entityName={'units'} />
|
||||
),
|
||||
},
|
||||
|
||||
{
|
||||
field: 'actions',
|
||||
type: 'actions',
|
||||
|
||||
@ -139,6 +139,19 @@ const CardUnits = ({
|
||||
</div>
|
||||
</dd>
|
||||
</div>
|
||||
|
||||
<div className='flex justify-between gap-x-4 py-3'>
|
||||
<dt className=' text-gray-500 dark:text-dark-600'>
|
||||
Owners
|
||||
</dt>
|
||||
<dd className='flex items-start gap-x-2'>
|
||||
<div className='font-medium line-clamp-4'>
|
||||
{dataFormatter
|
||||
.ownersManyListFormatter(item.owners)
|
||||
.join(', ')}
|
||||
</div>
|
||||
</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</li>
|
||||
))}
|
||||
|
||||
@ -84,6 +84,15 @@ const ListUnits = ({
|
||||
</p>
|
||||
<p className={'line-clamp-2'}>{item.parking_stall}</p>
|
||||
</div>
|
||||
|
||||
<div className={'flex-1 px-3'}>
|
||||
<p className={'text-xs text-gray-500 '}>Owners</p>
|
||||
<p className={'line-clamp-2'}>
|
||||
{dataFormatter
|
||||
.ownersManyListFormatter(item.owners)
|
||||
.join(', ')}
|
||||
</p>
|
||||
</div>
|
||||
</Link>
|
||||
<ListActionsPopover
|
||||
onDelete={onDelete}
|
||||
|
||||
@ -126,6 +126,25 @@ export const loadColumns = async (
|
||||
type: 'number',
|
||||
},
|
||||
|
||||
{
|
||||
field: 'owners',
|
||||
headerName: 'Owners',
|
||||
flex: 1,
|
||||
minWidth: 120,
|
||||
filterable: false,
|
||||
headerClassName: 'datagrid--header',
|
||||
cellClassName: 'datagrid--cell',
|
||||
|
||||
editable: false,
|
||||
sortable: false,
|
||||
type: 'singleSelect',
|
||||
valueFormatter: ({ value }) =>
|
||||
dataFormatter.ownersManyListFormatter(value).join(', '),
|
||||
renderEditCell: (params) => (
|
||||
<DataGridMultiSelect {...params} entityName={'owners'} />
|
||||
),
|
||||
},
|
||||
|
||||
{
|
||||
field: 'actions',
|
||||
type: 'actions',
|
||||
|
||||
@ -114,4 +114,23 @@ export default {
|
||||
if (!val) return '';
|
||||
return { label: val.name, id: val.id };
|
||||
},
|
||||
|
||||
ownersManyListFormatter(val) {
|
||||
if (!val || !val.length) return [];
|
||||
return val.map((item) => item.id);
|
||||
},
|
||||
ownersOneListFormatter(val) {
|
||||
if (!val) return '';
|
||||
return val.id;
|
||||
},
|
||||
ownersManyListFormatterEdit(val) {
|
||||
if (!val || !val.length) return [];
|
||||
return val.map((item) => {
|
||||
return { id: item.id, label: item.id };
|
||||
});
|
||||
},
|
||||
ownersOneListFormatterEdit(val) {
|
||||
if (!val) return '';
|
||||
return { label: val.id, id: val.id };
|
||||
},
|
||||
};
|
||||
|
||||
@ -35,7 +35,15 @@ import ImageField from '../../components/ImageField';
|
||||
const EditOwners = () => {
|
||||
const router = useRouter();
|
||||
const dispatch = useAppDispatch();
|
||||
const initVals = {};
|
||||
const initVals = {
|
||||
lives_on_site: false,
|
||||
|
||||
emergency_contact: '',
|
||||
|
||||
mailing_address: '',
|
||||
|
||||
unit: [],
|
||||
};
|
||||
const [initialValues, setInitialValues] = useState(initVals);
|
||||
|
||||
const { owners } = useAppSelector((state) => state.owners);
|
||||
@ -87,6 +95,40 @@ const EditOwners = () => {
|
||||
onSubmit={(values) => handleSubmit(values)}
|
||||
>
|
||||
<Form>
|
||||
<FormField label='Lives On Site' labelFor='lives_on_site'>
|
||||
<Field
|
||||
name='lives_on_site'
|
||||
id='lives_on_site'
|
||||
component={SwitchField}
|
||||
></Field>
|
||||
</FormField>
|
||||
|
||||
<FormField label='Emergency Contact'>
|
||||
<Field
|
||||
name='emergency_contact'
|
||||
placeholder='Emergency Contact'
|
||||
/>
|
||||
</FormField>
|
||||
|
||||
<FormField label='Mailing Address' hasTextareaHeight>
|
||||
<Field
|
||||
name='mailing_address'
|
||||
id='mailing_address'
|
||||
component={RichTextField}
|
||||
></Field>
|
||||
</FormField>
|
||||
|
||||
<FormField label='Unit' labelFor='unit'>
|
||||
<Field
|
||||
name='unit'
|
||||
id='unit'
|
||||
component={SelectFieldMany}
|
||||
options={initialValues.unit}
|
||||
itemRef={'units'}
|
||||
showField={'unit_number'}
|
||||
></Field>
|
||||
</FormField>
|
||||
|
||||
<BaseDivider />
|
||||
<BaseButtons>
|
||||
<BaseButton type='submit' color='info' label='Submit' />
|
||||
|
||||
@ -35,7 +35,15 @@ import ImageField from '../../components/ImageField';
|
||||
const EditOwnersPage = () => {
|
||||
const router = useRouter();
|
||||
const dispatch = useAppDispatch();
|
||||
const initVals = {};
|
||||
const initVals = {
|
||||
lives_on_site: false,
|
||||
|
||||
emergency_contact: '',
|
||||
|
||||
mailing_address: '',
|
||||
|
||||
unit: [],
|
||||
};
|
||||
const [initialValues, setInitialValues] = useState(initVals);
|
||||
|
||||
const { owners } = useAppSelector((state) => state.owners);
|
||||
@ -85,6 +93,40 @@ const EditOwnersPage = () => {
|
||||
onSubmit={(values) => handleSubmit(values)}
|
||||
>
|
||||
<Form>
|
||||
<FormField label='Lives On Site' labelFor='lives_on_site'>
|
||||
<Field
|
||||
name='lives_on_site'
|
||||
id='lives_on_site'
|
||||
component={SwitchField}
|
||||
></Field>
|
||||
</FormField>
|
||||
|
||||
<FormField label='Emergency Contact'>
|
||||
<Field
|
||||
name='emergency_contact'
|
||||
placeholder='Emergency Contact'
|
||||
/>
|
||||
</FormField>
|
||||
|
||||
<FormField label='Mailing Address' hasTextareaHeight>
|
||||
<Field
|
||||
name='mailing_address'
|
||||
id='mailing_address'
|
||||
component={RichTextField}
|
||||
></Field>
|
||||
</FormField>
|
||||
|
||||
<FormField label='Unit' labelFor='unit'>
|
||||
<Field
|
||||
name='unit'
|
||||
id='unit'
|
||||
component={SelectFieldMany}
|
||||
options={initialValues.unit}
|
||||
itemRef={'units'}
|
||||
showField={'unit_number'}
|
||||
></Field>
|
||||
</FormField>
|
||||
|
||||
<BaseDivider />
|
||||
<BaseButtons>
|
||||
<BaseButton type='submit' color='info' label='Submit' />
|
||||
|
||||
@ -28,7 +28,14 @@ const OwnersTablesPage = () => {
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const [filters] = useState([]);
|
||||
const [filters] = useState([
|
||||
{ label: 'Emergency Contact', title: 'emergency_contact' },
|
||||
{ label: 'Mailing Address', title: 'mailing_address' },
|
||||
|
||||
{ label: 'User Account', title: 'user_account' },
|
||||
|
||||
{ label: 'Unit', title: 'unit' },
|
||||
]);
|
||||
|
||||
const hasCreatePermission =
|
||||
currentUser && hasPermission(currentUser, 'CREATE_OWNERS');
|
||||
@ -121,6 +128,10 @@ const OwnersTablesPage = () => {
|
||||
<div className='md:inline-flex items-center ms-auto'>
|
||||
<div id='delete-rows-button'></div>
|
||||
</div>
|
||||
|
||||
<div className='md:inline-flex items-center ms-auto'>
|
||||
<Link href={'/owners/owners-table'}>Switch to Table</Link>
|
||||
</div>
|
||||
</CardBox>
|
||||
|
||||
<CardBox className='mb-6' hasTable>
|
||||
|
||||
@ -32,7 +32,15 @@ import { useAppDispatch } from '../../stores/hooks';
|
||||
import { useRouter } from 'next/router';
|
||||
import moment from 'moment';
|
||||
|
||||
const initialValues = {};
|
||||
const initialValues = {
|
||||
lives_on_site: false,
|
||||
|
||||
emergency_contact: '',
|
||||
|
||||
mailing_address: '',
|
||||
|
||||
unit: [],
|
||||
};
|
||||
|
||||
const OwnersNew = () => {
|
||||
const router = useRouter();
|
||||
@ -61,6 +69,39 @@ const OwnersNew = () => {
|
||||
onSubmit={(values) => handleSubmit(values)}
|
||||
>
|
||||
<Form>
|
||||
<FormField label='Lives On Site' labelFor='lives_on_site'>
|
||||
<Field
|
||||
name='lives_on_site'
|
||||
id='lives_on_site'
|
||||
component={SwitchField}
|
||||
></Field>
|
||||
</FormField>
|
||||
|
||||
<FormField label='Emergency Contact'>
|
||||
<Field
|
||||
name='emergency_contact'
|
||||
placeholder='Emergency Contact'
|
||||
/>
|
||||
</FormField>
|
||||
|
||||
<FormField label='Mailing Address' hasTextareaHeight>
|
||||
<Field
|
||||
name='mailing_address'
|
||||
id='mailing_address'
|
||||
component={RichTextField}
|
||||
></Field>
|
||||
</FormField>
|
||||
|
||||
<FormField label='Unit' labelFor='unit'>
|
||||
<Field
|
||||
name='unit'
|
||||
id='unit'
|
||||
itemRef={'units'}
|
||||
options={[]}
|
||||
component={SelectFieldMany}
|
||||
></Field>
|
||||
</FormField>
|
||||
|
||||
<BaseDivider />
|
||||
<BaseButtons>
|
||||
<BaseButton type='submit' color='info' label='Submit' />
|
||||
|
||||
@ -28,7 +28,14 @@ const OwnersTablesPage = () => {
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const [filters] = useState([]);
|
||||
const [filters] = useState([
|
||||
{ label: 'Emergency Contact', title: 'emergency_contact' },
|
||||
{ label: 'Mailing Address', title: 'mailing_address' },
|
||||
|
||||
{ label: 'User Account', title: 'user_account' },
|
||||
|
||||
{ label: 'Unit', title: 'unit' },
|
||||
]);
|
||||
|
||||
const hasCreatePermission =
|
||||
currentUser && hasPermission(currentUser, 'CREATE_OWNERS');
|
||||
@ -120,6 +127,10 @@ const OwnersTablesPage = () => {
|
||||
|
||||
<div className='md:inline-flex items-center ms-auto'>
|
||||
<div id='delete-rows-button'></div>
|
||||
|
||||
<Link href={'/owners/owners-list'}>
|
||||
Back to <span className='capitalize'>card</span>
|
||||
</Link>
|
||||
</div>
|
||||
</CardBox>
|
||||
<CardBox className='mb-6' hasTable>
|
||||
|
||||
@ -54,6 +54,81 @@ const OwnersView = () => {
|
||||
/>
|
||||
</SectionTitleLineWithButton>
|
||||
<CardBox>
|
||||
<FormField label='Lives On Site'>
|
||||
<SwitchField
|
||||
field={{ name: 'lives_on_site', value: owners?.lives_on_site }}
|
||||
form={{ setFieldValue: () => null }}
|
||||
disabled
|
||||
/>
|
||||
</FormField>
|
||||
|
||||
<div className={'mb-4'}>
|
||||
<p className={'block font-bold mb-2'}>Emergency Contact</p>
|
||||
<p>{owners?.emergency_contact}</p>
|
||||
</div>
|
||||
|
||||
<div className={'mb-4'}>
|
||||
<p className={'block font-bold mb-2'}>Mailing Address</p>
|
||||
{owners.mailing_address ? (
|
||||
<p dangerouslySetInnerHTML={{ __html: owners.mailing_address }} />
|
||||
) : (
|
||||
<p>No data</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<>
|
||||
<p className={'block font-bold mb-2'}>Unit</p>
|
||||
<CardBox
|
||||
className='mb-6 border border-gray-300 rounded overflow-hidden'
|
||||
hasTable
|
||||
>
|
||||
<div className='overflow-x-auto'>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>UnitNumber</th>
|
||||
|
||||
<th>Balance</th>
|
||||
|
||||
<th>Unit Factor</th>
|
||||
|
||||
<th>Cond Fee</th>
|
||||
|
||||
<th>Parking Stall</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{owners.unit &&
|
||||
Array.isArray(owners.unit) &&
|
||||
owners.unit.map((item: any) => (
|
||||
<tr
|
||||
key={item.id}
|
||||
onClick={() =>
|
||||
router.push(`/units/units-view/?id=${item.id}`)
|
||||
}
|
||||
>
|
||||
<td data-label='unit_number'>{item.unit_number}</td>
|
||||
|
||||
<td data-label='balance'>{item.balance}</td>
|
||||
|
||||
<td data-label='unit_factor'>{item.unit_factor}</td>
|
||||
|
||||
<td data-label='cond_fee'>{item.cond_fee}</td>
|
||||
|
||||
<td data-label='parking_stall'>
|
||||
{item.parking_stall}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{!owners?.unit?.length && (
|
||||
<div className={'text-center py-4'}>No data</div>
|
||||
)}
|
||||
</CardBox>
|
||||
</>
|
||||
|
||||
<BaseDivider />
|
||||
|
||||
<BaseButton
|
||||
|
||||
@ -47,6 +47,8 @@ const EditUnits = () => {
|
||||
cond_fee: '',
|
||||
|
||||
parking_stall: '',
|
||||
|
||||
owners: [],
|
||||
};
|
||||
const [initialValues, setInitialValues] = useState(initVals);
|
||||
|
||||
@ -138,6 +140,17 @@ const EditUnits = () => {
|
||||
/>
|
||||
</FormField>
|
||||
|
||||
<FormField label='Owners' labelFor='owners'>
|
||||
<Field
|
||||
name='owners'
|
||||
id='owners'
|
||||
component={SelectFieldMany}
|
||||
options={initialValues.owners}
|
||||
itemRef={'owners'}
|
||||
showField={'id'}
|
||||
></Field>
|
||||
</FormField>
|
||||
|
||||
<BaseDivider />
|
||||
<BaseButtons>
|
||||
<BaseButton type='submit' color='info' label='Submit' />
|
||||
|
||||
@ -47,6 +47,8 @@ const EditUnitsPage = () => {
|
||||
cond_fee: '',
|
||||
|
||||
parking_stall: '',
|
||||
|
||||
owners: [],
|
||||
};
|
||||
const [initialValues, setInitialValues] = useState(initVals);
|
||||
|
||||
@ -136,6 +138,17 @@ const EditUnitsPage = () => {
|
||||
/>
|
||||
</FormField>
|
||||
|
||||
<FormField label='Owners' labelFor='owners'>
|
||||
<Field
|
||||
name='owners'
|
||||
id='owners'
|
||||
component={SelectFieldMany}
|
||||
options={initialValues.owners}
|
||||
itemRef={'owners'}
|
||||
showField={'id'}
|
||||
></Field>
|
||||
</FormField>
|
||||
|
||||
<BaseDivider />
|
||||
<BaseButtons>
|
||||
<BaseButton type='submit' color='info' label='Submit' />
|
||||
|
||||
@ -36,6 +36,8 @@ const UnitsTablesPage = () => {
|
||||
{ label: 'Cond Fee', title: 'cond_fee', number: 'true' },
|
||||
|
||||
{ label: 'Owner', title: 'owner' },
|
||||
|
||||
{ label: 'Owners', title: 'owners' },
|
||||
]);
|
||||
|
||||
const hasCreatePermission =
|
||||
|
||||
@ -44,6 +44,8 @@ const initialValues = {
|
||||
cond_fee: '',
|
||||
|
||||
parking_stall: '',
|
||||
|
||||
owners: [],
|
||||
};
|
||||
|
||||
const UnitsNew = () => {
|
||||
@ -111,6 +113,16 @@ const UnitsNew = () => {
|
||||
/>
|
||||
</FormField>
|
||||
|
||||
<FormField label='Owners' labelFor='owners'>
|
||||
<Field
|
||||
name='owners'
|
||||
id='owners'
|
||||
itemRef={'owners'}
|
||||
options={[]}
|
||||
component={SelectFieldMany}
|
||||
></Field>
|
||||
</FormField>
|
||||
|
||||
<BaseDivider />
|
||||
<BaseButtons>
|
||||
<BaseButton type='submit' color='info' label='Submit' />
|
||||
|
||||
@ -36,6 +36,8 @@ const UnitsTablesPage = () => {
|
||||
{ label: 'Cond Fee', title: 'cond_fee', number: 'true' },
|
||||
|
||||
{ label: 'Owner', title: 'owner' },
|
||||
|
||||
{ label: 'Owners', title: 'owners' },
|
||||
]);
|
||||
|
||||
const hasCreatePermission =
|
||||
|
||||
@ -85,6 +85,49 @@ const UnitsView = () => {
|
||||
<p>{units?.parking_stall || 'No data'}</p>
|
||||
</div>
|
||||
|
||||
<>
|
||||
<p className={'block font-bold mb-2'}>Owners</p>
|
||||
<CardBox
|
||||
className='mb-6 border border-gray-300 rounded overflow-hidden'
|
||||
hasTable
|
||||
>
|
||||
<div className='overflow-x-auto'>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Lives On Site</th>
|
||||
|
||||
<th>Emergency Contact</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{units.owners &&
|
||||
Array.isArray(units.owners) &&
|
||||
units.owners.map((item: any) => (
|
||||
<tr
|
||||
key={item.id}
|
||||
onClick={() =>
|
||||
router.push(`/owners/owners-view/?id=${item.id}`)
|
||||
}
|
||||
>
|
||||
<td data-label='lives_on_site'>
|
||||
{dataFormatter.booleanFormatter(item.lives_on_site)}
|
||||
</td>
|
||||
|
||||
<td data-label='emergency_contact'>
|
||||
{item.emergency_contact}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{!units?.owners?.length && (
|
||||
<div className={'text-center py-4'}>No data</div>
|
||||
)}
|
||||
</CardBox>
|
||||
</>
|
||||
|
||||
<>
|
||||
<p className={'block font-bold mb-2'}>Users Unit</p>
|
||||
<CardBox
|
||||
|
||||
@ -197,6 +197,49 @@ const UsersView = () => {
|
||||
</CardBox>
|
||||
</>
|
||||
|
||||
<>
|
||||
<p className={'block font-bold mb-2'}>Owners User Account</p>
|
||||
<CardBox
|
||||
className='mb-6 border border-gray-300 rounded overflow-hidden'
|
||||
hasTable
|
||||
>
|
||||
<div className='overflow-x-auto'>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Lives On Site</th>
|
||||
|
||||
<th>Emergency Contact</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{users.owners_user_account &&
|
||||
Array.isArray(users.owners_user_account) &&
|
||||
users.owners_user_account.map((item: any) => (
|
||||
<tr
|
||||
key={item.id}
|
||||
onClick={() =>
|
||||
router.push(`/owners/owners-view/?id=${item.id}`)
|
||||
}
|
||||
>
|
||||
<td data-label='lives_on_site'>
|
||||
{dataFormatter.booleanFormatter(item.lives_on_site)}
|
||||
</td>
|
||||
|
||||
<td data-label='emergency_contact'>
|
||||
{item.emergency_contact}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{!users?.owners_user_account?.length && (
|
||||
<div className={'text-center py-4'}>No data</div>
|
||||
)}
|
||||
</CardBox>
|
||||
</>
|
||||
|
||||
<BaseDivider />
|
||||
|
||||
<BaseButton
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user