Commit d587b50a authored by Frank Bergmann's avatar Frank Bergmann

Initial Import

parents
Pipeline #943 failed with stages
<?xml version="1.0"?>
<!-- Generated by the OpenACS Package Manager -->
<package key="intranet-navision" url="http://openacs.org/repository/apm/packages/intranet-navision" type="apm_application">
<package-name>]project-open[ Microsoft NAV (Navision) Integration</package-name>
<pretty-plural>]project-open[ Microsoft NAV (Navision) Integration</pretty-plural>
<initial-install-p>f</initial-install-p>
<singleton-p>t</singleton-p>
<implements-subsite-p>f</implements-subsite-p>
<inherit-templates-p>f</inherit-templates-p>
<auto-mount>intranet-navision</auto-mount>
<version name="4.0.4.0.0" url="http://openacs.org/repository/download/apm/intranet-navision-4.0.4.0.0.apm">
<owner url="mailto:frank.bergmann@project-open.com">Frank Bergmann</owner>
<summary>Imports a number of objects from NAV into ]project-open[</summary>
<vendor url="http://www.project-open.com/">]project-open[</vendor>
<description format="text/html">Provides a number of PL/SQL scripts that take as input a number of NAV tables that have been copied to the PostgreSQL database. The scripts insert/update the relevant ]project-open[ objects.</description>
<maturity>0</maturity>
<provides url="intranet-navision" version="4.0.4.0.0"/>
<callbacks>
</callbacks>
<parameters>
<!-- No version parameters -->
</parameters>
</version>
</package>
This diff is collapsed.
---------------------------------------------------------------------------------
-- Navision Relationship between contacts and companies
---------------------------------------------------------------------------------
-- Adding the NAV "Contact Business Relationship" to acs_rels
drop function nav_import_contact_business_relationships();
create or replace function nav_import_contact_business_relationships ()
returns integer as $BODY$
DECLARE
row RECORD;
v_user_id integer;
v_company_id integer;
v_exists_p integer;
v_group_id integer;
BEGIN
FOR row IN
select *
from nav."Contact Business Relation"
order by "Contact No_", "No_"
LOOP
--------------------------------------------------------------------
-- Lookup user
select min(person_id) into v_user_id from persons
where nav_contact_nr ~ row."Contact No_";
IF v_user_id is null THEN
RAISE WARNING 'Did not find user=%', row."Contact No_";
continue;
END IF;
--------------------------------------------------------------------
-- Lookup company
select company_id into v_company_id from im_companies
where nav_vendor_nr = row."No_";
IF v_company_id is null THEN
select company_id into v_company_id from im_companies
where nav_customer_nr = row."No_";
END IF;
IF v_company_id is null THEN
RAISE WARNING 'Did not find company=%', row."No_";
continue;
END IF;
--------------------------------------------------------------------
-- Create the relationship between company and contact
RAISE NOTICE 'Making % member of %', im_name_from_user_id(v_user_id), v_company_id;
PERFORM im_biz_object_member__new (
null,
'im_biz_object_member',
v_company_id, -- the business object
v_user_id, -- the person related to biz_object
1300, -- role: Full Member
null, -- percentage
null, -- creation user
'0.0.0.0' -- creation IP
);
--------------------------------------------------------------------
-- Make the contact the "primary_contact_id" of the company
-- and set the nav_vendor_nr on the person
update im_companies
set primary_contact_id = v_user_id
where company_id = v_company_id;
update persons
set nav_primary_contact_for_company_id = v_company_id
where person_id = v_user_id;
--------------------------------------------------------------------
-- Make the user member of the groups Providers or Customers
IF 'Z' = substring(row."Business Relation Code" for 1) THEN
RAISE NOTICE 'User is a Customer: %', row."Contact No_";
select group_id into v_group_id from groups
where group_name = 'Customers';
ELSE
RAISE NOTICE 'User is a Provider: %', row."Contact No_";
select group_id into v_group_id from groups
where group_name = 'Freelancers';
END IF;
-- Check if the user is already a member of that group
select count(*)
into v_exists_p
from acs_rels r
where rel_type = 'membership_rel' and
object_id_one = v_group_id and
object_id_two = v_user_id;
-- Add the user to the group if he is not a member already.
IF v_exists_p = 0 THEN
RAISE NOTICE 'Adding User to Group: %', row."Contact No_";
PERFORM membership_rel__new(
null, -- rel_id, default null
'membership_rel', -- object_type, default membership_rel
v_group_id, -- object_id_one
v_user_id, -- object_id_two
'approved', -- new__member_state, default approved
null, -- creation_user, default null
'0.0.0.0' -- creation_ip, default null
);
END IF;
END LOOP;
RETURN 0;
END;$BODY$ language 'plpgsql';
select nav_import_contact_business_relationships ();
---------------------------------------------------------------------------------
-- Navision Services per Contacts
---------------------------------------------------------------------------------
-- Adding the services to the ]po[ Freelance Skill Database
drop function nav_import_contact_services();
create or replace function nav_import_contact_services ()
returns integer as $BODY$
DECLARE
row RECORD;
v_user_id integer;
v_service_id integer;
v_exists_p integer;
v_source_language varchar;
v_source_language_id integer;
v_target_language varchar;
v_target_language_id integer;
v_skill_type_id integer;
v_skill_type_category varchar;
BEGIN
FOR row IN
select *
from nav."Contact Service"
where "Service Name" = 'Translation'
order by "Contact No_"
LOOP
-- Lookup user
select person_id into v_user_id from persons
where nav_contact_nr ~ row."Contact No_";
IF v_user_id is null THEN
RAISE WARNING 'Did not find user=%', row."Contact No_";
continue;
END IF;
-- Transform source and target languages into ]po[ convention
v_source_language := lower(substring(row."Source Language" from '^(..)'));
v_source_language_id := import_cat(v_source_language, 'Intranet Translation Language');
IF v_source_language_id is null THEN
RAISE WARNING 'Did not find source language %', v_source_language;
continue;
END IF;
v_target_language := lower(substring(row."Target Language" from '^(..)'));
IF length(row."Target Language") > 2 THEN
v_target_language := v_target_language || '_' || lower(substring(row."Target Language" from '^...(..)'));
END IF;
v_target_language_id := import_cat(v_target_language, 'Intranet Translation Language');
IF v_target_language_id is null THEN
RAISE WARNING 'Did not find target language %', v_target_language;
continue;
END IF;
-- Add Source Language
v_skill_type_id := 2000;
select count(*) into v_exists_p from im_freelance_skills
where user_id = v_user_id and skill_id = v_source_language_id;
IF v_exists_p = 0 THEN
RAISE NOTICE 'Adding Source Language: User=%, Skill=%', row."Contact No_", v_source_language;
insert into im_freelance_skills (
user_id, skill_id, skill_type_id, claimed_experience_id, confirmed_experience_id
) values (
v_user_id, v_source_language_id, v_skill_type_id, 2203, 2203
);
END IF;
-- Add Target Language
v_skill_type_id := 2002;
select count(*) into v_exists_p from im_freelance_skills
where user_id = v_user_id and skill_id = v_target_language_id;
IF v_exists_p = 0 THEN
RAISE NOTICE 'Adding Target Language: User=%, Skill=%', row."Contact No_", v_target_language;
insert into im_freelance_skills (
user_id, skill_id, skill_type_id, claimed_experience_id, confirmed_experience_id
) values (
v_user_id, v_target_language_id, v_skill_type_id, 2203, 2203
);
END IF;
END LOOP;
RETURN 0;
END;$BODY$ language 'plpgsql';
select nav_import_contact_services ();
---------------------------------------------------------------------------------
-- Navision Tools per Contacts
---------------------------------------------------------------------------------
SELECT im_category_new (nextval('im_categories_seq')::integer,'Atril Deja Vu','Intranet TM Tool');
SELECT im_category_new (nextval('im_categories_seq')::integer,'Trados ExtraTerm','Intranet TM Tool');
SELECT im_category_new (nextval('im_categories_seq')::integer,'Trados MultiTerm','Intranet TM Tool');
SELECT im_category_new (nextval('im_categories_seq')::integer,'Trados TagEditor','Intranet TM Tool');
SELECT im_category_new (nextval('im_categories_seq')::integer,'Trados Workbench','Intranet TM Tool');
SELECT im_category_new (nextval('im_categories_seq')::integer,'WordFast','Intranet TM Tool');
SELECT im_category_new (nextval('im_categories_seq')::integer,'Star Transit','Intranet TM Tool');
drop function nav_import_contact_tool_categories();
create or replace function nav_import_contact_tool_categories ()
returns integer as $BODY$
DECLARE
row RECORD;
v_exists_p integer;
BEGIN
FOR row IN
select distinct "Tools Name"
from nav."Contact Tools"
LOOP
select count(*) into v_exists_p from im_categories
where category = row."Tools Name" and category_type in ('Intranet TM Tool', 'Intranet LOC Tool');
IF v_exists_p = 0 THEN
PERFORM im_category_new (nextval('im_categories_seq')::integer,row."Tools Name",'Intranet LOC Tool');
END IF;
END LOOP;
RETURN 0;
END;$BODY$ language 'plpgsql';
select nav_import_contact_tool_categories ();
-- Adding the tools the ]po[ Freelance Skill Database
drop function nav_import_contact_tools();
create or replace function nav_import_contact_tools ()
returns integer as $BODY$
DECLARE
row RECORD;
v_user_id integer;
v_tool_id integer;
v_exists_p integer;
v_skill_type_id integer;
v_skill_type_category varchar;
BEGIN
FOR row IN
select *
from nav."Contact Tools"
order by "Contact No_"
LOOP
-- Lookup user
select person_id into v_user_id from persons
where nav_contact_nr ~ row."Contact No_";
IF v_user_id is null THEN
RAISE WARNING 'Did not find user=%', row."Contact No_";
continue;
END IF;
-- Lookup Tool
select category_id into v_tool_id from im_categories
where category = row."Tools Name" and category_type in ('Intranet TM Tool', 'Intranet LOC Tool');
IF v_tool_id is null THEN
RAISE WARNING 'Did not find tool=%', row."Tools Name";
continue;
END IF;
-- Determine the skill type
select category_type into v_skill_type_category from im_categories where category_id = v_tool_id;
select category_id into v_skill_type_id from im_categories
where category_type = 'Intranet Skill Type' and
category_description = v_skill_type_category;
IF v_skill_type_id is null THEN
RAISE WARNING 'Did not find skill type=%, tool=%', v_skill_type_category, v_tool_id;
continue;
END IF;
-- Check if the entry was already there
select count(*) into v_exists_p from im_freelance_skills
where user_id = v_user_id and skill_id = v_tool_id;
IF v_exists_p = 0 THEN
RAISE NOTICE 'Adding Skill: User=%, Skill=%', row."Contact No_", row."Tools Name";
insert into im_freelance_skills (
user_id, skill_id, skill_type_id, claimed_experience_id, confirmed_experience_id
) values (
v_user_id, v_tool_id, v_skill_type_id, 2203, 2203
);
END IF;
END LOOP;
RETURN 0;
END;$BODY$ language 'plpgsql';
select nav_import_contact_tools ();
---------------------------------------------------------------------------------
-- Navision Contacts
---------------------------------------------------------------------------------
-- convert empty strings in NULL values to allow coalesce() to work
--
ALTER TABLE nav."Contact" ALTER COLUMN "First Name" DROP NOT NULL;
update nav."Contact" set "First Name" = null where "First Name" = '';
--
ALTER TABLE nav."Contact" ALTER COLUMN "Surname" DROP NOT NULL;
update nav."Contact" set "Surname" = null where "Surname" = '';
-- Actually create new users by going through the nav."Contact" table
-- line by line and inserting the user into the DB.
--
drop function nav_import_contact();
create or replace function nav_import_contact ()
returns integer as $BODY$
DECLARE
row RECORD;
v_user_id integer;
v_string varchar;
v_exists_p integer;
v_username varchar;
v_group_id integer;
v_email varchar;
v_email_domain varchar;
v_email_name varchar;
v_customer_group_id integer;
v_first_names varchar;
v_last_name varchar;
BEGIN
FOR row IN
select *,
coalesce("First Name", substring("Name" from '^([^ ]+)')) as first_names,
coalesce("Surname", substring("Name" from '^[^ ]+ (.*)$')) as last_name
from nav."Contact"
order by "No_"
LOOP
v_email := substring(lower(trim(row."E-Mail")) from '[a-zA-Z0-9_\_\.]+\@[a-zA-Z0-9_\_\.]+');
v_email_domain := substring(v_email from '@(.*)');
v_email_name := substring(v_email from '(.*)@');
v_email := v_email_name || '@' || v_email_domain;
-- Transform first and last name
v_first_names := row.first_names;
v_last_name := row.last_name;
-- Accept empty last names for company contacts. Replace by first name
IF row."Type" = 0 and (v_last_name is null OR v_last_name = '') THEN
v_last_name := v_first_names;
END IF;
-- Accept empty email for company contacts.
IF row."Type" = 0 and (v_email is null OR v_email = '') THEN
v_email = v_first_names ||'.'||v_last_name||'@nowhere.com';
END IF;
RAISE NOTICE 'Processing User: first=%, last=%, email=%, no=%, company_no=%',
v_first_names, v_last_name, v_email, row."No_", row."Company No_";
IF v_first_names is null OR v_first_names = '' THEN
RAISE NOTICE 'Skipping User (empty first_names): % % (%)', v_first_names, v_last_name, v_email;
continue;
END IF;
IF v_last_name is null OR v_last_name = '' THEN
RAISE NOTICE 'Skipping User (empty last_name): % % (%)', v_first_names, v_last_name, v_email;
continue;
END IF;
IF v_email is null OR v_email = '' THEN
RAISE NOTICE 'Skipping User (empty email): % % (%)', v_first_names, v_last_name, v_email;
continue;
END IF;
-- Check if the user already exists / has been imported already
-- during the last run of this script. PrimKey is first_names+last_name.
-- Check 1. ContactNo_, 2. Email and 3. Name
select min(person_id) into v_user_id from persons
where nav_contact_nr ~ row."No_";
IF v_user_id is null THEN
select min(party_id) into v_user_id from parties p
where trim(lower(p.email)) = trim(lower(v_email));
END IF;
IF v_user_id is null THEN
select min(person_id) into v_user_id from persons p
where (trim(lower(p.first_names)) = trim(lower(v_first_names)) and
trim(lower(p.last_name)) = trim(lower(v_last_name)));
END IF;
-- Create a new user if the user wasnt there
IF v_user_id is null THEN
RAISE NOTICE 'Insert User: % % (%)', v_first_names, v_last_name, v_email;
-- Create a default username
v_username := v_email;
v_user_id := acs__add_user(
null, 'user', now(), 0, '0.0.0.0',
null, v_username, v_email, null,
v_first_names, v_last_name,
'hashed_password', 'salt',
v_username, 't', 'approved'
);
INSERT INTO users_contact (user_id) VALUES (v_user_id);
INSERT INTO im_employees (employee_id) VALUES (v_user_id);
INSERT INTO im_freelancers (user_id) VALUES (v_user_id);
ELSE
SELECT username into v_username from users
where user_id = v_user_id;
END IF;
-----------------------------------------------------------------
-- This is the main part of the import process, this part is
-- executed for every line in the import_users table every time
-- this script is executed.
-- Update the users information, no matter whether its a new or
-- an already existing user.
RAISE NOTICE 'Update User: email=%, id=%', v_email, v_user_id;
update users_contact set
wa_line1 = row."Address",
wa_line2 = row."Address 2",
wa_city = row."City",
wa_postal_code = row."Post Code",
work_phone = row."Phone No_",
fax = row."Telex No_",
pager = row."Pager"
where user_id = v_user_id;
update users set
username = v_username
where user_id = v_user_id;
update persons set
first_names = v_first_names,
last_name = v_last_name,
nav_middle_name = row."Middle Name",
nav_skype = row."Skype"
where person_id = v_user_id;
update parties set
url = row."Home Page"
where party_id = v_user_id;
update im_employees set
job_title = row."Job Title"
where employee_id = v_user_id;
----------------------------------------------------------------
-- Update persons.nav_contact_nr. It's a space separated list of NAV contact_nrs
select coalesce(nav_contact_nr, '') into v_string
from persons where person_id = v_user_id;
IF v_string !~ row."No_" THEN
IF v_string is null or v_string = ''
THEN v_string := row."No_";
ELSE v_string := v_string || ' ' || row."No_";
END IF;
update persons
set nav_contact_nr = v_string
where person_id = v_user_id;
END IF;
----------------------------------------------------------------
-- Make the new user a member of group Customers or Providers
-- select out the ID of the Customers group
IF 'Z' = substring(row."No_" for 1) THEN
RAISE NOTICE 'User is a Customer: %', v_email;
select group_id into v_customer_group_id from groups
where group_name = 'Customers';
ELSE
RAISE NOTICE 'User is a Provider: %', v_email;
select group_id into v_customer_group_id from groups
where group_name = 'Freelancers';
END IF;
-- Check if the user is already a member of that group
select count(*)
into v_exists_p
from acs_rels r
where rel_type = 'membership_rel' and
object_id_one = v_customer_group_id and
object_id_two = v_user_id;
-- Add the user to the group if he is not a member already.
IF false AND v_exists_p = 0 THEN
RAISE NOTICE 'Adding User to Group: %', v_email;
PERFORM membership_rel__new(
null, -- rel_id, default null
'membership_rel', -- object_type, default membership_rel
v_customer_group_id, -- object_id_one
v_user_id, -- object_id_two
'approved', -- new__member_state, default approved
null, -- creation_user, default null
'0.0.0.0' -- creation_ip, default null
);
END IF;
END LOOP;
RETURN 0;
END;$BODY$ language 'plpgsql';
-- select nav_import_contact ();
-- Actually create new users by going through the nav."Contact" table
-- line by line and inserting the user into the DB.
--
drop function nav_import_contact_memberships();
create or replace function nav_import_contact_memberships ()
returns integer as $BODY$
DECLARE
row RECORD;
v_user_id integer;
v_company_id integer;
BEGIN
FOR row IN
select *,
coalesce("First Name", substring("Name" from '^([^ ]+)')) as first_names,
coalesce("Surname", substring("Name" from '^[^ ]+ (.*)$')) as last_name
from nav."Contact"
where " Company No_" = 'ZL00140'
order by "No_"
LOOP
RAISE NOTICE 'Contact Memberships: Processing User: name=%, email=%, no=%, company_no=%',
row."Name", row."E-Mail", row."No_", row."Company No_";
--------------------------------------------------------------------
-- Interpret the "Company No_".
-- This key references a "Contact" of type 0=Company, which in turn
-- is connected to the "Vendor" via "Contact Business Relation".
v_user_id := (select min(person_id) from persons where nav_contact_nr ~ row."No_");
IF v_user_id is null THEN
RAISE WARNING 'Contact Memberships: Did not find user no=%, name=%', row."No_", row."Name";
continue;
END IF;
-- Check for the type of contact:
-- 0=Company
-- 1=User
IF 0 = row."Type" THEN
RAISE NOTICE 'Contact Memberships: Found a "company": no=%, name=%', row."No_", row."Name";
-- Type=0: A company
select min(company_id) into v_company_id
from im_companies
where (nav_customer_nr in (select "No_" from nav."Contact Business Relation" where "Contact No_" = row."No_") OR
nav_vendor_nr in (select "No_" from nav."Contact Business Relation" where "Contact No_" = row."No_"))
;
ELSE
RAISE NOTICE 'Contact Memberships: Found a "person": no=%, name=%', row."No_", row."Name";
-- Type=1: A user that represents a company
v_company_id := (select min(company_id) from im_companies where nav_vendor_nr in (
select "No_" from nav."Vendor" where "No_" in (
select "No_" from nav."Contact Business Relation" where "Contact No_" in (
select "No_" from nav."Contact" where "No_" = row."Company No_"
)
)
));
END IF;
IF v_company_id is null THEN
RAISE WARNING 'Contact Memberships: Did not find company no=%', row."Company No_";
continue;
END IF;
RAISE NOTICE 'Contact Memberships: Adding User % to Company % for %', row."E-Mail", v_company_id, row."Company No_";
PERFORM im_biz_object_member__new (
null,
'im_biz_object_member',
v_company_id, -- the business object
v_user_id, -- the person related to biz_object
1300, -- role: Full Member
null, -- percentage
null, -- creation user
'0.0.0.0' -- creation IP
);
END LOOP;
RETURN 0;
END;$BODY$ language 'plpgsql';
select nav_import_contact_memberships ();
This diff is collapsed.
---------------------------------------------------------------------------------
-- Navision Employees Table
---------------------------------------------------------------------------------
-- This script should be run AFTER importing users from Secure Access
-- Again, the Email ("MT Email") is used as the primary key to identify
-- a user.
drop function nav_import_employee();
create or replace function nav_import_employee ()
returns integer as $BODY$
DECLARE
row RECORD;
v_loginname varchar;
v_disabled_p integer;
v_count integer;
v_user_id integer;
v_user_login varchar;
v_email varchar;
v_email_domain varchar;
v_email_name varchar;
v_supervisor_id integer;
v_exists_p integer;
v_group_id integer;
BEGIN
FOR row IN
select *,
trim(lower(substring("MT Email" from '^([^@]+)'))) as windows_login
from nav."Employee"
order by "Personal ID"
LOOP
-- get and massage the email.
v_email := lower(row."MT Email");
v_email_domain := substring(v_email from '@(.*)');
v_email_name := substring(v_email from '(.*)@');
v_email := v_email_name || '@' || v_email_domain;
IF row."First Name" is null OR row."First Name" = '' THEN
RAISE NOTICE 'Skipping User (empty first_name): % % (%)', row."First Name", row."Surname", v_email;
continue;
END IF;
IF row."Surname" is null OR row."Surname" = '' THEN
RAISE NOTICE 'Skipping User (empty last_name): % % (%)', row."First Name", row."Surname", v_email;
continue;
END IF;
IF row."MT Email" is null OR row."MT Email" = '' or v_email is null or v_email = '' THEN
RAISE NOTICE 'Skipping User (empty email): % % (%)', row."First Name", row."Surname", v_email;
continue;
END IF;
-- Check if the user already exists.
v_user_id := null;
IF v_user_id is null THEN
select min(person_id) into v_user_id from persons
where nav_windows_login = row.windows_login;
END IF;
IF v_user_id is null THEN
select min(party_id) into v_user_id from parties
where email = v_email;
END IF;
IF v_user_id is null THEN
RAISE WARNING 'Did not find user email: % % (%)', row."First Name", row."Surname", v_email;
continue;
END IF;
RAISE NOTICE 'Processing User: First=%, Last=%, Email=%, OID=% => %', row."First Name", row."Surname", v_email, row."Personal ID", v_user_id;
-- Get the supervisor and make sure the user is not his own supervisor
select lower(person_id) into v_supervisor_id from persons
where nav_windows_login = trim(lower(row."Superior"));
IF v_supervisor_id = v_user_id THEN v_supervisor_id := NULL; END IF;
IF row."Superior" is not null and row."Superior" != '' and v_supervisor_id is null THEN
RAISE WARNING 'Did not find superior % for user %', row."Superior", row."MT Email";
END IF;
update persons set
nav_employee_nr = row."Personal ID"
where person_id = v_user_id;
update im_employees set
supervisor_id = v_supervisor_id
where employee_id = v_user_id;
-- Make the new user an Employee
select group_id into v_group_id from groups
where group_name = 'Employees';
IF v_exists_p = 0 THEN
RAISE NOTICE 'Adding: user=%, group=%', v_user_id, v_group_id;
PERFORM membership_rel__new(
null, -- rel_id, default null
'membership_rel', -- object_type, default membership_rel
v_group_id, -- object_id_one
v_user_id, -- object_id_two
'approved', -- new__member_state, default approved
null, -- creation_user, default null
'0.0.0.0' -- creation_ip, default null
);
ELSE
RAISE NOTICE 'User % already member of group Employees', v_user_id;
END IF;
END LOOP;
RETURN 0;
END;$BODY$ language 'plpgsql';
select nav_import_employee ();
---------------------------------------------------------------------------------
-- Navision Price List
---------------------------------------------------------------------------------
drop function nav_import_pricelist ();
create or replace function nav_import_pricelist ()
returns integer as $BODY$
DECLARE
row RECORD;
v_counter integer;
v_price_id integer;
v_valid_p integer;
v_debug integer;
v_company_id integer;
v_project_id integer;
v_task_type_id integer;
v_subject_area_id integer;
v_source_language_id integer;
v_target_language_id integer;
v_uom_id integer;
v_file_type_id integer;
v_difficulty integer;
v_final_customer_id integer;
v_reuse_band_id integer;
v_activity_nr integer;
v_valid_from timestamptz;
v_valid_to timestamptz;
v_currency varchar;
BEGIN
v_counter := 0;
v_debug := 0;
FOR row IN
select *
from nav."Activities Price List" l,
nav."Item" i
where l."Activity No_" = i."No_"
LOOP
v_counter := v_counter + 1;
-- Get the company for the entry. At the moment only customers...
select company_id into v_company_id from im_companies
where nav_customer_nr = row."Partner No_";
IF v_company_id is null THEN
select company_id into v_company_id from im_companies
where nav_vendor_nr = row."Partner No_";
END IF;
-- Get the project for the entries. Project can be NULL
select project_id into v_project_id from im_projects
where nav_project_nr = row."Project No_";
-- Get the final company for the entry.
select company_id into v_final_customer_id from im_companies
where nav_customer_nr = row."Customer No_";
-- Get the Trans Task Type from ActivityGroup/SubActivity
select category_id into v_task_type_id from im_categories
where category = row."Activity Group" || '-' || row."Sub-Activity" and category_type = 'Intranet Translation Task Type';
-- Get the "Segment" (=Subject Area)
select category_id into v_subject_area_id from im_categories
where category = row."Segment" and category_type = 'Intranet Translation Subject Area';
-- Get the "Source Language"
select category_id into v_source_language_id from im_categories
where lower(category) = replace(lower(row."Source Language"),' ','_') and category_type = 'Intranet Translation Language';
-- Get the "Target Language"
select category_id into v_target_language_id from im_categories
where lower(category) = replace(lower(row."Target Language"),' ','_') and category_type = 'Intranet Translation Language';
-- Get the "UoM"
select category_id into v_uom_id from im_categories
where aux_string2 = row."Unit of Measure" and category_type = 'Intranet UoM';
-- Reuse Band
select category_id into v_reuse_band_id from im_categories
where aux_string2 = row."Price Type" and category_type = 'Navision Reuse Band';
v_valid_p := 1;
IF row."Partner No_" is not null AND v_company_id is null THEN
RAISE WARNING 'pricelist: company_id is null';
v_valid_p := 0;
END IF;
IF v_uom_id is null THEN
RAISE WARNING 'pricelist: uom_id is null';
v_valid_p := 0;
END IF;
IF v_task_type_id is null THEN
RAISE WARNING 'pricelist: task_type_id is null';
v_valid_p := 0;
END IF;
IF row."Segment" is not null AND row."Segment" != '' AND v_subject_area_id is null THEN
RAISE WARNING 'pricelist: subject_area_id is null';
v_valid_p := 0;
END IF;
IF row."Source Language" is not null AND v_source_language_id is null THEN
RAISE WARNING 'pricelist: source_language_id is null';
v_valid_p := 0;
END IF;
IF row."Target Language" is not null AND row."Target Language" != 'N/A' AND v_target_language_id is null THEN
RAISE WARNING 'pricelist: target_language is null';
v_valid_p := 0;
END IF;
IF row."Price Type" is not null AND v_reuse_band_id is null THEN
RAISE WARNING 'pricelist: reuse_band is null';
v_valid_p := 0;
END IF;
v_valid_from = row."Valid From";
v_valid_to = row."Valid To";
IF v_valid_to < '2000-01-01'::date THEN v_valid_to := '2010_12_31'::date; END IF;
v_currency = coalesce(row."Currency", 'ALL');
v_difficulty = row."Difficulty";
v_activity_nr = row."Activity No_";
IF trim(v_currency) = '' THEN v_currency := 'ALL'; END IF;
select price_id into v_price_id from im_trans_prices
where company_id = v_company_id and
coalesce(uom_id,0) = coalesce(v_uom_id,0) and
coalesce(project_id,0) = coalesce(v_project_id,0) and
coalesce(task_type_id,0) = coalesce(v_task_type_id,0) and
coalesce(target_language_id,0) = coalesce(v_target_language_id,0) and
coalesce(source_language_id,0) = coalesce(v_source_language_id,0) and
coalesce(subject_area_id,0) = coalesce(v_subject_area_id,0) and
coalesce(file_type_id,0) = coalesce(v_file_type_id,0) and
coalesce(currency,'AFA') = coalesce(v_currency,'AFA') and
coalesce(reuse_band_id,0) = coalesce(v_reuse_band_id,0) and
coalesce(difficulty,-1) = coalesce(v_difficulty,-1) and
coalesce(activity_nr,-1) = coalesce(v_activity_nr,-1) and
coalesce(final_customer_id,0) = coalesce(v_final_customer_id,0) and
coalesce(valid_from,'2000-01-01') = coalesce(v_valid_from,'2000-01-01') and
coalesce(valid_through,'2000-01-01') = coalesce(v_valid_to,'2000-01-01');
IF v_debug > 0 OR v_valid_p = 0 THEN
RAISE NOTICE 'pricelist #%: %=%, %=%, %=%, %=%, %=%, %=%, %=%, %=%, %=%, %=%, %=%, %=%, %=%, %=%',
v_counter,
row."Partner No_", v_company_id,
row."Project No_", v_project_id,
row."Activity Group" || '-' || row."Sub-Activity", v_task_type_id,
row."Unit of Measure", v_uom_id,
row."Currency", v_currency,
row."Activity No_", v_activity_nr,
row."Difficulty", v_difficulty,
row."Price Type", v_reuse_band_id,
row."Segment", v_subject_area_id,
row."Source Language", v_source_language_id,
row."Target Language", v_target_language_id,
row."Customer No_", v_final_customer_id,
row."Valid From"::date, v_valid_from::date,
row."Valid To"::date, v_valid_to::date
;
END IF;
-- Insert the price line
IF v_valid_p > 0 THEN
IF v_price_id is null THEN
INSERT INTO im_trans_prices (
price_id, uom_id,
company_id, task_type_id,
activity_nr,
target_language_id, source_language_id,
subject_area_id, file_type_id,
project_id, reuse_band_id,
difficulty, final_customer_id,
currency, price,
min_price, note,
valid_from, valid_through
) VALUES (
nextval('im_trans_prices_seq'), v_uom_id,
v_company_id, v_task_type_id,
v_activity_nr,
v_target_language_id, v_source_language_id,
v_subject_area_id, v_file_type_id,
v_project_id, v_reuse_band_id,
v_difficulty, v_final_customer_id,
v_currency, row."Price",
NULL, NULL,
v_valid_from, v_valid_to
);
ELSE
UPDATE im_trans_prices SET
uom_id = v_uom_id,
company_id = v_company_id,
task_type_id = v_task_type_id,
activity_nr = v_activity_nr,
target_language_id = v_target_language_id,
source_language_id = v_source_language_id,
subject_area_id = v_subject_area_id,
file_type_id = v_file_type_id,
project_id = v_project_id,
reuse_band_id = v_reuse_band_id,
difficulty = v_difficulty,
final_customer_id = v_final_customer_id,
currency = v_currency,
price = row."Price",
min_price = NULL,
note = NULL,
valid_from = v_valid_from,
valid_through = v_valid_to
WHERE price_id = v_price_id;
END IF;
END IF;
END LOOP;
RETURN 0;
END;$BODY$ language 'plpgsql';
select nav_import_pricelist();
---------------------------------------------------------------------------------
-- Navision Projects
---------------------------------------------------------------------------------
alter table nav."Job" alter column "Starting Date" drop not null;
alter table nav."Job" alter column "Ending Date" drop not null;
alter table nav."Job" alter column "Creation Date" drop not null;
alter table nav."Job" alter column "Delivery Date" drop not null;
alter table nav."Job" alter column "Closing Date" drop not null;
alter table nav."Job" alter column "Last Date" drop not null;
-- Replace garbage dates with NULL values in nav."Job":
update nav."Job" set "Starting Date" = null where "Starting Date" = '1753-01-01'::date;
update nav."Job" set "Ending Date" = null where "Ending Date" = '1753-01-01'::date;
update nav."Job" set "Creation Date" = null where "Creation Date" = '1753-01-01'::date;
update nav."Job" set "Delivery Date" = null where "Delivery Date" = '1753-01-01'::date;
update nav."Job" set "Closing Date" = null where "Closing Date" = '1753-01-01'::date;
update nav."Job" set "Last Date" = null where "Last Date" = '1753-01-01'::date;
drop function nav_import_project ();
create or replace function nav_import_project ()
returns integer as $body$
DECLARE
row RECORD;
v_counter integer;
v_exists_p integer;
v_duplicate_p integer;
v_project_id integer;
v_project_name varchar;
v_project_nr varchar;
v_project_status_id integer;
v_project_type_id integer;
v_customer_id integer;
v_note varchar;
v_bill_to_contact_id integer;
v_nav_project_manager_id integer;
v_nav_account_manager_id integer;
BEGIN
v_counter := 0;
FOR row IN
select *
from nav."Job"
order by "No_"
LOOP
v_counter := v_counter + 1;
------------------------ Name Fiddling ---------------------------------------------
-- Process the name in order to deal with duplicates.
-- ]po[ doesnt allow for duplicate project names.
-- By default just use the standard name
v_project_name := trim(row."Bill-to Name") || ' ' || trim(row."Description") || ' (' || row."No_" || ')';
v_project_nr := trim(lower(row."No_"));
------------------------ Status and Type ---------------------------------------------
RAISE NOTICE 'Processing #%: %', v_counter, v_project_name;
-- Default Type for project
v_project_type_id := import_cat('Translation Project', 'Intranet Project Type');
-- Status is set depending on the NAV status
v_project_status_id := import_cat('Open', 'Intranet Project Status');
IF 0 = row."Status" THEN v_project_status_id := import_cat('Inquiring', 'Intranet Project Status'); END IF;
IF 1 = row."Status" THEN v_project_status_id := import_cat('Quoting', 'Intranet Project Status'); END IF;
IF 2 = row."Status" THEN v_project_status_id := import_cat('Open', 'Intranet Project Status'); END IF;
IF 3 = row."Status" THEN v_project_status_id := import_cat('Closed', 'Intranet Project Status'); END IF;
-- set project to closed that are from 2008 or older
-- IF row."No_" < '2007' THEN
-- v_project_status_id := import_cat('Closed', 'Intranet Project Status');
-- END IF;
-- Start-date in 2008 or earlier
-- IF coalesce(row."Starting Date", row."Creation Date") < '2009-01-01'::date THEN
-- v_project_status_id := import_cat('Closed', 'Intranet Project Status');
-- END IF;
-- End-date in 2008 or earlier
-- IF coalesce(row."Ending Date", row."Delivery Date") < '2009-01-01'::date THEN
-- v_project_status_id := import_cat('Closed', 'Intranet Project Status');
-- END IF;
-- Blocked projects
IF row."Blocked" = 2 THEN
v_project_status_id := import_cat('Blocked', 'Intranet Project Status');
END IF;
-- Archived projects
IF row."Archived" > 0 THEN
v_project_status_id := import_cat('Archived', 'Intranet Project Status');
END IF;
------------------------ Customer ---------------------------------------------
select company_id into v_customer_id from im_companies
where nav_customer_nr = row."Bill-to Customer No_";
IF v_customer_id is null THEN
-- Check for the "internal" customer
IF row."Internal Project" = 1 THEN
select company_id into v_customer_id from im_companies
where company_path = 'internal';
END IF;
END IF;
IF v_customer_id is null THEN
RAISE WARNING 'Did not find customer #% for project #%', row."Bill-to Customer No_", row."No_";
continue;
END IF;
------------------------ New Project ------------------------------------
-- Check if the project is already there
select project_id into v_project_id from im_projects p
where p.nav_project_nr = row."No_";
-- Create a new project first, because the im_project.main_project_id is not null
IF v_project_id is null THEN
RAISE NOTICE 'Insert Project: %', v_project_name;
v_project_id := im_project__new (
NULL, -- project_id, NULL indicates to create new ID
'im_project', -- type of object to create, must be im_project
now(), -- date of creation - now
0, -- creation user - 0 is guest
'0.0.0.0', -- creation IP - any default
null, -- context_id - parent for permission inheritance - null
v_project_name, -- name of project, unique
v_project_nr, -- nr of project, unique
v_project_nr, -- path of project, unique
null, -- parent project - null means this is a main-project
v_customer_id, -- customer paying for the project
v_project_type_id, -- Type - sub-type for DynField field control
v_project_status_id -- Status - lifecylce control
);
END IF;
------------------------ Transform Fields ----------------------------------
-- Billing contact
select person_id into v_bill_to_contact_id from persons
where nav_contact_nr = row."Bill-to Contact No_";
IF v_bill_to_contact_id is null and coalesce(row."Bill-to Contact No_",'') != '' THEN
RAISE WARNING 'Did not find bill-to contact %', row."Bill-to Contact No_";
END IF;
-- Project Manager
select person_id into v_nav_project_manager_id from persons
where nav_employee_nr = row."Project Manager";
IF v_nav_project_manager_id is null and coalesce(row."Project Manager",'') != '' THEN
RAISE WARNING 'Did not find project manager %', row."Project Manager";
END IF;
-- Account Manager
select person_id into v_nav_account_manager_id from persons
where nav_employee_nr = row."Account Manager";
IF v_nav_account_manager_id is null and coalesce(row."Account Manager",'') != '' THEN
RAISE WARNING 'Did not find account manager %', row."Account Manager";
END IF;
-- Project Manager: Establish a im_biz_object_member relationship
-- between the project and the project manager as "Project Manager".
IF v_nav_project_manager_id is not null THEN
RAISE NOTICE 'Adding Project Manager for project: %', v_project_name;
PERFORM im_biz_object_member__new (
null,
'im_biz_object_member',
v_project_id, -- the business object
v_nav_project_manager_id, -- the person related to biz_object
1301, -- role: Project Manager
null, -- percentage
null, -- creation user
'0.0.0.0' -- creation IP
);
END IF;
IF v_nav_account_manager_id is not null THEN
RAISE NOTICE 'Adding Account Manager for project: %', v_project_name;
PERFORM im_biz_object_member__new (
null,
'im_biz_object_member',
v_project_id, -- the business object
v_nav_account_manager_id, -- the person related to biz_object
1301, -- role: Project Manager
null, -- percentage
null, -- creation user
'0.0.0.0' -- creation IP
);
END IF;
------------------------ Update Project ----------------------------------
RAISE NOTICE 'Update Project: %', v_project_name;
update im_projects set
project_name = v_project_name,
project_nr = v_project_nr,
project_path = v_project_nr,
parent_id = null,
company_id = v_customer_id,
project_status_id = v_project_status_id,
project_type_id = v_project_type_id,
project_lead_id = v_nav_project_manager_id,
supervisor_id = v_nav_account_manager_id,
company_contact_id = v_bill_to_contact_id,
start_date = coalesce(row."Starting Date", row."Creation Date"),
end_date = coalesce(row."Ending Date", row."Delivery Date"),
nav_delivery_date = row."Delivery Date",
nav_closing_date = row."Closing Date",
nav_last_date = row."Last Date",
note = v_note,
nav_project_nr = row."No_"
where project_id = v_project_id;
END LOOP;
RETURN 0;
END;$body$ language 'plpgsql';
select nav_import_project ();
--------------------------------------------------------------------------------
-- Check for users that are not included in Secure Access anymore
---------------------------------------------------------------------------------
-- Find out which users in po are not in Secure Access
--
drop function nav_prune_users();
create or replace function nav_prune_users ()
returns integer as $BODY$
DECLARE
row_user RECORD;
row_group RECORD;
v_count integer;
v_user_id integer;
BEGIN
v_count := 0;
FOR row_user IN
select *
from (select u.*,
auth.short_name as authority,
auth.short_name || '\\' || u.username as windows_login
from cc_users u,
auth_authorities auth
where u.authority_id = auth.authority_id and
u.member_state != 'banned'
) u
where
windows_login not in (
select lower(u."Loginname")
from sa."AR_User" u
)
and authority != 'local'
order by u.user_id
LOOP
v_count := v_count + 1;
RAISE NOTICE 'Disabling User #%: First=%, Last=%, Uname=%, Login=% => %',
v_count, row_user.first_names, row_user.last_name, row_user.username, row_user.windows_login, row_user.user_id;
update membership_rels
set member_state = 'banned'
where rel_id in (
select rel_id
from acs_rels
where object_id_one = -2 and
object_id_two = row_user.user_id
);
END LOOP;
RETURN 0;
END;$BODY$ language 'plpgsql';
select nav_prune_users ();
--------------------------------------------------------------------------------
-- Prune user grous
---------------------------------------------------------------------------------
-- Find out which users in po are not in Secure Access
--
drop function nav_prune_user_groups();
create or replace function nav_prune_user_groups ()
returns integer as $BODY$
DECLARE
row_user RECORD;
row_group RECORD;
v_count integer;
v_user_id integer;
BEGIN
v_count := 0;
FOR row_user IN
select *
from
(select u.*,
auth.short_name || '\\' || u.username as windows_login
from cc_users u,
auth_authorities auth
where u.authority_id = auth.authority_id
) u
where
windows_login not in (
select lower(u."Loginname")
from sa."AR_User" u
)
order by u.user_id
LOOP
v_count := v_count + 1;
RAISE NOTICE 'Processing User #%: First=%, Last=%, Login=%, Email=%', v_count, row_user.first_names, row_user.last_name, row_user.windows_login, row_user.email;
-- Delete the user from groups he is not a member of anymore
FOR row_group IN
select g.group_name,
r.rel_id
from acs_rels r, groups g, membership_rels mr
where r.rel_id = mr.rel_id and
r.object_id_one = g.group_id and
mr.member_state = 'approved' and
r.object_id_two = v_user_id and
g.group_name not in (
select sgm.po_group_name
from sa.view_ar_relationshipall_parent_valid var,
sa_group_mapping sgm
where var."ObjectName" = sgm.sa_group_name and
var."ChildObjectID" in (
-- build the union of all group memberships of all accounts
select "ObjectID"
from sa."AR_User"
where lower(trim("EmailAddress")) = v_email
)
) and
g.group_name not in ('Registered Users', 'The Public')
LOOP
RAISE NOTICE 'Deleting user % from group %', v_loginname, row_group.group_name;
-- Get the PO group_id
select group_id into v_group_id from groups where group_name = row_group.group_name;
RAISE NOTICE 'Deleting: user=%, group=%', v_user_id, v_group_id;
PERFORM membership_rel__delete(row_group.rel_id);
END LOOP;
END LOOP;
RETURN 0;
END;$BODY$ language 'plpgsql';
-- select nav_prune_user_groups ();
---------------------------------------------------------------------------------
-- Navision Receipts
---------------------------------------------------------------------------------
drop function nav_import_receipt ();
create or replace function nav_import_receipt ()
returns integer as $body$
DECLARE
row RECORD;
v_counter integer;
v_exists_p integer;
v_cost_id integer;
v_customer_id integer;
v_vendor_id integer;
v_project_id integer;
v_cost_type_id integer;
v_cost_status_id integer;
v_payment_days integer;
v_creation_user_id integer;
v_company_contact_id integer;
v_cost_center_id integer;
BEGIN
v_counter := 0;
FOR row IN
select *
from nav."IT$Purch_ Rcpt_ Header"
order by "No_"
LOOP
v_counter := v_counter + 1;
------------------------ Custome and Provider ---------------------------------------------
select company_id into v_vendor_id from im_companies
where nav_vendor_nr = row."Pay-to Vendor No_";
IF v_vendor_id is null THEN
RAISE WARNING 'Vendor % not found', row."Pay-to Vendor No_";
continue;
END IF;
select company_id into v_customer_id from im_companies
where company_path = 'internal';
------------------------ Default Values ---------------------------------------------
RAISE NOTICE 'Processing Receipt %: %', v_counter, row."No_";
v_cost_status_id := import_cat('Created', 'Intranet Cost Status');
v_cost_type_id := import_cat('Provider Receipt', 'Intranet Cost Type');
-- Creation user
select person_id into v_creation_user_id from persons
where nav_windows_login = lower(row."User ID");
-- Contact provider
select person_id into v_company_contact_id from persons
where lower(nav_contact_nr) ~ lower(row."Pay-to Contact No_");
-- Project
select project_id into v_project_id from im_projects
where nav_project_nr = row."Project No_";
-- Payment Conditions
v_payment_days := NULL;
IF row."Payment Terms Code" = '10_D' THEN v_payment_days := 10; END IF;
IF row."Payment Terms Code" = '14_D' THEN v_payment_days := 14; END IF;
IF row."Payment Terms Code" = '14_D_D' THEN v_payment_days := 14; END IF;
IF row."Payment Terms Code" = '20_D' THEN v_payment_days := 20; END IF;
IF row."Payment Terms Code" = '21_D' THEN v_payment_days := 21; END IF;
IF row."Payment Terms Code" = '30_D' THEN v_payment_days := 30; END IF;
IF row."Payment Terms Code" = '30_D_D' THEN v_payment_days := 30; END IF;
IF row."Payment Terms Code" = '45_D' THEN v_payment_days := 45; END IF;
IF row."Payment Terms Code" = '45_D_D' THEN v_payment_days := 45; END IF;
IF row."Payment Terms Code" = '60_D' THEN v_payment_days := 60; END IF;
IF row."Payment Terms Code" = '60_D_D' THEN v_payment_days := 60; END IF;
IF row."Payment Terms Code" = '75_D' THEN v_payment_days := 75; END IF;
IF row."Payment Terms Code" = '90_D' THEN v_payment_days := 90; END IF;
IF row."Payment Terms Code" = 'HALF_YEAR' THEN v_payment_days := 182; END IF;
IF row."Payment Terms Code" = '2_Y' THEN v_payment_days := 730; END IF;
IF row."Payment Terms Code" = 'IMM' THEN v_payment_days := 0; END IF;
IF row."Payment Terms Code" = 'UNDO' THEN v_payment_days := 10; END IF;
IF row."Payment Terms Code" = 'NEPLATIT' THEN v_payment_days := 10000; END IF;
-- make sure the currency code exists
select count(*) into v_exists_p from currency_codes
where iso = row."Currency Code";
IF v_exists_p = 0 THEN
RAISE WARNING 'Currency "%" does not exist for FinDoc: %', row."Currency Code", row."No_";
continue;
END IF;
------------------------ New Cost and Invoice ------------------------------------
-- Check if the cost item is already there
select cost_id into v_cost_id from im_costs c
where c.cost_name = row."No_";
IF v_cost_id is null THEN
RAISE NOTICE 'Insert Invoice: %', row."No_";
v_cost_id := im_invoice__new (
null, 'im_invoice', row."Document Date"::timestamptz, v_creation_user_id, '0.0.0.0', null,
row."No_", -- cost_nr
v_customer_id, -- customer
v_vendor_id, -- provider
null, -- customer contact
row."Order Date", -- effective_date
row."Currency Code", -- currency
null, -- template_id
v_cost_status_id, -- status_id
v_cost_type_id, -- type_id
null, -- payment_method_id
v_payment_days, -- payment_days
0.0, -- amount
null, -- vat
null, -- tax
null -- note
);
END IF;
update im_costs set
cost_name = row."No_",
cost_nr = v_cost_id::varchar,
customer_id = v_customer_id,
provider_id = v_vendor_id,
project_id = v_project_id,
effective_date = row."Order Date",
currency = row."Currency Code",
cost_status_id = v_cost_status_id,
cost_type_id = v_cost_type_id,
payment_days = v_payment_days,
amount = 0.0,
cost_center_id = v_cost_center_id,
tax = null,
vat = null,
nav_purchase_receipt_nr = row."No_"
where cost_id = v_cost_id;
update im_invoices set
company_contact_id = v_company_contact_id,
invoice_nr = row."No_",
payment_method_id = null
where invoice_id = v_cost_id;
END LOOP;
RETURN 0;
END;$body$ language 'plpgsql';
select nav_import_receipt ();
drop function nav_import_receipt_lines ();
create or replace function nav_import_receipt_lines ()
returns integer as $body$
DECLARE
row RECORD;
v_counter integer;
v_cost_id integer;
v_exists_p integer;
v_name varchar;
v_uom_id integer;
v_line_id integer;
v_currency_code varchar;
v_material_id integer;
v_amount numeric;
BEGIN
v_counter := 0;
FOR row IN
select *
from nav."IT$Purch_ Rcpt_ Line"
where "Document No_" in (select cost_name from im_costs)
order by "Document No_", "Line No_"
LOOP
v_counter := v_counter + 1;
------------------------ Financial Document ---------------------------------------------
select cost_id into v_cost_id from im_costs
where cost_name = row."Document No_";
IF v_cost_id is null THEN
RAISE WARNING 'FinDoc % not found', row."Document No_";
continue;
END IF;
select currency into v_currency_code from im_costs
where cost_id = v_cost_id;
------------------------ Transform Fields ------------------------------------
-- Unit of Measure
v_uom_id := import_cat ('Unit', 'Intranet UoM');
IF row."Unit of Measure" = 'hodina' THEN v_uom_id = import_cat ('Hour', 'Intranet UoM'); END IF;
IF row."Unit of Measure" = 'slovo' THEN v_uom_id = import_cat ('S-Word', 'Intranet UoM'); END IF;
IF row."Unit of Measure" = 'ks' THEN v_uom_id = import_cat ('Unit', 'Intranet UoM'); END IF;
IF row."Unit of Measure" = 'den' THEN v_uom_id = import_cat ('Day', 'Intranet UoM'); END IF;
IF row."Unit of Measure" = 'NS' THEN v_uom_id = import_cat ('Page', 'Intranet UoM'); END IF;
IF row."Unit of Measure" = 'strana' THEN v_uom_id = import_cat ('Page', 'Intranet UoM'); END IF;
IF row."Unit of Measure" = 'iNEW WORD' THEN v_uom_id = import_cat ('S-Word', 'Intranet UoM'); END IF;
IF row."Unit of Measure" = 'license' THEN v_uom_id = import_cat ('Unit', 'Intranet UoM'); END IF;
IF row."Unit of Measure" = 'znak' THEN v_uom_id = import_cat ('Unit', 'Intranet UoM'); END IF;
IF row."Unit of Measure" = 'kus' THEN v_uom_id = import_cat ('Unit', 'Intranet UoM'); END IF;
-- Name Generation
-- Names need to be unique in ]po[
v_name := coalesce(row."Description 2", row."Description");
v_name := v_name || ' (' || row."Source Language" || ' -> ' || row."Target Language" || ')';
-- Material
select material_id into v_material_id from im_materials
where material_nr = 'default';
------------------------ New Line ------------------------------------
-- Check for duplicated entries (i.e. names)
select count(*) into v_exists_p
from im_invoice_items
where item_name = v_name and
invoice_id = v_cost_id and
sort_order = row."Line No_" and
item_uom_id = v_uom_id;
IF v_exists_p > 1 THEN
RAISE WARNING 'Found more then one invoice line matching criteria for FinDoc: %', row."Document No_";
continue;
END IF;
select item_id into v_line_id
from im_invoice_items
where item_name = v_name and
invoice_id = v_cost_id and
sort_order = row."Line No_" and
item_uom_id = v_uom_id;
IF v_line_id is null THEN
RAISE NOTICE 'Insert Invoice Line for: %', row."Document No_";
v_line_id := nextval('im_invoice_items_seq');
insert into im_invoice_items (
item_id,
item_name,
invoice_id,
item_units,
item_uom_id,
price_per_unit,
currency,
sort_order,
item_type_id,
item_status_id,
description,
item_material_id
) values (
v_line_id,
v_name,
v_cost_id,
row."Quantity",
v_uom_id,
row."Direct Unit Cost",
v_currency_code,
row."Line No_",
null,
null,
null,
v_material_id
);
ELSE
RAISE NOTICE 'Update Invoice Line for: %', row."Document No_";
END IF;
update im_invoice_items set
item_name = v_name,
invoice_id = v_cost_id,
item_units = row."Quantity",
item_uom_id = v_uom_id,
price_per_unit = row."Direct Unit Cost",
currency = v_currency_code,
sort_order = row."Line No_",
item_type_id = null,
item_status_id = null,
description = null,
item_material_id = v_material_id
where item_id = v_line_id;
-- Update the amount of the invoice
select amount into v_amount from im_costs
where cost_id = v_cost_id;
v_amount := v_amount + row."Direct Unit Cost" * row."Quantity";
update im_costs set amount = v_amount
where cost_id = v_cost_id;
END LOOP;
RETURN 0;
END;$body$ language 'plpgsql';
select nav_import_receipt_lines ();
---------------------------------------------------------------------------------
-- Navision Vendors
---------------------------------------------------------------------------------
drop function nav_import_vendor ();
create or replace function nav_import_vendor ()
returns integer as $body$
DECLARE
row RECORD;
v_company_id integer;
v_office_id integer;
v_exists_p integer;
v_company_name varchar;
v_office_name varchar;
v_office_status_id integer;
v_office_type_id integer;
v_company_status_id integer;
v_company_type_id integer;
v_duplicate_p integer;
v_payment_days integer;
v_primary_contact_id integer;
v_note varchar;
v_parent_company_id integer;
v_nav_pm_id integer;
v_nav_account_manager_id integer;
v_country_code varchar;
v_counter integer;
BEGIN
v_counter := 0;
FOR row IN
select *
from nav."Vendor"
order by "No_"
LOOP
v_counter := v_counter + 1;
------------------------ Name Fiddling ---------------------------------------------
-- Process the name in order to deal with duplicates.
-- ]po[ doesnt allow for duplicate company or office names.
-- By default just use the standard name
v_company_name := row."Name";
-- Add the vendor no_ if the name is not unique within the NAV table
select count(*) into v_duplicate_p from nav."Vendor"
where lower("Name") = lower(v_company_name);
IF v_duplicate_p > 1 THEN
v_company_name := v_company_name || ' (' || row."No_" || ')';
END IF;
-- The office name is the company name + "Main Office".
v_office_name := v_company_name || ' Main Office';
------------------------ Default Values ---------------------------------------------
RAISE NOTICE 'Processing Vendor %: %', v_counter, v_company_name;
-- Default Status for company and office
v_office_status_id := import_cat('Active', 'Intranet Office Status');
v_office_type_id := import_cat('Main Office', 'Intranet Office Type');
v_company_status_id := import_cat('Active', 'Intranet Company Status');
v_company_type_id := import_cat('Provider', 'Intranet Company Type');
------------------------ New Office and Comany ------------------------------------
-- Check if the office is already there
select office_id into v_office_id from im_offices o
where lower(o.office_name) = lower(v_office_name);
IF v_office_id is null THEN
select office_id into v_office_id from im_offices o
where o.nav_vendor_nr = row."No_";
END IF;
-------------------------------------------------------------------------------------
-- Fix Country Codes
v_country_code := lower(row."Country_Region Code");
IF v_country_code = 'gb' THEN v_country_code := 'uk'; END IF;
IF v_country_code = '' THEN v_country_code := NULL; END IF;
select count(*) into v_exists_p
from country_codes where iso = v_country_code;
IF v_country_code is not null and v_exists_p < 1 THEN
RAISE WARNING 'Skipping (unknown country code %): %', v_country_code, v_office_name;
continue;
END IF;
-------------------------------------------------------------------------------------
-- Create a new office first, because the im_company.main_office_id is not null
IF v_office_id is null THEN
RAISE NOTICE 'Insert Office: %', v_office_name;
select count(*) into v_exists_p from im_offices
where lower(office_name) = lower(v_office_name);
IF v_exists_p > 0 THEN
v_office_name := v_office_name || ' (' || row."No_" || ')';
END IF;
v_office_id := im_office__new (
NULL, 'im_office', now()::date, 0, '0.0.0.0', null,
v_office_name, row."No_", v_office_type_id,
v_office_status_id, null
);
update im_offices set nav_vendor_nr = row."No_" where office_id = v_office_id;
END IF;
-- Check if the company is already there
select company_id into v_company_id from im_companies c
where c.nav_vendor_nr = row."No_";
IF v_company_id is null THEN
RAISE NOTICE 'Insert Company: %', v_company_name;
select count(*) into v_exists_p from im_companies
where lower(company_name) = lower(v_company_name);
IF v_exists_p > 0 THEN
v_company_name := v_company_name || ' (' || row."No_" || ')';
END IF;
v_company_id := im_company__new (
NULL, 'im_company', now()::date, 0, '0.0.0.0', null,
v_company_name, row."No_",
v_office_id, v_company_type_id, v_company_status_id
);
update im_companies set nav_vendor_nr = row."No_" where company_id = v_company_id;
END IF;
------------------------ Update Office and Comany----------------------------------
-- Conver Payment Terms Code
v_payment_days := NULL;
IF row."Payment Terms Code" = '10_D' THEN v_payment_days := 10; END IF;
IF row."Payment Terms Code" = '14_D' THEN v_payment_days := 14; END IF;
IF row."Payment Terms Code" = '14_D_D' THEN v_payment_days := 14; END IF;
IF row."Payment Terms Code" = '20_D' THEN v_payment_days := 20; END IF;
IF row."Payment Terms Code" = '21_D' THEN v_payment_days := 21; END IF;
IF row."Payment Terms Code" = '30_D' THEN v_payment_days := 30; END IF;
IF row."Payment Terms Code" = '30_D_D' THEN v_payment_days := 30; END IF;
IF row."Payment Terms Code" = '45_D' THEN v_payment_days := 45; END IF;
IF row."Payment Terms Code" = '45_D_D' THEN v_payment_days := 45; END IF;
IF row."Payment Terms Code" = '60_D' THEN v_payment_days := 60; END IF;
IF row."Payment Terms Code" = '60_D_D' THEN v_payment_days := 60; END IF;
IF row."Payment Terms Code" = '75_D' THEN v_payment_days := 75; END IF;
IF row."Payment Terms Code" = '90_D' THEN v_payment_days := 90; END IF;
IF row."Payment Terms Code" = 'HALF_YEAR' THEN v_payment_days := 182; END IF;
IF row."Payment Terms Code" = '2_Y' THEN v_payment_days := 730; END IF;
IF row."Payment Terms Code" = 'IMM' THEN v_payment_days := 0; END IF;
IF row."Payment Terms Code" = 'UNDO' THEN v_payment_days := 10; END IF;
IF row."Payment Terms Code" = 'NEPLATIT' THEN v_payment_days := 10000; END IF;
-- Add other fields to the "note" field
v_note := NULL;
IF row."Home Page" is not null AND row."Home Page" <> '' THEN v_note := v_note || 'Home Page=' || row."Home Page" ||', '; END IF;
IF row."VAT Bus_ Posting Group" is not null AND row."VAT Bus_ Posting Group" <> '' THEN v_note := v_note || 'VAT Bus Posting Group=' || row."VAT Bus_ Posting Group" || ', '; END IF;
IF row."Registration No_" is not null AND row."Registration No_" <> '' THEN v_note := v_note || 'Registration No_=' || row."Registration No_" ||', '; END IF;
IF row."Contact Text" is not null AND row."Contact Text" <> '' THEN v_note := v_note || 'Contact Text=' || row."Contact Text" ||', '; END IF;
IF row."Bank Account No_" is not null AND row."Bank Account No_" <> '' THEN v_note := v_note || 'Bank Account No_=' || row."Bank Account No_" ||', '; END IF;
-- Primary contact
select person_id into v_primary_contact_id from persons
where nav_contact_nr ~ row."Primary Contact No_";
IF v_primary_contact_id is null THEN
IF row."E-Mail" is not null AND row."E-Mail" <> '' THEN
v_primary_contact_id := lookup_user_email(row."E-Mail", 'nav_import_vendor.im_company.primary_contact_id');
END IF;
END IF;
-- Default Project Manager
select person_id into v_nav_pm_id from persons
where nav_employee_nr = row."Project Manager";
-- Parent Company
select company_id into v_parent_company_id from im_companies
where nav_vendor_nr = row."Mother Company";
RAISE NOTICE 'Update Office: %', v_office_name;
update im_offices set
office_name = v_office_name,
office_status_id = v_office_status_id,
office_type_id = v_office_type_id,
phone = row."Phone No_",
fax = row."Fax No_",
address_line1 = row."Address",
address_line2 = row."Address 2",
address_city = row."City",
address_country_code = v_country_code,
address_postal_code = row."Post Code",
nav_vendor_nr = row."No_"
where office_id = v_office_id;
RAISE NOTICE 'Update Company: %', v_company_name;
update im_companies set
company_name = v_company_name,
main_office_id = v_office_id,
company_status_id = v_company_status_id,
company_type_id = v_company_type_id,
vat_number = row."VAT Registration No_",
default_payment_days = v_payment_days,
primary_contact_id = v_primary_contact_id,
accounting_contact_id = v_primary_contact_id,
parent_company_id = v_parent_company_id,
note = v_note,
nav_vendor_posting_group = row."Vendor Posting Group",
nav_pm_percentage = row."PM %",
nav_vendor_nr = row."No_"
where company_id = v_company_id;
-- Account Manager: Establish a im_biz_object_member relationship
-- between the company and the account manager with as "Key Account".
select person_id into v_nav_account_manager_id from persons
where nav_employee_nr = row."Account Manager";
IF v_nav_account_manager_id is not null THEN
RAISE NOTICE 'Adding Account Manager for company: %', v_company_name;
PERFORM im_biz_object_member__new (
null,
'im_biz_object_member',
v_company_id, -- the business object
v_nav_account_manager_id, -- the person related to biz_object
1302, -- role: Key Account
null, -- percentage
null, -- creation user
'0.0.0.0' -- creation IP
);
END IF;
END LOOP;
RETURN 0;
END;$body$ language 'plpgsql';
select nav_import_vendor ();
# ----------------------------------------------------------
# Run all import scripts
# ----------------------------------------------------------
# Cleanup old log files
rm -f ~/log/import.*.log
# First import table extensions and categories
psql -f ~/packages/intranet-navision/sql/postgresql/nav-import.sql > ~/log/import.nav-import.log 2>&1
psql -f ~/packages/intranet-navision/sql/postgresql/nav-import-categories.sql > ~/log/import.nav-import-categories.log 2>&1
# Add users from Secure Access and Navision, and then delete the ones not in NAV or SA anymore
# Then import additional info about users including services and tools.
psql -f ~/packages/intranet-navision/sql/postgresql/sa-import-user.sql > ~/log/import.sa-import-user.log 2>&1
psql -f ~/packages/intranet-navision/sql/postgresql/nav-import-employees.sql > ~/log/import.nav-import-employees.log 2>&1
psql -f ~/packages/intranet-navision/sql/postgresql/nav-import-contacts.sql > ~/log/import.nav-import-contacts.log 2>&1
psql -f ~/packages/intranet-navision/sql/postgresql/nav-import-contacts-tools.sql > ~/log/import.nav-import-contacts-tools.log 2>&1
psql -f ~/packages/intranet-navision/sql/postgresql/nav-import-contacts-service.sql > ~/log/import.nav-import-contacts-service.log 2>&1
# Disabled while there is an issue with Secure Access import data containing wrong UTF-8 characters
# psql -f ~/packages/intranet-navision/sql/postgresql/nav-import-prune-users.sql > ~/log/import.nav-import-prune-users.log 2>&1
# Now come customer and provider companies
psql -f ~/packages/intranet-navision/sql/postgresql/nav-import-customer.sql > ~/log/import.nav-import-customer.log 2>&1
psql -f ~/packages/intranet-navision/sql/postgresql/nav-import-vendor.sql > ~/log/import.nav-import-vendor.log 2>&1
# Relationship between users and companies
psql -f ~/packages/intranet-navision/sql/postgresql/nav-import-contacts-business-relation.sql > ~/log/import.nav-import-contacts-business-relation.log 2>&1
# Projects require companies and users.
psql -f ~/packages/intranet-navision/sql/postgresql/nav-import-projects.sql > ~/log/import.nav-import-projects.log 2>&1
# Financial Document require projects and users
psql -f ~/packages/intranet-navision/sql/postgresql/nav-import-receipts.sql > ~/log/import.nav-import-receipts.log 2>&1
# The pricelist requires everything to be there and comes last.
psql -f ~/packages/intranet-navision/sql/postgresql/nav-import-pricelist.sql > ~/log/import.nav-import-pricelist.log 2>&1
---------------------------------------------------------------------------------
-- Update the data model
---------------------------------------------------------------------------------
drop trigger im_projects_calendar_update_tr on im_projects;
drop trigger im_forum_topics_calendar_update_tr on im_forum_topics;
-- Projects
alter table im_projects rename column nav_project_no to nav_project_no;
alter table im_projects add nav_project_nr text;
alter table im_projects add bill_to_contact_id integer references persons;
alter table im_projects add nav_delivery_date timestamptz;
alter table im_projects add nav_closing_date timestamptz;
alter table im_projects add nav_last_date timestamptz;
-- Create a check constraint on the project_path file to make
-- sure it is located on the /mnt/... share OR it is a relative path.
-- project_type_id=100 identified timesheet tasks, which are not
-- bound by these restrictions because they do not have a filestorage.
alter table im_projects add constraint im_project_path_ck check (
project_type_id = 100 OR
project_path ~ '^/mnt/.*$' OR
project_path ~ '^[a-zA-Z0-9_]*$'
);
-- Companies
alter table im_companies add parent_company_id integer;
alter table im_companies rename column nav_customer_no to nav_customer_nr;
alter table im_companies add nav_customer_nr text;
alter table im_companies rename column nav_vendor_no to nav_vendor_nr;
alter table im_companies add nav_vendor_nr text;
alter table im_companies add nav_customer_posting_group text;
alter table im_companies add nav_vendor_posting_group text;
alter table im_companies add nav_pm_percentage numeric(12,1);
alter table im_companies add nav_pm integer references persons;
alter table im_companies add nav_payment_terms integer;
alter table im_companies add nav_currency varchar;
alter table im_companies ADD COLUMN nav_name2 varchar(50);
alter table im_companies ADD COLUMN nav_gl_dimension_1 varchar(20);
alter table im_companies ADD COLUMN nav_blocked smallint;
alter table im_companies ADD COLUMN nav_payment_method integer;
alter table im_companies ADD COLUMN nav_gen_posting_group integer;
alter table im_companies ADD COLUMN nav_vat_posting_group integer;
alter table im_companies ADD COLUMN nav_minimal_tariff_pm numeric(38,20);
alter table im_companies ADD COLUMN nav_minimal_amount numeric(38,20);
alter table im_companies ADD COLUMN nav_division varchar(150);
alter table im_companies ADD COLUMN nav_line_discount_percentage numeric(12,1);
alter table im_companies ALTER COLUMN nav_customer_posting_group TYPE integer USING
lookup_category_id_from_aux_string2(nav_customer_posting_group::varchar, 'Navision General Posting Group'::varchar);
-- Offices
alter table im_offices rename column nav_customer_no to nav_customer_nr;
alter table im_offices add nav_customer_nr text;
alter table im_offices rename column nav_vendor_no to nav_vendor_nr;
alter table im_offices add nav_vendor_nr text;
-- Persons
alter table persons rename column nav_contact_no to nav_contact_nr;
alter table persons add nav_contact_nr varchar(20);
alter table persons rename column nav_employee_no to nav_employee_nr;
alter table persons add nav_employee_nr varchar(20);
alter table persons add nav_skype varchar;
alter table persons add nav_middle_name varchar;
alter table persons add nav_windows_login varchar;
alter table persons add nav_primary_contact_for_company_id integer;
-- Unique key for Secure Access
alter table persons add sa_object_id integer;
create unique index persons_sa_object_idx on persons (sa_object_id);
-- Fix old DynField definition
update acs_attributes set attribute_name = 'nav_project_nr' where attribute_name = 'navision_project_nr';
-- Costs
alter table im_costs add nav_sales_invoice_nr text;
alter table im_costs add nav_sales_quote_nr text;
alter table im_costs add nav_sales_delnote_nr text;
alter table im_costs add nav_purchase_invoice_nr text;
alter table im_costs add nav_purchase_po_nr text;
alter table im_costs add nav_purchase_receipt_nr text;
-- Categories extension table for Translation Task Types
create table im_categories_trans_task_ext (
category_id integer
constraint im_categories_trans_task_ext_pk
primary key
constraint im_categories_trans_task_ext_category_fk
references im_categories,
activity_code integer,
activity_group text,
sub_activity text,
reuse_band_id integer
constraint im_categories_trans_task_ext_reuse_band_fk
references im_categories,
difficulty integer,
description text,
without_pm_fee_p integer,
pm_fee_p integer
);
---------------------------------------------------------------------------------
-- Auxilary Functions and Helpers
---------------------------------------------------------------------------------
CREATE OR REPLACE FUNCTION nav.ms_getdate()
RETURNS timestamp without time zone AS 'SELECT LOCALTIMESTAMP'
LANGUAGE 'sql' VOLATILE;
-- Lookup a category in po and return the category_id
create or replace function import_cat (varchar, varchar)
returns integer as '
DECLARE
p_category alias for $1;
p_category_type alias for $2;
v_category_id integer;
BEGIN
SELECT c.category_id INTO v_category_id FROM im_categories c
WHERE lower(c.category) = lower(p_category)
AND lower(c.category_type) = lower(p_category_type);
IF v_category_id is null AND p_category is not null THEN
RAISE WARNING ''import_cat(%,%): Did not find category'', p_category, p_category_type;
END IF;
RETURN v_category_id;
END;' language 'plpgsql';
-- select import_cat('open','intranet project status');
-- Lookup the "primary key" (email or username) of a user into a user_id
create or replace function lookup_user_email (varchar, varchar)
returns integer as '
DECLARE
p_email alias for $1;
p_purpose alias for $2;
v_user_id integer;
BEGIN
IF p_email is null THEN return null; END IF;
IF p_email = '''' THEN return null; END IF;
SELECT p.party_id INTO v_user_id
FROM parties p
WHERE lower(p.email) = lower(p_email);
IF v_user_id is null THEN
SELECT u.user_id INTO v_user_id
FROM users u
WHERE lower(u.username) = lower(p_email);
END IF;
IF v_user_id is null THEN
RAISE WARNING ''lookup_user_email(%) for %: Did not find user'', p_email, p_purpose;
END IF;
RETURN v_user_id;
END;' language 'plpgsql';
-- Lookup the "primary key" (first_names + last_name) of a user into a user_id
create or replace function lookup_user_name (varchar, varchar, varchar)
returns integer as '
DECLARE
p_first_names alias for $1;
p_last_name alias for $2;
p_purpose alias for $3;
v_user_id integer;
BEGIN
IF p_first_names is null OR p_last_name is null THEN return null; END IF;
IF p_first_names = '''' OR p_last_name = '''' THEN return null; END IF;
SELECT p.person_id INTO v_user_id
FROM persons p
WHERE lower(p.first_names) = lower(p_first_names) and
lower(p.last_name) = lower(p_last_name);
IF v_user_id is null THEN
RAISE WARNING ''lookup_user_name(%) for % %: Did not find user'', p_first_names, p_last_name, p_purpose;
END IF;
RETURN v_user_id;
END;' language 'plpgsql';
---------------------------------------------------------------------------------
--Helper function im_category_id_from_aux_string2
---------------------------------------------------------------------------------
CREATE OR REPLACE FUNCTION lookup_category_id_from_aux_string2(varchar, varchar)
RETURNS integer AS $BODY$
DECLARE
p_aux2 alias for $1;
p_type alias for $2;
v_category_row RECORD;
BEGIN
SELECT category_id INTO v_category_row
FROM im_categories WHERE aux_string2 = p_aux2 AND category_type = p_type
LIMIT 1;
IF NOT FOUND THEN
RAISE WARNING 'lookup_category_id_from_aux_string2(%,%): Did not find category with specified aux_string2', p_aux2, p_type;
IF p_aux2 IS NULL OR p_aux2 = '' THEN
RETURN NULL;
ELSE
RETURN -1;
END IF;
ELSE
RETURN v_category_row.category_id;
END IF;
END; $BODY$ LANGUAGE 'plpgsql';
-- Function: timesheet_user__get_id(character varying, character varying)
-- DROP FUNCTION timesheet_user__get_id(character varying, character varying);
CREATE OR REPLACE FUNCTION timesheet_user__get_id(character varying, character varying)
RETURNS integer AS
$BODY$
DECLARE
p_user_name alias for $1;
p_email alias for $2;
v_user_id integer;
BEGIN
IF coalesce(p_user_name, '') = '' AND coalesce(p_email, '') = '' THEN
return NULL;
END IF;
SELECT o.object_id INTO v_user_id
FROM acs_objects o, parties pa, persons pe, users u
WHERE
o.object_id = pa.party_id AND
pa.party_id = pe.person_id AND
pe.person_id = u.user_id AND
(
(coalesce(p_user_name, '') <> '' AND u.username ~~* p_user_name)
OR (coalesce(p_email, '') <> '' AND pa.email ~~* p_email)
)
ORDER BY
pe.sa_object_id;
IF v_user_id IS NULL THEN
RAISE WARNING 'timesheet_user__get_id(''%'', ''%'') did not find user.', p_user_name, p_email;
END IF;
RETURN v_user_id;
END;$BODY$
LANGUAGE 'plpgsql' VOLATILE;
ALTER FUNCTION timesheet_user__get_id(character varying, character varying) OWNER TO postgres;
This diff is collapsed.
-- View: "timesheet_import"
-- DROP VIEW timesheet_import;
CREATE OR REPLACE VIEW timesheet_import AS
SELECT
d."Date"::timestamp with time zone AS "day",
fr."WorkTime"::numeric(7,4) AS hours,
rtrim(e."LoginName") AS username,
rtrim(e."MT_Email") AS email,
CASE
WHEN length(fr."ProjectID"::text) >= 8 THEN fr."ProjectID"::text
ELSE 'I'::text || lpad(fr."ProjectID"::text, 4, '0'::text)
END AS navision_project_nr,
p."InternalProject" AS project_internal
FROM
(SELECT raw."EmployeeID", raw."DateID", raw."ProjectID", sum(raw."WorkTime") AS "WorkTime"
FROM timesheet."TS_FactRow" raw
GROUP BY
raw."EmployeeID", raw."DateID", raw."ProjectID"
HAVING
sum(raw."WorkTime") > 0::numeric
) fr
JOIN timesheet."TS_Date" d ON fr."DateID" = d."DateID"
JOIN timesheet."TS_Employee" e ON fr."EmployeeID" = e."EmployeeID"
JOIN timesheet."TS_Project" p ON fr."ProjectID" = p."ProjectID"
;
-- Function: timesheet_import_routine()
-- DROP FUNCTION timesheet_import_routine();
CREATE OR REPLACE FUNCTION timesheet_import_routine()
RETURNS integer AS
$BODY$
DECLARE
row RECORD;
v_user_id integer;
v_project_id integer;
v_min_date timestamp with time zone;
v_count integer;
v_hours numeric;
BEGIN
-- Determine starting date for deleting entries
SELECT min(day) INTO v_min_date FROM timesheet_import;
-------------------------------------------------------------------
-- Deal with removed timesheet entries.
-- Search for those TS entries that are present in im_hours, but
-- not present (anymore...) in timesheet_import.
RAISE NOTICE 'timesheet-import-routine.sql: Starting to delete entries';
FOR row IN
select
h.day, h.project_id, h.user_id, h.cost_id
from
im_hours h,
im_projects p,
users u
where
h.day >= v_min_date and
h.project_id = p.project_id and
h.user_id = u.user_id and
not exists (
select *
from timesheet_import t
where p.nav_project_nr = t.navision_project_nr and
lower(u.username) = lower(t.username) and
h.day = t.day
)
LOOP
RAISE NOTICE 'timesheet-import-routine.sql: Deleting im_hours entry: user_id=%, project_id=%, day=%', row.user_id, row.project_id, row.day;
-- Deal with im_costs representing the timesheet cost.
-- Needs to be deleted before we can remove the im_hours entry.
UPDATE im_hours SET cost_id = NULL
WHERE cost_id = row.cost_id;
PERFORM im_cost__delete(row.cost_id);
DELETE from im_hours
WHERE day = row.day and
project_id = row.project_id and
user_id = row.user_id;
END LOOP;
-------------------------------------------------------------------
-- Import actual timesheet records
RAISE NOTICE 'timesheet-import-routine.sql: Starting to insert entries';
FOR row IN
SELECT * FROM timesheet_import
LOOP
v_user_id = timesheet_user__get_id(row.username, row.email);
IF v_user_id IS NULL THEN
RAISE WARNING 'timesheet-import-routine.sql: Did not find username % %', row.username, row.email;
CONTINUE;
END IF;
SELECT project_id INTO v_project_id FROM im_projects
WHERE nav_project_nr = row.navision_project_nr;
IF v_project_id IS NULL THEN
RAISE WARNING 'timesheet-import-routine.sql: Did not find project %', row.navision_project_nr;
CONTINUE;
END IF;
-- RAISE NOTICE 'timesheet-import-routine.sql: % %', row.username, row.email;
SELECT count(*) into v_count from im_hours
WHERE user_id = v_user_id and
project_id = v_project_id and
"day" = row."day";
IF v_count = 0 THEN
INSERT INTO im_hours(
user_id, project_id, "day", hours, note, internal_note, material_id
) VALUES (
v_user_id, v_project_id, row."day", row."hours", NULL, NULL, NULL
);
ELSE
-- Try to avoid updates, because updates trigger the
-- cost cache, which is a quite slow procedure.
SELECT hours into v_hours FROM im_hours
WHERE user_id = v_user_id and
project_id = v_project_id and
"day" = row."day";
IF v_hours != row.hours THEN
RAISE NOTICE 'timesheet-import-routine.sql: % %: Updating existing record', row.username, row.email;
UPDATE im_hours SET
hours = row.hours
WHERE user_id = v_user_id and
project_id = v_project_id and
"day" = row."day";
END IF;
END IF;
END LOOP;
RETURN 0;
END;$BODY$ LANGUAGE 'plpgsql' VOLATILE;
SELECT timesheet_import_routine();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment