Falukant production, family and administration enhancements

This commit is contained in:
Torsten Schulz
2025-04-14 15:17:35 +02:00
parent 90b4f51dcb
commit b15d93a798
77 changed files with 2429 additions and 1093 deletions

View File

@@ -52,13 +52,16 @@ import TownProductWorth from './falukant/data/town_product_worth.js';
import DayProduction from './falukant/log/dayproduction.js';
import DaySell from './falukant/log/daysell.js';
import MarriageProposal from './falukant/data/marriage_proposal.js';
import Notification from './falukant/log/notification';
import Notification from './falukant/log/notification.js';
import CharacterTrait from './falukant/type/character_trait.js';
import FalukantCharacterTrait from './falukant/data/falukant_character_trait.js';
import Mood from './falukant/type/mood.js';
import PromotionalGift from './falukant/type/promotional_gift.js';
import PromotionalGiftCharacterTrait from './falukant/predefine/promotional_gift_character_trait.js';
import PromotionalGiftMood from './falukant/predefine/promotional_gift_mood.js';
import RelationshipType from './falukant/type/relationship.js';
import Relationship from './falukant/data/relationship.js';
import PromotionalGiftLog from './falukant/log/promotional_gift.js';
export default function setupAssociations() {
// UserParam related associations
@@ -326,4 +329,27 @@ export default function setupAssociations() {
PromotionalGift.belongsToMany(Mood, {through: PromotionalGiftMood, foreignKey: 'gift_id', as: 'moods',});
Mood.belongsToMany(PromotionalGift, {through: PromotionalGiftMood, foreignKey: 'mood_id', as: 'gifts',});
Relationship.belongsTo(RelationshipType, { foreignKey: 'relationshipTypeId', as: 'relationshipType' });
RelationshipType.hasMany(Relationship, { foreignKey: 'relationshipTypeId', as: 'relationships' });
Relationship.belongsTo(FalukantCharacter, {foreignKey: 'character1Id', as: 'character1', });
Relationship.belongsTo(FalukantCharacter, {foreignKey: 'character2Id', as: 'character2', });
FalukantCharacter.hasMany(Relationship, {foreignKey: 'character1Id', as: 'relationshipsAsCharacter1', });
FalukantCharacter.hasMany(Relationship, {foreignKey: 'character2Id', as: 'relationshipsAsCharacter2', });
PromotionalGiftLog.belongsTo(PromotionalGift, { foreignKey: 'giftId', as: 'gift' });
PromotionalGift.hasMany(PromotionalGiftLog, { foreignKey: 'giftId', as: 'logs' });
PromotionalGiftLog.belongsTo(FalukantCharacter, { foreignKey: 'senderCharacterId', as: 'character' });
FalukantCharacter.hasMany(PromotionalGiftLog, { foreignKey: 'senderCharacterId', as: 'logs' });
PromotionalGiftLog.belongsTo(FalukantCharacter, { foreignKey: 'recipientCharacterId', as: 'recipient' });
FalukantCharacter.hasMany(PromotionalGiftLog, { foreignKey: 'recipientCharacterId', as: 'giftlogs' });
PromotionalGift.hasMany(PromotionalGiftCharacterTrait, { foreignKey: 'gift_id', as: 'characterTraits' });
PromotionalGift.hasMany(PromotionalGiftMood, { foreignKey: 'gift_id', as: 'promotionalgiftmoods' });
PromotionalGiftCharacterTrait.belongsTo(PromotionalGift, { foreignKey: 'gift_id', as: 'promotionalgiftcharactertrait' });
PromotionalGiftMood.belongsTo(PromotionalGift, { foreignKey: 'gift_id', as: 'promotionalgiftcharactermood' });
}

View File

@@ -5,19 +5,19 @@ class FalukantCharacter extends Model {}
FalukantCharacter.init(
{
user_id: {
userId: {
type: DataTypes.INTEGER,
allowNull: true,
},
region_id: {
regionId: {
type: DataTypes.INTEGER,
allowNull: false,
},
first_name: {
firstName: {
type: DataTypes.INTEGER,
allowNull: false,
},
last_name: {
lastName: {
type: DataTypes.INTEGER,
allowNull: false,
},

View File

@@ -35,6 +35,11 @@ Director.init({
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: true,
},
lastSalaryPayout: {
type: DataTypes.DATE,
allowNull: false,
defaultValue: new Date(0)
}
}, {
sequelize,

View File

@@ -0,0 +1,56 @@
import { Model, DataTypes } from 'sequelize';
import { sequelize } from '../../../utils/sequelize.js';
import FalukantCharacter from './character.js';
class Relationship extends Model {}
Relationship.init(
{
character1Id: {
type: DataTypes.INTEGER,
allowNull: false,
references: {
model: FalukantCharacter,
key: 'id',
},
onDelete: 'CASCADE',
},
character2Id: {
type: DataTypes.INTEGER,
allowNull: false,
references: {
model: FalukantCharacter,
key: 'id',
},
onDelete: 'CASCADE',
},
relationshipTypeId: {
type: DataTypes.INTEGER,
allowNull: false,
onDelete: 'CASCADE',
},
widowFirstName1: {
type: DataTypes.STRING,
allowNull: true,
},
widowFirstName2: {
type: DataTypes.STRING,
allowNull: true,
},
nextStepProgress: {
type: DataTypes.INTEGER,
allowNull: true,
defaultValue: 0,
},
},
{
sequelize,
modelName: 'Relationship',
tableName: 'relationship',
schema: 'falukant_data',
timestamps: true,
underscored: true,
}
);
export default Relationship;

View File

@@ -24,6 +24,11 @@ DayProduction.init({
type: DataTypes.DATE,
allowNull: false,
defaultValue: sequelize.literal('CURRENT_TIMESTAMP'),
},
productionDate: {
type: DataTypes.DATEONLY,
allowNull: false,
defaultValue: sequelize.literal('CURRENT_DATE'),
}
}, {
sequelize,
@@ -35,10 +40,9 @@ DayProduction.init({
indexes: [
{
unique: true,
fields: ['producer_id', 'product_id', 'region_id']
fields: ['producer_id', 'product_id', 'region_id', 'production_date']
}
]
});
export default DayProduction;

View File

@@ -0,0 +1,32 @@
import { Model, DataTypes } from 'sequelize';
import { sequelize } from '../../../utils/sequelize.js';
class PromotionalGiftLog extends Model { };
PromotionalGiftLog.init({
senderCharacterId: {
type: DataTypes.INTEGER,
allowNull: false,
},
recipientCharacterId: {
type: DataTypes.INTEGER,
allowNull: false,
},
giftId: {
type: DataTypes.INTEGER,
allowNull: false,
},
changeValue: {
type: DataTypes.INTEGER,
allowNull: false,
},
}, {
sequelize,
modelName: 'PromotionalGiftLog',
tableName: 'promotional_gift',
schema: 'falukant_log',
timestamps: true,
underscored: true,
});
export default PromotionalGiftLog;

View File

@@ -16,7 +16,7 @@ PromotionalGift.init(
value: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: 0, // Wert des Geschenks
defaultValue: 0,
},
},
{

View File

@@ -1,9 +1,9 @@
import { Model, DataTypes } from 'sequelize';
import { sequelize } from '../../../utils/sequelize.js';
class Relationship extends Model {}
class RelationshipType extends Model {}
Relationship.init(
RelationshipType.init(
{
tr: {
type: DataTypes.STRING,
@@ -12,7 +12,7 @@ Relationship.init(
},
{
sequelize,
modelName: 'Relationship',
modelName: 'RelationshipType',
tableName: 'relationship',
schema: 'falukant_type',
timestamps: false,
@@ -20,4 +20,4 @@ Relationship.init(
}
);
export default Relationship;
export default RelationshipType;

View File

@@ -7,6 +7,7 @@ FalukantStockType.init({
labelTr: {
type: DataTypes.STRING,
allowNull: false,
unique: true,
},
cost: {
type: DataTypes.INTEGER,

View File

@@ -55,15 +55,17 @@ import DirectorProposal from './falukant/data/director_proposal.js';
import TownProductWorth from './falukant/data/town_product_worth.js';
import DayProduction from './falukant/log/dayproduction.js';
import DaySell from './falukant/log/daysell.js';
import Notification from './falukant/log/notification';
import Notification from './falukant/log/notification.js';
import MarriageProposal from './falukant/data/marriage_proposal.js';
import Relationship from './falukant/type/relationship.js';
import RelationshipType from './falukant/type/relationship.js';
import CharacterTrait from './falukant/type/character_trait.js';
import FalukantCharacterTrait from './falukant/data/falukant_character_trait.js';
import Mood from './falukant/type/mood.js';
import PromotionalGift from './falukant/type/promotional_gift.js';
import PromotionalGiftCharacterTrait from './falukant/predefine/promotional_gift_character_trait.js';
import PromotionalGiftMood from './falukant/predefine/promotional_gift_mood.js';
import Relationship from './falukant/data/relationship.js';
import PromotionalGiftLog from './falukant/log/promotional_gift.js';
const models = {
SettingsType,
@@ -125,6 +127,7 @@ const models = {
DaySell,
Notification,
MarriageProposal,
RelationshipType,
Relationship,
CharacterTrait,
FalukantCharacterTrait,
@@ -132,6 +135,7 @@ const models = {
PromotionalGift,
PromotionalGiftCharacterTrait,
PromotionalGiftMood,
PromotionalGiftLog,
};
export default models;

View File

@@ -193,6 +193,7 @@ export async function createTriggers() {
await sequelize.query(createKnowledgeTriggerMethod);
await sequelize.query(createKnowledgeTrigger);
await sequelize.query(updateMoney);
await initializeCharacterTraitTrigger();
console.log('Triggers created successfully');
} catch (error) {
@@ -200,3 +201,53 @@ export async function createTriggers() {
}
}
export const initializeCharacterTraitTrigger = async () => {
try {
const triggerCheckQuery = `
SELECT tgname
FROM pg_trigger
WHERE tgname = 'trigger_assign_traits';
`;
const [existingTrigger] = await sequelize.query(triggerCheckQuery, { type: sequelize.QueryTypes.SELECT });
if (!existingTrigger) {
console.log('⚡ Erstelle den Trigger für zufällige Traits...');
const createTriggerFunctionQuery = `
CREATE OR REPLACE FUNCTION falukant_data.assign_random_traits()
RETURNS TRIGGER AS $$
DECLARE
trait_ids INTEGER[];
i INTEGER;
BEGIN
-- Zufällig 5 Trait-IDs auswählen
SELECT ARRAY(
SELECT id FROM falukant_type.character_trait
ORDER BY RANDOM()
LIMIT 5
) INTO trait_ids;
-- Die 5 Traits dem neuen Charakter zuweisen
FOR i IN 1..array_length(trait_ids, 1) LOOP
INSERT INTO falukant_data.falukant_character_trait (character_id, trait_id)
VALUES (NEW.id, trait_ids[i]);
END LOOP;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
`;
const createTriggerQuery = `
CREATE TRIGGER trigger_assign_traits
AFTER INSERT ON falukant_data.character
FOR EACH ROW EXECUTE FUNCTION falukant_data.assign_random_traits();
`;
await sequelize.query(createTriggerFunctionQuery);
await sequelize.query(createTriggerQuery);
console.log('✅ Trigger erfolgreich erstellt.');
} else {
console.log('🔹 Trigger existiert bereits. Keine Aktion erforderlich.');
}
} catch (error) {
console.error('❌ Fehler beim Erstellen des Triggers:', error);
}
};