diff --git a/.github/workflows/checking-repository-code.yml b/.github/workflows/checking-repository-code.yml new file mode 100644 index 0000000..173bd38 --- /dev/null +++ b/.github/workflows/checking-repository-code.yml @@ -0,0 +1,40 @@ +name: Checking Repository Code +on: [push] +jobs: + Checking-Repository-Code: + runs-on: ubuntu-latest + environment: Testing + env: + XXX: ${{ vars.XXX }} + steps: + - name: Environment Variables + run: | + echo "XXX: ${{ env.XXX }}" + - name: Checkout repository code + uses: actions/checkout@v4 + - name: Build Package + run: npm run install-build:production + - name: Testing code + run: npm run test-coverage:complete + - name: Prettier-linting code + run: npm run prettier-lint + - name: Set up Git + run: | + git config --global user.name 'github-actions[bot]' + git config --global user.email 'github-actions[bot]@users.noreply.github.com' + - name: Check for changes + id: changes + run: | + if [[ -n "$(git status --porcelain)" ]]; then + echo "changes=true" >> $GITHUB_ENV + else + echo "changes=false" >> $GITHUB_ENV + fi + - name: Commit and push changes + if: env.changes == 'true' + run: | + git add . + git commit --amend --no-edit + git push --force + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/db-ddl/01-table-index.sql b/db-ddl/01-table-index.sql new file mode 100644 index 0000000..9d25c64 --- /dev/null +++ b/db-ddl/01-table-index.sql @@ -0,0 +1,129 @@ +CREATE TABLE PUBLIC.PF_MED_FRECUENCY ( + MFRE_ID SERIAL PRIMARY KEY, + MFRE_EVERY_HOURS NUMERIC NOT NULL, + MFRE_QUANTITY NUMERIC NOT NULL +); + +CREATE INDEX IDX_MED_FRECUENCY_EVERYHOURS ON PUBLIC.PF_MED_FRECUENCY (MFRE_EVERY_HOURS); +CREATE INDEX IDX_MED_FRECUENCY_QUANTITY ON PUBLIC.PF_MED_FRECUENCY (MFRE_QUANTITY); +CREATE UNIQUE INDEX IDX_MED_FRECUENCY_ALL ON PUBLIC.PF_MED_FRECUENCY (MFRE_EVERY_HOURS, MFRE_QUANTITY); +CREATE UNIQUE INDEX IDX_MED_FRECUENCY_ID ON PUBLIC.PF_MED_FRECUENCY (MFRE_ID); + +CREATE TABLE PUBLIC.PF_MED_MANUFACTURER ( + MMAN_ID SERIAL PRIMARY KEY, + MMAN_NAME VARCHAR(255) NOT NULL +); + +CREATE UNIQUE INDEX IDX_MED_MANUFACTURER_ID ON PUBLIC.PF_MED_MANUFACTURER (MMAN_ID); +CREATE UNIQUE INDEX IDX_MED_MANUFACTURER_NAME ON PUBLIC.PF_MED_MANUFACTURER (MMAN_NAME); + +CREATE TABLE PUBLIC.PF_MED_SUBSTANCE ( + MSUB_ID SERIAL PRIMARY KEY, + MSUB_NAME VARCHAR(255) NOT NULL +); + +CREATE UNIQUE INDEX IDX_MED_SUBSTANCE_ID ON PUBLIC.PF_MED_SUBSTANCE (MSUB_ID); +CREATE UNIQUE INDEX IDX_MED_SUBSTANCE_NAME ON PUBLIC.PF_MED_SUBSTANCE (MSUB_NAME); + +CREATE TABLE PUBLIC.PF_USER ( + USER_ID SERIAL PRIMARY KEY, + USER_NAME VARCHAR(255) NOT NULL +); + +CREATE UNIQUE INDEX IDX_USER_ID ON PUBLIC.PF_USER (USER_ID); +CREATE UNIQUE INDEX IDX_USER_NAME ON PUBLIC.PF_USER (USER_NAME); + +CREATE TABLE PUBLIC.PF_MED_TYPE ( + MTYP_ID SERIAL PRIMARY KEY, + MTYP_NAME VARCHAR(255) NOT NULL +); + +CREATE UNIQUE INDEX IDX_MED_TYPE_ID ON PUBLIC.PF_MED_TYPE (MTYP_ID); +CREATE UNIQUE INDEX IDX_MED_TYPE_NAME ON PUBLIC.PF_MED_TYPE (MTYP_NAME); + +CREATE TABLE PUBLIC.PF_MED_BRANDED_MEDICINE ( + MBME_ID SERIAL PRIMARY KEY, + MBME_NAME VARCHAR(255) NOT NULL, + MTYP_ID INT NOT NULL REFERENCES PF_MED_TYPE(MTYP_ID), + MMAN_ID INT NOT NULL REFERENCES PF_MED_MANUFACTURER(MMAN_ID) +); + +CREATE INDEX IDX_MED_BRANDED_MEDICINE_MANUFACTURER ON PUBLIC.PF_MED_BRANDED_MEDICINE (MMAN_ID); +CREATE INDEX IDX_MED_BRANDED_MEDICINE_TYPE ON PUBLIC.PF_MED_BRANDED_MEDICINE (MTYP_ID); +CREATE UNIQUE INDEX IDX_MED_BRANDED_MEDICINE_ALL ON PUBLIC.PF_MED_BRANDED_MEDICINE (MBME_NAME, MTYP_ID, MMAN_ID); +CREATE UNIQUE INDEX IDX_MED_BRANDED_MEDICINE_ID ON PUBLIC.PF_MED_BRANDED_MEDICINE (MBME_ID); +CREATE UNIQUE INDEX IDX_MED_BRANDED_MEDICINE_NAME ON PUBLIC.PF_MED_BRANDED_MEDICINE (MBME_NAME); + +CREATE TABLE PUBLIC.PF_MED_BRANDED_PRESENTATION ( + MBPR_ID SERIAL PRIMARY KEY, + MBPR_QUANTITY NUMERIC NOT NULL, + MBME_ID INT NOT NULL REFERENCES PF_MED_BRANDED_MEDICINE(MBME_ID), + CONSTRAINT FK_BRANDED_PRESENTATION_BRANDED_MEDICINE FOREIGN KEY (MBME_ID) REFERENCES PF_MED_BRANDED_MEDICINE(MBME_ID) +); + +CREATE INDEX IDX_MED_BRANDED_PRESENTATION_BRANDED_MEDICINE ON PUBLIC.PF_MED_BRANDED_PRESENTATION (MBME_ID); +CREATE UNIQUE INDEX IDX_MED_BRANDED_PRESENTATION_ALL ON PUBLIC.PF_MED_BRANDED_PRESENTATION (MBPR_QUANTITY, MBME_ID); +CREATE UNIQUE INDEX IDX_MED_BRANDED_PRESENTATION_ID ON PUBLIC.PF_MED_BRANDED_PRESENTATION (MBPR_ID); + +CREATE TABLE PUBLIC.PF_MED_COMPONENT ( + MCOMP_ID SERIAL PRIMARY KEY, + MCOMP_GRAMS NUMERIC NOT NULL, + MSUB_ID INT NOT NULL REFERENCES PF_MED_SUBSTANCE(MSUB_ID), + MBPR_ID INT NOT NULL REFERENCES PF_MED_BRANDED_PRESENTATION(MBPR_ID) +); + +CREATE INDEX IDX_MED_COMPONENT_BRANDED_PRESENTATION ON PUBLIC.PF_MED_COMPONENT (MBPR_ID); +CREATE INDEX IDX_MED_COMPONENT_SUBSTANCE ON PUBLIC.PF_MED_COMPONENT (MSUB_ID); +CREATE UNIQUE INDEX IDX_MED_COMPONENT_ALL ON PUBLIC.PF_MED_COMPONENT (MCOMP_GRAMS, MSUB_ID, MBPR_ID); +CREATE UNIQUE INDEX IDX_MED_COMPONENT_ID ON PUBLIC.PF_MED_COMPONENT (MCOMP_ID); + +CREATE TABLE PUBLIC.PF_MED_PRESCRIPTION ( + MPRE_ID SERIAL PRIMARY KEY, + MPRE_ACTIVE BOOLEAN NOT NULL DEFAULT TRUE, + MPRE_DATE TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + MPRE_IS_SELF_MEDICATED BOOLEAN NOT NULL DEFAULT TRUE, + MTYP_ID INT NOT NULL REFERENCES PF_MED_TYPE(MTYP_ID), + MFRE_ID INT NOT NULL REFERENCES PF_MED_FRECUENCY(MFRE_ID), + USER_ID INT NOT NULL REFERENCES PF_USER(USER_ID) +); + +CREATE INDEX IDX_MED_PRESCRIPTION_ACTIVE ON PUBLIC.PF_MED_PRESCRIPTION (MPRE_ACTIVE); +CREATE INDEX IDX_MED_PRESCRIPTION_DATE ON PUBLIC.PF_MED_PRESCRIPTION (MPRE_DATE); +CREATE INDEX IDX_MED_PRESCRIPTION_FREQUENCY ON PUBLIC.PF_MED_PRESCRIPTION (MFRE_ID); +CREATE INDEX IDX_MED_PRESCRIPTION_IS_SELF_MEDICATED ON PUBLIC.PF_MED_PRESCRIPTION (MPRE_IS_SELF_MEDICATED); +CREATE INDEX IDX_MED_PRESCRIPTION_TYPE ON PUBLIC.PF_MED_PRESCRIPTION (MTYP_ID); +CREATE INDEX IDX_MED_PRESCRIPTION_USER ON PUBLIC.PF_MED_PRESCRIPTION (USER_ID); +CREATE UNIQUE INDEX IDX_MED_PRESCRIPTION_ALL ON PUBLIC.PF_MED_PRESCRIPTION (MPRE_ACTIVE, MPRE_DATE, MPRE_IS_SELF_MEDICATED, MTYP_ID, MFRE_ID, USER_ID); +CREATE UNIQUE INDEX IDX_MED_PRESCRIPTION_ID ON PUBLIC.PF_MED_PRESCRIPTION (MPRE_ID); + +CREATE TABLE PUBLIC.PF_MED_PURCHASE ( + MPUR_ID SERIAL PRIMARY KEY, + MPUR_DATE TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + MPUR_DISCOUNT NUMERIC NOT NULL, + MPUR_PRICE NUMERIC NOT NULL, + MPUR_SHIPPING_COST NUMERIC NOT NULL, + MBME_ID INT NOT NULL REFERENCES PF_MED_BRANDED_MEDICINE(MBME_ID) +); + +CREATE INDEX IDX_MED_PURCHASE_BRANDED_MEDICINE ON PUBLIC.PF_MED_PURCHASE (MBME_ID); +CREATE INDEX IDX_MED_PURCHASE_DATE ON PUBLIC.PF_MED_PURCHASE (MPUR_DATE); +CREATE INDEX IDX_MED_PURCHASE_DISCOUNT ON PUBLIC.PF_MED_PURCHASE (MPUR_DISCOUNT); +CREATE INDEX IDX_MED_PURCHASE_PRICE ON PUBLIC.PF_MED_PURCHASE (MPUR_PRICE); +CREATE INDEX IDX_MED_PURCHASE_SHIPPING_COST ON PUBLIC.PF_MED_PURCHASE (MPUR_SHIPPING_COST); +CREATE UNIQUE INDEX IDX_MED_PURCHASE_ALL ON PUBLIC.PF_MED_PURCHASE (MPUR_DATE, MPUR_DISCOUNT, MPUR_PRICE, MPUR_SHIPPING_COST, MBME_ID); +CREATE UNIQUE INDEX IDX_MED_PURCHASE_ID ON PUBLIC.PF_MED_PURCHASE (MPUR_ID); + +CREATE TABLE PUBLIC.PF_MED_STOCK ( + MSTO_ID SERIAL PRIMARY KEY, + MSTO_DATE TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + MSTO_QUANTITY NUMERIC NOT NULL, + MBPR_ID INT NOT NULL REFERENCES PF_MED_BRANDED_PRESENTATION(MBPR_ID), + USER_ID INT NOT NULL REFERENCES PF_USER(USER_ID) +); + +CREATE INDEX IDX_MED_STOCK_BRANDED_PRESENTATION ON PUBLIC.PF_MED_STOCK (MBPR_ID); +CREATE INDEX IDX_MED_STOCK_DATE ON PUBLIC.PF_MED_STOCK (MSTO_DATE); +CREATE INDEX IDX_MED_STOCK_QUANTITY ON PUBLIC.PF_MED_STOCK (MSTO_QUANTITY); +CREATE INDEX IDX_MED_STOCK_USER ON PUBLIC.PF_MED_STOCK (USER_ID); +CREATE UNIQUE INDEX IDX_MED_STOCK_ALL ON PUBLIC.PF_MED_STOCK (MSTO_DATE, MSTO_QUANTITY, MBPR_ID, USER_ID); +CREATE UNIQUE INDEX IDX_MED_STOCK_ID ON PUBLIC.PF_MED_STOCK (MSTO_ID); diff --git a/db-ddl/02-data.sql b/db-ddl/02-data.sql new file mode 100644 index 0000000..fdf42d3 --- /dev/null +++ b/db-ddl/02-data.sql @@ -0,0 +1,1907 @@ +DO $$ +DECLARE + local_user_id INT; + local_mtyp_id INT; + local_mtyp_ids INT[] := '{}'; + local_mman_id INT; + local_mman_ids INT[] := '{}'; + local_msub_id INT; + local_msub_ids INT[] := '{}'; + local_mbme_id INT; + local_mbme_ids INT[] := '{}'; + local_mbpr_id INT; + local_mbpr_ids INT[] := '{}'; + local_mcomp_id INT; + local_mcomp_ids INT[] := '{}'; + local_mfre_id INT; + local_mfre_ids INT[] := '{}'; + local_mpre_id INT; + local_mpre_ids INT[] := '{}'; +BEGIN + + -- PF_USER + + INSERT INTO public.pf_user (user_id, user_name) + VALUES + ( + nextval( + 'pf_user_user_id_seq' :: regclass + ), + 'Arturo Andrés Mendoza Benavides' + ) RETURNING user_id INTO local_user_id; -- local_user_id + RAISE NOTICE 'Inserted into pf_user, user_id: %', + local_user_id; + + + -- PF_MED_MANUFACTURER + + INSERT INTO public.pf_med_manufacturer (mman_id, mman_name) + VALUES + ( + nextval( + 'pf_med_manufacturer_mman_id_seq' :: regclass + ), + 'VITAMIN LIFE' + ) RETURNING mman_id INTO local_mman_id; + local_mman_ids := array_append(local_mman_ids, local_mman_id); -- local_mman_ids[1] + RAISE NOTICE 'Inserted into pf_med_manufacturer, mman_id: %', + local_mman_ids[array_length(local_mman_ids, 1) ]; + + INSERT INTO public.pf_med_manufacturer (mman_id, mman_name) + VALUES + ( + nextval( + 'pf_med_manufacturer_mman_id_seq' :: regclass + ), + 'ASCEND' + ) RETURNING mman_id INTO local_mman_id; + local_mman_ids := array_append(local_mman_ids, local_mman_id); -- local_mman_ids[2] + RAISE NOTICE 'Inserted into pf_med_manufacturer, mman_id: %', + local_mman_ids[array_length(local_mman_ids, 1) ]; + + INSERT INTO public.pf_med_manufacturer (mman_id, mman_name) + VALUES + ( + nextval( + 'pf_med_manufacturer_mman_id_seq' :: regclass + ), + 'SEVEN PHARMA' + ) RETURNING mman_id INTO local_mman_id; + local_mman_ids := array_append(local_mman_ids, local_mman_id); -- local_mman_ids[3] + RAISE NOTICE 'Inserted into pf_med_manufacturer, mman_id: %', + local_mman_ids[array_length(local_mman_ids, 1) ]; + + INSERT INTO public.pf_med_manufacturer (mman_id, mman_name) + VALUES + ( + nextval( + 'pf_med_manufacturer_mman_id_seq' :: regclass + ), + 'LABORATORIO CHILE' + ) RETURNING mman_id INTO local_mman_id; + local_mman_ids := array_append(local_mman_ids, local_mman_id); -- local_mman_ids[4] + RAISE NOTICE 'Inserted into pf_med_manufacturer, mman_id: %', + local_mman_ids[array_length(local_mman_ids, 1) ]; + + INSERT INTO public.pf_med_manufacturer (mman_id, mman_name) + VALUES + ( + nextval( + 'pf_med_manufacturer_mman_id_seq' :: regclass + ), + 'FARMACIA AHUMADA' + ) RETURNING mman_id INTO local_mman_id; + local_mman_ids := array_append(local_mman_ids, local_mman_id); -- local_mman_ids[5] + RAISE NOTICE 'Inserted into pf_med_manufacturer, mman_id: %', + local_mman_ids[array_length(local_mman_ids, 1) ]; + + INSERT INTO public.pf_med_manufacturer (mman_id, mman_name) + VALUES + ( + nextval( + 'pf_med_manufacturer_mman_id_seq' :: regclass + ), + 'LABORATORIO FNL' + ) RETURNING mman_id INTO local_mman_id; + local_mman_ids := array_append(local_mman_ids, local_mman_id); -- local_mman_ids[6] + RAISE NOTICE 'Inserted into pf_med_manufacturer, mman_id: %', + local_mman_ids[array_length(local_mman_ids, 1) ]; + + INSERT INTO public.pf_med_manufacturer (mman_id, mman_name) + VALUES + ( + nextval( + 'pf_med_manufacturer_mman_id_seq' :: regclass + ), + 'LABORATORIO ABEN LAB' + ) RETURNING mman_id INTO local_mman_id; + local_mman_ids := array_append(local_mman_ids, local_mman_id); -- local_mman_ids[7] + RAISE NOTICE 'Inserted into pf_med_manufacturer, mman_id: %', + local_mman_ids[array_length(local_mman_ids, 1) ]; + + INSERT INTO public.pf_med_manufacturer (mman_id, mman_name) + VALUES + ( + nextval( + 'pf_med_manufacturer_mman_id_seq' :: regclass + ), + 'GSK' + ) RETURNING mman_id INTO local_mman_id; + local_mman_ids := array_append(local_mman_ids, local_mman_id); -- local_mman_ids[8] + RAISE NOTICE 'Inserted into pf_med_manufacturer, mman_id: %', + local_mman_ids[array_length(local_mman_ids, 1) ]; + + + -- PF_MED_SUBSTANCE + + INSERT INTO public.pf_med_substance (msub_id, msub_name) + VALUES + ( + nextval( + 'pf_med_substance_msub_id_seq' :: regclass + ), + 'LACTOBACILLUS ACIDOPHILUS' + ) RETURNING msub_id INTO local_msub_id; + local_msub_ids := array_append(local_msub_ids, local_msub_id); -- local_msub_ids[1] + RAISE NOTICE 'Inserted into pf_med_substance, msub_id: %', + local_msub_ids[array_length(local_msub_ids, 1) ]; + + INSERT INTO public.pf_med_substance (msub_id, msub_name) + VALUES + ( + nextval( + 'pf_med_substance_msub_id_seq' :: regclass + ), + 'BIFIDOBACTERIUM BIFIDUM' + ) RETURNING msub_id INTO local_msub_id; + local_msub_ids := array_append(local_msub_ids, local_msub_id); -- local_msub_ids[2] + RAISE NOTICE 'Inserted into pf_med_substance, msub_id: %', + local_msub_ids[array_length(local_msub_ids, 1) ]; + + INSERT INTO public.pf_med_substance (msub_id, msub_name) + VALUES + ( + nextval( + 'pf_med_substance_msub_id_seq' :: regclass + ), + 'FOS-INULIN' + ) RETURNING msub_id INTO local_msub_id; + local_msub_ids := array_append(local_msub_ids, local_msub_id); -- local_msub_ids[3] + RAISE NOTICE 'Inserted into pf_med_substance, msub_id: %', + local_msub_ids[array_length(local_msub_ids, 1) ]; + + INSERT INTO public.pf_med_substance (msub_id, msub_name) + VALUES + ( + nextval( + 'pf_med_substance_msub_id_seq' :: regclass + ), + 'FENNEL SEED' + ) RETURNING msub_id INTO local_msub_id; + local_msub_ids := array_append(local_msub_ids, local_msub_id); -- local_msub_ids[4] + RAISE NOTICE 'Inserted into pf_med_substance, msub_id: %', + local_msub_ids[array_length(local_msub_ids, 1) ]; + + INSERT INTO public.pf_med_substance (msub_id, msub_name) + VALUES + ( + nextval( + 'pf_med_substance_msub_id_seq' :: regclass + ), + 'COLLAGEN' + ) RETURNING msub_id INTO local_msub_id; + local_msub_ids := array_append(local_msub_ids, local_msub_id); -- local_msub_ids[5] + RAISE NOTICE 'Inserted into pf_med_substance, msub_id: %', + local_msub_ids[array_length(local_msub_ids, 1) ]; + + INSERT INTO public.pf_med_substance (msub_id, msub_name) + VALUES + ( + nextval( + 'pf_med_substance_msub_id_seq' :: regclass + ), + 'VITAMIN C' + ) RETURNING msub_id INTO local_msub_id; + local_msub_ids := array_append(local_msub_ids, local_msub_id); -- local_msub_ids[6] + RAISE NOTICE 'Inserted into pf_med_substance, msub_id: %', + local_msub_ids[array_length(local_msub_ids, 1) ]; + + INSERT INTO public.pf_med_substance (msub_id, msub_name) + VALUES + ( + nextval( + 'pf_med_substance_msub_id_seq' :: regclass + ), + 'VITAMIN D' + ) RETURNING msub_id INTO local_msub_id; + local_msub_ids := array_append(local_msub_ids, local_msub_id); -- local_msub_ids[7] + RAISE NOTICE 'Inserted into pf_med_substance, msub_id: %', + local_msub_ids[array_length(local_msub_ids, 1) ]; + + INSERT INTO public.pf_med_substance (msub_id, msub_name) + VALUES + ( + nextval( + 'pf_med_substance_msub_id_seq' :: regclass + ), + 'BETA CAROTENE' + ) RETURNING msub_id INTO local_msub_id; + local_msub_ids := array_append(local_msub_ids, local_msub_id); -- local_msub_ids[8] + RAISE NOTICE 'Inserted into pf_med_substance, msub_id: %', + local_msub_ids[array_length(local_msub_ids, 1) ]; + + INSERT INTO public.pf_med_substance (msub_id, msub_name) + VALUES + ( + nextval( + 'pf_med_substance_msub_id_seq' :: regclass + ), + 'BIOTIN' + ) RETURNING msub_id INTO local_msub_id; + local_msub_ids := array_append(local_msub_ids, local_msub_id); -- local_msub_ids[9] + RAISE NOTICE 'Inserted into pf_med_substance, msub_id: %', + local_msub_ids[array_length(local_msub_ids, 1) ]; + + INSERT INTO public.pf_med_substance (msub_id, msub_name) + VALUES + ( + nextval( + 'pf_med_substance_msub_id_seq' :: regclass + ), + 'CHROMIUM' + ) RETURNING msub_id INTO local_msub_id; + local_msub_ids := array_append(local_msub_ids, local_msub_id); -- local_msub_ids[10] + RAISE NOTICE 'Inserted into pf_med_substance, msub_id: %', + local_msub_ids[array_length(local_msub_ids, 1) ]; + + INSERT INTO public.pf_med_substance (msub_id, msub_name) + VALUES + ( + nextval( + 'pf_med_substance_msub_id_seq' :: regclass + ), + 'FOLIC ACID' + ) RETURNING msub_id INTO local_msub_id; + local_msub_ids := array_append(local_msub_ids, local_msub_id); -- local_msub_ids[11] + RAISE NOTICE 'Inserted into pf_med_substance, msub_id: %', + local_msub_ids[array_length(local_msub_ids, 1) ]; + + INSERT INTO public.pf_med_substance (msub_id, msub_name) + VALUES + ( + nextval( + 'pf_med_substance_msub_id_seq' :: regclass + ), + 'IODINE' + ) RETURNING msub_id INTO local_msub_id; + local_msub_ids := array_append(local_msub_ids, local_msub_id); -- local_msub_ids[12] + RAISE NOTICE 'Inserted into pf_med_substance, msub_id: %', + local_msub_ids[array_length(local_msub_ids, 1) ]; + + INSERT INTO public.pf_med_substance (msub_id, msub_name) + VALUES + ( + nextval( + 'pf_med_substance_msub_id_seq' :: regclass + ), + 'KOREANINSENG' + ) RETURNING msub_id INTO local_msub_id; + local_msub_ids := array_append(local_msub_ids, local_msub_id); -- local_msub_ids[13] + RAISE NOTICE 'Inserted into pf_med_substance, msub_id: %', + local_msub_ids[array_length(local_msub_ids, 1) ]; + + INSERT INTO public.pf_med_substance (msub_id, msub_name) + VALUES + ( + nextval( + 'pf_med_substance_msub_id_seq' :: regclass + ), + 'MAGNESIUM' + ) RETURNING msub_id INTO local_msub_id; + local_msub_ids := array_append(local_msub_ids, local_msub_id); -- local_msub_ids[14] + RAISE NOTICE 'Inserted into pf_med_substance, msub_id: %', + local_msub_ids[array_length(local_msub_ids, 1) ]; + + INSERT INTO public.pf_med_substance (msub_id, msub_name) + VALUES + ( + nextval( + 'pf_med_substance_msub_id_seq' :: regclass + ), + 'MANGANESE SULFATE' + ) RETURNING msub_id INTO local_msub_id; + local_msub_ids := array_append(local_msub_ids, local_msub_id); -- local_msub_ids[15] + RAISE NOTICE 'Inserted into pf_med_substance, msub_id: %', + local_msub_ids[array_length(local_msub_ids, 1) ]; + + INSERT INTO public.pf_med_substance (msub_id, msub_name) + VALUES + ( + nextval( + 'pf_med_substance_msub_id_seq' :: regclass + ), + 'NIACINAMIDE' + ) RETURNING msub_id INTO local_msub_id; + local_msub_ids := array_append(local_msub_ids, local_msub_id); -- local_msub_ids[16] + RAISE NOTICE 'Inserted into pf_med_substance, msub_id: %', + local_msub_ids[array_length(local_msub_ids, 1) ]; + + INSERT INTO public.pf_med_substance (msub_id, msub_name) + VALUES + ( + nextval( + 'pf_med_substance_msub_id_seq' :: regclass + ), + 'PHOSPHORUS' + ) RETURNING msub_id INTO local_msub_id; + local_msub_ids := array_append(local_msub_ids, local_msub_id); -- local_msub_ids[17] + RAISE NOTICE 'Inserted into pf_med_substance, msub_id: %', + local_msub_ids[array_length(local_msub_ids, 1) ]; + + INSERT INTO public.pf_med_substance (msub_id, msub_name) + VALUES + ( + nextval( + 'pf_med_substance_msub_id_seq' :: regclass + ), + 'SELENIUM' + ) RETURNING msub_id INTO local_msub_id; + local_msub_ids := array_append(local_msub_ids, local_msub_id); -- local_msub_ids[18] + RAISE NOTICE 'Inserted into pf_med_substance, msub_id: %', + local_msub_ids[array_length(local_msub_ids, 1) ]; + + INSERT INTO public.pf_med_substance (msub_id, msub_name) + VALUES + ( + nextval( + 'pf_med_substance_msub_id_seq' :: regclass + ), + 'VITAMIN B1' + ) RETURNING msub_id INTO local_msub_id; + local_msub_ids := array_append(local_msub_ids, local_msub_id); -- local_msub_ids[19] + RAISE NOTICE 'Inserted into pf_med_substance, msub_id: %', + local_msub_ids[array_length(local_msub_ids, 1) ]; + + INSERT INTO public.pf_med_substance (msub_id, msub_name) + VALUES + ( + nextval( + 'pf_med_substance_msub_id_seq' :: regclass + ), + 'VITAMIN B12' + ) RETURNING msub_id INTO local_msub_id; + local_msub_ids := array_append(local_msub_ids, local_msub_id); -- local_msub_ids[20] + RAISE NOTICE 'Inserted into pf_med_substance, msub_id: %', + local_msub_ids[array_length(local_msub_ids, 1) ]; + + INSERT INTO public.pf_med_substance (msub_id, msub_name) + VALUES + ( + nextval( + 'pf_med_substance_msub_id_seq' :: regclass + ), + 'VITAMIN B2' + ) RETURNING msub_id INTO local_msub_id; + local_msub_ids := array_append(local_msub_ids, local_msub_id); -- local_msub_ids[21] + RAISE NOTICE 'Inserted into pf_med_substance, msub_id: %', + local_msub_ids[array_length(local_msub_ids, 1) ]; + + INSERT INTO public.pf_med_substance (msub_id, msub_name) + VALUES + ( + nextval( + 'pf_med_substance_msub_id_seq' :: regclass + ), + 'VITAMIN B5' + ) RETURNING msub_id INTO local_msub_id; + local_msub_ids := array_append(local_msub_ids, local_msub_id); -- local_msub_ids[22] + RAISE NOTICE 'Inserted into pf_med_substance, msub_id: %', + local_msub_ids[array_length(local_msub_ids, 1) ]; + + INSERT INTO public.pf_med_substance (msub_id, msub_name) + VALUES + ( + nextval( + 'pf_med_substance_msub_id_seq' :: regclass + ), + 'VITAMIN B6' + ) RETURNING msub_id INTO local_msub_id; + local_msub_ids := array_append(local_msub_ids, local_msub_id); -- local_msub_ids[23] + RAISE NOTICE 'Inserted into pf_med_substance, msub_id: %', + local_msub_ids[array_length(local_msub_ids, 1) ]; + + INSERT INTO public.pf_med_substance (msub_id, msub_name) + VALUES + ( + nextval( + 'pf_med_substance_msub_id_seq' :: regclass + ), + 'VITAMIN D3' + ) RETURNING msub_id INTO local_msub_id; + local_msub_ids := array_append(local_msub_ids, local_msub_id); -- local_msub_ids[24] + RAISE NOTICE 'Inserted into pf_med_substance, msub_id: %', + local_msub_ids[array_length(local_msub_ids, 1) ]; + + INSERT INTO public.pf_med_substance (msub_id, msub_name) + VALUES + ( + nextval( + 'pf_med_substance_msub_id_seq' :: regclass + ), + 'VITAMIN E' + ) RETURNING msub_id INTO local_msub_id; + local_msub_ids := array_append(local_msub_ids, local_msub_id); -- local_msub_ids[25] + RAISE NOTICE 'Inserted into pf_med_substance, msub_id: %', + local_msub_ids[array_length(local_msub_ids, 1) ]; + + INSERT INTO public.pf_med_substance (msub_id, msub_name) + VALUES + ( + nextval( + 'pf_med_substance_msub_id_seq' :: regclass + ), + 'VITAMIN K1' + ) RETURNING msub_id INTO local_msub_id; + local_msub_ids := array_append(local_msub_ids, local_msub_id); -- local_msub_ids[26] + RAISE NOTICE 'Inserted into pf_med_substance, msub_id: %', + local_msub_ids[array_length(local_msub_ids, 1) ]; + + INSERT INTO public.pf_med_substance (msub_id, msub_name) + VALUES + ( + nextval( + 'pf_med_substance_msub_id_seq' :: regclass + ), + 'ZINC' + ) RETURNING msub_id INTO local_msub_id; + local_msub_ids := array_append(local_msub_ids, local_msub_id); -- local_msub_ids[27] + RAISE NOTICE 'Inserted into pf_med_substance, msub_id: %', + local_msub_ids[array_length(local_msub_ids, 1) ]; + + INSERT INTO public.pf_med_substance (msub_id, msub_name) + VALUES + ( + nextval( + 'pf_med_substance_msub_id_seq' :: regclass + ), + 'EZETIMIBA' + ) RETURNING msub_id INTO local_msub_id; + local_msub_ids := array_append(local_msub_ids, local_msub_id); -- local_msub_ids[28] + RAISE NOTICE 'Inserted into pf_med_substance, msub_id: %', + local_msub_ids[array_length(local_msub_ids, 1) ]; + + INSERT INTO public.pf_med_substance (msub_id, msub_name) + VALUES + ( + nextval( + 'pf_med_substance_msub_id_seq' :: regclass + ), + 'ESCITALOPTRAM' + ) RETURNING msub_id INTO local_msub_id; + local_msub_ids := array_append(local_msub_ids, local_msub_id); -- local_msub_ids[29] + RAISE NOTICE 'Inserted into pf_med_substance, msub_id: %', + local_msub_ids[array_length(local_msub_ids, 1) ]; + + INSERT INTO public.pf_med_substance (msub_id, msub_name) + VALUES + ( + nextval( + 'pf_med_substance_msub_id_seq' :: regclass + ), + 'ATORVASTATINA' + ) RETURNING msub_id INTO local_msub_id; + local_msub_ids := array_append(local_msub_ids, local_msub_id); -- local_msub_ids[30] + RAISE NOTICE 'Inserted into pf_med_substance, msub_id: %', + local_msub_ids[array_length(local_msub_ids, 1) ]; + + INSERT INTO public.pf_med_substance (msub_id, msub_name) + VALUES + ( + nextval( + 'pf_med_substance_msub_id_seq' :: regclass + ), + 'MINOXIDIL' + ) RETURNING msub_id INTO local_msub_id; + local_msub_ids := array_append(local_msub_ids, local_msub_id); -- local_msub_ids[31] + RAISE NOTICE 'Inserted into pf_med_substance, msub_id: %', + local_msub_ids[array_length(local_msub_ids, 1) ]; + + INSERT INTO public.pf_med_substance (msub_id, msub_name) + VALUES + ( + nextval( + 'pf_med_substance_msub_id_seq' :: regclass + ), + 'FINASTERIDE' + ) RETURNING msub_id INTO local_msub_id; + local_msub_ids := array_append(local_msub_ids, local_msub_id); -- local_msub_ids[32] + RAISE NOTICE 'Inserted into pf_med_substance, msub_id: %', + local_msub_ids[array_length(local_msub_ids, 1) ]; + + INSERT INTO public.pf_med_substance (msub_id, msub_name) + VALUES + ( + nextval( + 'pf_med_substance_msub_id_seq' :: regclass + ), + 'CREATINE' + ) RETURNING msub_id INTO local_msub_id; + local_msub_ids := array_append(local_msub_ids, local_msub_id); -- local_msub_ids[33] + RAISE NOTICE 'Inserted into pf_med_substance, msub_id: %', + local_msub_ids[array_length(local_msub_ids, 1) ]; + + INSERT INTO public.pf_med_substance (msub_id, msub_name) + VALUES + ( + nextval( + 'pf_med_substance_msub_id_seq' :: regclass + ), + 'FLUTICASONE FUROATE' + ) RETURNING msub_id INTO local_msub_id; + local_msub_ids := array_append(local_msub_ids, local_msub_id); -- local_msub_ids[34] + RAISE NOTICE 'Inserted into pf_med_substance, msub_id: %', + local_msub_ids[array_length(local_msub_ids, 1) ]; + + INSERT INTO public.pf_med_substance (msub_id, msub_name) + VALUES + ( + nextval( + 'pf_med_substance_msub_id_seq' :: regclass + ), + 'VITAMIN A' + ) RETURNING msub_id INTO local_msub_id; + local_msub_ids := array_append(local_msub_ids, local_msub_id); -- local_msub_ids[35] + RAISE NOTICE 'Inserted into pf_med_substance, msub_id: %', + local_msub_ids[array_length(local_msub_ids, 1) ]; + + INSERT INTO public.pf_med_substance (msub_id, msub_name) + VALUES + ( + nextval( + 'pf_med_substance_msub_id_seq' :: regclass + ), + 'FISH OIL' + ) RETURNING msub_id INTO local_msub_id; + local_msub_ids := array_append(local_msub_ids, local_msub_id); -- local_msub_ids[36] + RAISE NOTICE 'Inserted into pf_med_substance, msub_id: %', + local_msub_ids[array_length(local_msub_ids, 1) ]; + + -- PF_MED_TYPE + + INSERT INTO public.pf_med_type (mtyp_id, mtyp_name) + VALUES + ( + nextval( + 'pf_med_type_mtyp_id_seq' :: regclass + ), + 'ATORVASTATINA' + ) RETURNING mtyp_id INTO local_mtyp_id; + local_mtyp_ids := array_append(local_mtyp_ids, local_mtyp_id); -- local_mtyp_ids[1] + RAISE NOTICE 'Inserted into pf_med_type, mtyp_id: %', + local_mtyp_ids[array_length(local_mtyp_ids, 1) ]; + + INSERT INTO public.pf_med_type (mtyp_id, mtyp_name) + VALUES + ( + nextval( + 'pf_med_type_mtyp_id_seq' :: regclass + ), + 'COLLAGEN' + ) RETURNING mtyp_id INTO local_mtyp_id; + local_mtyp_ids := array_append(local_mtyp_ids, local_mtyp_id); -- local_mtyp_ids[2] + RAISE NOTICE 'Inserted into pf_med_type, mtyp_id: %', + local_mtyp_ids[array_length(local_mtyp_ids, 1) ]; + + INSERT INTO public.pf_med_type (mtyp_id, mtyp_name) + VALUES + ( + nextval( + 'pf_med_type_mtyp_id_seq' :: regclass + ), + 'CORTICOSTEROID' + ) RETURNING mtyp_id INTO local_mtyp_id; + local_mtyp_ids := array_append(local_mtyp_ids, local_mtyp_id); -- local_mtyp_ids[3] + RAISE NOTICE 'Inserted into pf_med_type, mtyp_id: %', + local_mtyp_ids[array_length(local_mtyp_ids, 1) ]; + + INSERT INTO public.pf_med_type (mtyp_id, mtyp_name) + VALUES + ( + nextval( + 'pf_med_type_mtyp_id_seq' :: regclass + ), + 'CREATINE' + ) RETURNING mtyp_id INTO local_mtyp_id; + local_mtyp_ids := array_append(local_mtyp_ids, local_mtyp_id); -- local_mtyp_ids[4] + RAISE NOTICE 'Inserted into pf_med_type, mtyp_id: %', + local_mtyp_ids[array_length(local_mtyp_ids, 1) ]; + + INSERT INTO public.pf_med_type (mtyp_id, mtyp_name) + VALUES + ( + nextval( + 'pf_med_type_mtyp_id_seq' :: regclass + ), + 'ESCITALOPRAM' + ) RETURNING mtyp_id INTO local_mtyp_id; + local_mtyp_ids := array_append(local_mtyp_ids, local_mtyp_id); -- local_mtyp_ids[5] + RAISE NOTICE 'Inserted into pf_med_type, mtyp_id: %', + local_mtyp_ids[array_length(local_mtyp_ids, 1) ]; + + INSERT INTO public.pf_med_type (mtyp_id, mtyp_name) + VALUES + ( + nextval( + 'pf_med_type_mtyp_id_seq' :: regclass + ), + 'EZETIMIBA' + ) RETURNING mtyp_id INTO local_mtyp_id; + local_mtyp_ids := array_append(local_mtyp_ids, local_mtyp_id); -- local_mtyp_ids[6] + RAISE NOTICE 'Inserted into pf_med_type, mtyp_id: %', + local_mtyp_ids[array_length(local_mtyp_ids, 1) ]; + + INSERT INTO public.pf_med_type (mtyp_id, mtyp_name) + VALUES + ( + nextval( + 'pf_med_type_mtyp_id_seq' :: regclass + ), + 'HAIR GROWTH' + ) RETURNING mtyp_id INTO local_mtyp_id; + local_mtyp_ids := array_append(local_mtyp_ids, local_mtyp_id); -- local_mtyp_ids[7] + RAISE NOTICE 'Inserted into pf_med_type, mtyp_id: %', + local_mtyp_ids[array_length(local_mtyp_ids, 1) ]; + + INSERT INTO public.pf_med_type (mtyp_id, mtyp_name) + VALUES + ( + nextval( + 'pf_med_type_mtyp_id_seq' :: regclass + ), + 'MULTIVITAMIN' + ) RETURNING mtyp_id INTO local_mtyp_id; + local_mtyp_ids := array_append(local_mtyp_ids, local_mtyp_id); -- local_mtyp_ids[8] + RAISE NOTICE 'Inserted into pf_med_type, mtyp_id: %', + local_mtyp_ids[array_length(local_mtyp_ids, 1) ]; + + INSERT INTO public.pf_med_type (mtyp_id, mtyp_name) + VALUES + ( + nextval( + 'pf_med_type_mtyp_id_seq' :: regclass + ), + 'OMEGA-3' + ) RETURNING mtyp_id INTO local_mtyp_id; + local_mtyp_ids := array_append(local_mtyp_ids, local_mtyp_id); -- local_mtyp_ids[9] + RAISE NOTICE 'Inserted into pf_med_type, mtyp_id: %', + local_mtyp_ids[array_length(local_mtyp_ids, 1) ]; + + INSERT INTO public.pf_med_type (mtyp_id, mtyp_name) + VALUES + ( + nextval( + 'pf_med_type_mtyp_id_seq' :: regclass + ), + 'PROBIOTIC' + ) RETURNING mtyp_id INTO local_mtyp_id; + local_mtyp_ids := array_append(local_mtyp_ids, local_mtyp_id); -- local_mtyp_ids[10] + RAISE NOTICE 'Inserted into pf_med_type, mtyp_id: %', + local_mtyp_ids[array_length(local_mtyp_ids, 1) ]; + + INSERT INTO public.pf_med_type (mtyp_id, mtyp_name) + VALUES + ( + nextval( + 'pf_med_type_mtyp_id_seq' :: regclass + ), + 'VITAMIN A' + ) RETURNING mtyp_id INTO local_mtyp_id; + local_mtyp_ids := array_append(local_mtyp_ids, local_mtyp_id); -- local_mtyp_ids[11] + RAISE NOTICE 'Inserted into pf_med_type, mtyp_id: %', + local_mtyp_ids[array_length(local_mtyp_ids, 1) ]; + + + -- PF_MED_BRANDED_MEDICINE + + INSERT INTO public.pf_med_branded_medicine ( + mbme_id, mbme_name, mtyp_id, mman_id + ) + VALUES + ( + nextval( + 'pf_med_branded_medicine_mbme_id_seq' :: regclass + ), + 'DAILY BIOTIC FIBER', + local_mtyp_ids[10], + local_mman_ids[1] + ) RETURNING mbme_id INTO local_mbme_id; + local_mbme_ids := array_append(local_mbme_ids, local_mbme_id); -- local_mbme_ids[1] + RAISE NOTICE 'Inserted into pf_med_branded_medicine, mbme_id: %', + local_mbme_ids[array_length(local_mbme_ids, 1) ]; + + INSERT INTO public.pf_med_branded_medicine ( + mbme_id, mbme_name, mtyp_id, mman_id + ) + VALUES + ( + nextval( + 'pf_med_branded_medicine_mbme_id_seq' :: regclass + ), + 'COLLAGEN EXTRA', + local_mtyp_ids[2], + local_mman_ids[1] + ) RETURNING mbme_id INTO local_mbme_id; + local_mbme_ids := array_append(local_mbme_ids, local_mbme_id); -- local_mbme_ids[2] + RAISE NOTICE 'Inserted into pf_med_branded_medicine, mbme_id: %', + local_mbme_ids[array_length(local_mbme_ids, 1) ]; + + INSERT INTO public.pf_med_branded_medicine ( + mbme_id, mbme_name, mtyp_id, mman_id + ) + VALUES + ( + nextval( + 'pf_med_branded_medicine_mbme_id_seq' :: regclass + ), + 'MEN''S DAILY ONE', + local_mtyp_ids[8], + local_mman_ids[1] + ) RETURNING mbme_id INTO local_mbme_id; + local_mbme_ids := array_append(local_mbme_ids, local_mbme_id); -- local_mbme_ids[3] + RAISE NOTICE 'Inserted into pf_med_branded_medicine, mbme_id: %', + local_mbme_ids[array_length(local_mbme_ids, 1) ]; + + INSERT INTO public.pf_med_branded_medicine ( + mbme_id, mbme_name, mtyp_id, mman_id + ) + VALUES + ( + nextval( + 'pf_med_branded_medicine_mbme_id_seq' :: regclass + ), + 'ZERITOL', + local_mtyp_ids[6], + local_mman_ids[2] + ) RETURNING mbme_id INTO local_mbme_id; + local_mbme_ids := array_append(local_mbme_ids, local_mbme_id); -- local_mbme_ids[4] + RAISE NOTICE 'Inserted into pf_med_branded_medicine, mbme_id: %', + local_mbme_ids[array_length(local_mbme_ids, 1) ]; + + INSERT INTO public.pf_med_branded_medicine ( + mbme_id, mbme_name, mtyp_id, mman_id + ) + VALUES + ( + nextval( + 'pf_med_branded_medicine_mbme_id_seq' :: regclass + ), + 'ESCITALOPRAM', + local_mtyp_ids[5], + local_mman_ids[3] + ) RETURNING mbme_id INTO local_mbme_id; + local_mbme_ids := array_append(local_mbme_ids, local_mbme_id); -- local_mbme_ids[5] + RAISE NOTICE 'Inserted into pf_med_branded_medicine, mbme_id: %', + local_mbme_ids[array_length(local_mbme_ids, 1) ]; + + INSERT INTO public.pf_med_branded_medicine ( + mbme_id, mbme_name, mtyp_id, mman_id + ) + VALUES + ( + nextval( + 'pf_med_branded_medicine_mbme_id_seq' :: regclass + ), + 'ATORVASTATINA', + local_mtyp_ids[1], + local_mman_ids[4] + ) RETURNING mbme_id INTO local_mbme_id; + local_mbme_ids := array_append(local_mbme_ids, local_mbme_id); -- local_mbme_ids[6] + RAISE NOTICE 'Inserted into pf_med_branded_medicine, mbme_id: %', + local_mbme_ids[array_length(local_mbme_ids, 1) ]; + + INSERT INTO public.pf_med_branded_medicine ( + mbme_id, mbme_name, mtyp_id, mman_id + ) + VALUES + ( + nextval( + 'pf_med_branded_medicine_mbme_id_seq' :: regclass + ), + 'HAIR GROWTH', + local_mtyp_ids[7], + local_mman_ids[5] + ) RETURNING mbme_id INTO local_mbme_id; + local_mbme_ids := array_append(local_mbme_ids, local_mbme_id); -- local_mbme_ids[7] + RAISE NOTICE 'Inserted into pf_med_branded_medicine, mbme_id: %', + local_mbme_ids[array_length(local_mbme_ids, 1) ]; + + INSERT INTO public.pf_med_branded_medicine ( + mbme_id, mbme_name, mtyp_id, mman_id + ) + VALUES + ( + nextval( + 'pf_med_branded_medicine_mbme_id_seq' :: regclass + ), + 'POWDER CREATINA MONOHYDRATE', + local_mtyp_ids[4], + local_mman_ids[6] + ) RETURNING mbme_id INTO local_mbme_id; + local_mbme_ids := array_append(local_mbme_ids, local_mbme_id); -- local_mbme_ids[8] + RAISE NOTICE 'Inserted into pf_med_branded_medicine, mbme_id: %', + local_mbme_ids[array_length(local_mbme_ids, 1) ]; + + INSERT INTO public.pf_med_branded_medicine ( + mbme_id, mbme_name, mtyp_id, mman_id + ) + VALUES + ( + nextval( + 'pf_med_branded_medicine_mbme_id_seq' :: regclass + ), + 'AVAMYS', + local_mtyp_ids[3], + local_mman_ids[8] + ) RETURNING mbme_id INTO local_mbme_id; + local_mbme_ids := array_append(local_mbme_ids, local_mbme_id); -- local_mbme_ids[9] + RAISE NOTICE 'Inserted into pf_med_branded_medicine, mbme_id: %', + local_mbme_ids[array_length(local_mbme_ids, 1) ]; + + INSERT INTO public.pf_med_branded_medicine ( + mbme_id, mbme_name, mtyp_id, mman_id + ) + VALUES + ( + nextval( + 'pf_med_branded_medicine_mbme_id_seq' :: regclass + ), + 'SIMI SARDIN', + local_mtyp_ids[9], + local_mman_ids[7] + ) RETURNING mbme_id INTO local_mbme_id; + local_mbme_ids := array_append(local_mbme_ids, local_mbme_id); -- local_mbme_ids[10] + RAISE NOTICE 'Inserted into pf_med_branded_medicine, mbme_id: %', + local_mbme_ids[array_length(local_mbme_ids, 1) ]; + + INSERT INTO public.pf_med_branded_medicine ( + mbme_id, mbme_name, mtyp_id, mman_id + ) + VALUES + ( + nextval( + 'pf_med_branded_medicine_mbme_id_seq' :: regclass + ), + 'A RETINOL', + local_mtyp_ids[11], + local_mman_ids[6] + ) RETURNING mbme_id INTO local_mbme_id; + local_mbme_ids := array_append(local_mbme_ids, local_mbme_id); -- local_mbme_ids[11] + RAISE NOTICE 'Inserted into pf_med_branded_medicine, mbme_id: %', + local_mbme_ids[array_length(local_mbme_ids, 1) ]; + + + -- PF_MED_BRANDED_PRESENTATION + + INSERT INTO public.pf_med_branded_presentation (mbpr_id, mbme_id, mbpr_quantity) + VALUES + ( + nextval( + 'pf_med_branded_presentation_mbpr_id_seq' :: regclass + ), + local_mbme_ids[1], + 60 + ) RETURNING mbpr_id INTO local_mbpr_id; + local_mbpr_ids := array_append(local_mbpr_ids, local_mbpr_id); -- local_mbpr_ids[1] + RAISE NOTICE 'Inserted into pf_med_branded_presentation, mbpr_id: %', + local_mbpr_ids[array_length(local_mbpr_ids, 1) ]; + + INSERT INTO public.pf_med_branded_presentation (mbpr_id, mbme_id, mbpr_quantity) + VALUES + ( + nextval( + 'pf_med_branded_presentation_mbpr_id_seq' :: regclass + ), + local_mbme_ids[2], + 120 + ) RETURNING mbpr_id INTO local_mbpr_id; + local_mbpr_ids := array_append(local_mbpr_ids, local_mbpr_id); -- local_mbpr_ids[2] + RAISE NOTICE 'Inserted into pf_med_branded_presentation, mbpr_id: %', + local_mbpr_ids[array_length(local_mbpr_ids, 1) ]; + + INSERT INTO public.pf_med_branded_presentation (mbpr_id, mbme_id, mbpr_quantity) + VALUES + ( + nextval( + 'pf_med_branded_presentation_mbpr_id_seq' :: regclass + ), + local_mbme_ids[3], + 100 + ) RETURNING mbpr_id INTO local_mbpr_id; + local_mbpr_ids := array_append(local_mbpr_ids, local_mbpr_id); -- local_mbpr_ids[3] + RAISE NOTICE 'Inserted into pf_med_branded_presentation, mbpr_id: %', + local_mbpr_ids[array_length(local_mbpr_ids, 1) ]; + + INSERT INTO public.pf_med_branded_presentation (mbpr_id, mbme_id, mbpr_quantity) + VALUES + ( + nextval( + 'pf_med_branded_presentation_mbpr_id_seq' :: regclass + ), + local_mbme_ids[4], + 28 + ) RETURNING mbpr_id INTO local_mbpr_id; + local_mbpr_ids := array_append(local_mbpr_ids, local_mbpr_id); -- local_mbpr_ids[4] + RAISE NOTICE 'Inserted into pf_med_branded_presentation, mbpr_id: %', + local_mbpr_ids[array_length(local_mbpr_ids, 1) ]; + + INSERT INTO public.pf_med_branded_presentation (mbpr_id, mbme_id, mbpr_quantity) + VALUES + ( + nextval( + 'pf_med_branded_presentation_mbpr_id_seq' :: regclass + ), + local_mbme_ids[5], + 30 + ) RETURNING mbpr_id INTO local_mbpr_id; + local_mbpr_ids := array_append(local_mbpr_ids, local_mbpr_id); -- local_mbpr_ids[5] + RAISE NOTICE 'Inserted into pf_med_branded_presentation, mbpr_id: %', + local_mbpr_ids[array_length(local_mbpr_ids, 1) ]; + + INSERT INTO public.pf_med_branded_presentation (mbpr_id, mbme_id, mbpr_quantity) + VALUES + ( + nextval( + 'pf_med_branded_presentation_mbpr_id_seq' :: regclass + ), + local_mbme_ids[6], + 30 + ) RETURNING mbpr_id INTO local_mbpr_id; + local_mbpr_ids := array_append(local_mbpr_ids, local_mbpr_id); -- local_mbpr_ids[6] + RAISE NOTICE 'Inserted into pf_med_branded_presentation, mbpr_id: %', + local_mbpr_ids[array_length(local_mbpr_ids, 1) ]; + + INSERT INTO public.pf_med_branded_presentation (mbpr_id, mbme_id, mbpr_quantity) + VALUES + ( + nextval( + 'pf_med_branded_presentation_mbpr_id_seq' :: regclass + ), + local_mbme_ids[7], + 30 + ) RETURNING mbpr_id INTO local_mbpr_id; + local_mbpr_ids := array_append(local_mbpr_ids, local_mbpr_id); -- local_mbpr_ids[7] + RAISE NOTICE 'Inserted into pf_med_branded_presentation, mbpr_id: %', + local_mbpr_ids[array_length(local_mbpr_ids, 1) ]; + + INSERT INTO public.pf_med_branded_presentation (mbpr_id, mbme_id, mbpr_quantity) + VALUES + ( + nextval( + 'pf_med_branded_presentation_mbpr_id_seq' :: regclass + ), + local_mbme_ids[8], + 60 + ) RETURNING mbpr_id INTO local_mbpr_id; + local_mbpr_ids := array_append(local_mbpr_ids, local_mbpr_id); -- local_mbpr_ids[8] + RAISE NOTICE 'Inserted into pf_med_branded_presentation, mbpr_id: %', + local_mbpr_ids[array_length(local_mbpr_ids, 1) ]; + + INSERT INTO public.pf_med_branded_presentation (mbpr_id, mbme_id, mbpr_quantity) + VALUES + ( + nextval( + 'pf_med_branded_presentation_mbpr_id_seq' :: regclass + ), + local_mbme_ids[9], + 120 + ) RETURNING mbpr_id INTO local_mbpr_id; + local_mbpr_ids := array_append(local_mbpr_ids, local_mbpr_id); -- local_mbpr_ids[9] + RAISE NOTICE 'Inserted into pf_med_branded_presentation, mbpr_id: %', + local_mbpr_ids[array_length(local_mbpr_ids, 1) ]; + + INSERT INTO public.pf_med_branded_presentation (mbpr_id, mbme_id, mbpr_quantity) + VALUES + ( + nextval( + 'pf_med_branded_presentation_mbpr_id_seq' :: regclass + ), + local_mbme_ids[10], + 90 + ) RETURNING mbpr_id INTO local_mbpr_id; + local_mbpr_ids := array_append(local_mbpr_ids, local_mbpr_id); -- local_mbpr_ids[10] + RAISE NOTICE 'Inserted into pf_med_branded_presentation, mbpr_id: %', + local_mbpr_ids[array_length(local_mbpr_ids, 1) ]; + + INSERT INTO public.pf_med_branded_presentation (mbpr_id, mbme_id, mbpr_quantity) + VALUES + ( + nextval( + 'pf_med_branded_presentation_mbpr_id_seq' :: regclass + ), + local_mbme_ids[11], + 60 + ) RETURNING mbpr_id INTO local_mbpr_id; + local_mbpr_ids := array_append(local_mbpr_ids, local_mbpr_id); -- local_mbpr_ids[11] + RAISE NOTICE 'Inserted into pf_med_branded_presentation, mbpr_id: %', + local_mbpr_ids[array_length(local_mbpr_ids, 1) ]; + + + -- PF_MED_COMPONENT + + INSERT INTO public.pf_med_component ( + mcomp_id, mcomp_grams, msub_id, mbpr_id + ) + VALUES + ( + nextval( + 'pf_med_component_mcomp_id_seq' :: regclass + ), + 0.15, + local_msub_ids[1], + local_mbpr_ids[1] + ) RETURNING mcomp_id INTO local_mcomp_id; + local_mcomp_ids := array_append(local_mcomp_ids, local_mcomp_id); -- local_mcomp_ids[1] + RAISE NOTICE 'Inserted into pf_med_component, mcomp_id: %', + local_mcomp_ids[array_length(local_mcomp_ids, 1) ]; + + INSERT INTO public.pf_med_component ( + mcomp_id, mcomp_grams, msub_id, mbpr_id + ) + VALUES + ( + nextval( + 'pf_med_component_mcomp_id_seq' :: regclass + ), + 0.15, + local_msub_ids[2], + local_mbpr_ids[1] + ) RETURNING mcomp_id INTO local_mcomp_id; + local_mcomp_ids := array_append(local_mcomp_ids, local_mcomp_id); -- local_mcomp_ids[2] + RAISE NOTICE 'Inserted into pf_med_component, mcomp_id: %', + local_mcomp_ids[array_length(local_mcomp_ids, 1) ]; + + INSERT INTO public.pf_med_component ( + mcomp_id, mcomp_grams, msub_id, mbpr_id + ) + VALUES + ( + nextval( + 'pf_med_component_mcomp_id_seq' :: regclass + ), + 0.1, + local_msub_ids[3], + local_mbpr_ids[1] + ) RETURNING mcomp_id INTO local_mcomp_id; + local_mcomp_ids := array_append(local_mcomp_ids, local_mcomp_id); -- local_mcomp_ids[3] + RAISE NOTICE 'Inserted into pf_med_component, mcomp_id: %', + local_mcomp_ids[array_length(local_mcomp_ids, 1) ]; + + INSERT INTO public.pf_med_component ( + mcomp_id, mcomp_grams, msub_id, mbpr_id + ) + VALUES + ( + nextval( + 'pf_med_component_mcomp_id_seq' :: regclass + ), + 0.05, + local_msub_ids[4], + local_mbpr_ids[1] + ) RETURNING mcomp_id INTO local_mcomp_id; + local_mcomp_ids := array_append(local_mcomp_ids, local_mcomp_id); -- local_mcomp_ids[4] + RAISE NOTICE 'Inserted into pf_med_component, mcomp_id: %', + local_mcomp_ids[array_length(local_mcomp_ids, 1) ]; + + INSERT INTO public.pf_med_component ( + mcomp_id, mcomp_grams, msub_id, mbpr_id + ) + VALUES + ( + nextval( + 'pf_med_component_mcomp_id_seq' :: regclass + ), + 4, + local_msub_ids[5], + local_mbpr_ids[2] + ) RETURNING mcomp_id INTO local_mcomp_id; + local_mcomp_ids := array_append(local_mcomp_ids, local_mcomp_id); -- local_mcomp_ids[5] + RAISE NOTICE 'Inserted into pf_med_component, mcomp_id: %', + local_mcomp_ids[array_length(local_mcomp_ids, 1) ]; + + INSERT INTO public.pf_med_component ( + mcomp_id, mcomp_grams, msub_id, mbpr_id + ) + VALUES + ( + nextval( + 'pf_med_component_mcomp_id_seq' :: regclass + ), + 0.2, + local_msub_ids[6], + local_mbpr_ids[2] + ) RETURNING mcomp_id INTO local_mcomp_id; + local_mcomp_ids := array_append(local_mcomp_ids, local_mcomp_id); -- local_mcomp_ids[6] + RAISE NOTICE 'Inserted into pf_med_component, mcomp_id: %', + local_mcomp_ids[array_length(local_mcomp_ids, 1) ]; + + INSERT INTO public.pf_med_component ( + mcomp_id, mcomp_grams, msub_id, mbpr_id + ) + VALUES + ( + nextval( + 'pf_med_component_mcomp_id_seq' :: regclass + ), + 0.00002, + local_msub_ids[7], + local_mbpr_ids[2] + ) RETURNING mcomp_id INTO local_mcomp_id; + local_mcomp_ids := array_append(local_mcomp_ids, local_mcomp_id); -- local_mcomp_ids[7] + RAISE NOTICE 'Inserted into pf_med_component, mcomp_id: %', + local_mcomp_ids[array_length(local_mcomp_ids, 1) ]; + + INSERT INTO public.pf_med_component ( + mcomp_id, mcomp_grams, msub_id, mbpr_id + ) + VALUES + ( + nextval( + 'pf_med_component_mcomp_id_seq' :: regclass + ), + 0.15, + local_msub_ids[6], + local_mbpr_ids[3] + ) RETURNING mcomp_id INTO local_mcomp_id; + local_mcomp_ids := array_append(local_mcomp_ids, local_mcomp_id); -- local_mcomp_ids[8] + RAISE NOTICE 'Inserted into pf_med_component, mcomp_id: %', + local_mcomp_ids[array_length(local_mcomp_ids, 1) ]; + + INSERT INTO public.pf_med_component ( + mcomp_id, mcomp_grams, msub_id, mbpr_id + ) + VALUES + ( + nextval( + 'pf_med_component_mcomp_id_seq' :: regclass + ), + 0.0045, + local_msub_ids[8], + local_mbpr_ids[3] + ) RETURNING mcomp_id INTO local_mcomp_id; + local_mcomp_ids := array_append(local_mcomp_ids, local_mcomp_id); -- local_mcomp_ids[9] + RAISE NOTICE 'Inserted into pf_med_component, mcomp_id: %', + local_mcomp_ids[array_length(local_mcomp_ids, 1) ]; + + INSERT INTO public.pf_med_component ( + mcomp_id, mcomp_grams, msub_id, mbpr_id + ) + VALUES + ( + nextval( + 'pf_med_component_mcomp_id_seq' :: regclass + ), + 0.000125, + local_msub_ids[9], + local_mbpr_ids[3] + ) RETURNING mcomp_id INTO local_mcomp_id; + local_mcomp_ids := array_append(local_mcomp_ids, local_mcomp_id); -- local_mcomp_ids[10] + RAISE NOTICE 'Inserted into pf_med_component, mcomp_id: %', + local_mcomp_ids[array_length(local_mcomp_ids, 1) ]; + + INSERT INTO public.pf_med_component ( + mcomp_id, mcomp_grams, msub_id, mbpr_id + ) + VALUES + ( + nextval( + 'pf_med_component_mcomp_id_seq' :: regclass + ), + 0.000025, + local_msub_ids[10], + local_mbpr_ids[3] + ) RETURNING mcomp_id INTO local_mcomp_id; + local_mcomp_ids := array_append(local_mcomp_ids, local_mcomp_id); -- local_mcomp_ids[11] + RAISE NOTICE 'Inserted into pf_med_component, mcomp_id: %', + local_mcomp_ids[array_length(local_mcomp_ids, 1) ]; + + INSERT INTO public.pf_med_component ( + mcomp_id, mcomp_grams, msub_id, mbpr_id + ) + VALUES + ( + nextval( + 'pf_med_component_mcomp_id_seq' :: regclass + ), + 0.0002, + local_msub_ids[11], + local_mbpr_ids[3] + ) RETURNING mcomp_id INTO local_mcomp_id; + local_mcomp_ids := array_append(local_mcomp_ids, local_mcomp_id); -- local_mcomp_ids[12] + RAISE NOTICE 'Inserted into pf_med_component, mcomp_id: %', + local_mcomp_ids[array_length(local_mcomp_ids, 1) ]; + + INSERT INTO public.pf_med_component ( + mcomp_id, mcomp_grams, msub_id, mbpr_id + ) + VALUES + ( + nextval( + 'pf_med_component_mcomp_id_seq' :: regclass + ), + 0.000075, + local_msub_ids[12], + local_mbpr_ids[3] + ) RETURNING mcomp_id INTO local_mcomp_id; + local_mcomp_ids := array_append(local_mcomp_ids, local_mcomp_id); -- local_mcomp_ids[13] + RAISE NOTICE 'Inserted into pf_med_component, mcomp_id: %', + local_mcomp_ids[array_length(local_mcomp_ids, 1) ]; + + INSERT INTO public.pf_med_component ( + mcomp_id, mcomp_grams, msub_id, mbpr_id + ) + VALUES + ( + nextval( + 'pf_med_component_mcomp_id_seq' :: regclass + ), + 0.04, + local_msub_ids[13], + local_mbpr_ids[3] + ) RETURNING mcomp_id INTO local_mcomp_id; + local_mcomp_ids := array_append(local_mcomp_ids, local_mcomp_id); -- local_mcomp_ids[14] + RAISE NOTICE 'Inserted into pf_med_component, mcomp_id: %', + local_mcomp_ids[array_length(local_mcomp_ids, 1) ]; + + INSERT INTO public.pf_med_component ( + mcomp_id, mcomp_grams, msub_id, mbpr_id + ) + VALUES + ( + nextval( + 'pf_med_component_mcomp_id_seq' :: regclass + ), + 0.05, + local_msub_ids[14], + local_mbpr_ids[3] + ) RETURNING mcomp_id INTO local_mcomp_id; + local_mcomp_ids := array_append(local_mcomp_ids, local_mcomp_id); -- local_mcomp_ids[15] + RAISE NOTICE 'Inserted into pf_med_component, mcomp_id: %', + local_mcomp_ids[array_length(local_mcomp_ids, 1) ]; + + INSERT INTO public.pf_med_component ( + mcomp_id, mcomp_grams, msub_id, mbpr_id + ) + VALUES + ( + nextval( + 'pf_med_component_mcomp_id_seq' :: regclass + ), + 0.0025, + local_msub_ids[15], + local_mbpr_ids[3] + ) RETURNING mcomp_id INTO local_mcomp_id; + local_mcomp_ids := array_append(local_mcomp_ids, local_mcomp_id); -- local_mcomp_ids[16] + RAISE NOTICE 'Inserted into pf_med_component, mcomp_id: %', + local_mcomp_ids[array_length(local_mcomp_ids, 1) ]; + + INSERT INTO public.pf_med_component ( + mcomp_id, mcomp_grams, msub_id, mbpr_id + ) + VALUES + ( + nextval( + 'pf_med_component_mcomp_id_seq' :: regclass + ), + 0.015, + local_msub_ids[16], + local_mbpr_ids[3] + ) RETURNING mcomp_id INTO local_mcomp_id; + local_mcomp_ids := array_append(local_mcomp_ids, local_mcomp_id); -- local_mcomp_ids[17] + RAISE NOTICE 'Inserted into pf_med_component, mcomp_id: %', + local_mcomp_ids[array_length(local_mcomp_ids, 1) ]; + + INSERT INTO public.pf_med_component ( + mcomp_id, mcomp_grams, msub_id, mbpr_id + ) + VALUES + ( + nextval( + 'pf_med_component_mcomp_id_seq' :: regclass + ), + 0.106, + local_msub_ids[17], + local_mbpr_ids[3] + ) RETURNING mcomp_id INTO local_mcomp_id; + local_mcomp_ids := array_append(local_mcomp_ids, local_mcomp_id); -- local_mcomp_ids[18] + RAISE NOTICE 'Inserted into pf_med_component, mcomp_id: %', + local_mcomp_ids[array_length(local_mcomp_ids, 1) ]; + + INSERT INTO public.pf_med_component ( + mcomp_id, mcomp_grams, msub_id, mbpr_id + ) + VALUES + ( + nextval( + 'pf_med_component_mcomp_id_seq' :: regclass + ), + 0.00005, + local_msub_ids[18], + local_mbpr_ids[3] + ) RETURNING mcomp_id INTO local_mcomp_id; + local_mcomp_ids := array_append(local_mcomp_ids, local_mcomp_id); -- local_mcomp_ids[19] + RAISE NOTICE 'Inserted into pf_med_component, mcomp_id: %', + local_mcomp_ids[array_length(local_mcomp_ids, 1) ]; + + INSERT INTO public.pf_med_component ( + mcomp_id, mcomp_grams, msub_id, mbpr_id + ) + VALUES + ( + nextval( + 'pf_med_component_mcomp_id_seq' :: regclass + ), + 0.006, + local_msub_ids[19], + local_mbpr_ids[3] + ) RETURNING mcomp_id INTO local_mcomp_id; + local_mcomp_ids := array_append(local_mcomp_ids, local_mcomp_id); -- local_mcomp_ids[20] + RAISE NOTICE 'Inserted into pf_med_component, mcomp_id: %', + local_mcomp_ids[array_length(local_mcomp_ids, 1) ]; + + INSERT INTO public.pf_med_component ( + mcomp_id, mcomp_grams, msub_id, mbpr_id + ) + VALUES + ( + nextval( + 'pf_med_component_mcomp_id_seq' :: regclass + ), + 0.000012, + local_msub_ids[20], + local_mbpr_ids[3] + ) RETURNING mcomp_id INTO local_mcomp_id; + local_mcomp_ids := array_append(local_mcomp_ids, local_mcomp_id); -- local_mcomp_ids[21] + RAISE NOTICE 'Inserted into pf_med_component, mcomp_id: %', + local_mcomp_ids[array_length(local_mcomp_ids, 1) ]; + + INSERT INTO public.pf_med_component ( + mcomp_id, mcomp_grams, msub_id, mbpr_id + ) + VALUES + ( + nextval( + 'pf_med_component_mcomp_id_seq' :: regclass + ), + 0.006, + local_msub_ids[21], + local_mbpr_ids[3] + ) RETURNING mcomp_id INTO local_mcomp_id; + local_mcomp_ids := array_append(local_mcomp_ids, local_mcomp_id); -- local_mcomp_ids[22] + RAISE NOTICE 'Inserted into pf_med_component, mcomp_id: %', + local_mcomp_ids[array_length(local_mcomp_ids, 1) ]; + + INSERT INTO public.pf_med_component ( + mcomp_id, mcomp_grams, msub_id, mbpr_id + ) + VALUES + ( + nextval( + 'pf_med_component_mcomp_id_seq' :: regclass + ), + 0.015, + local_msub_ids[22], + local_mbpr_ids[3] + ) RETURNING mcomp_id INTO local_mcomp_id; + local_mcomp_ids := array_append(local_mcomp_ids, local_mcomp_id); -- local_mcomp_ids[23] + RAISE NOTICE 'Inserted into pf_med_component, mcomp_id: %', + local_mcomp_ids[array_length(local_mcomp_ids, 1) ]; + + INSERT INTO public.pf_med_component ( + mcomp_id, mcomp_grams, msub_id, mbpr_id + ) + VALUES + ( + nextval( + 'pf_med_component_mcomp_id_seq' :: regclass + ), + 0.015, + local_msub_ids[23], + local_mbpr_ids[3] + ) RETURNING mcomp_id INTO local_mcomp_id; + local_mcomp_ids := array_append(local_mcomp_ids, local_mcomp_id); -- local_mcomp_ids[24] + RAISE NOTICE 'Inserted into pf_med_component, mcomp_id: %', + local_mcomp_ids[array_length(local_mcomp_ids, 1) ]; + + INSERT INTO public.pf_med_component ( + mcomp_id, mcomp_grams, msub_id, mbpr_id + ) + VALUES + ( + nextval( + 'pf_med_component_mcomp_id_seq' :: regclass + ), + 0.0000025, + local_msub_ids[24], + local_mbpr_ids[3] + ) RETURNING mcomp_id INTO local_mcomp_id; + local_mcomp_ids := array_append(local_mcomp_ids, local_mcomp_id); -- local_mcomp_ids[25] + RAISE NOTICE 'Inserted into pf_med_component, mcomp_id: %', + local_mcomp_ids[array_length(local_mcomp_ids, 1) ]; + + INSERT INTO public.pf_med_component ( + mcomp_id, mcomp_grams, msub_id, mbpr_id + ) + VALUES + ( + nextval( + 'pf_med_component_mcomp_id_seq' :: regclass + ), + 0.033, + local_msub_ids[25], + local_mbpr_ids[3] + ) RETURNING mcomp_id INTO local_mcomp_id; + local_mcomp_ids := array_append(local_mcomp_ids, local_mcomp_id); -- local_mcomp_ids[26] + RAISE NOTICE 'Inserted into pf_med_component, mcomp_id: %', + local_mcomp_ids[array_length(local_mcomp_ids, 1) ]; + + INSERT INTO public.pf_med_component ( + mcomp_id, mcomp_grams, msub_id, mbpr_id + ) + VALUES + ( + nextval( + 'pf_med_component_mcomp_id_seq' :: regclass + ), + 0.000038, + local_msub_ids[26], + local_mbpr_ids[3] + ) RETURNING mcomp_id INTO local_mcomp_id; + local_mcomp_ids := array_append(local_mcomp_ids, local_mcomp_id); -- local_mcomp_ids[27] + RAISE NOTICE 'Inserted into pf_med_component, mcomp_id: %', + local_mcomp_ids[array_length(local_mcomp_ids, 1) ]; + + INSERT INTO public.pf_med_component ( + mcomp_id, mcomp_grams, msub_id, mbpr_id + ) + VALUES + ( + nextval( + 'pf_med_component_mcomp_id_seq' :: regclass + ), + 0.02, + local_msub_ids[27], + local_mbpr_ids[3] + ) RETURNING mcomp_id INTO local_mcomp_id; + local_mcomp_ids := array_append(local_mcomp_ids, local_mcomp_id); -- local_mcomp_ids[28] + RAISE NOTICE 'Inserted into pf_med_component, mcomp_id: %', + local_mcomp_ids[array_length(local_mcomp_ids, 1) ]; + + INSERT INTO public.pf_med_component ( + mcomp_id, mcomp_grams, msub_id, mbpr_id + ) + VALUES + ( + nextval( + 'pf_med_component_mcomp_id_seq' :: regclass + ), + 0.01, + local_msub_ids[28], + local_mbpr_ids[4] + ) RETURNING mcomp_id INTO local_mcomp_id; + local_mcomp_ids := array_append(local_mcomp_ids, local_mcomp_id); -- local_mcomp_ids[29] + RAISE NOTICE 'Inserted into pf_med_component, mcomp_id: %', + local_mcomp_ids[array_length(local_mcomp_ids, 1) ]; + + INSERT INTO public.pf_med_component ( + mcomp_id, mcomp_grams, msub_id, mbpr_id + ) + VALUES + ( + nextval( + 'pf_med_component_mcomp_id_seq' :: regclass + ), + 0.01, + local_msub_ids[29], + local_mbpr_ids[5] + ) RETURNING mcomp_id INTO local_mcomp_id; + local_mcomp_ids := array_append(local_mcomp_ids, local_mcomp_id); -- local_mcomp_ids[30] + RAISE NOTICE 'Inserted into pf_med_component, mcomp_id: %', + local_mcomp_ids[array_length(local_mcomp_ids, 1) ]; + + INSERT INTO public.pf_med_component ( + mcomp_id, mcomp_grams, msub_id, mbpr_id + ) + VALUES + ( + nextval( + 'pf_med_component_mcomp_id_seq' :: regclass + ), + 0.01, + local_msub_ids[30], + local_mbpr_ids[6] + ) RETURNING mcomp_id INTO local_mcomp_id; + local_mcomp_ids := array_append(local_mcomp_ids, local_mcomp_id); -- local_mcomp_ids[31] + RAISE NOTICE 'Inserted into pf_med_component, mcomp_id: %', + local_mcomp_ids[array_length(local_mcomp_ids, 1) ]; + + INSERT INTO public.pf_med_component ( + mcomp_id, mcomp_grams, msub_id, mbpr_id + ) + VALUES + ( + nextval( + 'pf_med_component_mcomp_id_seq' :: regclass + ), + 0.003, + local_msub_ids[31], + local_mbpr_ids[7] + ) RETURNING mcomp_id INTO local_mcomp_id; + local_mcomp_ids := array_append(local_mcomp_ids, local_mcomp_id); -- local_mcomp_ids[32] + RAISE NOTICE 'Inserted into pf_med_component, mcomp_id: %', + local_mcomp_ids[array_length(local_mcomp_ids, 1) ]; + + INSERT INTO public.pf_med_component ( + mcomp_id, mcomp_grams, msub_id, mbpr_id + ) + VALUES + ( + nextval( + 'pf_med_component_mcomp_id_seq' :: regclass + ), + 0.001, + local_msub_ids[32], + local_mbpr_ids[7] + ) RETURNING mcomp_id INTO local_mcomp_id; + local_mcomp_ids := array_append(local_mcomp_ids, local_mcomp_id); -- local_mcomp_ids[33] + RAISE NOTICE 'Inserted into pf_med_component, mcomp_id: %', + local_mcomp_ids[array_length(local_mcomp_ids, 1) ]; + + INSERT INTO public.pf_med_component ( + mcomp_id, mcomp_grams, msub_id, mbpr_id + ) + VALUES + ( + nextval( + 'pf_med_component_mcomp_id_seq' :: regclass + ), + 0.001, + local_msub_ids[33], + local_mbpr_ids[8] + ) RETURNING mcomp_id INTO local_mcomp_id; + local_mcomp_ids := array_append(local_mcomp_ids, local_mcomp_id); -- local_mcomp_ids[34] + RAISE NOTICE 'Inserted into pf_med_component, mcomp_id: %', + local_mcomp_ids[array_length(local_mcomp_ids, 1) ]; + + INSERT INTO public.pf_med_component ( + mcomp_id, mcomp_grams, msub_id, mbpr_id + ) + VALUES + ( + nextval( + 'pf_med_component_mcomp_id_seq' :: regclass + ), + 0.0000275, + local_msub_ids[34], + local_mbpr_ids[9] + ) RETURNING mcomp_id INTO local_mcomp_id; + local_mcomp_ids := array_append(local_mcomp_ids, local_mcomp_id); -- local_mcomp_ids[35] + RAISE NOTICE 'Inserted into pf_med_component, mcomp_id: %', + local_mcomp_ids[array_length(local_mcomp_ids, 1) ]; + + INSERT INTO public.pf_med_component ( + mcomp_id, mcomp_grams, msub_id, mbpr_id + ) + VALUES + ( + nextval( + 'pf_med_component_mcomp_id_seq' :: regclass + ), + 2.92, + local_msub_ids[36], + local_mbpr_ids[10] + ) RETURNING mcomp_id INTO local_mcomp_id; + local_mcomp_ids := array_append(local_mcomp_ids, local_mcomp_id); -- local_mcomp_ids[36] + RAISE NOTICE 'Inserted into pf_med_component, mcomp_id: %', + local_mcomp_ids[array_length(local_mcomp_ids, 1) ]; + + INSERT INTO public.pf_med_component ( + mcomp_id, mcomp_grams, msub_id, mbpr_id + ) + VALUES + ( + nextval( + 'pf_med_component_mcomp_id_seq' :: regclass + ), + 0.001, + local_msub_ids[35], + local_mbpr_ids[11] + ) RETURNING mcomp_id INTO local_mcomp_id; + local_mcomp_ids := array_append(local_mcomp_ids, local_mcomp_id); -- local_mcomp_ids[37] + RAISE NOTICE 'Inserted into pf_med_component, mcomp_id: %', + local_mcomp_ids[array_length(local_mcomp_ids, 1) ]; + + + -- PF_MED_FRECUENCY + + INSERT INTO public.pf_med_frecuency ( + mfre_id, mfre_quantity, mfre_every_hours + ) + VALUES + ( + nextval( + 'pf_med_frecuency_mfre_id_seq' :: regclass + ), + 1, + 24 + ) RETURNING mfre_id INTO local_mfre_id; + local_mfre_ids := array_append(local_mfre_ids, local_mfre_id); -- local_mfre_ids[1] + RAISE NOTICE 'Inserted into pf_med_frecuency, mfre_id: %', + local_mfre_ids[array_length(local_mfre_ids, 1) ]; + + INSERT INTO public.pf_med_frecuency ( + mfre_id, mfre_quantity, mfre_every_hours + ) + VALUES + ( + nextval( + 'pf_med_frecuency_mfre_id_seq' :: regclass + ), + 2, + 24 + ) RETURNING mfre_id INTO local_mfre_id; + local_mfre_ids := array_append(local_mfre_ids, local_mfre_id); -- local_mfre_ids[2] + RAISE NOTICE 'Inserted into pf_med_frecuency, mfre_id: %', + local_mfre_ids[array_length(local_mfre_ids, 1) ]; + + INSERT INTO public.pf_med_frecuency ( + mfre_id, mfre_quantity, mfre_every_hours + ) + VALUES + ( + nextval( + 'pf_med_frecuency_mfre_id_seq' :: regclass + ), + 4, + 24 + ) RETURNING mfre_id INTO local_mfre_id; + local_mfre_ids := array_append(local_mfre_ids, local_mfre_id); -- local_mfre_ids[3] + RAISE NOTICE 'Inserted into pf_med_frecuency, mfre_id: %', + local_mfre_ids[array_length(local_mfre_ids, 1) ]; + + + -- PF_MED_PRESCRIPTION + + INSERT INTO public.pf_med_prescription ( + mpre_id, mtyp_id, mfre_id, mpre_active, + mpre_is_self_medicated, mpre_date, + user_id + ) + VALUES + ( + nextval( + 'pf_med_prescription_mpre_id_seq' :: regclass + ), + local_mtyp_ids[10], + local_mfre_ids[1], + true, + true, + CURRENT_TIMESTAMP, + local_user_id + ) RETURNING mpre_id INTO local_mpre_id; + local_mpre_ids := array_append(local_mpre_ids, local_mpre_id); -- local_mpre_ids[1] + RAISE NOTICE 'Inserted into pf_med_prescription, mpre_id: %', + local_mpre_ids[array_length(local_mpre_ids, 1) ]; + + INSERT INTO public.pf_med_prescription ( + mpre_id, mtyp_id, mfre_id, mpre_active, + mpre_is_self_medicated, mpre_date, + user_id + ) + VALUES + ( + nextval( + 'pf_med_prescription_mpre_id_seq' :: regclass + ), + local_mtyp_ids[2], + local_mfre_ids[1], + true, + true, + CURRENT_TIMESTAMP, + local_user_id + ) RETURNING mpre_id INTO local_mpre_id; + local_mpre_ids := array_append(local_mpre_ids, local_mpre_id); -- local_mpre_ids[2] + RAISE NOTICE 'Inserted into pf_med_prescription, mpre_id: %', + local_mpre_ids[array_length(local_mpre_ids, 1) ]; + + INSERT INTO public.pf_med_prescription ( + mpre_id, mtyp_id, mfre_id, mpre_active, + mpre_is_self_medicated, mpre_date, + user_id + ) + VALUES + ( + nextval( + 'pf_med_prescription_mpre_id_seq' :: regclass + ), + local_mtyp_ids[8], + local_mfre_ids[1], + true, + true, + CURRENT_TIMESTAMP, + local_user_id + ) RETURNING mpre_id INTO local_mpre_id; + local_mpre_ids := array_append(local_mpre_ids, local_mpre_id); -- local_mpre_ids[3] + RAISE NOTICE 'Inserted into pf_med_prescription, mpre_id: %', + local_mpre_ids[array_length(local_mpre_ids, 1) ]; + + INSERT INTO public.pf_med_prescription ( + mpre_id, mtyp_id, mfre_id, mpre_active, + mpre_is_self_medicated, mpre_date, + user_id + ) + VALUES + ( + nextval( + 'pf_med_prescription_mpre_id_seq' :: regclass + ), + local_mtyp_ids[1], + local_mfre_ids[1], + true, + true, + CURRENT_TIMESTAMP, + local_user_id + ) RETURNING mpre_id INTO local_mpre_id; + local_mpre_ids := array_append(local_mpre_ids, local_mpre_id); -- local_mpre_ids[4] + RAISE NOTICE 'Inserted into pf_med_prescription, mpre_id: %', + local_mpre_ids[array_length(local_mpre_ids, 1) ]; + + INSERT INTO public.pf_med_prescription ( + mpre_id, mtyp_id, mfre_id, mpre_active, + mpre_is_self_medicated, mpre_date, + user_id + ) + VALUES + ( + nextval( + 'pf_med_prescription_mpre_id_seq' :: regclass + ), + local_mtyp_ids[5], + local_mfre_ids[1], + true, + true, + CURRENT_TIMESTAMP, + local_user_id + ) RETURNING mpre_id INTO local_mpre_id; + local_mpre_ids := array_append(local_mpre_ids, local_mpre_id); -- local_mpre_ids[5] + RAISE NOTICE 'Inserted into pf_med_prescription, mpre_id: %', + local_mpre_ids[array_length(local_mpre_ids, 1) ]; + + INSERT INTO public.pf_med_prescription ( + mpre_id, mtyp_id, mfre_id, mpre_active, + mpre_is_self_medicated, mpre_date, + user_id + ) + VALUES + ( + nextval( + 'pf_med_prescription_mpre_id_seq' :: regclass + ), + local_mtyp_ids[6], + local_mfre_ids[1], + true, + true, + CURRENT_TIMESTAMP, + local_user_id + ) RETURNING mpre_id INTO local_mpre_id; + local_mpre_ids := array_append(local_mpre_ids, local_mpre_id); -- local_mpre_ids[6] + RAISE NOTICE 'Inserted into pf_med_prescription, mpre_id: %', + local_mpre_ids[array_length(local_mpre_ids, 1) ]; + + INSERT INTO public.pf_med_prescription ( + mpre_id, mtyp_id, mfre_id, mpre_active, + mpre_is_self_medicated, mpre_date, + user_id + ) + VALUES + ( + nextval( + 'pf_med_prescription_mpre_id_seq' :: regclass + ), + local_mtyp_ids[7], + local_mfre_ids[1], + true, + true, + CURRENT_TIMESTAMP, + local_user_id + ) RETURNING mpre_id INTO local_mpre_id; + local_mpre_ids := array_append(local_mpre_ids, local_mpre_id); -- local_mpre_ids[7] + RAISE NOTICE 'Inserted into pf_med_prescription, mpre_id: %', + local_mpre_ids[array_length(local_mpre_ids, 1) ]; + + INSERT INTO public.pf_med_prescription ( + mpre_id, mtyp_id, mfre_id, mpre_active, + mpre_is_self_medicated, mpre_date, + user_id + ) + VALUES + ( + nextval( + 'pf_med_prescription_mpre_id_seq' :: regclass + ), + local_mtyp_ids[4], + local_mfre_ids[1], + true, + true, + CURRENT_TIMESTAMP, + local_user_id + ) RETURNING mpre_id INTO local_mpre_id; + local_mpre_ids := array_append(local_mpre_ids, local_mpre_id); -- local_mpre_ids[8] + RAISE NOTICE 'Inserted into pf_med_prescription, mpre_id: %', + local_mpre_ids[array_length(local_mpre_ids, 1) ]; + + INSERT INTO public.pf_med_prescription ( + mpre_id, mtyp_id, mfre_id, mpre_active, + mpre_is_self_medicated, mpre_date, + user_id + ) + VALUES + ( + nextval( + 'pf_med_prescription_mpre_id_seq' :: regclass + ), + local_mtyp_ids[3], + local_mfre_ids[3], + true, + true, + CURRENT_TIMESTAMP, + local_user_id + ) RETURNING mpre_id INTO local_mpre_id; + local_mpre_ids := array_append(local_mpre_ids, local_mpre_id); -- local_mpre_ids[9] + RAISE NOTICE 'Inserted into pf_med_prescription, mpre_id: %', + local_mpre_ids[array_length(local_mpre_ids, 1) ]; + + INSERT INTO public.pf_med_prescription ( + mpre_id, mtyp_id, mfre_id, mpre_active, + mpre_is_self_medicated, mpre_date, + user_id + ) + VALUES + ( + nextval( + 'pf_med_prescription_mpre_id_seq' :: regclass + ), + local_mtyp_ids[9], + local_mfre_ids[2], + true, + true, + CURRENT_TIMESTAMP, + local_user_id + ) RETURNING mpre_id INTO local_mpre_id; + local_mpre_ids := array_append(local_mpre_ids, local_mpre_id); -- local_mpre_ids[10] + RAISE NOTICE 'Inserted into pf_med_prescription, mpre_id: %', + local_mpre_ids[array_length(local_mpre_ids, 1) ]; + + INSERT INTO public.pf_med_prescription ( + mpre_id, mtyp_id, mfre_id, mpre_active, + mpre_is_self_medicated, mpre_date, + user_id + ) + VALUES + ( + nextval( + 'pf_med_prescription_mpre_id_seq' :: regclass + ), + local_mtyp_ids[11], + local_mfre_ids[1], + true, + true, + CURRENT_TIMESTAMP, + local_user_id + ) RETURNING mpre_id INTO local_mpre_id; + local_mpre_ids := array_append(local_mpre_ids, local_mpre_id); -- local_mpre_ids[11] + RAISE NOTICE 'Inserted into pf_med_prescription, mpre_id: %', + local_mpre_ids[array_length(local_mpre_ids, 1) ]; + + +END $$; +COMMIT; diff --git a/package.json b/package.json index df198f1..2d21636 100644 --- a/package.json +++ b/package.json @@ -60,16 +60,19 @@ "@types/humanize-duration": "^3.27.4", "@types/jest": "^29.5.11", "@types/node": "^20.11.6", + "@types/pg": "^8.11.6", "@types/swagger-ui-express": "^4.1.6", "@types/uuid": "^9.0.7", "@types/yamljs": "^0.2.34", "body-parser": "^1.20.2", "dotenv": "^16.4.1", "express": "^4.18.2", + "fs": "^0.0.1-security", "helmet": "^7.1.0", "humanize-duration": "^3.31.0", "jest": "^29.7.0", "path": "^0.12.7", + "pg": "^8.11.5", "swagger-ui-express": "^5.0.0", "ts-jest": "^29.1.2", "uuid": "^9.0.1", diff --git a/src/domain/model/activeComponentsByUnit.model.ts b/src/domain/model/activeComponentsByUnit.model.ts new file mode 100644 index 0000000..3ed82b0 --- /dev/null +++ b/src/domain/model/activeComponentsByUnit.model.ts @@ -0,0 +1,35 @@ +import { Domain as DomainError } from '../error/domain.error'; +import { Substance as SubstanceModel } from './substance.model'; +export class ActiveComponentByUnit { + private _grams!: number; + private _substance!: SubstanceModel; + constructor(grams: number, substance: SubstanceModel) { + this.grams = grams; + this.substance = substance; + } + public get grams(): number { + return this._grams; + } + public set grams(value: number) { + if (value <= 0) + throw new DomainError( + 'Active component by unit grams cannot be less or equal than zero' + ); + this._grams = value; + } + public get substance(): SubstanceModel { + return this._substance; + } + public set substance(value: SubstanceModel) { + this._substance = value; + } + public json(): { + grams: number; + substance: any; + } { + return { + grams: this.grams, + substance: this.substance.json() + }; + } +} diff --git a/src/domain/model/brandedMedicine.model.ts b/src/domain/model/brandedMedicine.model.ts new file mode 100644 index 0000000..f33958d --- /dev/null +++ b/src/domain/model/brandedMedicine.model.ts @@ -0,0 +1,67 @@ +import { Domain as DomainError } from '../error/domain.error'; +import { Converter as ConverterUtil } from '../util/converter.util'; +import { Manufacturer as ManufacturerModel } from './manufacturer.model'; +import { Type as TypeModel } from './type.model'; +export class BrandedMedicine { + private _id!: number | undefined; + private _name!: string; + private _type!: TypeModel; + private _manufacturer!: ManufacturerModel; + constructor( + id: number | string | undefined | null, + name: string, + type: TypeModel, + manufacturer: ManufacturerModel + ) { + this.id = id; + this.name = name; + this.type = type; + this.manufacturer = manufacturer; + } + public get id(): number | undefined { + return this._id; + } + public set id(value: number | string | undefined | null) { + try { + this._id = ConverterUtil.toNumber(value); + } catch (error) { + if (error instanceof Error) { + throw new DomainError(['Invalid branded medicine ID', error.message]); + } + } + } + public get name(): string { + return this._name; + } + public set name(value: string) { + value = value.trim().toUpperCase(); + if (value.length === 0) + throw new DomainError('Branded medicine name cannot be empty'); + this._name = value; + } + public get type(): TypeModel { + return this._type; + } + public set type(value: TypeModel) { + this._type = value; + } + public get manufacturer(): ManufacturerModel { + return this._manufacturer; + } + public set manufacturer(value: ManufacturerModel) { + this._manufacturer = value; + } + public json(): { + id: number | undefined; + name: string; + type: any; + manufacturer: any; + } { + return { + id: this.id, + name: this.name, + type: this.type.json(), + manufacturer: this.manufacturer.json() + }; + } +} diff --git a/src/domain/model/brandedPresentation.model.ts b/src/domain/model/brandedPresentation.model.ts new file mode 100644 index 0000000..0eb2131 --- /dev/null +++ b/src/domain/model/brandedPresentation.model.ts @@ -0,0 +1,92 @@ +import { Domain as DomainError } from '../error/domain.error'; +import { Converter as ConverterUtil } from '../util/converter.util'; +import { BrandedMedicine as BrandedMedicineModel } from './brandedMedicine.model'; +import { ActiveComponentByUnit as ActiveComponentByUnitModel } from './activeComponentsByUnit.model'; +export class BrandedPresentation { + private _id!: number | undefined; + private _brandedMedicine!: BrandedMedicineModel; + private _activeComponentsByUnit!: ActiveComponentByUnitModel[]; + private _quantity!: number; + constructor( + id: number | string | undefined | null, + brandedMedicine: BrandedMedicineModel, + activeComponentsByUnit: ActiveComponentByUnitModel[], + quantity: number + ) { + this.id = id; + this.brandedMedicine = brandedMedicine; + this.activeComponentsByUnit = activeComponentsByUnit; + this.quantity = quantity; + } + public get id(): number | undefined { + return this._id; + } + public set id(value: number | string | undefined | null) { + try { + this._id = ConverterUtil.toNumber(value); + } catch (error) { + if (error instanceof Error) { + throw new DomainError([ + 'Invalid branded presentation ID', + error.message + ]); + } + } + } + public get brandedMedicine(): BrandedMedicineModel { + return this._brandedMedicine; + } + public set brandedMedicine(value: BrandedMedicineModel) { + this._brandedMedicine = value; + } + public get activeComponentsByUnit(): ActiveComponentByUnitModel[] { + return this._activeComponentsByUnit; + } + public set activeComponentsByUnit(value: ActiveComponentByUnitModel[]) { + if (value.length === 0) { + throw new DomainError('Active components list cannot be empty'); + } + const uniqueIds = new Set(); + const uniqueNames = new Set(); + for (const item of value) { + const substanceId = item.substance.id; + const substanceName = item.substance.name; + if (substanceId) { + if (uniqueIds.has(substanceId)) { + throw new DomainError( + `Substance with ID '${substanceId}' is duplicated` + ); + } + uniqueIds.add(substanceId); + } + if (uniqueNames.has(substanceName)) { + throw new DomainError( + `Substance with name '${substanceName}' is duplicated` + ); + } + uniqueNames.add(substanceName); + } + this._activeComponentsByUnit = value; + } + public get quantity(): number { + return this._quantity; + } + public set quantity(value: number) { + this._quantity = value; + } + public json(): { + id: number | undefined; + brandedMedicine: any; + quantity: number; + activeComponentsByUnit: any[]; + } { + return { + id: this.id, + brandedMedicine: this.brandedMedicine.json(), + quantity: this.quantity, + activeComponentsByUnit: this.activeComponentsByUnit.map((item) => + item.json() + ) + }; + } +} diff --git a/src/domain/model/frecuency.model.ts b/src/domain/model/frecuency.model.ts new file mode 100644 index 0000000..ef9b019 --- /dev/null +++ b/src/domain/model/frecuency.model.ts @@ -0,0 +1,57 @@ +import { Domain as DomainError } from '../error/domain.error'; +import { Converter as ConverterUtil } from '../util/converter.util'; +export class Frecuency { + private _id!: number | undefined; + private _quantity!: number; + private _everyHours!: number; + constructor( + id: number | string | undefined | null, + quantity: number, + everyHours: number = 24 + ) { + this.id = id; + this.quantity = quantity; + this.everyHours = everyHours; + } + public get id(): number | undefined { + return this._id; + } + public set id(value: number | string | undefined | null) { + try { + this._id = ConverterUtil.toNumber(value); + } catch (error) { + if (error instanceof Error) { + throw new DomainError(['Invalid frecuency ID', error.message]); + } + } + } + public get quantity(): number { + return this._quantity; + } + public set quantity(value: number) { + if (value <= 0) + throw new DomainError( + 'Frecuency quantity cannot be less or equal than zero' + ); + this._quantity = value; + } + public get everyHours(): number { + return this._everyHours; + } + public set everyHours(value: number) { + if (value <= 0) + throw new DomainError('Frecuency time cannot be less or equal than zero'); + this._everyHours = value; + } + public json(): { + id: number | undefined; + quantity: number; + everyHours: number; + } { + return { + id: this.id, + quantity: this.quantity, + everyHours: this.everyHours + }; + } +} diff --git a/src/domain/model/manufacturer.model.ts b/src/domain/model/manufacturer.model.ts new file mode 100644 index 0000000..e2e1ddb --- /dev/null +++ b/src/domain/model/manufacturer.model.ts @@ -0,0 +1,40 @@ +import { Domain as DomainError } from '../error/domain.error'; +import { Converter as ConverterUtil } from '../util/converter.util'; +export class Manufacturer { + private _id!: number | undefined; + private _name!: string; + constructor(id: number | string | undefined | null, name: string) { + this.id = id; + this.name = name; + } + public get id(): number | undefined { + return this._id; + } + public set id(value: number | string | undefined | null) { + try { + this._id = ConverterUtil.toNumber(value); + } catch (error) { + if (error instanceof Error) { + throw new DomainError(['Invalid manufacturer ID', error.message]); + } + } + } + public get name(): string { + return this._name; + } + public set name(value: string) { + value = value.trim().toUpperCase(); + if (value.length === 0) + throw new DomainError('Manufacturer name cannot be empty'); + this._name = value; + } + public json(): { + id: number | undefined; + name: string; + } { + return { + id: this.id, + name: this.name + }; + } +} diff --git a/src/domain/model/prescription.model.ts b/src/domain/model/prescription.model.ts new file mode 100644 index 0000000..f3ab5d3 --- /dev/null +++ b/src/domain/model/prescription.model.ts @@ -0,0 +1,84 @@ +import { Domain as DomainError } from '../error/domain.error'; +import { Frecuency as FrecuencyModel } from './frecuency.model'; +import { Converter as ConverterUtil } from '../util/converter.util'; +import { Type as TypeModel } from './type.model'; +export class Prescription { + public static buildJSONArray(prescriptions: Prescription[]): { + id: number | undefined; + type: any; + frecuency: any; + isSelfMedicated: boolean; + date: Date; + }[] { + return prescriptions.map((prescription) => prescription.json()); + } + private _id!: number | undefined; + private _type!: TypeModel; + private _frecuency!: FrecuencyModel; + private _isSelfMedicated!: boolean; + private _date!: Date; + constructor( + id: number | string | undefined | null, + type: TypeModel, + frecuency: FrecuencyModel, + isSelfMedicated: boolean, + date: Date | undefined = undefined + ) { + this.id = id; + this.type = type; + this.frecuency = frecuency; + this.isSelfMedicated = isSelfMedicated; + this.date = date || new Date(); + } + public get id(): number | undefined { + return this._id; + } + public set id(value: number | string | undefined | null) { + try { + this._id = ConverterUtil.toNumber(value); + } catch (error) { + if (error instanceof Error) { + throw new DomainError(['Invalid prescription ID', error.message]); + } + } + } + public get type(): TypeModel { + return this._type; + } + public set type(value: TypeModel) { + this._type = value; + } + public get frecuency(): FrecuencyModel { + return this._frecuency; + } + public set frecuency(value: FrecuencyModel) { + this._frecuency = value; + } + public get date(): Date { + return this._date; + } + public set date(value: Date) { + this._date = value; + } + public get isSelfMedicated(): boolean { + return this._isSelfMedicated; + } + public set isSelfMedicated(value: boolean) { + this._isSelfMedicated = value; + } + public json(): { + id: number | undefined; + type: any; + frecuency: any; + isSelfMedicated: boolean; + date: Date; + } { + return { + id: this.id, + type: this.type.json(), + frecuency: this.frecuency.json(), + isSelfMedicated: this.isSelfMedicated, + date: this.date + }; + } +} diff --git a/src/domain/model/purchase.model.ts b/src/domain/model/purchase.model.ts new file mode 100644 index 0000000..018e651 --- /dev/null +++ b/src/domain/model/purchase.model.ts @@ -0,0 +1,95 @@ +import { Domain as DomainError } from '../error/domain.error'; +import { BrandedPresentation as BrandedPresentationModel } from './brandedPresentation.model'; +import { Converter as ConverterUtil } from '../util/converter.util'; +export class Purchase { + public static buildJSONArray(purchases: Purchase[]): { + id: number | undefined; + date: Date; + brandedPresentation: any; + price: number; + discount: number; + shippingCost: number; + }[] { + return purchases.map((purchase) => purchase.json()); + } + private _id!: number | undefined; + private _date!: Date; + private _brandedPresentation!: BrandedPresentationModel; + private _price!: number; + private _discount!: number; + private _shippingCost!: number; + constructor( + id: number | string | undefined | null, + brandedPresentation: BrandedPresentationModel, + price: number, + discount: number, + shippingCost: number, + date: Date | undefined = undefined + ) { + this.id = id; + this.date = date || new Date(); + this.brandedPresentation = brandedPresentation; + this.price = price; + this.discount = discount; + this.shippingCost = shippingCost; + } + public get id(): number | undefined { + return this._id; + } + public set id(value: number | string | undefined | null) { + try { + this._id = ConverterUtil.toNumber(value); + } catch (error) { + if (error instanceof Error) { + throw new DomainError(['Invalid purchase ID', error.message]); + } + } + } + public get date(): Date { + return this._date; + } + public set date(value: Date) { + this._date = value; + } + public get brandedPresentation(): BrandedPresentationModel { + return this._brandedPresentation; + } + public set brandedPresentation(value: BrandedPresentationModel) { + this._brandedPresentation = value; + } + public get price(): number { + return this._price; + } + public set price(value: number) { + this._price = value; + } + public get discount(): number { + return this._discount; + } + public set discount(value: number) { + this._discount = value; + } + public get shippingCost(): number { + return this._shippingCost; + } + public set shippingCost(value: number) { + this._shippingCost = value; + } + public json(): { + id: number | undefined; + date: Date; + brandedPresentation: any; + price: number; + discount: number; + shippingCost: number; + } { + return { + id: this.id, + date: this.date, + brandedPresentation: this.brandedPresentation.json(), + price: this.price, + discount: this.discount, + shippingCost: this.shippingCost + }; + } +} diff --git a/src/domain/model/stock.model.ts b/src/domain/model/stock.model.ts new file mode 100644 index 0000000..75a4d83 --- /dev/null +++ b/src/domain/model/stock.model.ts @@ -0,0 +1,71 @@ +import { Domain as DomainError } from '../error/domain.error'; +import { BrandedPresentation as BrandedPresentationModel } from './brandedPresentation.model'; +import { Converter as ConverterUtil } from '../util/converter.util'; +export class Stock { + public static buildJSONArray(stocks: Stock[]): { + id: number | undefined; + brandedPresentation: any; + quantity: number; + date: Date; + }[] { + return stocks.map((stock) => stock.json()); + } + private _id!: number | undefined; + private _brandedPresentation!: BrandedPresentationModel; + private _quantity!: number; + private _date!: Date; + constructor( + id: number | string | undefined | null, + brandedPresentation: BrandedPresentationModel, + quantity: number, + date: Date | undefined = undefined + ) { + this.id = id; + this.brandedPresentation = brandedPresentation; + this.quantity = quantity; + this.date = date || new Date(); + } + public get id(): number | undefined { + return this._id; + } + public set id(value: number | string | undefined | null) { + try { + this._id = ConverterUtil.toNumber(value); + } catch (error) { + if (error instanceof Error) { + throw new DomainError(['Invalid stock ID', error.message]); + } + } + } + public get brandedPresentation(): BrandedPresentationModel { + return this._brandedPresentation; + } + public set brandedPresentation(value: BrandedPresentationModel) { + this._brandedPresentation = value; + } + public get quantity(): number { + return this._quantity; + } + public set quantity(value: number) { + this._quantity = value; + } + public get date(): Date { + return this._date; + } + public set date(value: Date) { + this._date = value; + } + public json(): { + id: number | undefined; + brandedPresentation: any; + quantity: number; + date: Date; + } { + return { + id: this.id, + brandedPresentation: this.brandedPresentation.json(), + quantity: this.quantity, + date: this.date + }; + } +} diff --git a/src/domain/model/substance.model.ts b/src/domain/model/substance.model.ts new file mode 100644 index 0000000..bac633b --- /dev/null +++ b/src/domain/model/substance.model.ts @@ -0,0 +1,40 @@ +import { Domain as DomainError } from '../error/domain.error'; +import { Converter as ConverterUtil } from '../util/converter.util'; +export class Substance { + private _id!: number | undefined; + private _name!: string; + constructor(id: number | string | undefined | null, name: string) { + this.id = id; + this.name = name; + } + public get id(): number | undefined { + return this._id; + } + public set id(value: number | string | undefined | null) { + try { + this._id = ConverterUtil.toNumber(value); + } catch (error) { + if (error instanceof Error) { + throw new DomainError(['Invalid substance ID', error.message]); + } + } + } + public get name(): string { + return this._name; + } + public set name(value: string) { + value = value.trim().toUpperCase(); + if (value.length === 0) + throw new DomainError('Substance name cannot be empty'); + this._name = value; + } + public json(): { + id: number | undefined; + name: string; + } { + return { + id: this.id, + name: this.name + }; + } +} diff --git a/src/domain/model/type.model.ts b/src/domain/model/type.model.ts new file mode 100644 index 0000000..fc83a6f --- /dev/null +++ b/src/domain/model/type.model.ts @@ -0,0 +1,39 @@ +import { Domain as DomainError } from '../error/domain.error'; +import { Converter as ConverterUtil } from '../util/converter.util'; +export class Type { + private _id!: number | undefined; + private _name!: string; + constructor(id: number | string | undefined | null, name: string) { + this.id = id; + this.name = name; + } + public get id(): number | undefined { + return this._id; + } + public set id(value: number | string | undefined | null) { + try { + this._id = ConverterUtil.toNumber(value); + } catch (error) { + if (error instanceof Error) { + throw new DomainError(['Invalid type ID', error.message]); + } + } + } + public get name(): string { + return this._name; + } + public set name(value: string) { + value = value.trim().toUpperCase(); + if (value.length === 0) throw new DomainError('Type name cannot be empty'); + this._name = value; + } + public json(): { + id: number | undefined; + name: string; + } { + return { + id: this.id, + name: this.name + }; + } +} diff --git a/src/domain/model/user.model.ts b/src/domain/model/user.model.ts new file mode 100644 index 0000000..a0fe724 --- /dev/null +++ b/src/domain/model/user.model.ts @@ -0,0 +1,78 @@ +import { Domain as DomainError } from '../error/domain.error'; +import { Prescription as PrescriptionModel } from './prescription.model'; +import { Purchase as PurchaseModel } from './purchase.model'; +import { Stock as StockModel } from './stock.model'; +import { Converter as ConverterUtil } from '../util/converter.util'; +export class User { + private _id!: number | undefined; + private _name!: string; + private _prescriptions!: PrescriptionModel[]; + private _purchases!: PurchaseModel[]; + private _stocks!: StockModel[]; + constructor( + id: number | string | undefined | null, + name: string, + prescriptions: PrescriptionModel[] = [], + purchases: PurchaseModel[] = [], + stocks: StockModel[] = [] + ) { + this.id = id; + this.name = name; + this.prescriptions = prescriptions; + this.purchases = purchases; + this.stocks = stocks; + } + public get id(): number | undefined { + return this._id; + } + public set id(value: number | string | undefined | null) { + try { + this._id = ConverterUtil.toNumber(value); + } catch (error) { + if (error instanceof Error) { + throw new DomainError(['Invalid user ID', error.message]); + } + } + } + public get name(): string { + return this._name; + } + public set name(value: string) { + value = value.trim().toUpperCase(); + if (value.length === 0) throw new DomainError('User name cannot be empty'); + this._name = value; + } + public get prescriptions(): PrescriptionModel[] { + return this._prescriptions; + } + public set prescriptions(value: PrescriptionModel[]) { + this._prescriptions = value; + } + public get purchases(): PurchaseModel[] { + return this._purchases; + } + public set purchases(value: PurchaseModel[]) { + this._purchases = value; + } + public get stocks(): StockModel[] { + return this._stocks; + } + public set stocks(value: StockModel[]) { + this._stocks = value; + } + public json(): { + id: number | undefined; + name: string; + prescriptions: any[]; + purchases: any[]; + stocks: any[]; + } { + return { + id: this.id, + name: this.name, + prescriptions: PrescriptionModel.buildJSONArray(this.prescriptions), + purchases: PurchaseModel.buildJSONArray(this.purchases), + stocks: StockModel.buildJSONArray(this.stocks) + }; + } +} diff --git a/src/domain/util/configuration.util.ts b/src/domain/util/configuration.util.ts index 27db9ea..5371515 100644 --- a/src/domain/util/configuration.util.ts +++ b/src/domain/util/configuration.util.ts @@ -58,8 +58,26 @@ export class Configuration { 3000 ); } - public static xxx(): string { - return new Configuration(process.env.XXX).value; + public static postgresql(): { + personalFinance: { + database: string; + host: string; + password: string; + port: number; + user: string; + }; + } { + return { + personalFinance: { + database: new Configuration(process.env.POSTGRESQL_PF_DATABASE).value, + host: new Configuration(process.env.POSTGRESQL_PF_HOST).value, + password: new Configuration(process.env.POSTGRESQL_PF_PASSWORD).value, + port: Configuration.valueToNumber( + new Configuration(process.env.POSTGRESQL_PF_PORT) + ), + user: new Configuration(process.env.POSTGRESQL_PF_USER).value + } + }; } public static showValues( preLog: number | string | undefined | null = undefined @@ -74,6 +92,26 @@ export class Configuration { ]); LoggerUtil.debug([preLog, ` * nodeEnv: ${Configuration.nodeEnv()}`]); LoggerUtil.debug([preLog, ` * port: ${Configuration.port()}`]); + LoggerUtil.debug([ + preLog, + ` * postgresql.personalFinance.database: ${Configuration.postgresql().personalFinance.database}` + ]); + LoggerUtil.debug([ + preLog, + ` * postgresql.personalFinance.host: ${Configuration.postgresql().personalFinance.host}` + ]); + LoggerUtil.debug([ + preLog, + ` * postgresql.personalFinance.password: ${Configuration.postgresql().personalFinance.password}` + ]); + LoggerUtil.debug([ + preLog, + ` * postgresql.personalFinance.port: ${Configuration.postgresql().personalFinance.port}` + ]); + LoggerUtil.debug([ + preLog, + ` * postgresql.personalFinance.user: ${Configuration.postgresql().personalFinance.user}` + ]); } private _value!: string; constructor(value: string | null | undefined = undefined) { diff --git a/src/domain/util/converter.util.ts b/src/domain/util/converter.util.ts new file mode 100644 index 0000000..b03ca4a --- /dev/null +++ b/src/domain/util/converter.util.ts @@ -0,0 +1,18 @@ +export class Converter { + public static toNumber( + value: number | string | undefined | null + ): number | undefined { + let result: number | undefined = undefined; + const numericRegex = /^[0-9]+$/; + if (typeof value === 'number') { + result = value; + } else if (value === null || value === undefined || value.trim() === '') { + result = undefined; + } else if (numericRegex.test(value.trim().toLowerCase()) === true) { + result = +value.trim(); + } else { + throw new Error(`${value} is not a number`); + } + return result; + } +} diff --git a/src/infrastructure/persistence/queries/allFrecuencies.query.sql b/src/infrastructure/persistence/queries/allFrecuencies.query.sql new file mode 100644 index 0000000..4d92532 --- /dev/null +++ b/src/infrastructure/persistence/queries/allFrecuencies.query.sql @@ -0,0 +1,8 @@ +select + fr.mfre_id, + fr.mfre_every_hours, + fr.mfre_quantity +from + public.pf_med_frecuency fr +order by + fr.mfre_id asc; \ No newline at end of file diff --git a/src/infrastructure/persistence/queries/allManufacturers.query.sql b/src/infrastructure/persistence/queries/allManufacturers.query.sql new file mode 100644 index 0000000..bd84b20 --- /dev/null +++ b/src/infrastructure/persistence/queries/allManufacturers.query.sql @@ -0,0 +1,7 @@ +select + ma.mman_id, + ma.mman_name +from + public.pf_med_manufacturer ma +order by + ma.mman_id asc; \ No newline at end of file diff --git a/src/infrastructure/persistence/queries/allSubstances.query.sql b/src/infrastructure/persistence/queries/allSubstances.query.sql new file mode 100644 index 0000000..6fc581d --- /dev/null +++ b/src/infrastructure/persistence/queries/allSubstances.query.sql @@ -0,0 +1,7 @@ +select + su.msub_id, + su.msub_name +from + public.pf_med_substance su +order by + su.msub_id asc; \ No newline at end of file diff --git a/src/infrastructure/persistence/queries/allTypes.query.sql b/src/infrastructure/persistence/queries/allTypes.query.sql new file mode 100644 index 0000000..d16c752 --- /dev/null +++ b/src/infrastructure/persistence/queries/allTypes.query.sql @@ -0,0 +1,7 @@ +select + ty.mtyp_id, + ty.mtyp_name +from + public.pf_med_type ty +order by + ty.mtyp_id asc; \ No newline at end of file diff --git a/src/infrastructure/persistence/queries/allUsers.query.sql b/src/infrastructure/persistence/queries/allUsers.query.sql new file mode 100644 index 0000000..4eb8201 --- /dev/null +++ b/src/infrastructure/persistence/queries/allUsers.query.sql @@ -0,0 +1,7 @@ +select + us.user_id, + us.user_name +from + public.pf_user us +order by + us.user_id asc; \ No newline at end of file diff --git a/src/infrastructure/persistence/queries/frecuencyById.query.sql b/src/infrastructure/persistence/queries/frecuencyById.query.sql new file mode 100644 index 0000000..42ae79b --- /dev/null +++ b/src/infrastructure/persistence/queries/frecuencyById.query.sql @@ -0,0 +1,10 @@ +select + fr.mfre_id, + fr.mfre_every_hours, + fr.mfre_quantity +from + public.pf_med_frecuency fr +where + fr.mfre_id = $1 +order by + fr.mfre_id asc; \ No newline at end of file diff --git a/src/infrastructure/persistence/queries/manufacturerById.query.sql b/src/infrastructure/persistence/queries/manufacturerById.query.sql new file mode 100644 index 0000000..9a3885f --- /dev/null +++ b/src/infrastructure/persistence/queries/manufacturerById.query.sql @@ -0,0 +1,9 @@ +select + ma.mman_id, + ma.mman_name +from + public.pf_med_manufacturer ma +where + ma.mman_id = $1 +order by + ma.mman_id asc; \ No newline at end of file diff --git a/src/infrastructure/persistence/queries/prescriptionsByUser.query.sql b/src/infrastructure/persistence/queries/prescriptionsByUser.query.sql new file mode 100644 index 0000000..93b3611 --- /dev/null +++ b/src/infrastructure/persistence/queries/prescriptionsByUser.query.sql @@ -0,0 +1,14 @@ +select + pre.mpre_id, + pre.mpre_active, + pre.mpre_date, + pre.mpre_is_self_medicated, + pre.mtyp_id, + pre.mfre_id +from + public.pf_med_prescription pre +where + pre.user_id = $1 +order by + pre.mtyp_id asc, + pre.mpre_date desc; diff --git a/src/infrastructure/persistence/queries/substanceById.query.sql b/src/infrastructure/persistence/queries/substanceById.query.sql new file mode 100644 index 0000000..9a4abc4 --- /dev/null +++ b/src/infrastructure/persistence/queries/substanceById.query.sql @@ -0,0 +1,9 @@ +select + su.msub_id, + su.msub_name +from + public.pf_med_substance su +where + su.msub_id = $1 +order by + su.msub_id asc; \ No newline at end of file diff --git a/src/infrastructure/persistence/queries/typeById.query.sql b/src/infrastructure/persistence/queries/typeById.query.sql new file mode 100644 index 0000000..ad2c3e3 --- /dev/null +++ b/src/infrastructure/persistence/queries/typeById.query.sql @@ -0,0 +1,9 @@ +select + ty.mtyp_id, + ty.mtyp_name +from + public.pf_med_type ty +where + ty.mtyp_id = $1 +order by + ty.mtyp_id asc; \ No newline at end of file diff --git a/src/infrastructure/persistence/queries/userById.query.sql b/src/infrastructure/persistence/queries/userById.query.sql new file mode 100644 index 0000000..923cddb --- /dev/null +++ b/src/infrastructure/persistence/queries/userById.query.sql @@ -0,0 +1,9 @@ +select + us.user_id, + us.user_name +from + public.pf_user us +where + us.user_id = $1 +order by + us.user_id asc; \ No newline at end of file diff --git a/src/infrastructure/persistence/repositories/frecuency.repository.ts b/src/infrastructure/persistence/repositories/frecuency.repository.ts new file mode 100644 index 0000000..174458d --- /dev/null +++ b/src/infrastructure/persistence/repositories/frecuency.repository.ts @@ -0,0 +1,70 @@ +import { Frecuency as FrecuencyModel } from '../../../domain/model/frecuency.model'; +import { Pool as PgPool, QueryResult as PgQueryResult } from 'pg'; +import fs from 'fs'; +import path from 'path'; +type FrecuencyRow = { + mfre_id: number; + mfre_every_hours: number; + mfre_quantity: number; +}; +export class Frecuency { + private _pgPool!: PgPool; + private _queries!: any; + constructor(pgPool: PgPool) { + this.pgPool = pgPool; + const queriesPath = { + allFrecuencies: path.join( + __dirname, + '../queries/allFrecuencies.query.sql' + ), + frecuencyById: path.join(__dirname, '../queries/frecuencyById.query.sql') + }; + this._queries = { + allFrecuencies: fs + .readFileSync(queriesPath.allFrecuencies, 'utf8') + .split(';')[0], + frecuencyById: fs + .readFileSync(queriesPath.frecuencyById, 'utf8') + .split(';')[0] + }; + } + private get pgPool(): PgPool { + return this._pgPool; + } + private set pgPool(value: PgPool) { + this._pgPool = value; + } + public async getAllFrecuencies(): Promise { + const result: FrecuencyModel[] = []; + const dbResponse = (await this.pgPool.query( + this._queries.allFrecuencies + )) as PgQueryResult; + for (const row of dbResponse.rows) { + const oRow = JSON.parse(JSON.stringify(row)) as FrecuencyRow; + result.push( + new FrecuencyModel( + oRow.mfre_id, + oRow.mfre_quantity, + oRow.mfre_every_hours + ) + ); + } + return result; + } + public async getFrecuencyById( + id: number + ): Promise { + const dbResponse = (await this.pgPool.query(this._queries.frecuencyById, [ + id + ])) as PgQueryResult; + for (const row of dbResponse.rows) { + const oRow = JSON.parse(JSON.stringify(row)) as FrecuencyRow; + return new FrecuencyModel( + oRow.mfre_id, + oRow.mfre_quantity, + oRow.mfre_every_hours + ); + } + return undefined; + } +} diff --git a/src/infrastructure/persistence/repositories/manufacturer.repository.ts b/src/infrastructure/persistence/repositories/manufacturer.repository.ts new file mode 100644 index 0000000..d01f617 --- /dev/null +++ b/src/infrastructure/persistence/repositories/manufacturer.repository.ts @@ -0,0 +1,63 @@ +import { Manufacturer as ManufacturerModel } from '../../../domain/model/manufacturer.model'; +import { Pool as PgPool, QueryResult as PgQueryResult } from 'pg'; +import fs from 'fs'; +import path from 'path'; +type ManufacturerRow = { + mman_id: number; + mman_name: string; +}; +export class Manufacturer { + private _pgPool!: PgPool; + private _queries!: any; + constructor(pgPool: PgPool) { + this.pgPool = pgPool; + const queriesPath = { + allManufacturers: path.join( + __dirname, + '../queries/allManufacturers.query.sql' + ), + manufacturerById: path.join( + __dirname, + '../queries/manufacturerById.query.sql' + ) + }; + this._queries = { + allManufacturers: fs + .readFileSync(queriesPath.allManufacturers, 'utf8') + .split(';')[0], + manufacturerById: fs + .readFileSync(queriesPath.manufacturerById, 'utf8') + .split(';')[0] + }; + } + private get pgPool(): PgPool { + return this._pgPool; + } + private set pgPool(value: PgPool) { + this._pgPool = value; + } + public async getAllManufacturers(): Promise { + const result: ManufacturerModel[] = []; + const dbResponse = (await this.pgPool.query( + this._queries.allManufacturers + )) as PgQueryResult; + for (const row of dbResponse.rows) { + const oRow = JSON.parse(JSON.stringify(row)) as ManufacturerRow; + result.push(new ManufacturerModel(oRow.mman_id, oRow.mman_name)); + } + return result; + } + public async getManufacturerById( + id: number + ): Promise { + const dbResponse = (await this.pgPool.query( + this._queries.manufacturerById, + [id] + )) as PgQueryResult; + for (const row of dbResponse.rows) { + const oRow = JSON.parse(JSON.stringify(row)) as ManufacturerRow; + return new ManufacturerModel(oRow.mman_id, oRow.mman_name); + } + return undefined; + } +} diff --git a/src/infrastructure/persistence/repositories/prescription.repository.ts b/src/infrastructure/persistence/repositories/prescription.repository.ts new file mode 100644 index 0000000..ebae9a8 --- /dev/null +++ b/src/infrastructure/persistence/repositories/prescription.repository.ts @@ -0,0 +1,69 @@ +import { User as UserModel } from '../../../domain/model/user.model'; +import { Prescription as PrescriptionModel } from '../../../domain/model/prescription.model'; +import { Pool as PgPool, QueryResult as PgQueryResult } from 'pg'; +import fs from 'fs'; +import path from 'path'; +import { Type as TypeModel } from '../../../domain/model/type.model'; +import { Frecuency as FrecuencyModel } from '../../../domain/model/frecuency.model'; +import { Type as TypeRepository } from './type.repository'; +import { Frecuency as FrecuencyRepository } from './frecuency.repository'; +type PrescriptionRow = { + mpre_id: number; + mpre_active: boolean; + mpre_date: Date; + mpre_is_self_medicated: boolean; + mtyp_id: number; + mfre_id: number; +}; +export class Prescription { + private _pgPool!: PgPool; + private _queries!: any; + constructor(pgPool: PgPool) { + this.pgPool = pgPool; + const queriesPath = path.join( + __dirname, + '../queries/prescriptionsByUser.query.sql' + ); + const queries = fs.readFileSync(queriesPath, 'utf8').split(';'); + this._queries = { + prescriptionsByUser: queries[0] + }; + } + private get pgPool(): PgPool { + return this._pgPool; + } + private set pgPool(value: PgPool) { + this._pgPool = value; + } + public async getPrescriptionsByUser( + user: UserModel + ): Promise { + const result: PrescriptionModel[] = []; + const dbResponse = (await this.pgPool.query( + this._queries.prescriptionsByUser, + [user.id] + )) as PgQueryResult; + const typeRepository = new TypeRepository(this.pgPool); + const frecuencyRepository = new FrecuencyRepository(this.pgPool); + for (const row of dbResponse.rows) { + const oRow = JSON.parse(JSON.stringify(row)) as PrescriptionRow; + const type: TypeModel | undefined = await typeRepository.getTypeById( + oRow.mtyp_id + ); + const frecuency: FrecuencyModel | undefined = + await frecuencyRepository.getFrecuencyById(oRow.mfre_id); + if (type && frecuency) { + result.push( + new PrescriptionModel( + oRow.mpre_id, + type, + frecuency, + oRow.mpre_is_self_medicated, + oRow.mpre_date + ) + ); + } + } + return result; + } +} diff --git a/src/infrastructure/persistence/repositories/substance.repository.ts b/src/infrastructure/persistence/repositories/substance.repository.ts new file mode 100644 index 0000000..67dd18d --- /dev/null +++ b/src/infrastructure/persistence/repositories/substance.repository.ts @@ -0,0 +1,56 @@ +import { Substance as SubstanceModel } from '../../../domain/model/substance.model'; +import { Pool as PgPool, QueryResult as PgQueryResult } from 'pg'; +import fs from 'fs'; +import path from 'path'; +type SubstanceRow = { + msub_id: number; + msub_name: string; +}; +export class Substance { + private _pgPool!: PgPool; + private _queries!: any; + constructor(pgPool: PgPool) { + this.pgPool = pgPool; + const queriesPath = { + allSubstances: path.join(__dirname, '../queries/allSubstances.query.sql'), + substanceById: path.join(__dirname, '../queries/substanceById.query.sql') + }; + this._queries = { + allSubstances: fs + .readFileSync(queriesPath.allSubstances, 'utf8') + .split(';')[0], + substanceById: fs + .readFileSync(queriesPath.substanceById, 'utf8') + .split(';')[0] + }; + } + private get pgPool(): PgPool { + return this._pgPool; + } + private set pgPool(value: PgPool) { + this._pgPool = value; + } + public async getAllSubstances(): Promise { + const result: SubstanceModel[] = []; + const dbResponse = (await this.pgPool.query( + this._queries.allSubstances + )) as PgQueryResult; + for (const row of dbResponse.rows) { + const oRow = JSON.parse(JSON.stringify(row)) as SubstanceRow; + result.push(new SubstanceModel(oRow.msub_id, oRow.msub_name)); + } + return result; + } + public async getSubstanceById( + id: number + ): Promise { + const dbResponse = (await this.pgPool.query(this._queries.substanceById, [ + id + ])) as PgQueryResult; + for (const row of dbResponse.rows) { + const oRow = JSON.parse(JSON.stringify(row)) as SubstanceRow; + return new SubstanceModel(oRow.msub_id, oRow.msub_name); + } + return undefined; + } +} diff --git a/src/infrastructure/persistence/repositories/type.repository.ts b/src/infrastructure/persistence/repositories/type.repository.ts new file mode 100644 index 0000000..5a1f033 --- /dev/null +++ b/src/infrastructure/persistence/repositories/type.repository.ts @@ -0,0 +1,50 @@ +import { Type as TypeModel } from '../../../domain/model/type.model'; +import { Pool as PgPool, QueryResult as PgQueryResult } from 'pg'; +import fs from 'fs'; +import path from 'path'; +type TypeRow = { + mtyp_id: number; + mtyp_name: string; +}; +export class Type { + private _pgPool!: PgPool; + private _queries!: any; + constructor(pgPool: PgPool) { + this.pgPool = pgPool; + const queriesPath = { + allTypes: path.join(__dirname, '../queries/allTypes.query.sql'), + typeById: path.join(__dirname, '../queries/typeById.query.sql') + }; + this._queries = { + allTypes: fs.readFileSync(queriesPath.allTypes, 'utf8').split(';')[0], + typeById: fs.readFileSync(queriesPath.typeById, 'utf8').split(';')[0] + }; + } + private get pgPool(): PgPool { + return this._pgPool; + } + private set pgPool(value: PgPool) { + this._pgPool = value; + } + public async getAllTypes(): Promise { + const result: TypeModel[] = []; + const dbResponse = (await this.pgPool.query( + this._queries.allTypes + )) as PgQueryResult; + for (const row of dbResponse.rows) { + const oRow = JSON.parse(JSON.stringify(row)) as TypeRow; + result.push(new TypeModel(oRow.mtyp_id, oRow.mtyp_name)); + } + return result; + } + public async getTypeById(id: number): Promise { + const dbResponse = (await this.pgPool.query(this._queries.typeById, [ + id + ])) as PgQueryResult; + for (const row of dbResponse.rows) { + const oRow = JSON.parse(JSON.stringify(row)) as TypeRow; + return new TypeModel(oRow.mtyp_id, oRow.mtyp_name); + } + return undefined; + } +} diff --git a/src/infrastructure/persistence/repositories/user.repository.ts b/src/infrastructure/persistence/repositories/user.repository.ts new file mode 100644 index 0000000..76bd0fa --- /dev/null +++ b/src/infrastructure/persistence/repositories/user.repository.ts @@ -0,0 +1,50 @@ +import { User as UserModel } from '../../../domain/model/user.model'; +import { Pool as PgPool, QueryResult as PgQueryResult } from 'pg'; +import fs from 'fs'; +import path from 'path'; +type UserRow = { + user_id: number; + user_name: string; +}; +export class User { + private _pgPool!: PgPool; + private _queries!: any; + constructor(pgPool: PgPool) { + this.pgPool = pgPool; + const queriesPath = { + allUsers: path.join(__dirname, '../queries/allUsers.query.sql'), + userById: path.join(__dirname, '../queries/userById.query.sql') + }; + this._queries = { + allUsers: fs.readFileSync(queriesPath.allUsers, 'utf8').split(';')[0], + userById: fs.readFileSync(queriesPath.userById, 'utf8').split(';')[0] + }; + } + private get pgPool(): PgPool { + return this._pgPool; + } + private set pgPool(value: PgPool) { + this._pgPool = value; + } + public async getAllUsers(): Promise { + const result: UserModel[] = []; + const dbResponse = (await this.pgPool.query( + this._queries.allUsers + )) as PgQueryResult; + for (const row of dbResponse.rows) { + const oRow = JSON.parse(JSON.stringify(row)) as UserRow; + result.push(new UserModel(oRow.user_id, oRow.user_name)); + } + return result; + } + public async getUserById(id: number): Promise { + const dbResponse = (await this.pgPool.query(this._queries.userById, [ + id + ])) as PgQueryResult; + for (const row of dbResponse.rows) { + const oRow = JSON.parse(JSON.stringify(row)) as UserRow; + return new UserModel(oRow.user_id, oRow.user_name); + } + return undefined; + } +} diff --git a/src/infrastructure/service/databasePool.service.ts b/src/infrastructure/service/databasePool.service.ts new file mode 100644 index 0000000..a79d1dc --- /dev/null +++ b/src/infrastructure/service/databasePool.service.ts @@ -0,0 +1,69 @@ +import { Pool as PgPool } from 'pg'; +export class DatabasePool { + private _user!: string; + private _host!: string; + private _database!: string; + private _password!: string; + private _port!: number; + private _ssl!: boolean | any | undefined; + constructor( + host: string, + database: string, + credentials: { user: string; password: string }, + port: number = 5432, + ssl: boolean | any | undefined = undefined + ) { + this.user = credentials.user; + this.host = host; + this.database = database; + this.password = credentials.password; + this.port = port; + this.ssl = ssl; + } + public get user(): string { + return this._user; + } + public set user(user: string) { + this._user = user; + } + public get host(): string { + return this._host; + } + public set host(host: string) { + this._host = host; + } + public get database(): string { + return this._database; + } + public set database(database: string) { + this._database = database; + } + public get password(): string { + return this._password; + } + public set password(password: string) { + this._password = password; + } + public get port(): number { + return this._port; + } + public set port(port: number) { + this._port = port; + } + public get ssl(): boolean | any | undefined { + return this._ssl; + } + public set ssl(value: boolean | any | undefined) { + this._ssl = value; + } + public get get(): PgPool { + return new PgPool({ + user: this.user, + host: this.host, + database: this.database, + password: this.password, + port: this.port, + ssl: this.ssl + }); + } +} diff --git a/test/domain/model/activeComponentsByUnit.model.utest.ts b/test/domain/model/activeComponentsByUnit.model.utest.ts new file mode 100644 index 0000000..85f04fd --- /dev/null +++ b/test/domain/model/activeComponentsByUnit.model.utest.ts @@ -0,0 +1,28 @@ +import { ActiveComponentByUnit as ActiveComponentByUnitModel } from '../../../src/domain/model/activeComponentsByUnit.model'; +import { Substance as SubstanceModel } from '../../../src/domain/model/substance.model'; +const substance1: SubstanceModel = new SubstanceModel(1, 'NAME'); +describe('Class ActiveComponentByUnit Model', () => { + it('Happy Path 1', async () => { + const activeComponentsByUnit: ActiveComponentByUnitModel = + new ActiveComponentByUnitModel(1, substance1); + expect(activeComponentsByUnit.grams).toBe(1); + expect(activeComponentsByUnit.substance.json()).toEqual(substance1.json()); + expect(activeComponentsByUnit.json()).toEqual({ + grams: 1, + substance: substance1.json() + }); + }); + it('Error - Invalid grams', async () => { + let errorMsg: string = ''; + try { + new ActiveComponentByUnitModel(0, substance1); + } catch (error) { + if (error instanceof Error) { + errorMsg = error.message; + } + } + expect(errorMsg).toBe( + 'Active component by unit grams cannot be less or equal than zero' + ); + }); +}); diff --git a/test/domain/model/brandedMedicine.model.utest.ts b/test/domain/model/brandedMedicine.model.utest.ts new file mode 100644 index 0000000..ae20f3b --- /dev/null +++ b/test/domain/model/brandedMedicine.model.utest.ts @@ -0,0 +1,64 @@ +import { BrandedMedicine as BrandedMedicineModel } from '../../../src/domain/model/brandedMedicine.model'; +import { Manufacturer as ManufacturerModel } from '../../../src/domain/model/manufacturer.model'; +import { Type as TypeModel } from '../../../src/domain/model/type.model'; +const manufacturer: ManufacturerModel = new ManufacturerModel(1, 'NAME'); +const type: TypeModel = new TypeModel(1, 'NAME'); +describe('Class BrandedMedicine Model', () => { + it('Happy Path 1', async () => { + const brandedMedicine: BrandedMedicineModel = new BrandedMedicineModel( + 1, + ' name ', + type, + manufacturer + ); + expect(brandedMedicine.id).toBe(1); + expect(brandedMedicine.name).toBe('NAME'); + expect(brandedMedicine.type.json()).toEqual(type.json()); + expect(brandedMedicine.manufacturer.json()).toEqual(manufacturer.json()); + expect(brandedMedicine.json()).toEqual({ + id: 1, + name: 'NAME', + type: type.json(), + manufacturer: manufacturer.json() + }); + }); + it('Happy Path 2', async () => { + const brandedMedicine: BrandedMedicineModel = new BrandedMedicineModel( + undefined, + ' name ', + type, + manufacturer + ); + expect(brandedMedicine.id).toBeUndefined(); + expect(brandedMedicine.name).toBe('NAME'); + expect(brandedMedicine.type.json()).toEqual(type.json()); + expect(brandedMedicine.manufacturer.json()).toEqual(manufacturer.json()); + expect(brandedMedicine.json()).toEqual({ + name: 'NAME', + type: type.json(), + manufacturer: manufacturer.json() + }); + }); + it('Error - Empty Name', async () => { + let errorMsg: string = ''; + try { + new BrandedMedicineModel(1, ' ', type, manufacturer); + } catch (error) { + if (error instanceof Error) { + errorMsg = error.message; + } + } + expect(errorMsg).toBe('Branded medicine name cannot be empty'); + }); + it('Error - Invalid ID', async () => { + let errorMsg: string = ''; + try { + new BrandedMedicineModel('A', ' name ', type, manufacturer); + } catch (error) { + if (error instanceof Error) { + errorMsg = error.message; + } + } + expect(errorMsg).toBe('Invalid branded medicine ID | A is not a number'); + }); +}); diff --git a/test/domain/model/brandedPresentation.model.utest.ts b/test/domain/model/brandedPresentation.model.utest.ts new file mode 100644 index 0000000..e6d4145 --- /dev/null +++ b/test/domain/model/brandedPresentation.model.utest.ts @@ -0,0 +1,156 @@ +import { BrandedMedicine as BrandedMedicineModel } from '../../../src/domain/model/brandedMedicine.model'; +import { BrandedPresentation as BrandedPresentationModel } from '../../../src/domain/model/brandedPresentation.model'; +import { Manufacturer as ManufacturerModel } from '../../../src/domain/model/manufacturer.model'; +import { Substance as SubstanceModel } from '../../../src/domain/model/substance.model'; +import { Type as TypeModel } from '../../../src/domain/model/type.model'; +import { ActiveComponentByUnit as ActiveComponentByUnitModel } from '../../../src/domain/model/activeComponentsByUnit.model'; +const manufacturer: ManufacturerModel = new ManufacturerModel(1, 'NAME'); +const substance1: SubstanceModel = new SubstanceModel(1, 'NAME'); +const substance2: SubstanceModel = new SubstanceModel(undefined, 'NAME'); +const type: TypeModel = new TypeModel(1, 'NAME'); +const brandedMedicine: BrandedMedicineModel = new BrandedMedicineModel( + 1, + 'NAME', + type, + manufacturer +); +describe('Class BrandedPresentation Model', () => { + it('Happy Path 1', async () => { + const brandedPresentation: BrandedPresentationModel = + new BrandedPresentationModel( + 1, + brandedMedicine, + [new ActiveComponentByUnitModel(1, substance1)], + 1 + ); + expect(brandedPresentation.id).toBe(1); + expect(brandedPresentation.brandedMedicine.json()).toEqual( + brandedMedicine.json() + ); + expect( + brandedPresentation.activeComponentsByUnit.map((item) => item.json()) + ).toEqual([new ActiveComponentByUnitModel(1, substance1).json()]); + expect(brandedPresentation.quantity).toBe(1); + expect(brandedPresentation.json()).toEqual({ + id: 1, + brandedMedicine: brandedMedicine.json(), + quantity: 1, + activeComponentsByUnit: [ + new ActiveComponentByUnitModel(1, substance1).json() + ] + }); + }); + it('Happy Path 2', async () => { + const brandedPresentation: BrandedPresentationModel = + new BrandedPresentationModel( + undefined, + brandedMedicine, + [new ActiveComponentByUnitModel(1, substance2)], + 1 + ); + expect(brandedPresentation.id).toBeUndefined(); + expect(brandedPresentation.brandedMedicine.json()).toEqual( + brandedMedicine.json() + ); + expect(brandedPresentation.activeComponentsByUnit).toEqual([ + new ActiveComponentByUnitModel(1, substance2) + ]); + expect(brandedPresentation.quantity).toBe(1); + expect(brandedPresentation.json()).toEqual({ + brandedMedicine: brandedMedicine.json(), + quantity: 1, + activeComponentsByUnit: [ + new ActiveComponentByUnitModel(1, substance2).json() + ] + }); + }); + it('Error - Empty active components list', async () => { + let errorMsg: string = ''; + try { + new BrandedPresentationModel(1, brandedMedicine, [], 1); + } catch (error) { + if (error instanceof Error) { + errorMsg = error.message; + } + } + expect(errorMsg).toBe('Active components list cannot be empty'); + }); + it('Error - Duplicated substance IDs', async () => { + let errorMsg: string = ''; + try { + new BrandedPresentationModel( + 1, + brandedMedicine, + [ + new ActiveComponentByUnitModel(1, new SubstanceModel(1, 'NAME1')), + new ActiveComponentByUnitModel(1, new SubstanceModel(1, 'NAME2')), + new ActiveComponentByUnitModel( + 1, + new SubstanceModel(undefined, 'NAME3') + ) + ], + 1 + ); + } catch (error) { + if (error instanceof Error) { + errorMsg = error.message; + } + } + expect(errorMsg).toBe("Substance with ID '1' is duplicated"); + }); + it('Error - Duplicated substance names', async () => { + let errorMsg: string = ''; + try { + new BrandedPresentationModel( + 1, + brandedMedicine, + [ + new ActiveComponentByUnitModel(1, new SubstanceModel('1', 'NAME1')), + new ActiveComponentByUnitModel(1, new SubstanceModel('2', 'NAME1')) + ], + 1 + ); + } catch (error) { + if (error instanceof Error) { + errorMsg = error.message; + } + } + expect(errorMsg).toBe("Substance with name 'NAME1' is duplicated"); + }); + it('Error - Grams must be greater than zero', async () => { + let errorMsg: string = ''; + try { + new BrandedPresentationModel( + 1, + brandedMedicine, + [new ActiveComponentByUnitModel(0, new SubstanceModel('1', 'NAME1'))], + 1 + ); + } catch (error) { + if (error instanceof Error) { + errorMsg = error.message; + } + } + expect(errorMsg).toBe( + 'Active component by unit grams cannot be less or equal than zero' + ); + }); + it('Error - Invalid ID', async () => { + let errorMsg: string = ''; + try { + new BrandedPresentationModel( + 'A', + brandedMedicine, + [new ActiveComponentByUnitModel(1, substance1)], + 1 + ); + } catch (error) { + if (error instanceof Error) { + errorMsg = error.message; + } + } + expect(errorMsg).toBe( + 'Invalid branded presentation ID | A is not a number' + ); + }); +}); diff --git a/test/domain/model/frecuency.model.utest.ts b/test/domain/model/frecuency.model.utest.ts new file mode 100644 index 0000000..c98a685 --- /dev/null +++ b/test/domain/model/frecuency.model.utest.ts @@ -0,0 +1,52 @@ +import { Frecuency as FrecuencyModel } from '../../../src/domain/model/frecuency.model'; +describe('Class Frecuency Model', () => { + it('Happy Path 1', async () => { + const frecuency: FrecuencyModel = new FrecuencyModel(1, 1, 1); + expect(frecuency.id).toBe(1); + expect(frecuency.quantity).toBe(1); + expect(frecuency.everyHours).toBe(1); + expect(frecuency.json()).toEqual({ id: 1, quantity: 1, everyHours: 1 }); + }); + it('Happy Path 2', async () => { + const frecuency: FrecuencyModel = new FrecuencyModel(1, 1); + expect(frecuency.id).toBe(1); + expect(frecuency.quantity).toBe(1); + expect(frecuency.everyHours).toBe(24); + expect(frecuency.json()).toEqual({ id: 1, quantity: 1, everyHours: 24 }); + }); + it('Error - Invalid quantity', async () => { + let errorMsg: string = ''; + try { + new FrecuencyModel(1, 0, 1); + } catch (error) { + if (error instanceof Error) { + errorMsg = error.message; + } + } + expect(errorMsg).toBe( + 'Frecuency quantity cannot be less or equal than zero' + ); + }); + it('Error - Invalid everyHours', async () => { + let errorMsg: string = ''; + try { + new FrecuencyModel(1, 1, 0); + } catch (error) { + if (error instanceof Error) { + errorMsg = error.message; + } + } + expect(errorMsg).toBe('Frecuency time cannot be less or equal than zero'); + }); + it('Error - Invalid ID', async () => { + let errorMsg: string = ''; + try { + new FrecuencyModel('A', 1); + } catch (error) { + if (error instanceof Error) { + errorMsg = error.message; + } + } + expect(errorMsg).toBe('Invalid frecuency ID | A is not a number'); + }); +}); diff --git a/test/domain/model/manufacturer.model.utest.ts b/test/domain/model/manufacturer.model.utest.ts new file mode 100644 index 0000000..7b62559 --- /dev/null +++ b/test/domain/model/manufacturer.model.utest.ts @@ -0,0 +1,43 @@ +import { Manufacturer as ManufacturerModel } from '../../../src/domain/model/manufacturer.model'; +describe('Class Manufacturer Model', () => { + it('Happy Path 1', async () => { + const manufacturer: ManufacturerModel = new ManufacturerModel( + 1, + ' name ' + ); + expect(manufacturer.id).toBe(1); + expect(manufacturer.name).toBe('NAME'); + expect(manufacturer.json()).toEqual({ id: 1, name: 'NAME' }); + }); + it('Happy Path 2', async () => { + const manufacturer: ManufacturerModel = new ManufacturerModel( + undefined, + ' name ' + ); + expect(manufacturer.id).toBeUndefined(); + expect(manufacturer.name).toBe('NAME'); + expect(manufacturer.json()).toEqual({ name: 'NAME' }); + }); + it('Error - Empty Name', async () => { + let errorMsg: string = ''; + try { + new ManufacturerModel(1, ' '); + } catch (error) { + if (error instanceof Error) { + errorMsg = error.message; + } + } + expect(errorMsg).toBe('Manufacturer name cannot be empty'); + }); + it('Error - Invalid ID', async () => { + let errorMsg: string = ''; + try { + new ManufacturerModel('A', ' name '); + } catch (error) { + if (error instanceof Error) { + errorMsg = error.message; + } + } + expect(errorMsg).toBe('Invalid manufacturer ID | A is not a number'); + }); +}); diff --git a/test/domain/model/prescription.model.utest.ts b/test/domain/model/prescription.model.utest.ts new file mode 100644 index 0000000..28d85bd --- /dev/null +++ b/test/domain/model/prescription.model.utest.ts @@ -0,0 +1,70 @@ +import { Frecuency as FrecuencyModel } from '../../../src/domain/model/frecuency.model'; +import { Prescription as PrescriptionModel } from '../../../src/domain/model/prescription.model'; +import { Type as TypeModel } from '../../../src/domain/model/type.model'; +const type: TypeModel = new TypeModel(1, 'NAME'); +const frecuency: FrecuencyModel = new FrecuencyModel(1, 1); +const date: Date = new Date(); +describe('Class Prescription Model', () => { + it('Happy Path 1', async () => { + const prescription: PrescriptionModel = new PrescriptionModel( + 1, + type, + frecuency, + true, + date + ); + expect(prescription.id).toBe(1); + expect(prescription.type).toBe(type); + expect(prescription.frecuency).toBe(frecuency); + expect(prescription.isSelfMedicated).toBeTruthy(); + expect(prescription.date).toBe(date); + expect(prescription.json()).toEqual({ + id: 1, + type: type.json(), + frecuency: frecuency.json(), + isSelfMedicated: true, + date: date + }); + }); + it('Happy Path 2', async () => { + const prescription: PrescriptionModel = new PrescriptionModel( + undefined, + type, + frecuency, + true + ); + expect(prescription.id).toBeUndefined(); + expect(prescription.type).toBe(type); + expect(prescription.frecuency).toBe(frecuency); + expect(prescription.isSelfMedicated).toBeTruthy(); + expect(prescription.date).not.toBeUndefined(); + expect(typeof prescription.date).toBe('object'); + }); + it('Happy Path 3', async () => { + const prescriptions: PrescriptionModel[] = [ + new PrescriptionModel(1, type, frecuency, true, date) + ]; + const jsonResult: any[] = PrescriptionModel.buildJSONArray(prescriptions); + expect(jsonResult.length).toBe(1); + expect(jsonResult).toEqual([ + { + id: 1, + type: type.json(), + frecuency: frecuency.json(), + isSelfMedicated: true, + date: date + } + ]); + }); + it('Error - Invalid ID', async () => { + let errorMsg: string = ''; + try { + new PrescriptionModel('A', type, frecuency, true, date); + } catch (error) { + if (error instanceof Error) { + errorMsg = error.message; + } + } + expect(errorMsg).toBe('Invalid prescription ID | A is not a number'); + }); +}); diff --git a/test/domain/model/purchase.model.utest.ts b/test/domain/model/purchase.model.utest.ts new file mode 100644 index 0000000..ab32396 --- /dev/null +++ b/test/domain/model/purchase.model.utest.ts @@ -0,0 +1,98 @@ +import { BrandedMedicine as BrandedMedicineModel } from '../../../src/domain/model/brandedMedicine.model'; +import { BrandedPresentation as BrandedPresentationModel } from '../../../src/domain/model/brandedPresentation.model'; +import { Manufacturer as ManufacturerModel } from '../../../src/domain/model/manufacturer.model'; +import { Substance as SubstanceModel } from '../../../src/domain/model/substance.model'; +import { Purchase as PurchaseModel } from '../../../src/domain/model/purchase.model'; +import { Type as TypeModel } from '../../../src/domain/model/type.model'; +import { ActiveComponentByUnit as ActiveComponentByUnitModel } from '../../../src/domain/model/activeComponentsByUnit.model'; +const manufacturer: ManufacturerModel = new ManufacturerModel(1, 'NAME'); +const substance1: SubstanceModel = new SubstanceModel(1, 'NAME'); +const type: TypeModel = new TypeModel(1, 'NAME'); +const brandedMedicine: BrandedMedicineModel = new BrandedMedicineModel( + 1, + 'NAME', + type, + manufacturer +); +const brandedPresentation: BrandedPresentationModel = + new BrandedPresentationModel( + 1, + brandedMedicine, + [new ActiveComponentByUnitModel(1, substance1)], + 1 + ); +describe('Class Purchase Model', () => { + it('Happy Path 1', async () => { + const date: Date = new Date(); + const purchase: PurchaseModel = new PurchaseModel( + 1, + brandedPresentation, + 1, + 1, + 1, + date + ); + expect(purchase.id).toBe(1); + expect(purchase.brandedPresentation.json()).toEqual( + brandedPresentation.json() + ); + expect(purchase.price).toBe(1); + expect(purchase.discount).toBe(1); + expect(purchase.shippingCost).toBe(1); + expect(purchase.date).toBe(date); + expect(purchase.json()).toEqual({ + id: 1, + date: date, + brandedPresentation: brandedPresentation.json(), + price: 1, + discount: 1, + shippingCost: 1 + }); + }); + it('Happy Path 2', async () => { + const purchase: PurchaseModel = new PurchaseModel( + null, + brandedPresentation, + 1, + 1, + 1 + ); + expect(purchase.id).toBeUndefined(); + expect(purchase.brandedPresentation.json()).toEqual( + brandedPresentation.json() + ); + expect(purchase.price).toBe(1); + expect(purchase.discount).toBe(1); + expect(purchase.shippingCost).toBe(1); + expect(purchase.date).not.toBeUndefined(); + expect(typeof purchase.date).toBe('object'); + }); + it('Happy Path 3', async () => { + const date: Date = new Date(); + const purchases: PurchaseModel[] = [ + new PurchaseModel(1, brandedPresentation, 1, 1, 1, date) + ]; + const jsonResult: any[] = PurchaseModel.buildJSONArray(purchases); + expect(jsonResult.length).toBe(1); + expect(jsonResult[0]).toEqual({ + id: 1, + date: date, + brandedPresentation: brandedPresentation.json(), + price: 1, + discount: 1, + shippingCost: 1 + }); + }); + it('Error - Invalid ID', async () => { + const date: Date = new Date(); + let errorMsg: string = ''; + try { + new PurchaseModel('A', brandedPresentation, 1, 1, 1, date); + } catch (error) { + if (error instanceof Error) { + errorMsg = error.message; + } + } + expect(errorMsg).toBe('Invalid purchase ID | A is not a number'); + }); +}); diff --git a/test/domain/model/stock.model.utest.ts b/test/domain/model/stock.model.utest.ts new file mode 100644 index 0000000..37e3766 --- /dev/null +++ b/test/domain/model/stock.model.utest.ts @@ -0,0 +1,77 @@ +import { BrandedMedicine as BrandedMedicineModel } from '../../../src/domain/model/brandedMedicine.model'; +import { BrandedPresentation as BrandedPresentationModel } from '../../../src/domain/model/brandedPresentation.model'; +import { Manufacturer as ManufacturerModel } from '../../../src/domain/model/manufacturer.model'; +import { Stock as StockModel } from '../../../src/domain/model/stock.model'; +import { Substance as SubstanceModel } from '../../../src/domain/model/substance.model'; +import { Type as TypeModel } from '../../../src/domain/model/type.model'; +import { ActiveComponentByUnit as ActiveComponentByUnitModel } from '../../../src/domain/model/activeComponentsByUnit.model'; +const date: Date = new Date(); +const type: TypeModel = new TypeModel(1, 'NAME'); +const manufacturer: ManufacturerModel = new ManufacturerModel(1, 'NAME'); +const substance: SubstanceModel = new SubstanceModel(1, 'NAME'); +const brandedMedicine: BrandedMedicineModel = new BrandedMedicineModel( + 1, + 'NAME', + type, + manufacturer +); +const brandedPresentation: BrandedPresentationModel = + new BrandedPresentationModel( + 1, + brandedMedicine, + [new ActiveComponentByUnitModel(1, substance)], + 1 + ); +describe('Class Stock Model', () => { + it('Happy Path 1', async () => { + const stock: StockModel = new StockModel(1, brandedPresentation, 1, date); + expect(stock.id).toBe(1); + expect(stock.brandedPresentation.json()).toEqual( + brandedPresentation.json() + ); + expect(stock.quantity).toBe(1); + expect(stock.date).toBe(date); + expect(stock.json()).toEqual({ + id: 1, + brandedPresentation: brandedPresentation.json(), + quantity: 1, + date: date + }); + }); + it('Happy Path 2', async () => { + const stock: StockModel = new StockModel(undefined, brandedPresentation, 1); + expect(stock.id).toBeUndefined(); + expect(stock.brandedPresentation.json()).toEqual( + brandedPresentation.json() + ); + expect(stock.quantity).toBe(1); + expect(stock.date).not.toBeUndefined(); + expect(typeof stock.date).toBe('object'); + }); + it('Happy Path 3', async () => { + const stocks: StockModel[] = [ + new StockModel(1, brandedPresentation, 1, date) + ]; + const jsonResult: any[] = StockModel.buildJSONArray(stocks); + expect(jsonResult.length).toBe(1); + expect(jsonResult).toEqual([ + { + id: 1, + brandedPresentation: brandedPresentation.json(), + quantity: 1, + date: date + } + ]); + }); + it('Error - Invalid ID', async () => { + let errorMsg: string = ''; + try { + new StockModel('A', brandedPresentation, 1, date); + } catch (error) { + if (error instanceof Error) { + errorMsg = error.message; + } + } + expect(errorMsg).toBe('Invalid stock ID | A is not a number'); + }); +}); diff --git a/test/domain/model/substance.model.utest.ts b/test/domain/model/substance.model.utest.ts new file mode 100644 index 0000000..2b1ea5a --- /dev/null +++ b/test/domain/model/substance.model.utest.ts @@ -0,0 +1,37 @@ +import { Substance as SubstanceModel } from '../../../src/domain/model/substance.model'; +describe('Class Substance Model', () => { + it('Happy Path 1', async () => { + const substance: SubstanceModel = new SubstanceModel(1, ' name '); + expect(substance.id).toBe(1); + expect(substance.name).toBe('NAME'); + expect(substance.json()).toEqual({ id: 1, name: 'NAME' }); + }); + it('Happy Path 2', async () => { + const substance: SubstanceModel = new SubstanceModel(undefined, ' name '); + expect(substance.id).toBeUndefined(); + expect(substance.name).toBe('NAME'); + expect(substance.json()).toEqual({ name: 'NAME' }); + }); + it('Error - Empty Name', async () => { + let errorMsg: string = ''; + try { + new SubstanceModel(1, ' '); + } catch (error) { + if (error instanceof Error) { + errorMsg = error.message; + } + } + expect(errorMsg).toBe('Substance name cannot be empty'); + }); + it('Error - Invalid ID', async () => { + let errorMsg: string = ''; + try { + new SubstanceModel('A', ' name '); + } catch (error) { + if (error instanceof Error) { + errorMsg = error.message; + } + } + expect(errorMsg).toBe('Invalid substance ID | A is not a number'); + }); +}); diff --git a/test/domain/model/type.model.utest.ts b/test/domain/model/type.model.utest.ts new file mode 100644 index 0000000..dc30e17 --- /dev/null +++ b/test/domain/model/type.model.utest.ts @@ -0,0 +1,37 @@ +import { Type as TypeModel } from '../../../src/domain/model/type.model'; +describe('Class Type Model', () => { + it('Happy Path 1', async () => { + const type: TypeModel = new TypeModel(1, ' name '); + expect(type.id).toBe(1); + expect(type.name).toBe('NAME'); + expect(type.json()).toEqual({ id: 1, name: 'NAME' }); + }); + it('Happy Path 2', async () => { + const type: TypeModel = new TypeModel(undefined, ' name '); + expect(type.id).toBeUndefined(); + expect(type.name).toBe('NAME'); + expect(type.json()).toEqual({ name: 'NAME' }); + }); + it('Error - Empty Name', async () => { + let errorMsg: string = ''; + try { + new TypeModel(1, ' '); + } catch (error) { + if (error instanceof Error) { + errorMsg = error.message; + } + } + expect(errorMsg).toBe('Type name cannot be empty'); + }); + it('Error - Invalid ID', async () => { + let errorMsg: string = ''; + try { + new TypeModel('A', ' name '); + } catch (error) { + if (error instanceof Error) { + errorMsg = error.message; + } + } + expect(errorMsg).toBe('Invalid type ID | A is not a number'); + }); +}); diff --git a/test/domain/model/user.model.utest.ts b/test/domain/model/user.model.utest.ts new file mode 100644 index 0000000..98fecc1 --- /dev/null +++ b/test/domain/model/user.model.utest.ts @@ -0,0 +1,110 @@ +import { ActiveComponentByUnit as ActiveComponentByUnitModel } from '../../../src/domain/model/activeComponentsByUnit.model'; +import { BrandedMedicine as BrandedMedicineModel } from '../../../src/domain/model/brandedMedicine.model'; +import { BrandedPresentation as BrandedPresentationModel } from '../../../src/domain/model/brandedPresentation.model'; +import { Frecuency as FrecuencyModel } from '../../../src/domain/model/frecuency.model'; +import { Manufacturer as ManufacturerModel } from '../../../src/domain/model/manufacturer.model'; +import { Prescription as PrescriptionModel } from '../../../src/domain/model/prescription.model'; +import { Purchase as PurchaseModel } from '../../../src/domain/model/purchase.model'; +import { Stock as StockModel } from '../../../src/domain/model/stock.model'; +import { Substance as SubstanceModel } from '../../../src/domain/model/substance.model'; +import { Type as TypeModel } from '../../../src/domain/model/type.model'; +import { User as UserModel } from '../../../src/domain/model/user.model'; +describe('Class User Model', () => { + it('Happy Path 1', async () => { + const User: UserModel = new UserModel(1, ' name '); + expect(User.id).toBe(1); + expect(User.name).toBe('NAME'); + expect(User.json()).toEqual({ + id: 1, + name: 'NAME', + prescriptions: [], + purchases: [], + stocks: [] + }); + }); + it('Happy Path 2', async () => { + const User: UserModel = new UserModel(undefined, ' name ', [], [], []); + expect(User.id).toBeUndefined(); + expect(User.name).toBe('NAME'); + expect(User.json()).toEqual({ + name: 'NAME', + prescriptions: [], + purchases: [], + stocks: [] + }); + }); + it('Happy Path 3', async () => { + const date: Date = new Date(); + const frecuency: FrecuencyModel = new FrecuencyModel(1, 1); + const manufacturer: ManufacturerModel = new ManufacturerModel(1, 'NAME'); + const substance: SubstanceModel = new SubstanceModel(1, 'NAME'); + const type: TypeModel = new TypeModel(1, 'NAME'); + const brandedMedicine: BrandedMedicineModel = new BrandedMedicineModel( + 1, + 'NAME', + type, + manufacturer + ); + const brandedPresentation: BrandedPresentationModel = + new BrandedPresentationModel( + 1, + brandedMedicine, + [new ActiveComponentByUnitModel(1, substance)], + 1 + ); + const prescription: PrescriptionModel = new PrescriptionModel( + 1, + type, + frecuency, + true, + date + ); + const purchase: PurchaseModel = new PurchaseModel( + 1, + brandedPresentation, + 1, + 1, + 1, + date + ); + const stock: StockModel = new StockModel(1, brandedPresentation, 1, date); + const user: UserModel = new UserModel( + 1, + ' name ', + [prescription], + [purchase], + [stock] + ); + expect(user.id).toBe(1); + expect(user.name).toBe('NAME'); + expect(user.json()).toEqual({ + id: 1, + name: 'NAME', + prescriptions: PrescriptionModel.buildJSONArray([prescription]), + purchases: PurchaseModel.buildJSONArray([purchase]), + stocks: StockModel.buildJSONArray([stock]) + }); + }); + it('Error - Empty Name', async () => { + let errorMsg: string = ''; + try { + new UserModel(1, ' ', [], [], []); + } catch (error) { + if (error instanceof Error) { + errorMsg = error.message; + } + } + expect(errorMsg).toBe('User name cannot be empty'); + }); + it('Error - Invalid ID', async () => { + let errorMsg: string = ''; + try { + new UserModel('A', ' name '); + } catch (error) { + if (error instanceof Error) { + errorMsg = error.message; + } + } + expect(errorMsg).toBe('Invalid user ID | A is not a number'); + }); +}); diff --git a/test/domain/util/configuration.util.utest.ts b/test/domain/util/configuration.util.utest.ts index 85e032a..11a4d39 100644 --- a/test/domain/util/configuration.util.utest.ts +++ b/test/domain/util/configuration.util.utest.ts @@ -7,9 +7,15 @@ describe('Class Configuration', () => { expect(ConfigurationUtil.packageName()).not.toBeNull(); expect(ConfigurationUtil.packageName()).not.toBeUndefined(); expect(ConfigurationUtil.port()).toBeGreaterThan(0); - expect(ConfigurationUtil.xxx()).not.toBe(''); - expect(ConfigurationUtil.xxx()).not.toBeNull(); - expect(ConfigurationUtil.xxx()).not.toBeUndefined(); + expect(ConfigurationUtil.postgresql().personalFinance.database).not.toBe( + '' + ); + expect(ConfigurationUtil.postgresql().personalFinance.host).not.toBe(''); + expect(ConfigurationUtil.postgresql().personalFinance.password).not.toBe( + '' + ); + expect(ConfigurationUtil.postgresql().personalFinance.port).not.toBe(0); + expect(ConfigurationUtil.postgresql().personalFinance.user).not.toBe(''); expect(ConfigurationUtil.isTrue('')).toBe(true); expect(ConfigurationUtil.isTrue('N')).toBe(false); expect(ConfigurationUtil.isTrue('S')).toBe(true); diff --git a/test/domain/util/converter.util.utest.ts b/test/domain/util/converter.util.utest.ts new file mode 100644 index 0000000..347e4c0 --- /dev/null +++ b/test/domain/util/converter.util.utest.ts @@ -0,0 +1,37 @@ +import { Converter as ConverterUtil } from '../../../src/domain/util/converter.util'; +describe('Class Converter', () => { + it('Happy Path - toNumber', async () => { + let errorMessage1 = ''; + expect(ConverterUtil.toNumber(undefined)).toBeUndefined(); + expect(ConverterUtil.toNumber(null)).toBeUndefined(); + expect(ConverterUtil.toNumber(' ')).toBeUndefined(); + expect(ConverterUtil.toNumber('')).toBeUndefined(); + expect(ConverterUtil.toNumber(' 1 ')).toBe(1); + expect(ConverterUtil.toNumber('1')).toBe(1); + expect(ConverterUtil.toNumber(1)).toBe(1); + try { + ConverterUtil.toNumber('A'); + } catch (error) { + if (error instanceof Error) { + errorMessage1 = error.message; + } + } + expect(errorMessage1).toBe('A is not a number'); + try { + ConverterUtil.toNumber('1.1'); + } catch (error) { + if (error instanceof Error) { + errorMessage1 = error.message; + } + } + expect(errorMessage1).toBe('1.1 is not a number'); + try { + ConverterUtil.toNumber('-1'); + } catch (error) { + if (error instanceof Error) { + errorMessage1 = error.message; + } + } + expect(errorMessage1).toBe('-1 is not a number'); + }); +}); diff --git a/test/infrastructure/persistence/repositories/frecuency.repository.itest.ts b/test/infrastructure/persistence/repositories/frecuency.repository.itest.ts new file mode 100644 index 0000000..093a166 --- /dev/null +++ b/test/infrastructure/persistence/repositories/frecuency.repository.itest.ts @@ -0,0 +1,39 @@ +import { Frecuency as FrecuencyModel } from '../../../../src/domain/model/frecuency.model'; +import { Configuration as ConfigurationUtil } from '../../../../src/domain/util/configuration.util'; +import { DatabasePool as DatabasePoolService } from '../../../../src/infrastructure/service/databasePool.service'; +import { Frecuency as FrecuencyRepository } from '../../../../src/infrastructure/persistence/repositories/frecuency.repository'; +describe('Class Frecuency Repository', () => { + it('Happy Path', async () => { + const dataConfiguration = ConfigurationUtil.postgresql().personalFinance; + const dbPool = new DatabasePoolService( + dataConfiguration.host, + dataConfiguration.database, + { user: dataConfiguration.user, password: dataConfiguration.password }, + dataConfiguration.port, + { rejectUnauthorized: false } + ); + const frecuencyRepository = new FrecuencyRepository(dbPool.get); + const allFrecuencies: FrecuencyModel[] = + await frecuencyRepository.getAllFrecuencies(); + expect(allFrecuencies.length).toBeGreaterThan(0); + if ( + allFrecuencies.length >= 0 && + allFrecuencies[0] && + allFrecuencies[0].id + ) { + const frecuency1: FrecuencyModel | undefined = + await frecuencyRepository.getFrecuencyById(allFrecuencies[0].id); + expect(frecuency1).not.toBeUndefined(); + const maxId = allFrecuencies.reduce( + (max, frecuency) => + frecuency.id && max && frecuency.id > max ? frecuency.id : max, + allFrecuencies[0].id + ); + if (maxId) { + const frecuency2: FrecuencyModel | undefined = + await frecuencyRepository.getFrecuencyById(maxId + 1); + expect(frecuency2).toBeUndefined(); + } + } + }); +}); diff --git a/test/infrastructure/persistence/repositories/manufacturer.repository.itest.ts b/test/infrastructure/persistence/repositories/manufacturer.repository.itest.ts new file mode 100644 index 0000000..9d42f47 --- /dev/null +++ b/test/infrastructure/persistence/repositories/manufacturer.repository.itest.ts @@ -0,0 +1,43 @@ +import { Manufacturer as ManufacturerModel } from '../../../../src/domain/model/manufacturer.model'; +import { Configuration as ConfigurationUtil } from '../../../../src/domain/util/configuration.util'; +import { DatabasePool as DatabasePoolService } from '../../../../src/infrastructure/service/databasePool.service'; +import { Manufacturer as ManufacturerRepository } from '../../../../src/infrastructure/persistence/repositories/manufacturer.repository'; +describe('Class Manufacturer Repository', () => { + it('Happy Path', async () => { + const dataConfiguration = ConfigurationUtil.postgresql().personalFinance; + const dbPool = new DatabasePoolService( + dataConfiguration.host, + dataConfiguration.database, + { user: dataConfiguration.user, password: dataConfiguration.password }, + dataConfiguration.port, + { rejectUnauthorized: false } + ); + const manufacturerRepository = new ManufacturerRepository(dbPool.get); + const allManufacturers: ManufacturerModel[] = + await manufacturerRepository.getAllManufacturers(); + expect(allManufacturers.length).toBeGreaterThan(0); + if ( + allManufacturers.length >= 0 && + allManufacturers[0] && + allManufacturers[0].id + ) { + const manufacturer1: ManufacturerModel | undefined = + await manufacturerRepository.getManufacturerById( + allManufacturers[0].id + ); + expect(manufacturer1).not.toBeUndefined(); + const maxId = allManufacturers.reduce( + (max, manufacturer) => + manufacturer.id && max && manufacturer.id > max + ? manufacturer.id + : max, + allManufacturers[0].id + ); + if (maxId) { + const manufacturer2: ManufacturerModel | undefined = + await manufacturerRepository.getManufacturerById(maxId + 1); + expect(manufacturer2).toBeUndefined(); + } + } + }); +}); diff --git a/test/infrastructure/persistence/repositories/prescription.repository.itest.ts b/test/infrastructure/persistence/repositories/prescription.repository.itest.ts new file mode 100644 index 0000000..71fe16e --- /dev/null +++ b/test/infrastructure/persistence/repositories/prescription.repository.itest.ts @@ -0,0 +1,26 @@ +import { User as UserModel } from '../../../../src/domain/model/user.model'; +import { Prescription as PrescriptionModel } from '../../../../src/domain/model/prescription.model'; +import { Configuration as ConfigurationUtil } from '../../../../src/domain/util/configuration.util'; +import { Prescription as PrescriptionRepository } from '../../../../src/infrastructure/persistence/repositories/prescription.repository'; +import { DatabasePool as DatabasePoolService } from '../../../../src/infrastructure/service/databasePool.service'; +import { User as UserRepository } from '../../../../src/infrastructure/persistence/repositories/user.repository'; +describe('Class Prescription Repository', () => { + it('Happy Path 1', async () => { + const dataConfiguration = ConfigurationUtil.postgresql().personalFinance; + const dbPool = new DatabasePoolService( + dataConfiguration.host, + dataConfiguration.database, + { user: dataConfiguration.user, password: dataConfiguration.password }, + dataConfiguration.port, + { rejectUnauthorized: false } + ); + const prescription = new PrescriptionRepository(dbPool.get); + const userRepository = new UserRepository(dbPool.get); + const allUsers: UserModel[] = await userRepository.getAllUsers(); + if (allUsers.length > 0) { + const result: PrescriptionModel[] = + await prescription.getPrescriptionsByUser(allUsers[0]); + expect(result.length).toBeGreaterThan(0); + } + }, 10000); +}); diff --git a/test/infrastructure/persistence/repositories/substance.repository.itest.ts b/test/infrastructure/persistence/repositories/substance.repository.itest.ts new file mode 100644 index 0000000..525e20b --- /dev/null +++ b/test/infrastructure/persistence/repositories/substance.repository.itest.ts @@ -0,0 +1,35 @@ +import { Substance as SubstanceModel } from '../../../../src/domain/model/substance.model'; +import { Configuration as ConfigurationUtil } from '../../../../src/domain/util/configuration.util'; +import { DatabasePool as DatabasePoolService } from '../../../../src/infrastructure/service/databasePool.service'; +import { Substance as SubstanceRepository } from '../../../../src/infrastructure/persistence/repositories/substance.repository'; +describe('Class Substance Repository', () => { + it('Happy Path', async () => { + const dataConfiguration = ConfigurationUtil.postgresql().personalFinance; + const dbPool = new DatabasePoolService( + dataConfiguration.host, + dataConfiguration.database, + { user: dataConfiguration.user, password: dataConfiguration.password }, + dataConfiguration.port, + { rejectUnauthorized: false } + ); + const substanceRepository = new SubstanceRepository(dbPool.get); + const allSubstances: SubstanceModel[] = + await substanceRepository.getAllSubstances(); + expect(allSubstances.length).toBeGreaterThan(0); + if (allSubstances.length >= 0 && allSubstances[0] && allSubstances[0].id) { + const substance1: SubstanceModel | undefined = + await substanceRepository.getSubstanceById(allSubstances[0].id); + expect(substance1).not.toBeUndefined(); + const maxId = allSubstances.reduce( + (max, substance) => + substance.id && max && substance.id > max ? substance.id : max, + allSubstances[0].id + ); + if (maxId) { + const substance2: SubstanceModel | undefined = + await substanceRepository.getSubstanceById(maxId + 1); + expect(substance2).toBeUndefined(); + } + } + }); +}); diff --git a/test/infrastructure/persistence/repositories/type.repository.itest.ts b/test/infrastructure/persistence/repositories/type.repository.itest.ts new file mode 100644 index 0000000..61f04ba --- /dev/null +++ b/test/infrastructure/persistence/repositories/type.repository.itest.ts @@ -0,0 +1,35 @@ +import { Type as TypeModel } from '../../../../src/domain/model/type.model'; +import { Configuration as ConfigurationUtil } from '../../../../src/domain/util/configuration.util'; +import { DatabasePool as DatabasePoolService } from '../../../../src/infrastructure/service/databasePool.service'; +import { Type as TypeRepository } from '../../../../src/infrastructure/persistence/repositories/type.repository'; +describe('Class Type Repository', () => { + it('Happy Path', async () => { + const dataConfiguration = ConfigurationUtil.postgresql().personalFinance; + const dbPool = new DatabasePoolService( + dataConfiguration.host, + dataConfiguration.database, + { user: dataConfiguration.user, password: dataConfiguration.password }, + dataConfiguration.port, + { rejectUnauthorized: false } + ); + const typeRepository = new TypeRepository(dbPool.get); + const allTypes: TypeModel[] = await typeRepository.getAllTypes(); + expect(allTypes.length).toBeGreaterThan(0); + if (allTypes.length >= 0 && allTypes[0] && allTypes[0].id) { + const type1: TypeModel | undefined = await typeRepository.getTypeById( + allTypes[0].id + ); + expect(type1).not.toBeUndefined(); + const maxId = allTypes.reduce( + (max, type) => (type.id && max && type.id > max ? type.id : max), + allTypes[0].id + ); + if (maxId) { + const type2: TypeModel | undefined = await typeRepository.getTypeById( + maxId + 1 + ); + expect(type2).toBeUndefined(); + } + } + }); +}); diff --git a/test/infrastructure/persistence/repositories/user.repository.itest.ts b/test/infrastructure/persistence/repositories/user.repository.itest.ts new file mode 100644 index 0000000..36b3542 --- /dev/null +++ b/test/infrastructure/persistence/repositories/user.repository.itest.ts @@ -0,0 +1,35 @@ +import { User as UserModel } from '../../../../src/domain/model/user.model'; +import { Configuration as ConfigurationUtil } from '../../../../src/domain/util/configuration.util'; +import { DatabasePool as DatabasePoolService } from '../../../../src/infrastructure/service/databasePool.service'; +import { User as UserRepository } from '../../../../src/infrastructure/persistence/repositories/user.repository'; +describe('Class User Repository', () => { + it('Happy Path', async () => { + const dataConfiguration = ConfigurationUtil.postgresql().personalFinance; + const dbPool = new DatabasePoolService( + dataConfiguration.host, + dataConfiguration.database, + { user: dataConfiguration.user, password: dataConfiguration.password }, + dataConfiguration.port, + { rejectUnauthorized: false } + ); + const userRepository = new UserRepository(dbPool.get); + const allUsers: UserModel[] = await userRepository.getAllUsers(); + expect(allUsers.length).toBeGreaterThan(0); + if (allUsers.length >= 0 && allUsers[0] && allUsers[0].id) { + const user1: UserModel | undefined = await userRepository.getUserById( + allUsers[0].id + ); + expect(user1).not.toBeUndefined(); + const maxId = allUsers.reduce( + (max, user) => (user.id && max && user.id > max ? user.id : max), + allUsers[0].id + ); + if (maxId) { + const user2: UserModel | undefined = await userRepository.getUserById( + maxId + 1 + ); + expect(user2).toBeUndefined(); + } + } + }); +}); diff --git a/test/infrastructure/service/databasePool.servicer.itest.ts b/test/infrastructure/service/databasePool.servicer.itest.ts new file mode 100644 index 0000000..f56a399 --- /dev/null +++ b/test/infrastructure/service/databasePool.servicer.itest.ts @@ -0,0 +1,27 @@ +import { Pool as PgPool } from 'pg'; +import { Configuration as ConfigurationUtil } from '../../../src/domain/util/configuration.util'; +import { DatabasePool as DatabasePoolService } from '../../../src/infrastructure/service/databasePool.service'; +describe('Class Database Pool Service - Integration', () => { + it('Happy Path', async () => { + let errorMsg = ''; + const dataConfiguration = ConfigurationUtil.postgresql().personalFinance; + const dbPool = new DatabasePoolService( + dataConfiguration.host, + dataConfiguration.database, + { user: dataConfiguration.user, password: dataConfiguration.password }, + dataConfiguration.port, + { rejectUnauthorized: false } + ); + let pgPool: PgPool; + try { + pgPool = dbPool.get; + const res = await pgPool.query('SELECT version()'); + console.log('Connected to PostgreSQL:', res.rows[0].version); + } catch (error) { + if (error instanceof Error) { + errorMsg = error.message; + } + } + expect(errorMsg).toBe(''); + }); +}); diff --git a/test/infrastructure/service/databasePool.servicer.utest.ts b/test/infrastructure/service/databasePool.servicer.utest.ts new file mode 100644 index 0000000..ddf2392 --- /dev/null +++ b/test/infrastructure/service/databasePool.servicer.utest.ts @@ -0,0 +1,37 @@ +import { DatabasePool as DatabasePoolService } from '../../../src/infrastructure/service/databasePool.service'; +describe('Class Database Pool Service - Unit', () => { + it('Happy Path 1', async () => { + const dbPool = new DatabasePoolService( + 'host', + 'database', + { user: 'user', password: 'password' }, + 1234, + { rejectUnauthorized: false } + ); + expect(dbPool.host).toBe('host'); + expect(dbPool.database).toBe('database'); + expect(dbPool.password).toBe('password'); + expect(dbPool.port).toBe(1234); + expect(dbPool.ssl).toEqual({ rejectUnauthorized: false }); + expect(dbPool.user).toBe('user'); + try { + dbPool.get; + } catch (error) { + if (error instanceof Error) { + console.log(error.message); + } + } + }); + it('Happy Path 2', async () => { + const dbPool = new DatabasePoolService('host', 'database', { + user: 'user', + password: 'password' + }); + expect(dbPool.host).toBe('host'); + expect(dbPool.database).toBe('database'); + expect(dbPool.password).toBe('password'); + expect(dbPool.port).toBe(5432); + expect(dbPool.ssl).toBeUndefined(); + expect(dbPool.user).toBe('user'); + }); +});