diff --git a/apps/mappings/migrations/0011_auto_20231107_0720.py b/apps/mappings/migrations/0011_auto_20231107_0720.py new file mode 100644 index 00000000..b01d4a84 --- /dev/null +++ b/apps/mappings/migrations/0011_auto_20231107_0720.py @@ -0,0 +1,23 @@ +# Generated by Django 3.1.14 on 2023-11-07 07:20 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('mappings', '0010_auto_20231025_0915'), + ] + + operations = [ + migrations.AddField( + model_name='generalmapping', + name='department_id', + field=models.CharField(help_text='NetSuite Department id', max_length=255, null=True), + ), + migrations.AddField( + model_name='generalmapping', + name='department_name', + field=models.CharField(help_text='NetSuite Department name', max_length=255, null=True), + ), + ] diff --git a/apps/mappings/models.py b/apps/mappings/models.py index 9f1131d6..983d562b 100644 --- a/apps/mappings/models.py +++ b/apps/mappings/models.py @@ -27,26 +27,35 @@ class GeneralMapping(models.Model): General Mapping """ id = models.AutoField(primary_key=True) + location_name = models.CharField(max_length=255, help_text='NetSuite Location name', null=True) location_id = models.CharField(max_length=255, help_text='NetSuite Location id', null=True) location_level = models.CharField(max_length=255, help_text='Transaction Body, Line, Both', null=True) - accounts_payable_name = models.CharField(max_length=255, help_text='NetSuite Accounts Payable Account name', - null=True) + + accounts_payable_name = models.CharField(max_length=255, help_text='NetSuite Accounts Payable Account name', null=True) accounts_payable_id = models.CharField(max_length=255, help_text='NetSuite Accounts Payable Account id', null=True) - reimbursable_account_name = models.CharField(max_length=255, help_text='Reimbursable Expenses Account name', - null=True) + + reimbursable_account_name = models.CharField(max_length=255, help_text='Reimbursable Expenses Account name', null=True) reimbursable_account_id = models.CharField(max_length=255, help_text='Reimbursable Expenses Account id', null=True) + default_ccc_account_name = models.CharField(max_length=255, help_text='CCC Expenses Account name', null=True) default_ccc_account_id = models.CharField(max_length=255, help_text='CCC Expenses Account id', null=True) - vendor_payment_account_id = models.CharField(max_length=255, help_text='NetSuite VendorPayment Account id', - null=True) + use_employee_department = models.BooleanField(default=False, help_text='use employee department in netsuite') use_employee_class = models.BooleanField(default=False, help_text='use employee class in netsuite') use_employee_location = models.BooleanField(default=False, help_text='use employee location in netsuite') + + department_name = models.CharField(max_length=255, help_text='NetSuite Department name', null=True) + department_id = models.CharField(max_length=255, help_text='NetSuite Department id', null=True) department_level = models.CharField(max_length=255, help_text='Transaction Body, Line, Both', null=True) + + vendor_payment_account_id = models.CharField( + max_length=255, help_text='NetSuite VendorPayment Account id', null=True) vendor_payment_account_name = models.CharField(max_length=255, help_text='VendorPayment Account name', null=True) + default_ccc_vendor_id = models.CharField(max_length=255, help_text='Default CCC Vendor ID', null=True) default_ccc_vendor_name = models.CharField(max_length=255, help_text='Default CCC Vendor Name', null=True) + workspace = models.OneToOneField(Workspace, on_delete=models.PROTECT, help_text='Reference to Workspace model', related_name='general_mappings') created_at = models.DateTimeField(auto_now_add=True, help_text='Created at datetime') updated_at = models.DateTimeField(auto_now=True, help_text='Updated at datetime') diff --git a/apps/netsuite/connector.py b/apps/netsuite/connector.py index 60485701..38171c8e 100644 --- a/apps/netsuite/connector.py +++ b/apps/netsuite/connector.py @@ -1165,6 +1165,12 @@ def __construct_bill(self, bill: Bill, bill_lineitems: List[BillLineitem]) -> Di 'externalId': None, 'type': 'location' }, + 'department': { + 'name': None, + 'internalId': bill.department_id, + 'externalId': None, + 'type': 'department' + }, 'approvalStatus': None, 'nextApprover': None, 'vatRegNum': None, diff --git a/apps/netsuite/migrations/0023_bill_department_id.py b/apps/netsuite/migrations/0023_bill_department_id.py new file mode 100644 index 00000000..47e593d7 --- /dev/null +++ b/apps/netsuite/migrations/0023_bill_department_id.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1.14 on 2023-11-07 07:09 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('netsuite', '0022_creditcardcharge_department_id'), + ] + + operations = [ + migrations.AddField( + model_name='bill', + name='department_id', + field=models.CharField(help_text='NetSuite department id', max_length=255, null=True), + ), + ] diff --git a/apps/netsuite/models.py b/apps/netsuite/models.py index a397847b..e4181c45 100644 --- a/apps/netsuite/models.py +++ b/apps/netsuite/models.py @@ -334,6 +334,7 @@ class Bill(models.Model): accounts_payable_id = models.CharField(max_length=255, help_text='NetSuite Accounts Payable Account id') entity_id = models.CharField(max_length=255, help_text='NetSuite vendor id') subsidiary_id = models.CharField(max_length=255, help_text='NetSuite subsidiary id') + department_id = models.CharField(max_length=255, help_text='NetSuite department id', null=True) location_id = models.CharField(max_length=255, help_text='NetSuite Location id', null=True) currency = models.CharField(max_length=255, help_text='Bill Currency') memo = models.TextField(help_text='Bill Description') @@ -380,6 +381,8 @@ def create_bill(expense_group: ExpenseGroup): 'subsidiary_id': subsidiary_mappings.internal_id, 'accounts_payable_id': general_mappings.accounts_payable_id, 'entity_id': vendor_id, + 'department_id': general_mappings.department_id if general_mappings.department_level in [ + 'TRANSACTION_BODY', 'ALL'] else None, 'location_id': general_mappings.location_id if general_mappings.location_level in [ 'TRANSACTION_BODY', 'ALL'] else None, 'memo': 'Reimbursable expenses by {0}'.format(description.get('employee_email')) if @@ -464,6 +467,10 @@ def create_bill_lineitems(expense_group: ExpenseGroup, configuration: Configurat if employee_mapping and employee_mapping.destination_employee: if employee_mapping.destination_employee.detail.get('department_id'): department_id = employee_mapping.destination_employee.detail.get('department_id') + + if not department_id: + if general_mappings.department_id and general_mappings.department_level in ['TRANSACTION_LINE', 'ALL']: + department_id = general_mappings.department_id location_id = get_location_id_or_none(expense_group, lineitem) @@ -673,6 +680,10 @@ def create_credit_card_charge_lineitem(expense_group: ExpenseGroup, configuratio if employee_mapping.destination_employee.detail.get('department_id'): department_id = employee_mapping.destination_employee.detail.get('department_id') + if not department_id: + if general_mappings.department_id and general_mappings.department_level in ['TRANSACTION_LINE', 'ALL']: + department_id = general_mappings.department_id + location_id = get_location_id_or_none(expense_group, lineitem) if expense_group.fund_source == 'CCC' and general_mappings.use_employee_location and\ @@ -786,6 +797,9 @@ def create_expense_report(expense_group: ExpenseGroup): if general_mappings.use_employee_department and general_mappings.department_level in ( 'ALL', 'TRANSACTION_BODY') and employee_field_mapping == 'EMPLOYEE': department_id = employee_mapping.destination_employee.detail.get('department_id') + else: + department_id = general_mappings.department_id if general_mappings.department_level in [ + 'TRANSACTION_BODY', 'ALL'] else None if general_mappings.use_employee_location and general_mappings.location_level in ('ALL', 'TRANSACTION_BODY') \ and employee_field_mapping == 'EMPLOYEE': @@ -901,6 +915,10 @@ def create_expense_report_lineitems(expense_group: ExpenseGroup, configuration: else: department_id = get_department_id_or_none(expense_group, lineitem) + if not department_id: + if general_mappings.department_id and general_mappings.department_level in ['TRANSACTION_LINE', 'ALL']: + department_id = general_mappings.department_id + customer_id = get_customer_id_or_none(expense_group, lineitem) if general_mappings.use_employee_location and \ @@ -1129,6 +1147,10 @@ def create_journal_entry_lineitems(expense_group: ExpenseGroup, configuration: C elif expense_group.fund_source == 'PERSONAL': department_id = get_department_id_or_none(expense_group, lineitem) + if not department_id: + if general_mappings.department_id and general_mappings.department_level in ['TRANSACTION_LINE', 'ALL']: + department_id = general_mappings.department_id + if general_mappings.use_employee_location and general_mappings.location_level in ('ALL', 'TRANSACTION_LINE')\ and employee_field_mapping == 'EMPLOYEE'and employee_mapping and employee_mapping.destination_employee: location_id = employee_mapping.destination_employee.detail.get('location_id') diff --git a/tests/sql_fixtures/reset_db_fixtures/reset_db.sql b/tests/sql_fixtures/reset_db_fixtures/reset_db.sql index 9cdb94e4..e00398b6 100644 --- a/tests/sql_fixtures/reset_db_fixtures/reset_db.sql +++ b/tests/sql_fixtures/reset_db_fixtures/reset_db.sql @@ -2,8 +2,8 @@ -- PostgreSQL database dump -- --- Dumped from database version 15.2 (Debian 15.2-1.pgdg110+1) --- Dumped by pg_dump version 15.4 (Debian 15.4-2.pgdg100+1) +-- Dumped from database version 15.4 (Debian 15.4-2.pgdg120+1) +-- Dumped by pg_dump version 15.4 (Debian 15.4-2.pgdg120+1) SET statement_timeout = 0; SET lock_timeout = 0; @@ -221,7 +221,8 @@ CREATE TABLE public.bills ( transaction_date timestamp with time zone NOT NULL, payment_synced boolean NOT NULL, paid_on_netsuite boolean NOT NULL, - reference_number character varying(255) + reference_number character varying(255), + department_id character varying(255) ); @@ -294,7 +295,7 @@ ALTER SEQUENCE public.category_mappings_id_seq OWNED BY public.category_mappings CREATE TABLE public.configurations ( id integer NOT NULL, - reimbursable_expenses_object character varying(50) NOT NULL, + reimbursable_expenses_object character varying(50), corporate_credit_card_expenses_object character varying(50), created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL, @@ -1329,7 +1330,9 @@ CREATE TABLE public.general_mappings ( department_level character varying(255), use_employee_department boolean NOT NULL, use_employee_class boolean NOT NULL, - use_employee_location boolean NOT NULL + use_employee_location boolean NOT NULL, + department_id character varying(255), + department_name character varying(255) ); @@ -2432,7 +2435,7 @@ COPY public.bill_lineitems (id, account_id, location_id, department_id, class_id -- Data for Name: bills; Type: TABLE DATA; Schema: public; Owner: postgres -- -COPY public.bills (id, entity_id, accounts_payable_id, subsidiary_id, location_id, currency, memo, external_id, created_at, updated_at, expense_group_id, transaction_date, payment_synced, paid_on_netsuite, reference_number) FROM stdin; +COPY public.bills (id, entity_id, accounts_payable_id, subsidiary_id, location_id, currency, memo, external_id, created_at, updated_at, expense_group_id, transaction_date, payment_synced, paid_on_netsuite, reference_number, department_id) FROM stdin; \. @@ -7708,6 +7711,12 @@ COPY public.django_migrations (id, app, name, applied) FROM stdin; 163 django_q 0014_schedule_cluster 2023-07-17 14:43:54.845689+00 164 netsuite 0022_creditcardcharge_department_id 2023-07-26 10:31:38.187076+00 165 workspaces 0033_workspace_onboarding_state 2023-10-11 09:59:47.359324+00 +166 workspaces 0034_auto_20231012_0750 2023-11-07 07:21:37.223551+00 +167 workspaces 0035_auto_20231019_1025 2023-11-07 07:21:37.232972+00 +168 fyle 0026_auto_20231025_0913 2023-11-07 07:21:37.250979+00 +169 mappings 0010_auto_20231025_0915 2023-11-07 07:21:37.268291+00 +170 mappings 0011_auto_20231107_0720 2023-11-07 07:21:37.285191+00 +171 netsuite 0023_bill_department_id 2023-11-07 07:21:37.291269+00 \. @@ -11357,10 +11366,10 @@ COPY public.fyle_credentials (id, refresh_token, created_at, updated_at, workspa -- Data for Name: general_mappings; Type: TABLE DATA; Schema: public; Owner: postgres -- -COPY public.general_mappings (id, location_name, location_id, accounts_payable_name, accounts_payable_id, created_at, updated_at, workspace_id, default_ccc_account_id, default_ccc_account_name, reimbursable_account_id, reimbursable_account_name, default_ccc_vendor_id, default_ccc_vendor_name, vendor_payment_account_id, vendor_payment_account_name, location_level, department_level, use_employee_department, use_employee_class, use_employee_location) FROM stdin; -1 hubajuba 8 Accounts Payable 25 2021-11-15 08:56:31.432106+00 2021-11-15 13:21:26.113427+00 1 \N \N 118 Unapproved Expense Reports 1674 Ashwin Vendor \N \N TRANSACTION_BODY \N f f f -2 \N \N Accounts Payable 25 2021-11-16 04:18:39.195287+00 2021-11-16 04:18:39.195312+00 2 228 Aus Account 118 Unapproved Expense Reports 12104 Nilesh Aus Vendor \N \N \N \N f f f -3 hukiju 10 \N \N 2021-12-03 11:24:17.962764+00 2021-12-03 11:24:17.962809+00 49 228 Aus Account 228 Aus Account 12104 Nilesh Aus Vendor \N \N TRANSACTION_BODY \N f f f +COPY public.general_mappings (id, location_name, location_id, accounts_payable_name, accounts_payable_id, created_at, updated_at, workspace_id, default_ccc_account_id, default_ccc_account_name, reimbursable_account_id, reimbursable_account_name, default_ccc_vendor_id, default_ccc_vendor_name, vendor_payment_account_id, vendor_payment_account_name, location_level, department_level, use_employee_department, use_employee_class, use_employee_location, department_id, department_name) FROM stdin; +1 hubajuba 8 Accounts Payable 25 2021-11-15 08:56:31.432106+00 2021-11-15 13:21:26.113427+00 1 \N \N 118 Unapproved Expense Reports 1674 Ashwin Vendor \N \N TRANSACTION_BODY \N f f f \N \N +2 \N \N Accounts Payable 25 2021-11-16 04:18:39.195287+00 2021-11-16 04:18:39.195312+00 2 228 Aus Account 118 Unapproved Expense Reports 12104 Nilesh Aus Vendor \N \N \N \N f f f \N \N +3 hukiju 10 \N \N 2021-12-03 11:24:17.962764+00 2021-12-03 11:24:17.962809+00 49 228 Aus Account 228 Aus Account 12104 Nilesh Aus Vendor \N \N TRANSACTION_BODY \N f f f \N \N \. @@ -11587,7 +11596,7 @@ SELECT pg_catalog.setval('public.django_content_type_id_seq', 43, true); -- Name: django_migrations_id_seq; Type: SEQUENCE SET; Schema: public; Owner: postgres -- -SELECT pg_catalog.setval('public.django_migrations_id_seq', 165, true); +SELECT pg_catalog.setval('public.django_migrations_id_seq', 171, true); -- @@ -13049,6 +13058,14 @@ ALTER TABLE ONLY public.expense_filters ADD CONSTRAINT expense_filters_workspace_id_0ecd4914_fk_workspaces_id FOREIGN KEY (workspace_id) REFERENCES public.workspaces(id) DEFERRABLE INITIALLY DEFERRED; +-- +-- Name: expense_group_settings expense_group_settings_workspace_id_4c110bbe_fk_workspaces_id; Type: FK CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.expense_group_settings + ADD CONSTRAINT expense_group_settings_workspace_id_4c110bbe_fk_workspaces_id FOREIGN KEY (workspace_id) REFERENCES public.workspaces(id) DEFERRABLE INITIALLY DEFERRED; + + -- -- Name: expense_groups_expenses expense_groups_expen_expensegroup_id_c5b379a2_fk_expense_g; Type: FK CONSTRAINT; Schema: public; Owner: postgres -- @@ -13129,14 +13146,6 @@ ALTER TABLE ONLY public.fyle_credentials ADD CONSTRAINT fyle_credentials_workspace_id_52f7febf_fk_workspaces_id FOREIGN KEY (workspace_id) REFERENCES public.workspaces(id) DEFERRABLE INITIALLY DEFERRED; --- --- Name: expense_group_settings fyle_expensegroupset_workspace_id_98c370a1_fk_workspace; Type: FK CONSTRAINT; Schema: public; Owner: postgres --- - -ALTER TABLE ONLY public.expense_group_settings - ADD CONSTRAINT fyle_expensegroupset_workspace_id_98c370a1_fk_workspace FOREIGN KEY (workspace_id) REFERENCES public.workspaces(id) DEFERRABLE INITIALLY DEFERRED; - - -- -- Name: auth_tokens fyle_rest_auth_authtokens_user_id_3b4bd82e_fk_users_user_id; Type: FK CONSTRAINT; Schema: public; Owner: postgres -- diff --git a/tests/test_netsuite/fixtures.py b/tests/test_netsuite/fixtures.py index 38c9dd97..0431a0df 100644 --- a/tests/test_netsuite/fixtures.py +++ b/tests/test_netsuite/fixtures.py @@ -160,6 +160,12 @@ "externalId": None, "type": "location", }, + 'department': { + 'name': None, + 'internalId': None, + 'externalId': None, + 'type': 'department' + }, "approvalStatus": None, "nextApprover": None, "vatRegNum": None, @@ -301,6 +307,12 @@ "externalId": None, "type": "location", }, + 'department': { + 'name': None, + 'internalId': None, + 'externalId': None, + 'type': 'department' + }, "approvalStatus": None, "nextApprover": None, "vatRegNum": None, @@ -447,6 +459,12 @@ "externalId": None, "type": "location", }, + 'department': { + 'name': None, + 'internalId': None, + 'externalId': None, + 'type': 'department' + }, "approvalStatus": None, "nextApprover": None, "vatRegNum": None,