115 lines
4.1 KiB
JavaScript
115 lines
4.1 KiB
JavaScript
import {
|
|
CREATE as MSSQL_CREATE,
|
|
GET_NEXT_SORT as MSSQL_GET_NEXT_SORT,
|
|
} from '../../providers/mssql/queries/entityaddress.js';
|
|
import {
|
|
CREATE as SQLITE_CREATE,
|
|
GET_NEXT_SORT as SQLITE_GET_NEXT_SORT,
|
|
} from '../../providers/sqlite3/queries/entityaddress.js';
|
|
import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js';
|
|
import resolveEntityAccess from '../entity/resolveEntityAccess.js';
|
|
import makeRunner from '../runner.js';
|
|
|
|
function shape(row) {
|
|
return {
|
|
id: row.id,
|
|
entityId: row.entityId,
|
|
firstName: row.firstName ?? null,
|
|
name: row.name ?? null,
|
|
street: row.street ?? null,
|
|
streetNumber: row.streetNumber ?? null,
|
|
zip: row.zip ?? null,
|
|
city: row.city ?? null,
|
|
county: row.county ?? null,
|
|
addressType: row.addressType,
|
|
sort: row.sort,
|
|
};
|
|
}
|
|
|
|
function optionalString(value) {
|
|
if (value == null || value === '') return null;
|
|
const s = String(value).trim();
|
|
return s || null;
|
|
}
|
|
|
|
export default function create(provider) {
|
|
const access = resolveSelectedCompanyAccess(provider);
|
|
const entityAccess = resolveEntityAccess(provider);
|
|
const isSqlite = provider?.dialect === 'sqlite3';
|
|
const getSortSql = isSqlite ? SQLITE_GET_NEXT_SORT : MSSQL_GET_NEXT_SORT;
|
|
const createSql = isSqlite ? SQLITE_CREATE : MSSQL_CREATE;
|
|
|
|
/**
|
|
* Creates a new address for an entity.
|
|
*
|
|
* @param {number} googleAuthId - The id of the Google auth user.
|
|
* @param {number} entityId - The id of the entity.
|
|
* @param {object} input - The address input.
|
|
* @param {string} input.addressType - The address type (e.g. `'billing'`).
|
|
* @param {string} [input.firstName] - The first name.
|
|
* @param {string} [input.name] - The name.
|
|
* @param {string} [input.street] - The street.
|
|
* @param {string} [input.streetNumber] - The street number.
|
|
* @param {string} [input.zip] - The zip code.
|
|
* @param {string} [input.city] - The city.
|
|
* @param {string} [input.county] - The county.
|
|
* @param {number} [input.sort] - Optional sort order.
|
|
* @param {object} [tx] - Optional transaction to run within.
|
|
* @returns {Promise<{id: number, entityId: number, firstName: string|null, name: string|null, street: string|null, streetNumber: string|null, zip: string|null, city: string|null, county: string|null, addressType: string, sort: number}>} The created address.
|
|
* @throws {Error} If the address type is missing.
|
|
*
|
|
* @example
|
|
* const address = await store.entityaddress.create(42, 5, { addressType: 'billing', street: 'Main St', city: 'Berlin' });
|
|
* // => { id, entityId, firstName, name, street, streetNumber, zip, city, county, addressType, sort }
|
|
*/
|
|
return async (googleAuthId, entityId, input = {}, tx) => {
|
|
const addressType = input.addressType?.trim?.()
|
|
? input.addressType.trim()
|
|
: null;
|
|
if (!addressType) {
|
|
throw new Error('Address type required');
|
|
}
|
|
|
|
const runner = makeRunner(provider, tx);
|
|
const { companyId } = await access(googleAuthId, tx);
|
|
await entityAccess(companyId, entityId, tx);
|
|
|
|
let sort = input.sort;
|
|
if (sort === undefined || sort === null) {
|
|
const next = await runner.query(getSortSql, { entityId });
|
|
sort = next.rows[0].sort;
|
|
} else if (!Number.isFinite(sort)) {
|
|
throw new Error('Invalid sort');
|
|
}
|
|
|
|
const result = await runner.query(createSql, {
|
|
entityId,
|
|
firstName: optionalString(input.firstName),
|
|
name: optionalString(input.name),
|
|
street: optionalString(input.street),
|
|
streetNumber: optionalString(input.streetNumber),
|
|
zip: optionalString(input.zip),
|
|
city: optionalString(input.city),
|
|
county: optionalString(input.county),
|
|
addressType,
|
|
sort,
|
|
});
|
|
|
|
const row = result.rows[0] ?? {
|
|
id: result.insertId,
|
|
entityId,
|
|
firstName: optionalString(input.firstName),
|
|
name: optionalString(input.name),
|
|
street: optionalString(input.street),
|
|
streetNumber: optionalString(input.streetNumber),
|
|
zip: optionalString(input.zip),
|
|
city: optionalString(input.city),
|
|
county: optionalString(input.county),
|
|
addressType,
|
|
sort,
|
|
};
|
|
|
|
return shape(row);
|
|
};
|
|
}
|