feat: Add IČO and DIČ fields to companies
- Add ico and dic columns to companies table schema - Add validation for ico and dic in createCompanySchema and updateCompanySchema - Update company.service.js to include ico and dic in all CRUD operations - Include migration file for database changes Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
19
src/db/migrations/0002_soft_black_tarantula.sql
Normal file
19
src/db/migrations/0002_soft_black_tarantula.sql
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
ALTER TYPE "public"."role" ADD VALUE 'team_leader' BEFORE 'member';--> statement-breakpoint
|
||||||
|
ALTER TABLE "companies" ADD COLUMN "postal_code" text;--> statement-breakpoint
|
||||||
|
ALTER TABLE "companies" ADD COLUMN "ico" text;--> statement-breakpoint
|
||||||
|
ALTER TABLE "companies" ADD COLUMN "dic" text;--> statement-breakpoint
|
||||||
|
ALTER TABLE "kurzy" ADD COLUMN "farba" varchar(20);--> statement-breakpoint
|
||||||
|
ALTER TABLE "kurzy" ADD COLUMN "datum_od" date;--> statement-breakpoint
|
||||||
|
ALTER TABLE "kurzy" ADD COLUMN "datum_do" date;--> statement-breakpoint
|
||||||
|
ALTER TABLE "services" ADD COLUMN "pricing_tiers" text;--> statement-breakpoint
|
||||||
|
ALTER TABLE "time_entries" ADD COLUMN "paused_at" timestamp;--> statement-breakpoint
|
||||||
|
ALTER TABLE "time_entries" ADD COLUMN "paused_duration" integer DEFAULT 0 NOT NULL;--> statement-breakpoint
|
||||||
|
ALTER TABLE "ucastnici" ADD COLUMN "firma_ico" varchar(20);--> statement-breakpoint
|
||||||
|
ALTER TABLE "ucastnici" ADD COLUMN "firma_dic" varchar(20);--> statement-breakpoint
|
||||||
|
ALTER TABLE "ucastnici" ADD COLUMN "firma_ic_dph" varchar(25);--> statement-breakpoint
|
||||||
|
ALTER TABLE "ucastnici" ADD COLUMN "firma_sidlo" text;--> statement-breakpoint
|
||||||
|
ALTER TABLE "ucastnici" ADD COLUMN "needs_followup" boolean DEFAULT false NOT NULL;--> statement-breakpoint
|
||||||
|
ALTER TABLE "users" ADD COLUMN "last_seen" timestamp;--> statement-breakpoint
|
||||||
|
ALTER TABLE "registracie" DROP COLUMN "datum_od";--> statement-breakpoint
|
||||||
|
ALTER TABLE "registracie" DROP COLUMN "datum_do";--> statement-breakpoint
|
||||||
|
ALTER TABLE "registracie" DROP COLUMN "pocet_ucastnikov";
|
||||||
3627
src/db/migrations/meta/0002_snapshot.json
Normal file
3627
src/db/migrations/meta/0002_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -15,6 +15,13 @@
|
|||||||
"when": 1768990516243,
|
"when": 1768990516243,
|
||||||
"tag": "0001_living_natasha_romanoff",
|
"tag": "0001_living_natasha_romanoff",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 2,
|
||||||
|
"version": "7",
|
||||||
|
"when": 1769754011560,
|
||||||
|
"tag": "0002_soft_black_tarantula",
|
||||||
|
"breakpoints": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -132,6 +132,8 @@ export const companies = pgTable('companies', {
|
|||||||
phone: text('phone'),
|
phone: text('phone'),
|
||||||
email: text('email'),
|
email: text('email'),
|
||||||
website: text('website'),
|
website: text('website'),
|
||||||
|
ico: text('ico'), // IČO - Company ID number
|
||||||
|
dic: text('dic'), // DIČ - Tax ID number
|
||||||
status: companyStatusEnum('status').default('registered').notNull(), // stav firmy
|
status: companyStatusEnum('status').default('registered').notNull(), // stav firmy
|
||||||
createdBy: uuid('created_by').references(() => users.id, { onDelete: 'set null' }),
|
createdBy: uuid('created_by').references(() => users.id, { onDelete: 'set null' }),
|
||||||
createdAt: timestamp('created_at').defaultNow().notNull(),
|
createdAt: timestamp('created_at').defaultNow().notNull(),
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ export const getAllCompanies = async (searchTerm = null, userId = null, userRole
|
|||||||
phone: companies.phone,
|
phone: companies.phone,
|
||||||
email: companies.email,
|
email: companies.email,
|
||||||
website: companies.website,
|
website: companies.website,
|
||||||
|
ico: companies.ico,
|
||||||
|
dic: companies.dic,
|
||||||
status: companies.status,
|
status: companies.status,
|
||||||
createdBy: companies.createdBy,
|
createdBy: companies.createdBy,
|
||||||
createdAt: companies.createdAt,
|
createdAt: companies.createdAt,
|
||||||
@@ -111,6 +113,8 @@ export const getCompanyById = async (companyId) => {
|
|||||||
phone: companies.phone,
|
phone: companies.phone,
|
||||||
email: companies.email,
|
email: companies.email,
|
||||||
website: companies.website,
|
website: companies.website,
|
||||||
|
ico: companies.ico,
|
||||||
|
dic: companies.dic,
|
||||||
status: companies.status,
|
status: companies.status,
|
||||||
createdBy: companies.createdBy,
|
createdBy: companies.createdBy,
|
||||||
createdAt: companies.createdAt,
|
createdAt: companies.createdAt,
|
||||||
@@ -136,7 +140,7 @@ export const getCompanyById = async (companyId) => {
|
|||||||
* Create new company
|
* Create new company
|
||||||
*/
|
*/
|
||||||
export const createCompany = async (userId, data, auditContext = null) => {
|
export const createCompany = async (userId, data, auditContext = null) => {
|
||||||
const { name, description, address, city, postalCode, country, phone, email, website, status } = data;
|
const { name, description, address, city, postalCode, country, phone, email, website, ico, dic, status } = data;
|
||||||
|
|
||||||
// Check if company with same name already exists
|
// Check if company with same name already exists
|
||||||
const [existing] = await db
|
const [existing] = await db
|
||||||
@@ -161,6 +165,8 @@ export const createCompany = async (userId, data, auditContext = null) => {
|
|||||||
phone: phone || null,
|
phone: phone || null,
|
||||||
email: email || null,
|
email: email || null,
|
||||||
website: website || null,
|
website: website || null,
|
||||||
|
ico: ico || null,
|
||||||
|
dic: dic || null,
|
||||||
status: status || 'registered',
|
status: status || 'registered',
|
||||||
createdBy: userId,
|
createdBy: userId,
|
||||||
})
|
})
|
||||||
@@ -187,7 +193,7 @@ export const createCompany = async (userId, data, auditContext = null) => {
|
|||||||
export const updateCompany = async (companyId, data, auditContext = null) => {
|
export const updateCompany = async (companyId, data, auditContext = null) => {
|
||||||
const company = await getCompanyById(companyId);
|
const company = await getCompanyById(companyId);
|
||||||
|
|
||||||
const { name, description, address, city, postalCode, country, phone, email, website, status } = data;
|
const { name, description, address, city, postalCode, country, phone, email, website, ico, dic, status } = data;
|
||||||
|
|
||||||
// If name is being changed, check for duplicates
|
// If name is being changed, check for duplicates
|
||||||
if (name && name !== company.name) {
|
if (name && name !== company.name) {
|
||||||
@@ -214,6 +220,8 @@ export const updateCompany = async (companyId, data, auditContext = null) => {
|
|||||||
phone: phone !== undefined ? phone : company.phone,
|
phone: phone !== undefined ? phone : company.phone,
|
||||||
email: email !== undefined ? email : company.email,
|
email: email !== undefined ? email : company.email,
|
||||||
website: website !== undefined ? website : company.website,
|
website: website !== undefined ? website : company.website,
|
||||||
|
ico: ico !== undefined ? ico : company.ico,
|
||||||
|
dic: dic !== undefined ? dic : company.dic,
|
||||||
status: status !== undefined ? status : company.status,
|
status: status !== undefined ? status : company.status,
|
||||||
updatedAt: new Date(),
|
updatedAt: new Date(),
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ export const createCompanySchema = z.object({
|
|||||||
phone: z.string().max(50).optional(),
|
phone: z.string().max(50).optional(),
|
||||||
email: z.string().email('Neplatný formát emailu').max(255).optional().or(z.literal('')),
|
email: z.string().email('Neplatný formát emailu').max(255).optional().or(z.literal('')),
|
||||||
website: z.string().url('Neplatný formát URL').max(255).optional().or(z.literal('')),
|
website: z.string().url('Neplatný formát URL').max(255).optional().or(z.literal('')),
|
||||||
|
ico: z.string().max(20).optional().or(z.literal('')),
|
||||||
|
dic: z.string().max(20).optional().or(z.literal('')),
|
||||||
status: z.enum(['registered', 'lead', 'customer', 'inactive']).optional(),
|
status: z.enum(['registered', 'lead', 'customer', 'inactive']).optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -29,6 +31,8 @@ export const updateCompanySchema = z.object({
|
|||||||
phone: z.string().max(50).optional(),
|
phone: z.string().max(50).optional(),
|
||||||
email: z.string().email('Neplatný formát emailu').max(255).optional().or(z.literal('')),
|
email: z.string().email('Neplatný formát emailu').max(255).optional().or(z.literal('')),
|
||||||
website: z.string().url('Neplatný formát URL').max(255).optional().or(z.literal('')),
|
website: z.string().url('Neplatný formát URL').max(255).optional().or(z.literal('')),
|
||||||
|
ico: z.string().max(20).optional().or(z.literal('').or(z.null())),
|
||||||
|
dic: z.string().max(20).optional().or(z.literal('').or(z.null())),
|
||||||
status: z.enum(['registered', 'lead', 'customer', 'inactive']).optional(),
|
status: z.enum(['registered', 'lead', 'customer', 'inactive']).optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user